From 8a5ccf1d7184f79fe793a3f964c110a2fda67856 Mon Sep 17 00:00:00 2001 From: Noel De Martin Date: Thu, 12 Aug 2021 13:26:46 +0200 Subject: [PATCH] MOBILE-3833 core: Extract constructor initializers --- src/addons/mod/lti/lti.module.ts | 3 +- src/addons/mod/lti/services/lti-helper.ts | 12 ++++--- .../settings/services/settings-helper.ts | 7 +++- src/core/features/settings/settings.module.ts | 12 ++----- src/core/initializers/initialize-services.ts | 25 +++++++++++++ src/core/initializers/inject-ios-scripts.ts | 26 ++++++++++++++ src/core/initializers/watch-network.ts | 24 +++++++++++++ src/core/services/cron.ts | 14 ++------ src/core/services/filepool.ts | 36 +++++++++---------- src/core/services/lang.ts | 10 +++--- src/core/services/local-notifications.ts | 30 ++++++++-------- src/core/services/utils/iframe.ts | 9 ++--- 12 files changed, 133 insertions(+), 75 deletions(-) create mode 100644 src/core/initializers/initialize-services.ts create mode 100644 src/core/initializers/inject-ios-scripts.ts create mode 100644 src/core/initializers/watch-network.ts diff --git a/src/addons/mod/lti/lti.module.ts b/src/addons/mod/lti/lti.module.ts index 6c6b08390..8b9c43fc0 100644 --- a/src/addons/mod/lti/lti.module.ts +++ b/src/addons/mod/lti/lti.module.ts @@ -24,7 +24,7 @@ import { AddonModLtiListLinkHandler } from './services/handlers/list-link'; import { AddonModLtiModuleHandler, AddonModLtiModuleHandlerService } from './services/handlers/module'; import { AddonModLtiPrefetchHandler } from './services/handlers/prefetch'; import { AddonModLtiProvider } from './services/lti'; -import { AddonModLtiHelperProvider } from './services/lti-helper'; +import { AddonModLtiHelper, AddonModLtiHelperProvider } from './services/lti-helper'; export const ADDON_MOD_LTI_SERVICES: Type[] = [ AddonModLtiProvider, @@ -44,6 +44,7 @@ const routes: Routes = [ AddonModLtiComponentsModule, ], providers: [ + { provide: APP_INITIALIZER, multi: true, useValue: () => AddonModLtiHelper.watchPendingCompletions() }, { provide: APP_INITIALIZER, multi: true, diff --git a/src/addons/mod/lti/services/lti-helper.ts b/src/addons/mod/lti/services/lti-helper.ts index 905252c24..ae3d56fda 100644 --- a/src/addons/mod/lti/services/lti-helper.ts +++ b/src/addons/mod/lti/services/lti-helper.ts @@ -31,6 +31,13 @@ export class AddonModLtiHelperProvider { protected pendingCheckCompletion: {[moduleId: string]: {courseId: number; module: CoreCourseModule}} = {}; constructor() { + // Clear pending completion on logout. + CoreEvents.on(CoreEvents.LOGOUT, () => { + this.pendingCheckCompletion = {}; + }); + } + + watchPendingCompletions(): void { Platform.resume.subscribe(() => { // User went back to the app, check pending completions. for (const moduleId in this.pendingCheckCompletion) { @@ -39,11 +46,6 @@ export class AddonModLtiHelperProvider { CoreCourse.checkModuleCompletion(data.courseId, data.module.completiondata); } }); - - // Clear pending completion on logout. - CoreEvents.on(CoreEvents.LOGOUT, () => { - this.pendingCheckCompletion = {}; - }); } /** diff --git a/src/core/features/settings/services/settings-helper.ts b/src/core/features/settings/services/settings-helper.ts index 94fddfc40..2d68d2330 100644 --- a/src/core/features/settings/services/settings-helper.ts +++ b/src/core/features/settings/services/settings-helper.ts @@ -65,7 +65,7 @@ export class CoreSettingsHelperProvider { protected colorSchemes: CoreColorScheme[] = []; protected currentColorScheme = CoreColorScheme.LIGHT; - constructor() { + async initialize(): Promise { this.prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); if (!CoreConstants.CONFIG.forceColorScheme) { @@ -94,6 +94,11 @@ export class CoreSettingsHelperProvider { // Listen for changes to the prefers-color-scheme media query. this.prefersDark.addEventListener && this.prefersDark.addEventListener('change', this.toggleDarkModeListener.bind(this)); + + // Init zoom level. + await this.upgradeZoomLevel(); + + this.initDomSettings(); } /** diff --git a/src/core/features/settings/settings.module.ts b/src/core/features/settings/settings.module.ts index 28db5b75b..e94d2072b 100644 --- a/src/core/features/settings/settings.module.ts +++ b/src/core/features/settings/settings.module.ts @@ -17,7 +17,7 @@ import { Routes } from '@angular/router'; import { AppRoutingModule } from '@/app/app-routing.module'; import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module'; -import { CoreSettingsHelperProvider } from './services/settings-helper'; +import { CoreSettingsHelper, CoreSettingsHelperProvider } from './services/settings-helper'; import { CoreSettingsDelegateService } from './services/settings-delegate'; export const CORE_SETTINGS_SERVICES: Type[] = [ @@ -49,15 +49,7 @@ const mainMenuMoreRoutes: Routes = [ CoreMainMenuTabRoutingModule.forChild(mainMenuMoreRoutes), ], providers: [ - { - provide: APP_INITIALIZER, - multi: true, - deps: [CoreSettingsHelperProvider], - useFactory: (helper: CoreSettingsHelperProvider) => async () => { - await helper.upgradeZoomLevel(); - helper.initDomSettings(); - }, - }, + { provide: APP_INITIALIZER, multi: true, useValue: () => CoreSettingsHelper.initialize() }, ], }) export class CoreSettingsModule {} diff --git a/src/core/initializers/initialize-services.ts b/src/core/initializers/initialize-services.ts new file mode 100644 index 000000000..c07eeafff --- /dev/null +++ b/src/core/initializers/initialize-services.ts @@ -0,0 +1,25 @@ +// (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. + +import { CoreFilepool } from '@services/filepool'; +import { CoreLang } from '@services/lang'; +import { CoreLocalNotifications } from '@services/local-notifications'; + +export default async function(): Promise { + await Promise.all([ + CoreFilepool.initialize(), + CoreLang.initialize(), + CoreLocalNotifications.initialize(), + ]); +} diff --git a/src/core/initializers/inject-ios-scripts.ts b/src/core/initializers/inject-ios-scripts.ts new file mode 100644 index 000000000..a1a728bb2 --- /dev/null +++ b/src/core/initializers/inject-ios-scripts.ts @@ -0,0 +1,26 @@ +// (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. + +import { CoreApp } from '@services/app'; +import { CoreIframeUtils } from '@services/utils/iframe'; +import { Platform } from '@singletons'; + +export default async function(): Promise { + if (!CoreApp.isIOS() || !('WKUserScript' in window)) { + return; + } + + await Platform.ready(); + await CoreIframeUtils.injectiOSScripts(window); +} diff --git a/src/core/initializers/watch-network.ts b/src/core/initializers/watch-network.ts new file mode 100644 index 000000000..ee867a42e --- /dev/null +++ b/src/core/initializers/watch-network.ts @@ -0,0 +1,24 @@ +// (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. + +import { CoreCronDelegate } from '@services/cron'; +import { Network, NgZone } from '@singletons'; + +export default function(): void { + // When the app is re-connected, start network handlers that were stopped. + Network.onConnect().subscribe(() => { + // Execute the callback in the Angular zone, so change detection doesn't stop working. + NgZone.run(() => CoreCronDelegate.startNetworkHandlers()); + }); +} diff --git a/src/core/services/cron.ts b/src/core/services/cron.ts index dd39cd04d..76a043947 100644 --- a/src/core/services/cron.ts +++ b/src/core/services/cron.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, NgZone } from '@angular/core'; +import { Injectable } from '@angular/core'; import { CoreApp } from '@services/app'; import { CoreConfig } from '@services/config'; @@ -21,7 +21,7 @@ import { CoreConstants } from '@/core/constants'; import { SQLiteDB } from '@classes/sqlitedb'; import { CoreError } from '@classes/errors/error'; -import { makeSingleton, Network } from '@singletons'; +import { makeSingleton } from '@singletons'; import { CoreLogger } from '@singletons/logger'; import { APP_SCHEMA, CRON_TABLE_NAME, CronDBEntry } from '@services/database/cron'; @@ -44,17 +44,9 @@ export class CoreCronDelegateService { protected appDB: Promise; protected resolveAppDB!: (appDB: SQLiteDB) => void; - constructor(zone: NgZone) { + constructor() { this.appDB = new Promise(resolve => this.resolveAppDB = resolve); this.logger = CoreLogger.getInstance('CoreCronDelegate'); - - // When the app is re-connected, start network handlers that were stopped. - Network.onConnect().subscribe(() => { - // Execute the callback in the Angular zone, so change detection doesn't stop working. - zone.run(() => { - this.startNetworkHandlers(); - }); - }); } /** diff --git a/src/core/services/filepool.ts b/src/core/services/filepool.ts index 3cc4c2854..275785a4a 100644 --- a/src/core/services/filepool.ts +++ b/src/core/services/filepool.ts @@ -97,8 +97,24 @@ export class CoreFilepoolProvider { constructor() { this.appDB = new Promise(resolve => this.resolveAppDB = resolve); this.logger = CoreLogger.getInstance('CoreFilepoolProvider'); + } - this.init(); + /** + * Initialize queue. + */ + async initialize(): Promise { + // Waiting for the app to be ready to start processing the queue. + await ApplicationInit.donePromise; + + this.checkQueueProcessing(); + + // Start queue when device goes online. + Network.onConnect().subscribe(() => { + // Execute the callback in the Angular zone, so change detection doesn't stop working. + NgZone.run(() => { + this.checkQueueProcessing(); + }); + }); } /** @@ -114,24 +130,6 @@ export class CoreFilepoolProvider { this.resolveAppDB(CoreApp.getDB()); } - /** - * Init some properties. - */ - protected async init(): Promise { - // Waiting for the app to be ready to start processing the queue. - await ApplicationInit.donePromise; - - this.checkQueueProcessing(); - - // Start queue when device goes online. - Network.onConnect().subscribe(() => { - // Execute the callback in the Angular zone, so change detection doesn't stop working. - NgZone.run(() => { - this.checkQueueProcessing(); - }); - }); - } - /** * Link a file with a component. * diff --git a/src/core/services/lang.ts b/src/core/services/lang.ts index 7d9f54ebe..c14cd0054 100644 --- a/src/core/services/lang.ts +++ b/src/core/services/lang.ts @@ -37,13 +37,11 @@ export class CoreLangProvider { protected customStringsRaw?: string; protected sitePluginsStrings: CoreLanguageObject = {}; // Strings defined by site plugins. - constructor() { + async initialize(): Promise { // Set fallback language and language to use until the app determines the right language to use. Translate.setDefaultLang(this.fallbackLanguage); Translate.use(this.defaultLanguage); - this.initLanguage(); - Translate.onLangChange.subscribe((event: LangChangeEvent) => { document.documentElement.setAttribute('lang', event.lang); @@ -51,12 +49,14 @@ export class CoreLangProvider { dir = dir.indexOf('rtl') != -1 ? 'rtl' : 'ltr'; document.documentElement.setAttribute('dir', dir); }); + + await this.initializeCurrentLanguage(); } /** * Init language. */ - protected async initLanguage(): Promise { + protected async initializeCurrentLanguage(): Promise { await Platform.ready(); let language: string; @@ -68,7 +68,7 @@ export class CoreLangProvider { language = await this.getCurrentLanguage(); } - return this.changeCurrentLanguage(language); + await this.changeCurrentLanguage(language); } /** diff --git a/src/core/services/local-notifications.ts b/src/core/services/local-notifications.ts index df0869718..c6547f8fe 100644 --- a/src/core/services/local-notifications.ts +++ b/src/core/services/local-notifications.ts @@ -62,27 +62,12 @@ export class CoreLocalNotificationsProvider { this.appDB = new Promise(resolve => this.resolveAppDB = resolve); this.logger = CoreLogger.getInstance('CoreLocalNotificationsProvider'); this.queueRunner = new CoreQueueRunner(10); - - this.init(); - } - - /** - * Initialize database. - */ - async initializeDatabase(): Promise { - try { - await CoreApp.createTablesFromSchema(APP_SCHEMA); - } catch (e) { - // Ignore errors. - } - - this.resolveAppDB(CoreApp.getDB()); } /** * Init some properties. */ - protected async init(): Promise { + async initialize(): Promise { await Platform.ready(); if (!this.isAvailable()) { @@ -131,6 +116,19 @@ export class CoreLocalNotificationsProvider { }); } + /** + * Initialize database. + */ + async initializeDatabase(): Promise { + try { + await CoreApp.createTablesFromSchema(APP_SCHEMA); + } catch (e) { + // Ignore errors. + } + + this.resolveAppDB(CoreApp.getDB()); + } + /** * Cancel a local notification. * diff --git a/src/core/services/utils/iframe.ts b/src/core/services/utils/iframe.ts index b9bb6c531..99f6e15bf 100644 --- a/src/core/services/utils/iframe.ts +++ b/src/core/services/utils/iframe.ts @@ -25,7 +25,7 @@ import { CoreTextUtils } from '@services/utils/text'; import { CoreUrlUtils } from '@services/utils/url'; import { CoreUtils, PromiseDefer } from '@services/utils/utils'; -import { makeSingleton, Network, Platform, NgZone, Translate, Diagnostic } from '@singletons'; +import { makeSingleton, Network, NgZone, Translate, Diagnostic } from '@singletons'; import { CoreLogger } from '@singletons/logger'; import { CoreUrl } from '@singletons/url'; import { CoreWindow } from '@singletons/window'; @@ -52,11 +52,6 @@ export class CoreIframeUtilsProvider { constructor() { this.logger = CoreLogger.getInstance('CoreUtilsProvider'); - - if (CoreApp.isIOS() && 'WKUserScript' in window) { - // eslint-disable-next-line promise/catch-or-return - Platform.ready().then(() => this.injectiOSScripts(window)); - } } /** @@ -558,7 +553,7 @@ export class CoreIframeUtilsProvider { * * @param userScriptWindow Window. */ - private injectiOSScripts(userScriptWindow: WKUserScriptWindow) { + injectiOSScripts(userScriptWindow: WKUserScriptWindow): void { const wwwPath = CoreFile.getWWWAbsolutePath(); const linksPath = CoreTextUtils.concatenatePaths(wwwPath, 'assets/js/iframe-treat-links.js');