Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mobile 4331 #3737

Merged
merged 3 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
<preference name="GradlePluginGoogleServicesVersion" value="4.3.10" />
<preference name="GradlePluginKotlinVersion" value="1.7.21" />
<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="StatusBarBackgroundColor" value="#FFFFFF" />
<preference name="NavigationBarBackgroundColor" value="#FFFFFF" />
<feature name="StatusBar">
<param name="ios-package" onload="true" value="CDVStatusBar" />
</feature>
Expand Down
42 changes: 1 addition & 41 deletions cordova-plugin-moodleapp/src/android/SystemUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,7 @@ public class SystemUI extends CordovaPlugin {
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
dpalou marked this conversation as resolved.
Show resolved Hide resolved
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);
Expand All @@ -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);
}
}
});
}

}
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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": {},
Expand Down
34 changes: 31 additions & 3 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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-';
Expand Down Expand Up @@ -206,9 +207,39 @@ export class AppComponent implements OnInit, AfterViewInit {

this.logger.debug('Hide splash screen');
SplashScreen.hide();
this.setSystemUIColorsAfterSplash();
});
}

/**
dpalou marked this conversation as resolved.
Show resolved Hide resolved
* Set the system UI Colors after hiding the splash to ensure it's correct.
*
* @returns Promise resolved when done.
*/
protected async setSystemUIColorsAfterSplash(): Promise<void> {
// 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<void>();

const interval = window.setInterval(() => {
CoreApp.setSystemUIColors();
});
setTimeout(() => {
clearInterval(interval);
promise.resolve();

}, 1000);

return promise;
}

/**
* Async init function on platform ready.
*/
Expand Down Expand Up @@ -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();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/core/features/settings/services/settings-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ export class CoreSettingsHelperProvider {
CoreDomUtils.toggleModeClass('dark', enable, { includeLegacy: true });
this.darkModeObservable.next(enable);

CoreApp.setStatusBarColor();
CoreApp.setSystemUIColors();
}
}

Expand Down
12 changes: 5 additions & 7 deletions src/core/features/styles/services/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,7 @@ export class CoreStylesService {
this.disableStyleElement(style, true);
});

// Set StatusBar properties.
CoreApp.setStatusBarColor();
CoreApp.setSystemUIColors();
}

/**
Expand Down Expand Up @@ -341,7 +340,7 @@ export class CoreStylesService {
this.disableStyleElementByName(siteId, sourceName, false);
}

CoreApp.setStatusBarColor();
CoreApp.setSystemUIColors();
}
}

Expand Down Expand Up @@ -371,8 +370,7 @@ export class CoreStylesService {
}));

if (!disabled) {
// Set StatusBar properties.
CoreApp.setStatusBarColor();
CoreApp.setSystemUIColors();
}
}

Expand All @@ -390,7 +388,7 @@ export class CoreStylesService {
await this.setStyle(CoreStylesService.TMP_SITE_ID, handler, false, config);
}));

CoreApp.setStatusBarColor();
CoreApp.setSystemUIColors();
}

/**
Expand Down Expand Up @@ -438,7 +436,7 @@ export class CoreStylesService {
}
delete this.stylesEls[siteId];

CoreApp.setStatusBarColor();
CoreApp.setSystemUIColors();
}
}

Expand Down
49 changes: 37 additions & 12 deletions src/core/services/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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.
Expand All @@ -56,9 +57,14 @@ export class CoreAppProvider {
protected keyboardClosing = false;
protected redirect?: CoreRedirectData;
protected schemaVersionsTable = asyncInstance<CoreDatabaseTable<SchemaVersionsDBEntry, 'name'>>();
protected mainMenuListener?: CoreEventObserver;

constructor() {
this.logger = CoreLogger.getInstance('CoreAppProvider');
if (CorePlatform.isAndroid()) {
this.mainMenuListener =
CoreEvents.on(CoreMainMenuProvider.MAIN_MENU_VISIBILITY_UPDATED, () => this.setAndroidNavigationBarColor());
}
}

/**
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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.
*
Expand All @@ -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);
}

/**
Expand Down Expand Up @@ -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}`);

(<any> window).StatusBar.navigationBackgroundColorByHexString(color);
}

}

export const CoreApp = makeSingleton(CoreAppProvider);
Expand Down
19 changes: 19 additions & 0 deletions src/core/singletons/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

}
Loading