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/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);
- }
- }
- });
- }
}
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 eebb41b500d..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",
@@ -109,11 +110,9 @@
"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",
- "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",
@@ -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",
@@ -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": {},
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);
+ }
+
}