UNPKG

@nativescript-community/systemui

Version:

Provides API for changing the styles of SystemUI (StatusBar, NavigationBar...) on iOS.

274 lines 10.4 kB
import { Application, Frame, View } from '@nativescript/core'; import { SDK_VERSION } from '@nativescript/core/utils'; import { statusBarStyleProperty } from '@nativescript/core/ui/page'; import { applyMixins, cssNavigationBarColorProperty, cssNavigationBarStyleProperty, cssProperty, cssStatusBarColorProperty, keepScreenAwakeProperty, screenBrightnessProperty, screenOrientationProperty, statusBarHiddenProperty } from './index-common'; const isPostLollipop = SDK_VERSION >= 21; let defaultStatusBarHidden; const SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000; const SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR = 0x00000010; const FLAG_TRANSLUCENT_NAVIGATION = 0x08000000; const FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = 0x80000000; const SYSTEM_UI_FLAG_LAYOUT_STABLE = 0x00000100; const SYSTEM_UI_FLAG_VISIBLE = 0x00000000; const orientationConstants = { landscape: 6, portrait: 7, all: 10 }; let defaultOrientationValue; let overridenScreenOrientation; export async function setScreenOrientation(type) { const activity = Application.android.startActivity; if (!activity) { return; } if (defaultOrientationValue === undefined) { defaultOrientationValue = activity.getRequestedOrientation(); } type = type?.toLowerCase(); let requestedOrientationConstant = defaultOrientationValue; if (type && orientationConstants[type]) { requestedOrientationConstant = orientationConstants[type]; overridenScreenOrientation = requestedOrientationConstant; } activity.setRequestedOrientation(requestedOrientationConstant); } let currentScreenBrightness = -1; export async function setScreenBrightness(page, value) { const window = await getPageWindow(page); const params = window.getAttributes(); params.screenBrightness = currentScreenBrightness = value; window.setAttributes(params); } async function getPageWindow(view) { let topView = view.page; while (topView.parent || topView._dialogFragment) { if (topView._dialogFragment) { const dialog = topView._dialogFragment.getDialog(); if (dialog) { return dialog.getWindow(); } else { return new Promise((resolve) => { topView.once(View.shownModallyEvent, () => { resolve(topView._dialogFragment.getDialog().getWindow()); }); }); } } topView = topView.parent; } return topView._context.getWindow(); } class PageExtended { async [cssStatusBarColorProperty.setNative](color) { if (isPostLollipop) { const window = await getPageWindow(this); window.setStatusBarColor(color ? color.android : 0); } } async [cssNavigationBarColorProperty.setNative](color) { if (isPostLollipop) { const window = await getPageWindow(this); if (color) { window.addFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.setNavigationBarColor(color.android); } else { // window.clearFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.setNavigationBarColor(0); } } } async [cssNavigationBarStyleProperty.setNative](value) { if (isPostLollipop) { const window = await getPageWindow(this); const decorView = window.getDecorView(); let uiOptions = decorView.getSystemUiVisibility(); if (value === 'light') { window.addFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.clearFlags(FLAG_TRANSLUCENT_NAVIGATION); decorView.setSystemUiVisibility(uiOptions | SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); uiOptions = decorView.getSystemUiVisibility(); } else if (value === 'dark') { decorView.setSystemUiVisibility(uiOptions & ~SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); } else if (value === 'transparent') { window.addFlags(FLAG_TRANSLUCENT_NAVIGATION); decorView.setSystemUiVisibility(uiOptions & ~SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); } } } async [statusBarStyleProperty.setNative](value) { if (isPostLollipop) { const window = await getPageWindow(this); const decorView = window.getDecorView(); const uiOptions = decorView.getSystemUiVisibility(); if (value === 'light') { decorView.setSystemUiVisibility(uiOptions | SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); } else if (value === 'dark') { decorView.setSystemUiVisibility(uiOptions & ~SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); } else if (value === 'transparent') { decorView.setSystemUiVisibility(uiOptions | SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_VISIBLE); } else { decorView.setSystemUiVisibility(uiOptions | value); } } } async [keepScreenAwakeProperty.setNative](value) { const window = await getPageWindow(this); if (value) { window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } else { window.clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } async [screenBrightnessProperty.setNative](value) { setScreenBrightness(this, value); } async [screenOrientationProperty.setNative](value) { setScreenOrientation(value); } } __decorate([ cssProperty ], PageExtended.prototype, "navigationBarColor", void 0); __decorate([ cssProperty ], PageExtended.prototype, "statusBarColor", void 0); __decorate([ cssProperty ], PageExtended.prototype, "keepScreenAwake", void 0); __decorate([ cssProperty ], PageExtended.prototype, "screenBrightness", void 0); __decorate([ cssProperty ], PageExtended.prototype, "screenOrientation", void 0); function updatePagewSystemUI(page) { page.checkStatusBarVisibility(); // if (page.navigationBarColor) { page[cssNavigationBarColorProperty.setNative](page.navigationBarColor); // } if (page.navigationBarStyle) { page[cssNavigationBarStyleProperty.setNative](page.navigationBarStyle); } if (page.statusBarStyle) { page[statusBarStyleProperty.setNative](page.statusBarStyle); } if (page.statusBarColor) { page[cssStatusBarColorProperty.setNative](page.statusBarColor); } if (page.keepScreenAwake) { page[keepScreenAwakeProperty.setNative](page.keepScreenAwake); } if (page.screenBrightness) { page[screenBrightnessProperty.setNative](page.screenBrightness); } else if (currentScreenBrightness !== -1) { setScreenBrightness(page, -1); } if (page.screenOrientation) { setScreenOrientation(page.screenOrientation); } else if (overridenScreenOrientation) { setScreenOrientation(null); } } class PageExtended2 { async setStatusBarVisibility(value) { const window = await getPageWindow(this); const decorView = window.getDecorView(); const uiOptions = decorView.getSystemUiVisibility(); window.getDecorView().setSystemUiVisibility(value ? uiOptions | SYSTEM_UI_FLAG_VISIBLE : (uiOptions | 0x00000004) & ~SYSTEM_UI_FLAG_VISIBLE); } async checkStatusBarVisibility() { if (defaultStatusBarHidden === undefined) { const page = this; const view = page.parent ?? this; let window; const dialogFragment = view._dialogFragment; if (dialogFragment) { const dialog = dialogFragment.getDialog(); if (dialog) { window = dialog.getWindow(); } } window = window || page._context.getWindow(); if (window) { const rect = new android.graphics.Rect(); window.getDecorView().getWindowVisibleDisplayFrame(rect); defaultStatusBarHidden = rect.top === 0; } else { defaultStatusBarHidden = false; } } this.setStatusBarVisibility(!(this.statusBarHidden ?? defaultStatusBarHidden)); } async showStatusBar(animated) { this.setStatusBarVisibility(true); } async hideStatusBar(animated) { this.setStatusBarVisibility(false); } _raiseShowingModallyEvent() { updatePagewSystemUI(this); } _raiseShowingBottomSheetEvent() { updatePagewSystemUI(this); } _raiseClosingModallyEvent() { // if (this.keepScreenAwake) { // this[keepScreenAwakeProperty.setNative](0); // } const currentPage = Frame.topmost()?.currentPage; if (currentPage) { updatePagewSystemUI(currentPage); } } _raiseClosedBottomSheetEvent() { // if (this.keepScreenAwake) { // this[keepScreenAwakeProperty.setNative](0); // } const currentPage = Frame.topmost()?.currentPage; if (currentPage) { updatePagewSystemUI(currentPage); } } onNavigatingTo(context, isBackNavigation, bindingContext) { if (isBackNavigation) { updatePagewSystemUI(this); } } onNavigatingFrom(context, isBackNavigation, bindingContext) { // this wont get called for modals but not a big deal as the window is closed if (this.keepScreenAwake) { this[keepScreenAwakeProperty.setNative](0); } } async [statusBarHiddenProperty.setNative](value) { this.setStatusBarVisibility(value); } } __decorate([ cssProperty ], PageExtended2.prototype, "statusBarHidden", void 0); let mixinInstalled = false; export function overridePageBase() { const NSPage = require('@nativescript/core/ui/page').Page; applyMixins(NSPage, [PageExtended], { override: true }); applyMixins(NSPage, [PageExtended2], { after: true }); } export function installMixins() { if (!mixinInstalled) { mixinInstalled = true; overridePageBase(); } } //# sourceMappingURL=index.android.js.map