MOBILE-3635 settings: Improve color scheme preference detection
parent
05e6e48668
commit
8f1ea5c3ef
|
@ -6,7 +6,8 @@
|
||||||
"cannotsyncoffline": "Cannot synchronise offline.",
|
"cannotsyncoffline": "Cannot synchronise offline.",
|
||||||
"cannotsyncwithoutwifi": "Cannot synchronise because the current settings only allow to synchronise when connected to Wi-Fi. Please connect to a Wi-Fi network.",
|
"cannotsyncwithoutwifi": "Cannot synchronise because the current settings only allow to synchronise when connected to Wi-Fi. Please connect to a Wi-Fi network.",
|
||||||
"colorscheme": "Color Scheme",
|
"colorscheme": "Color Scheme",
|
||||||
"colorscheme-auto": "Auto (based on system settings)",
|
"colorscheme-system": "System default",
|
||||||
|
"colorscheme-system-notice": "System default mode will depend on your device support.",
|
||||||
"colorscheme-dark": "Dark",
|
"colorscheme-dark": "Dark",
|
||||||
"colorscheme-light": "Light",
|
"colorscheme-light": "Light",
|
||||||
"compilationinfo": "Compilation info",
|
"compilationinfo": "Compilation info",
|
||||||
|
|
|
@ -32,7 +32,8 @@
|
||||||
</ion-segment-button>
|
</ion-segment-button>
|
||||||
</ion-segment>
|
</ion-segment>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap core-settings-general-color-scheme" *ngIf="colorSchemes.length > 0">
|
<ion-item class="ion-text-wrap core-settings-general-color-scheme" *ngIf="colorSchemes.length > 0"
|
||||||
|
[lines]="selectedScheme=='system' && isAndroid ? 'none' : 'inset'">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ 'core.settings.colorscheme' | translate }}</h2>
|
<h2>{{ 'core.settings.colorscheme' | translate }}</h2>
|
||||||
<p *ngIf="colorSchemeDisabled" class="text-danger">{{ 'core.settings.forcedsetting' | translate }}</p>
|
<p *ngIf="colorSchemeDisabled" class="text-danger">{{ 'core.settings.forcedsetting' | translate }}</p>
|
||||||
|
@ -43,6 +44,9 @@
|
||||||
{{ 'core.settings.colorscheme-' + scheme | translate }}</ion-select-option>
|
{{ 'core.settings.colorscheme-' + scheme | translate }}</ion-select-option>
|
||||||
</ion-select>
|
</ion-select>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
<ion-item text-wrap *ngIf="colorSchemes.length > 0 && selectedScheme=='system' && isAndroid">
|
||||||
|
<ion-label><p>{{ 'core.settings.colorscheme-system-notice' | translate }}</p></ion-label>
|
||||||
|
</ion-item>
|
||||||
<ion-item class="ion-text-wrap">
|
<ion-item class="ion-text-wrap">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ 'core.settings.enablerichtexteditor' | translate }}</h2>
|
<h2>{{ 'core.settings.enablerichtexteditor' | translate }}</h2>
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { CoreLang } from '@services/lang';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
|
import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
|
||||||
import { CoreSettingsHelper, CoreColorScheme, CoreZoomLevel } from '../../services/settings-helper';
|
import { CoreSettingsHelper, CoreColorScheme, CoreZoomLevel } from '../../services/settings-helper';
|
||||||
|
import { CoreApp } from '@services/app';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays the general settings.
|
* Page that displays the general settings.
|
||||||
|
@ -42,6 +43,7 @@ export class CoreSettingsGeneralPage {
|
||||||
colorSchemes: CoreColorScheme[] = [];
|
colorSchemes: CoreColorScheme[] = [];
|
||||||
selectedScheme: CoreColorScheme = CoreColorScheme.LIGHT;
|
selectedScheme: CoreColorScheme = CoreColorScheme.LIGHT;
|
||||||
colorSchemeDisabled = false;
|
colorSchemeDisabled = false;
|
||||||
|
isAndroid = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.asyncInit();
|
this.asyncInit();
|
||||||
|
@ -72,14 +74,8 @@ export class CoreSettingsGeneralPage {
|
||||||
this.colorSchemes.push(CoreColorScheme.LIGHT);
|
this.colorSchemes.push(CoreColorScheme.LIGHT);
|
||||||
this.selectedScheme = this.colorSchemes[0];
|
this.selectedScheme = this.colorSchemes[0];
|
||||||
} else {
|
} else {
|
||||||
this.colorSchemes.push(CoreColorScheme.LIGHT);
|
this.isAndroid = CoreApp.isAndroid();
|
||||||
this.colorSchemes.push(CoreColorScheme.DARK);
|
this.colorSchemes = CoreSettingsHelper.getAllowedColorSchemes();
|
||||||
|
|
||||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches ||
|
|
||||||
window.matchMedia('(prefers-color-scheme: light)').matches) {
|
|
||||||
this.colorSchemes.push(CoreColorScheme.AUTO);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selectedScheme = await CoreConfig.get(CoreConstants.SETTINGS_COLOR_SCHEME, CoreColorScheme.LIGHT);
|
this.selectedScheme = await CoreConfig.get(CoreConstants.SETTINGS_COLOR_SCHEME, CoreColorScheme.LIGHT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ export interface CoreSiteSpaceUsage {
|
||||||
* Constants to define color schemes.
|
* Constants to define color schemes.
|
||||||
*/
|
*/
|
||||||
export const enum CoreColorScheme {
|
export const enum CoreColorScheme {
|
||||||
AUTO = 'auto',
|
SYSTEM = 'system',
|
||||||
LIGHT = 'light',
|
LIGHT = 'light',
|
||||||
DARK = 'dark',
|
DARK = 'dark',
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,7 @@ export class CoreSettingsHelperProvider {
|
||||||
|
|
||||||
protected syncPromises: { [s: string]: Promise<void> } = {};
|
protected syncPromises: { [s: string]: Promise<void> } = {};
|
||||||
protected prefersDark?: MediaQueryList;
|
protected prefersDark?: MediaQueryList;
|
||||||
|
protected colorSchemes: CoreColorScheme[] = [];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
if (!CoreConstants.CONFIG.forceColorScheme) {
|
if (!CoreConstants.CONFIG.forceColorScheme) {
|
||||||
|
@ -404,13 +405,37 @@ export class CoreSettingsHelperProvider {
|
||||||
document.documentElement.style.zoom = zoom + '%';
|
document.documentElement.style.zoom = zoom + '%';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get system allowed color schemes.
|
||||||
|
*
|
||||||
|
* @return Allowed color schemes.
|
||||||
|
*/
|
||||||
|
getAllowedColorSchemes(): CoreColorScheme[] {
|
||||||
|
if (this.colorSchemes.length > 0) {
|
||||||
|
return this.colorSchemes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CoreConstants.CONFIG.forceColorScheme) {
|
||||||
|
this.colorSchemes.push(CoreColorScheme.LIGHT);
|
||||||
|
this.colorSchemes.push(CoreColorScheme.DARK);
|
||||||
|
|
||||||
|
if (this.canIUsePrefersColorScheme()) {
|
||||||
|
this.colorSchemes.push(CoreColorScheme.SYSTEM);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.colorSchemes = [CoreConstants.CONFIG.forceColorScheme];
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.colorSchemes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set body color scheme.
|
* Set body color scheme.
|
||||||
*
|
*
|
||||||
* @param colorScheme Name of the color scheme.
|
* @param colorScheme Name of the color scheme.
|
||||||
*/
|
*/
|
||||||
setColorScheme(colorScheme: CoreColorScheme): void {
|
setColorScheme(colorScheme: CoreColorScheme): void {
|
||||||
if (colorScheme == CoreColorScheme.AUTO && this.prefersDark) {
|
if (colorScheme == CoreColorScheme.SYSTEM && this.prefersDark) {
|
||||||
// Listen for changes to the prefers-color-scheme media query.
|
// Listen for changes to the prefers-color-scheme media query.
|
||||||
this.prefersDark.addEventListener('change', this.toggleDarkModeListener);
|
this.prefersDark.addEventListener('change', this.toggleDarkModeListener);
|
||||||
|
|
||||||
|
@ -423,6 +448,18 @@ export class CoreSettingsHelperProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if device can detect color scheme system preference.
|
||||||
|
* https://caniuse.com/prefers-color-scheme
|
||||||
|
*
|
||||||
|
* @returns if the color scheme system preference is avalaible.
|
||||||
|
*/
|
||||||
|
canIUsePrefersColorScheme(): boolean {
|
||||||
|
// The following check will check browser support but system may differ from that.
|
||||||
|
// @todo Detect SO support to watch media query.
|
||||||
|
return window.matchMedia('(prefers-color-scheme)').media !== 'not all';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener function to toggle dark mode.
|
* Listener function to toggle dark mode.
|
||||||
*
|
*
|
||||||
|
|
|
@ -52,6 +52,15 @@ ion-item.ion-text-wrap ion-label {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@each $color-name, $value in $colors {
|
||||||
|
$value: map-get($colors, $color-name);
|
||||||
|
$base: map-get($value, base);
|
||||||
|
|
||||||
|
.text-#{$color-name},
|
||||||
|
p.text-#{$color-name} {
|
||||||
|
color: $base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ionic toolbar.
|
// Ionic toolbar.
|
||||||
ion-toolbar ion-back-button,
|
ion-toolbar ion-back-button,
|
||||||
|
@ -466,3 +475,8 @@ ion-button.core-button-select {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hide virtual utilities.
|
||||||
|
.core-browser-copy-area {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue