From db020f18fe61a60c11272c1965b325dad10d2e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Fri, 9 Jun 2023 10:51:56 +0200 Subject: [PATCH 1/3] MOBILE-4331 app: Change navigation bar color according to the theme --- config.xml | 2 + package.json | 2 +- src/app/app.component.ts | 34 +++++++++++-- .../settings/services/settings-helper.ts | 2 +- src/core/features/styles/services/styles.ts | 12 ++--- src/core/services/app.ts | 49 ++++++++++++++----- src/core/singletons/colors.ts | 19 +++++++ 7 files changed, 96 insertions(+), 24 deletions(-) diff --git a/config.xml b/config.xml index fa90163595e..18f423f71c6 100644 --- a/config.xml +++ b/config.xml @@ -51,6 +51,8 @@ + + diff --git a/package.json b/package.json index eebb41b500d..a76b756bc4b 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,6 @@ "cordova-plugin-geolocation": "^4.1.0", "cordova-plugin-ionic-keyboard": "^2.2.0", "cordova-plugin-media-capture": "3.0.3", - "cordova-plugin-moodleapp": "file:cordova-plugin-moodleapp", "cordova-plugin-network-information": "^3.0.0", "cordova-plugin-prevent-override": "^1.0.1", "cordova-plugin-screen-orientation": "^3.0.2", @@ -161,6 +160,7 @@ "check-es-compat": "^1.1.1", "compare-versions": "^4.1.4", "concurrently": "^8.2.0", + "cordova-plugin-moodleapp": "file:cordova-plugin-moodleapp", "cross-env": "^7.0.3", "eslint": "^7.25.0", "eslint-config-prettier": "^8.3.0", diff --git a/src/app/app.component.ts b/src/app/app.component.ts index dafc3ff30e2..4f80053058f 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -34,6 +34,7 @@ import { CoreDom } from '@singletons/dom'; import { CorePlatform } from '@services/platform'; import { CoreUrl } from '@singletons/url'; import { CoreLogger } from '@singletons/logger'; +import { CorePromisedValue } from '@classes/promised-value'; const MOODLE_SITE_URL_PREFIX = 'url-'; const MOODLE_VERSION_PREFIX = 'version-'; @@ -206,9 +207,39 @@ export class AppComponent implements OnInit, AfterViewInit { this.logger.debug('Hide splash screen'); SplashScreen.hide(); + this.setSystemUIColorsAfterSplash(); }); } + /** + * Set the system UI Colors after hiding the splash to ensure it's correct. + * + * @returns Promise resolved when done. + */ + protected async setSystemUIColorsAfterSplash(): Promise { + // When the app starts and the splash is hidden, the color of the bars changes from transparent to black. + // We have to set the current color but we don't know when the change will be made. + // This problem is only related to Android, so on iOS it will be only set once. + if (!CorePlatform.isAndroid()) { + CoreApp.setSystemUIColors(); + + return; + } + + const promise = new CorePromisedValue(); + + const interval = window.setInterval(() => { + CoreApp.setSystemUIColors(); + }); + setTimeout(() => { + clearInterval(interval); + promise.resolve(); + + }, 1000); + + return promise; + } + /** * Async init function on platform ready. */ @@ -240,9 +271,6 @@ export class AppComponent implements OnInit, AfterViewInit { const isOnline = CoreNetwork.isOnline(); CoreDomUtils.toggleModeClass('core-offline', !isOnline, { includeLegacy: true }); - - // Set StatusBar properties. - CoreApp.setStatusBarColor(); } /** diff --git a/src/core/features/settings/services/settings-helper.ts b/src/core/features/settings/services/settings-helper.ts index 6e96f877432..b5fdf00ad0e 100644 --- a/src/core/features/settings/services/settings-helper.ts +++ b/src/core/features/settings/services/settings-helper.ts @@ -465,7 +465,7 @@ export class CoreSettingsHelperProvider { CoreDomUtils.toggleModeClass('dark', enable, { includeLegacy: true }); this.darkModeObservable.next(enable); - CoreApp.setStatusBarColor(); + CoreApp.setSystemUIColors(); } } diff --git a/src/core/features/styles/services/styles.ts b/src/core/features/styles/services/styles.ts index 3414d71c2d0..119730d1202 100644 --- a/src/core/features/styles/services/styles.ts +++ b/src/core/features/styles/services/styles.ts @@ -278,8 +278,7 @@ export class CoreStylesService { this.disableStyleElement(style, true); }); - // Set StatusBar properties. - CoreApp.setStatusBarColor(); + CoreApp.setSystemUIColors(); } /** @@ -341,7 +340,7 @@ export class CoreStylesService { this.disableStyleElementByName(siteId, sourceName, false); } - CoreApp.setStatusBarColor(); + CoreApp.setSystemUIColors(); } } @@ -371,8 +370,7 @@ export class CoreStylesService { })); if (!disabled) { - // Set StatusBar properties. - CoreApp.setStatusBarColor(); + CoreApp.setSystemUIColors(); } } @@ -390,7 +388,7 @@ export class CoreStylesService { await this.setStyle(CoreStylesService.TMP_SITE_ID, handler, false, config); })); - CoreApp.setStatusBarColor(); + CoreApp.setSystemUIColors(); } /** @@ -438,7 +436,7 @@ export class CoreStylesService { } delete this.stylesEls[siteId]; - CoreApp.setStatusBarColor(); + CoreApp.setSystemUIColors(); } } diff --git a/src/core/services/app.ts b/src/core/services/app.ts index 56263b14365..1b8f62d55e0 100644 --- a/src/core/services/app.ts +++ b/src/core/services/app.ts @@ -15,7 +15,7 @@ import { Injectable } from '@angular/core'; import { CoreDB } from '@services/db'; -import { CoreEvents } from '@singletons/events'; +import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb'; import { makeSingleton, Keyboard, StatusBar } from '@singletons'; @@ -31,6 +31,7 @@ import { CorePromisedValue } from '@classes/promised-value'; import { Subscription } from 'rxjs'; import { CorePlatform } from '@services/platform'; import { CoreNetwork, CoreNetworkConnection } from '@services/network'; +import { CoreMainMenuProvider } from '@features/mainmenu/services/mainmenu'; /** * Factory to provide some global functionalities, like access to the global app database. @@ -56,9 +57,14 @@ export class CoreAppProvider { protected keyboardClosing = false; protected redirect?: CoreRedirectData; protected schemaVersionsTable = asyncInstance>(); + protected mainMenuListener?: CoreEventObserver; constructor() { this.logger = CoreLogger.getInstance('CoreAppProvider'); + if (CorePlatform.isAndroid()) { + this.mainMenuListener = + CoreEvents.on(CoreMainMenuProvider.MAIN_MENU_VISIBILITY_UPDATED, () => this.setAndroidNavigationBarColor()); + } } /** @@ -200,7 +206,7 @@ export class CoreAppProvider { * @returns Store URL. */ getAppStoreUrl(storesConfig: CoreStoreConfig): string | undefined { - if (this.isIOS() && storesConfig.ios) { + if (CorePlatform.isIOS() && storesConfig.ios) { return 'itms-apps://itunes.apple.com/app/' + storesConfig.ios; } @@ -618,6 +624,14 @@ export class CoreAppProvider { return () => false; } + /** + * Set System UI Colors. + */ + setSystemUIColors(): void { + this.setStatusBarColor(); + this.setAndroidNavigationBarColor(); + } + /** * Set StatusBar color depending on platform. * @@ -635,16 +649,7 @@ export class CoreAppProvider { this.logger.debug(`Set status bar color ${color}`); - const useLightText = CoreColors.isWhiteContrastingBetter(color); - - // styleDefault will use white text on iOS when darkmode is on. Force the background to black. - if (this.isIOS() && !useLightText && window.matchMedia('(prefers-color-scheme: dark)').matches) { - StatusBar.backgroundColorByHexString('#000000'); - StatusBar.styleLightContent(); - } else { - StatusBar.backgroundColorByHexString(color); - useLightText ? StatusBar.styleLightContent() : StatusBar.styleDefault(); - } + StatusBar.backgroundColorByHexString(color); } /** @@ -684,6 +689,26 @@ export class CoreAppProvider { } } + /** + * Set NavigationBar color for Android + * + * @param color RGB color to use as background. If not set the css variable will be read. + */ + protected setAndroidNavigationBarColor(color?: string): void { + if (!CorePlatform.isAndroid()) { + return; + } + + if (!color) { + // Get the default color to change it. + color = CoreColors.getBottomPageBackgroundColor(); + } + + this.logger.debug(`Set navigation bar color ${color}`); + + ( window).StatusBar.navigationBackgroundColorByHexString(color); + } + } export const CoreApp = makeSingleton(CoreAppProvider); diff --git a/src/core/singletons/colors.ts b/src/core/singletons/colors.ts index 44affaa5909..806fffe7412 100644 --- a/src/core/singletons/colors.ts +++ b/src/core/singletons/colors.ts @@ -206,4 +206,23 @@ export class CoreColors { return CoreColors.getColorHex(color); } + /** + * Get the bottom page current background color. Bottom bar if shown or page background otherwise. + * + * @returns Color in hex format. + */ + static getBottomPageBackgroundColor(): string { + const element = document.querySelector('ion-tabs.placement-bottom:not(.tabshidden) ion-tab-bar.mainmenu-tabs'); + let color: string; + + if (element) { + color = getComputedStyle(element).getPropertyValue('--background').trim(); + } else { + // Fallback, it won't always work. + color = getComputedStyle(document.body).getPropertyValue('--ion-background-color').trim(); + } + + return CoreColors.getColorHex(color); + } + } From 7c97b6aedb2df2c1b900eb56ef6ea7ac3d85b51f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 29 Aug 2023 13:09:10 +0200 Subject: [PATCH 2/3] MOBILE-4331 app: Fork Statusbar plugin --- package-lock.json | 10 +++++----- package.json | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index f5dc1a5a421..ad06a7c1515 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4801,6 +4801,10 @@ "webrtc-adapter": "^3.1.4" } }, + "@moodlehq/cordova-plugin-statusbar": { + "version": "4.0.0-moodle.1", + "resolved": "git+https://github.com/moodlemobile/cordova-plugin-statusbar.git#5dfcf11cd262da2da466fab740291b434e3abba4" + }, "@moodlehq/cordova-plugin-zip": { "version": "3.1.0-moodle.1", "resolved": "https://registry.npmjs.org/@moodlehq/cordova-plugin-zip/-/cordova-plugin-zip-3.1.0-moodle.1.tgz", @@ -12175,6 +12179,7 @@ }, "cordova-plugin-moodleapp": { "version": "file:cordova-plugin-moodleapp", + "dev": true, "dependencies": { "chokidar-cli": { "version": "3.0.0", @@ -12224,11 +12229,6 @@ "resolved": "https://registry.npmjs.org/cordova-plugin-screen-orientation/-/cordova-plugin-screen-orientation-3.0.3.tgz", "integrity": "sha512-Dt8lO8BECZfE/pKbYQZ72Wr811fYMScxw7c9v/gJ3etOPCBrgl8xIHOOZu4nY2ehRyxFPtZi3VeGvIG+3DZoZQ==" }, - "cordova-plugin-statusbar": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cordova-plugin-statusbar/-/cordova-plugin-statusbar-3.0.0.tgz", - "integrity": "sha512-nzkeWeyLA6+1FryzO0aeB6NS8MZ45gnBYeq2VZqfdNbddZEgtpI4XPYdBVxvm9NhcVoJ3tdA1OBnQD9JryoV0Q==" - }, "cordova-plugin-wkuserscript": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cordova-plugin-wkuserscript/-/cordova-plugin-wkuserscript-1.0.1.tgz", diff --git a/package.json b/package.json index a76b756bc4b..293e624dd08 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,7 @@ "@moodlehq/cordova-plugin-ionic-webview": "5.0.0-moodle.2", "@moodlehq/cordova-plugin-local-notification": "0.9.0-moodle.11", "@moodlehq/cordova-plugin-qrscanner": "3.0.1-moodle.5", + "@moodlehq/cordova-plugin-statusbar": "4.0.0-moodle.1", "@moodlehq/cordova-plugin-zip": "3.1.0-moodle.1", "@moodlehq/ionic-native-push": "5.36.0-moodle.2", "@moodlehq/phonegap-plugin-push": "4.0.0-moodle.6", @@ -112,7 +113,6 @@ "cordova-plugin-network-information": "^3.0.0", "cordova-plugin-prevent-override": "^1.0.1", "cordova-plugin-screen-orientation": "^3.0.2", - "cordova-plugin-statusbar": "^3.0.0", "cordova-plugin-wkuserscript": "^1.0.1", "cordova-plugin-wkwebview-cookies": "^1.0.1", "cordova-sqlite-storage": "^6.1.0", @@ -229,7 +229,7 @@ "cordova-plugin-media-capture": {}, "cordova-plugin-network-information": {}, "@moodlehq/cordova-plugin-qrscanner": {}, - "cordova-plugin-statusbar": {}, + "@moodlehq/cordova-plugin-statusbar": {}, "cordova-plugin-wkuserscript": {}, "cordova-plugin-wkwebview-cookies": {}, "@moodlehq/cordova-plugin-zip": {}, From 701c71c6cbd9e9ee70ae4eaaf01b73c0d67fe221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 29 Aug 2023 13:09:33 +0200 Subject: [PATCH 3/3] MOBILE-4331 app: Remove status bar color from local plugin --- .../src/android/SystemUI.java | 42 +------------------ 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/cordova-plugin-moodleapp/src/android/SystemUI.java b/cordova-plugin-moodleapp/src/android/SystemUI.java index 217c72df9d3..ed20bd28aa5 100644 --- a/cordova-plugin-moodleapp/src/android/SystemUI.java +++ b/cordova-plugin-moodleapp/src/android/SystemUI.java @@ -32,11 +32,7 @@ public class SystemUI extends CordovaPlugin { public boolean execute(String action, JSONArray args, CallbackContext callbackContext) { try { switch (action) { - case "setNavigationBarColor": - this.setNavigationBarColor(args.getString(0)); - callbackContext.success(); - - return true; + // No actions yet. } } catch (Throwable e) { Log.e(TAG, "Failed executing action: " + action, e); @@ -45,41 +41,5 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo return false; } - private void setNavigationBarColor(String color) { - if (Build.VERSION.SDK_INT < 21) { - return; - } - - if (color == null || color.isEmpty()) { - return; - } - - Log.d(TAG, "Setting navigation bar color to " + color); - - this.cordova.getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - final int FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = 0x80000000; - final int SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR = 0x00000010; - final Window window = cordova.getActivity().getWindow(); - int uiOptions = window.getDecorView().getSystemUiVisibility(); - - uiOptions = uiOptions | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; - uiOptions = uiOptions & ~SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - - window.getDecorView().setSystemUiVisibility(uiOptions); - - try { - // Using reflection makes sure any 5.0+ device will work without having to compile with SDK level 21 - window.getClass().getDeclaredMethod("setNavigationBarColor", int.class).invoke(window, Color.parseColor(color)); - } catch (IllegalArgumentException ignore) { - Log.e(TAG, "Invalid hexString argument, use f.i. '#999999'"); - } catch (Exception ignore) { - // this should not happen, only in case Android removes this method in a version > 21 - Log.w(TAG, "Method window.setNavigationBarColor not found for SDK level " + Build.VERSION.SDK_INT); - } - } - }); - } }