commit
6f4d8a8440
|
@ -31,6 +31,7 @@
|
|||
<preference name="BackupWebStorage" value="none" />
|
||||
<preference name="ScrollEnabled" value="false" />
|
||||
<preference name="KeyboardDisplayRequiresUserAction" value="false" />
|
||||
<preference name="HideKeyboardFormAccessoryBar" value="false" />
|
||||
<preference name="AllowInlineMediaPlayback" value="true" />
|
||||
<preference name="LoadUrlTimeoutValue" value="60000" />
|
||||
<preference name="load-url-timeout" value="60000" />
|
||||
|
|
|
@ -86,14 +86,6 @@
|
|||
"forcedefaultlanguage": false,
|
||||
"privacypolicy": "https:\/\/moodle.net\/moodle-app-privacy\/",
|
||||
"notificoncolor": "#f98012",
|
||||
"statusbarbg": false,
|
||||
"statusbarlighttext": false,
|
||||
"statusbarbgios": "#f98012",
|
||||
"statusbarlighttextios": true,
|
||||
"statusbarbgandroid": "#df7310",
|
||||
"statusbarlighttextandroid": true,
|
||||
"statusbarbgremotetheme": "#000000",
|
||||
"statusbarlighttextremotetheme": true,
|
||||
"enableanalytics": false,
|
||||
"enableonboarding": true,
|
||||
"forceColorScheme": "",
|
||||
|
|
|
@ -6522,7 +6522,7 @@
|
|||
"integrity": "sha512-EYC5eQFVkoYXq39l7tYKE6lEjHJ04mvTmKXxGL7quHLdFPfJMNzru/UYpn92AOfpl3PQaZmou78C7EgmFOwFQQ=="
|
||||
},
|
||||
"cordova-plugin-wkuserscript": {
|
||||
"version": "git+https://github.com/moodlemobile/cordova-plugin-wkuserscript.git#6413f4bb3c2565f353e690b5c1450b69ad9e860e",
|
||||
"version": "git+https://github.com/moodlemobile/cordova-plugin-wkuserscript.git#aa77d0f98a3fb106f2e798e5adf5882f01a2c947",
|
||||
"from": "git+https://github.com/moodlemobile/cordova-plugin-wkuserscript.git"
|
||||
},
|
||||
"cordova-plugin-wkwebview-cookies": {
|
||||
|
|
|
@ -17,9 +17,16 @@ import { NavController } from '@ionic/angular';
|
|||
|
||||
import { CoreLangProvider } from '@services/lang';
|
||||
import { CoreLoginHelperProvider } from '@features/login/services/login.helper';
|
||||
import { CoreEvents, CoreEventSessionExpiredData } from '@singletons/events';
|
||||
import {
|
||||
CoreEvents,
|
||||
CoreEventSessionExpiredData,
|
||||
CoreEventSiteAddedData,
|
||||
CoreEventSiteData,
|
||||
CoreEventSiteUpdatedData,
|
||||
} from '@singletons/events';
|
||||
import { Network, NgZone, Platform } from '@singletons/core.singletons';
|
||||
import { CoreApp } from '@services/app';
|
||||
import { CoreSites } from '@services/sites';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
|
@ -37,6 +44,14 @@ export class AppComponent implements OnInit {
|
|||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*
|
||||
* @todo Review all old code to see if something is missing:
|
||||
* - IAB events listening.
|
||||
* - Platform pause/resume subscriptions.
|
||||
* - handleOpenURL and openWindowSafely.
|
||||
* - Screen orientation events (probably it can be removed).
|
||||
* - Back button registering to close modal first.
|
||||
* - Note: HideKeyboardFormAccessoryBar has been moved to config.xml.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
CoreEvents.on(CoreEvents.LOGOUT, () => {
|
||||
|
@ -55,9 +70,59 @@ export class AppComponent implements OnInit {
|
|||
this.loginHelper.sessionExpired(data);
|
||||
});
|
||||
|
||||
// Listen for passwordchange and usernotfullysetup events to open InAppBrowser.
|
||||
CoreEvents.on(CoreEvents.PASSWORD_CHANGE_FORCED, (data: CoreEventSiteData) => {
|
||||
this.loginHelper.passwordChangeForced(data.siteId!);
|
||||
});
|
||||
CoreEvents.on(CoreEvents.USER_NOT_FULLY_SETUP, (data: CoreEventSiteData) => {
|
||||
this.loginHelper.openInAppForEdit(data.siteId!, '/user/edit.php', 'core.usernotfullysetup');
|
||||
});
|
||||
|
||||
// Listen for sitepolicynotagreed event to accept the site policy.
|
||||
CoreEvents.on(CoreEvents.SITE_POLICY_NOT_AGREED, (data: CoreEventSiteData) => {
|
||||
this.loginHelper.sitePolicyNotAgreed(data.siteId);
|
||||
});
|
||||
|
||||
CoreEvents.on(CoreEvents.LOGIN, async (data: CoreEventSiteData) => {
|
||||
if (data.siteId) {
|
||||
const site = await CoreSites.instance.getSite(data.siteId);
|
||||
const info = site.getInfo();
|
||||
if (info) {
|
||||
// Add version classes to body.
|
||||
this.removeVersionClass();
|
||||
this.addVersionClass(CoreSites.instance.getReleaseNumber(info.release || ''));
|
||||
}
|
||||
}
|
||||
|
||||
this.loadCustomStrings();
|
||||
});
|
||||
|
||||
CoreEvents.on(CoreEvents.SITE_UPDATED, (data: CoreEventSiteUpdatedData) => {
|
||||
if (data.siteId == CoreSites.instance.getCurrentSiteId()) {
|
||||
this.loadCustomStrings();
|
||||
|
||||
// Add version classes to body.
|
||||
this.removeVersionClass();
|
||||
this.addVersionClass(CoreSites.instance.getReleaseNumber(data.release || ''));
|
||||
}
|
||||
});
|
||||
|
||||
CoreEvents.on(CoreEvents.SITE_ADDED, (data: CoreEventSiteAddedData) => {
|
||||
if (data.siteId == CoreSites.instance.getCurrentSiteId()) {
|
||||
this.loadCustomStrings();
|
||||
|
||||
// Add version classes to body.
|
||||
this.removeVersionClass();
|
||||
this.addVersionClass(CoreSites.instance.getReleaseNumber(data.release || ''));
|
||||
}
|
||||
});
|
||||
|
||||
this.onPlatformReady();
|
||||
}
|
||||
|
||||
/**
|
||||
* Async init function on platform ready.
|
||||
*/
|
||||
protected async onPlatformReady(): Promise<void> {
|
||||
await Platform.instance.ready();
|
||||
|
||||
|
@ -81,6 +146,19 @@ export class AppComponent implements OnInit {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Set StatusBar properties.
|
||||
CoreApp.instance.setStatusBarColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load custom lang strings. This cannot be done inside the lang provider because it causes circular dependencies.
|
||||
*/
|
||||
protected loadCustomStrings(): void {
|
||||
const currentSite = CoreSites.instance.getCurrentSite();
|
||||
if (currentSite) {
|
||||
this.langProvider.loadCustomStringsFromSite(currentSite);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,13 +20,10 @@ import { CoreSearchComponentsModule } from './components/components.module';
|
|||
import { SITE_SCHEMA } from './services/search-history-db';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
],
|
||||
imports: [
|
||||
CoreSearchComponentsModule,
|
||||
],
|
||||
providers: [
|
||||
CoreSearchComponentsModule,
|
||||
{ provide: CORE_SITE_SCHEMAS, useValue: [SITE_SCHEMA], multi: true },
|
||||
],
|
||||
})
|
||||
|
|
|
@ -26,6 +26,7 @@ import { CoreConstants } from '@/core/constants';
|
|||
import { makeSingleton, Keyboard, Network, StatusBar, Platform, Device } from '@singletons/core.singletons';
|
||||
import { CoreLogger } from '@singletons/logger';
|
||||
import { DBNAME, SCHEMA_VERSIONS_TABLE_NAME, SCHEMA_VERSIONS_TABLE_SCHEMA, SchemaVersionsDBEntry } from '@services/app.db';
|
||||
import { CoreColors } from '../singletons/colors';
|
||||
|
||||
/**
|
||||
* Factory to provide some global functionalities, like access to the global app database.
|
||||
|
@ -611,43 +612,35 @@ export class CoreAppProvider {
|
|||
|
||||
/**
|
||||
* Set StatusBar color depending on platform.
|
||||
*
|
||||
* @param color RGB color to use as status bar background. If not set the css variable will be read.
|
||||
*/
|
||||
setStatusBarColor(): void {
|
||||
if (typeof CoreConstants.CONFIG.statusbarbgios == 'string' && this.isIOS()) {
|
||||
// IOS Status bar properties.
|
||||
StatusBar.instance.overlaysWebView(false);
|
||||
StatusBar.instance.backgroundColorByHexString(CoreConstants.CONFIG.statusbarbgios);
|
||||
CoreConstants.CONFIG.statusbarlighttextios ? StatusBar.instance.styleLightContent() : StatusBar.instance.styleDefault();
|
||||
} else if (typeof CoreConstants.CONFIG.statusbarbgandroid == 'string' && this.isAndroid()) {
|
||||
// Android Status bar properties.
|
||||
StatusBar.instance.backgroundColorByHexString(CoreConstants.CONFIG.statusbarbgandroid);
|
||||
CoreConstants.CONFIG.statusbarlighttextandroid ?
|
||||
StatusBar.instance.styleLightContent() : StatusBar.instance.styleDefault();
|
||||
} else if (typeof CoreConstants.CONFIG.statusbarbg == 'string') {
|
||||
// Generic Status bar properties.
|
||||
this.isIOS() && StatusBar.instance.overlaysWebView(false);
|
||||
StatusBar.instance.backgroundColorByHexString(CoreConstants.CONFIG.statusbarbg);
|
||||
CoreConstants.CONFIG.statusbarlighttext ? StatusBar.instance.styleLightContent() : StatusBar.instance.styleDefault();
|
||||
} else {
|
||||
// Default Status bar properties.
|
||||
this.isAndroid() ? StatusBar.instance.styleLightContent() : StatusBar.instance.styleDefault();
|
||||
setStatusBarColor(color?: string): void {
|
||||
if (!color) {
|
||||
// Get the default color to reset it.
|
||||
color = getComputedStyle(document.documentElement).getPropertyValue('--ion-statusbar-background').trim();
|
||||
}
|
||||
|
||||
// Make darker on Android.
|
||||
if (this.isAndroid()) {
|
||||
color = CoreColors.darker(color);
|
||||
}
|
||||
|
||||
const useLightText = CoreColors.isWhiteContrastingBetter(color);
|
||||
const statusBar = StatusBar.instance;
|
||||
statusBar.backgroundColorByHexString(color);
|
||||
useLightText ? statusBar.styleLightContent() : statusBar.styleDefault();
|
||||
|
||||
this.isIOS() && statusBar.overlaysWebView(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset StatusBar color if any was set.
|
||||
*
|
||||
* @deprecated Use setStatusBarColor passing the color of the new statusbar color loaded on remote theme or no color to reset.
|
||||
*/
|
||||
resetStatusBarColor(): void {
|
||||
if (typeof CoreConstants.CONFIG.statusbarbgremotetheme == 'string' &&
|
||||
((typeof CoreConstants.CONFIG.statusbarbgios == 'string' && this.isIOS()) ||
|
||||
(typeof CoreConstants.CONFIG.statusbarbgandroid == 'string' && this.isAndroid()) ||
|
||||
typeof CoreConstants.CONFIG.statusbarbg == 'string')) {
|
||||
// If the status bar has been overriden and there's a fallback color for remote themes, use it now.
|
||||
this.isIOS() && StatusBar.instance.overlaysWebView(false);
|
||||
StatusBar.instance.backgroundColorByHexString(CoreConstants.CONFIG.statusbarbgremotetheme);
|
||||
CoreConstants.CONFIG.statusbarlighttextremotetheme ?
|
||||
StatusBar.instance.styleLightContent() : StatusBar.instance.styleDefault();
|
||||
}
|
||||
this.setStatusBarColor();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,6 +21,7 @@ import { CoreConfig } from '@services/config';
|
|||
import { makeSingleton, Translate, Platform } from '@singletons/core.singletons';
|
||||
|
||||
import * as moment from 'moment';
|
||||
import { CoreSite } from '../classes/site';
|
||||
|
||||
/*
|
||||
* Service to handle language features, like changing the current language.
|
||||
|
@ -311,6 +312,19 @@ export class CoreLangProvider {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads custom strings obtained from site.
|
||||
*
|
||||
* @param currentSite Current site object.
|
||||
*/
|
||||
loadCustomStringsFromSite(currentSite: CoreSite): void {
|
||||
const customStrings = currentSite.getStoredConfig('tool_mobile_customlangstrings');
|
||||
|
||||
if (typeof customStrings != 'undefined') {
|
||||
this.loadCustomStrings(customStrings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load certain custom strings.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* Color components contained within a rgb color.
|
||||
*/
|
||||
interface ColorComponents {
|
||||
red: number; // Red component of an RGB color [0-255].
|
||||
green: number; // Green component of an RGB color [0-255].
|
||||
blue: number; // Blue component of an RGB color [0-255].
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton with helper functions for colors.
|
||||
*/
|
||||
export class CoreColors {
|
||||
|
||||
/**
|
||||
* Returns better contrast color.
|
||||
*
|
||||
* @param color Black or white texts.
|
||||
* @return True if white contrasts better than black. False otherwise.
|
||||
*/
|
||||
static isWhiteContrastingBetter(color: string): boolean {
|
||||
return CoreColors.luma(color) < 165;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the same color 10% darker to be used as status bar on Android.
|
||||
*
|
||||
* @param color Color to get darker.
|
||||
* @return Darker Hex RGB color.
|
||||
*/
|
||||
static darker(color: string, percent: number = 10): string {
|
||||
percent = 1 - (percent / 100);
|
||||
const components = CoreColors.hexToRGB(color);
|
||||
components.red = Math.floor(components.red * percent) ;
|
||||
components.green = Math.floor(components.green * percent) ;
|
||||
components.blue = Math.floor(components.blue * percent) ;
|
||||
|
||||
return CoreColors.RGBToHex(components);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the luma of a color.
|
||||
*
|
||||
* @param color Hex RGB color.
|
||||
* @return Luma number based on SMPTE C, Rec. 709 weightings.
|
||||
*/
|
||||
protected static luma(color: string): number {
|
||||
const rgb = CoreColors.hexToRGB(color);
|
||||
|
||||
return (rgb.red * 0.2126) + (rgb.green * 0.7152) + (rgb.blue * 0.0722);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts Hex RGB to Color components.
|
||||
*
|
||||
* @param color Hexadec RGB Color.
|
||||
* @return RGB color components.
|
||||
*/
|
||||
protected static hexToRGB(color: string): ColorComponents {
|
||||
if (color.charAt(0) == '#') {
|
||||
color = color.substr(1);
|
||||
}
|
||||
|
||||
if (color.length === 3) {
|
||||
color = color.charAt(0) + color.charAt(0) + color.charAt(1) + color.charAt(1) + color.charAt(2) + color.charAt(2);
|
||||
} else if (color.length !== 6) {
|
||||
throw('Invalid hex color: ' + color);
|
||||
}
|
||||
|
||||
return {
|
||||
red: parseInt(color.substr(0, 2), 16),
|
||||
green: parseInt(color.substr(2, 2), 16),
|
||||
blue: parseInt(color.substr(4, 2), 16),
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts RGB components to Hex string.
|
||||
*
|
||||
* @param color Color components.
|
||||
* @return RGB color in string.
|
||||
*/
|
||||
protected static RGBToHex(color: ColorComponents): string {
|
||||
return '#' + CoreColors.componentToHex(color.red) +
|
||||
CoreColors.componentToHex(color.green) +
|
||||
CoreColors.componentToHex(color.blue);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a color component from decimal to hexadec.
|
||||
*
|
||||
* @param c color component in decimal.
|
||||
* @return Hexadec of the color component.
|
||||
*/
|
||||
protected static componentToHex(c: number): string {
|
||||
const hex = c.toString(16);
|
||||
|
||||
return hex.length == 1 ? '0' + hex : hex;
|
||||
}
|
||||
|
||||
}
|
|
@ -205,6 +205,11 @@ export type CoreEventSiteData = {
|
|||
*/
|
||||
export type CoreEventSiteUpdatedData = CoreEventSiteData & CoreSiteInfoResponse;
|
||||
|
||||
/**
|
||||
* Data passed to SITE_ADDED event.
|
||||
*/
|
||||
export type CoreEventSiteAddedData = CoreEventSiteData & CoreSiteInfoResponse;
|
||||
|
||||
/**
|
||||
* Data passed to SESSION_EXPIRED event.
|
||||
*/
|
||||
|
|
|
@ -100,9 +100,10 @@
|
|||
--color: var(--custom-bottom-tabs-color, var(--white));
|
||||
}
|
||||
|
||||
--ion-statusbar-background: var(--custom-toolbar-background, var(--ion-color-primary));
|
||||
ion-toolbar {
|
||||
--color: var(--custom-toolbar-color, var(--ion-color-primary-contrast));
|
||||
--background: var(--custom-toolbar-background, var(--ion-color-primary));
|
||||
--background: var(--ion-statusbar-background);
|
||||
|
||||
ion-spinner {
|
||||
--color: var(--custom-toolbar-color, var(--ion-color-primary-contrast));
|
||||
|
|
|
@ -50,14 +50,6 @@ declare global {
|
|||
forcedefaultlanguage: boolean;
|
||||
privacypolicy: string;
|
||||
notificoncolor: string;
|
||||
statusbarbg: boolean;
|
||||
statusbarlighttext: boolean;
|
||||
statusbarbgios: string;
|
||||
statusbarlighttextios: boolean;
|
||||
statusbarbgandroid: string;
|
||||
statusbarlighttextandroid: boolean;
|
||||
statusbarbgremotetheme: string;
|
||||
statusbarlighttextremotetheme: boolean;
|
||||
enableanalytics: boolean;
|
||||
enableonboarding: boolean;
|
||||
forceColorScheme: CoreColorScheme;
|
||||
|
|
Loading…
Reference in New Issue