Skip to content

Commit

Permalink
MOBILE-4331 app: Change navigation bar color according to the theme
Browse files Browse the repository at this point in the history
  • Loading branch information
crazyserver committed Sep 4, 2023
1 parent 7f987f3 commit 2b8c178
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 24 deletions.
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
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
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();
});
}

/**
* 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);
}

}

0 comments on commit 2b8c178

Please sign in to comment.