diff --git a/src/core/features/compile/services/compile.ts b/src/core/features/compile/services/compile.ts index b11698062..8b7ea6a68 100644 --- a/src/core/features/compile/services/compile.ts +++ b/src/core/features/compile/services/compile.ts @@ -47,7 +47,7 @@ import { CORE_CONTENTLINKS_SERVICES } from '@features/contentlinks/contentlinks. import { CORE_COURSE_SERVICES } from '@features/course/course.module'; import { CORE_COURSES_SERVICES } from '@features/courses/courses.module'; import { CORE_EDITOR_SERVICES } from '@features/editor/editor.module'; -import { IONIC_NATIVE_SERVICES } from '@features/emulator/emulator.module'; +import { CORE_NATIVE_SERVICES } from '@features/native/native.module'; import { CORE_FILEUPLOADER_SERVICES } from '@features/fileuploader/fileuploader.module'; import { CORE_FILTER_SERVICES } from '@features/filter/filter.module'; import { CORE_GRADES_SERVICES } from '@features/grades/grades.module'; @@ -285,7 +285,7 @@ export class CoreCompileProvider { ...CORE_STYLE_SERVICES, ...CORE_USER_SERVICES, ...CORE_XAPI_SERVICES, - ...IONIC_NATIVE_SERVICES, + ...CORE_NATIVE_SERVICES, ...this.OTHER_SERVICES, ...extraProviders, ...ADDON_BADGES_SERVICES, diff --git a/src/core/features/emulator/emulator.module.ts b/src/core/features/emulator/emulator.module.ts index 70d1ae44b..227648524 100644 --- a/src/core/features/emulator/emulator.module.ts +++ b/src/core/features/emulator/emulator.module.ts @@ -13,63 +13,21 @@ // limitations under the License. import { APP_INITIALIZER, NgModule } from '@angular/core'; -import { Platform } from '@ionic/angular'; -import { CoreEmulatorHelperProvider } from './services/emulator-helper'; +import { CoreEmulatorHelper } from './services/emulator-helper'; import { CoreEmulatorComponentsModule } from './components/components.module'; // Ionic Native services. -import { Badge } from '@ionic-native/badge/ngx'; import { Camera } from '@ionic-native/camera/ngx'; -import { Chooser } from '@ionic-native/chooser/ngx'; import { Clipboard } from '@ionic-native/clipboard/ngx'; -import { Device } from '@ionic-native/device/ngx'; -import { Diagnostic } from '@ionic-native/diagnostic/ngx'; import { File } from '@ionic-native/file/ngx'; import { FileOpener } from '@ionic-native/file-opener/ngx'; import { FileTransfer } from '@ionic-native/file-transfer/ngx'; import { Geolocation } from '@ionic-native/geolocation/ngx'; -import { HTTP } from '@ionic-native/http/ngx'; import { InAppBrowser } from '@ionic-native/in-app-browser/ngx'; -import { WebView } from '@ionic-native/ionic-webview/ngx'; -import { Keyboard } from '@ionic-native/keyboard/ngx'; -import { LocalNotifications } from '@ionic-native/local-notifications/ngx'; -import { Media } from '@ionic-native/media/ngx'; import { MediaCapture } from '@ionic-native/media-capture/ngx'; -import { Push } from '@ionic-native/push/ngx'; -import { QRScanner } from '@ionic-native/qr-scanner/ngx'; -import { SplashScreen } from '@ionic-native/splash-screen/ngx'; -import { SQLite } from '@ionic-native/sqlite/ngx'; -import { StatusBar } from '@ionic-native/status-bar/ngx'; -import { WebIntent } from '@ionic-native/web-intent/ngx'; import { Zip } from '@ionic-native/zip/ngx'; -export const IONIC_NATIVE_SERVICES = [ - Badge, - Camera, - Chooser, - Clipboard, - Device, - Diagnostic, - File, - FileOpener, - FileTransfer, - Geolocation, - HTTP, - InAppBrowser, - Keyboard, - LocalNotifications, - Media, - MediaCapture, - Push, - QRScanner, - SplashScreen, - StatusBar, - SQLite, - WebIntent, - WebView, - Zip, -]; // Mock services. import { CameraMock } from './services/camera'; import { ClipboardMock } from './services/clipboard'; @@ -80,6 +38,7 @@ import { GeolocationMock } from './services/geolocation'; import { InAppBrowserMock } from './services/inappbrowser'; import { MediaCaptureMock } from './services/media-capture'; import { ZipMock } from './services/zip'; +import { CorePlatform } from '@services/platform'; /** * This module handles the emulation of Cordova plugins in browser and desktop. @@ -91,81 +50,54 @@ import { ZipMock } from './services/zip'; * functions we check if the app is running in mobile or not, and then provide the right service to use. */ @NgModule({ - declarations: [ - ], imports: [ CoreEmulatorComponentsModule, ], providers: [ - Badge, { provide: Camera, - deps: [Platform], - useFactory: (platform: Platform): Camera => platform.is('cordova') ? new Camera() : new CameraMock(), + useFactory: (): Camera => CorePlatform.is('cordova') ? new Camera() : new CameraMock(), }, - Chooser, { provide: Clipboard, - deps: [Platform], // Use platform instead of AppProvider to prevent errors with singleton injection. - useFactory: (platform: Platform): Clipboard => platform.is('cordova') ? new Clipboard() : new ClipboardMock(), + useFactory: (): Clipboard => CorePlatform.is('cordova') ? new Clipboard() : new ClipboardMock(), }, - Device, - Diagnostic, { provide: File, - deps: [Platform], - useFactory: (platform: Platform): File => platform.is('cordova') ? new File() : new FileMock(), + useFactory: (): File => CorePlatform.is('cordova') ? new File() : new FileMock(), }, { provide: FileOpener, - deps: [Platform], - useFactory: (platform: Platform): FileOpener => platform.is('cordova') ? new FileOpener() : new FileOpenerMock(), + useFactory: (): FileOpener => CorePlatform.is('cordova') ? new FileOpener() : new FileOpenerMock(), }, { provide: FileTransfer, - deps: [Platform], - useFactory: (platform: Platform): FileTransfer => platform.is('cordova') ? new FileTransfer() : new FileTransferMock(), + useFactory: (): FileTransfer => CorePlatform.is('cordova') ? new FileTransfer() : new FileTransferMock(), }, { provide: Geolocation, - deps: [Platform], - useFactory: (platform: Platform): Geolocation => platform.is('cordova') ? new Geolocation() : new GeolocationMock(), + useFactory: (): Geolocation => CorePlatform.is('cordova') ? new Geolocation() : new GeolocationMock(), }, - HTTP, { provide: InAppBrowser, - deps: [Platform], - useFactory: (platform: Platform): InAppBrowser => platform.is('cordova') ? new InAppBrowser() : new InAppBrowserMock(), + useFactory: (): InAppBrowser => CorePlatform.is('cordova') ? new InAppBrowser() : new InAppBrowserMock(), }, - Keyboard, - LocalNotifications, - Media, { provide: MediaCapture, - deps: [Platform], - useFactory: (platform: Platform): MediaCapture => platform.is('cordova') ? new MediaCapture() : new MediaCaptureMock(), + useFactory: (): MediaCapture => CorePlatform.is('cordova') ? new MediaCapture() : new MediaCaptureMock(), }, - Push, - QRScanner, - SplashScreen, - SQLite, - StatusBar, - WebIntent, - WebView, { provide: Zip, - deps: [Platform, File], - useFactory: (platform: Platform, file: File): Zip => platform.is('cordova') ? new Zip() : new ZipMock(file), + useFactory: (): Zip => CorePlatform.is('cordova') ? new Zip() : new ZipMock(), }, { provide: APP_INITIALIZER, - deps: [Platform, CoreEmulatorHelperProvider], - useFactory: (platform: Platform, helperProvider: CoreEmulatorHelperProvider) => () => { - if (platform.is('cordova')) { + useFactory: () => () => { + if (CorePlatform.is('cordova')) { return; } - return helperProvider.load(); + return CoreEmulatorHelper.load(); }, multi: true, }, diff --git a/src/core/features/emulator/services/emulator-helper.ts b/src/core/features/emulator/services/emulator-helper.ts index d6cd71f86..dd9e9da64 100644 --- a/src/core/features/emulator/services/emulator-helper.ts +++ b/src/core/features/emulator/services/emulator-helper.ts @@ -13,10 +13,9 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { File } from '@ionic-native/file/ngx'; import { CoreFile } from '@services/file'; -import { CoreUtils } from '@services/utils/utils'; +import { File, makeSingleton } from '@singletons'; import { CoreLogger } from '@singletons/logger'; import { FileMock } from './file'; import { FileTransferErrorMock } from './file-transfer'; @@ -29,9 +28,7 @@ export class CoreEmulatorHelperProvider { protected logger: CoreLogger; - constructor( - protected file: File, - ) { + constructor() { this.logger = CoreLogger.getInstance('CoreEmulatorHelper'); } @@ -40,18 +37,18 @@ export class CoreEmulatorHelperProvider { * * @return Promise resolved when loaded. */ - load(): Promise { - const promises: Promise[] = []; - + async load(): Promise { window.FileTransferError = FileTransferErrorMock; - promises.push(( this.file).load().then((basePath: string) => { + const fileService = File.instance; + + if (fileService instanceof FileMock) { + const basePath = await fileService.load(); + CoreFile.setHTMLBasePath(basePath); - - return; - })); - - return CoreUtils.allPromises(promises); + } } } + +export const CoreEmulatorHelper = makeSingleton(CoreEmulatorHelperProvider); diff --git a/src/core/features/emulator/services/zip.ts b/src/core/features/emulator/services/zip.ts index 0420b2dce..bfc0a9c4e 100644 --- a/src/core/features/emulator/services/zip.ts +++ b/src/core/features/emulator/services/zip.ts @@ -13,10 +13,10 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { File } from '@ionic-native/file/ngx'; import { Zip } from '@ionic-native/zip/ngx'; import * as JSZip from 'jszip'; import { CoreText } from '@singletons/text'; +import { File } from '@singletons'; /** * Emulates the Cordova Zip plugin in browser. @@ -24,10 +24,6 @@ import { CoreText } from '@singletons/text'; @Injectable() export class ZipMock extends Zip { - constructor(private file: File) { - super(); - } - /** * Create a directory. It creates all the foldes in dirPath 1 by 1 to prevent errors. * @@ -42,7 +38,7 @@ export class ZipMock extends Zip { for (let i = 0; i < folders.length; i++) { const folder = folders[i]; - await this.file.createDir(destination, folder, true); + await File.createDir(destination, folder, true); // Folder created, add it to the destination path. destination = CoreText.concatenatePaths(destination, folder); @@ -69,7 +65,7 @@ export class ZipMock extends Zip { try { // Read the file first. - const data = await this.file.readAsArrayBuffer(sourceDir, sourceName); + const data = await File.readAsArrayBuffer(sourceDir, sourceName); // Now load the file using the JSZip library. await zip.loadAsync(data); @@ -83,7 +79,7 @@ export class ZipMock extends Zip { const destParent = destination.substring(0, destination.lastIndexOf('/')); const destFolderName = destination.substring(destination.lastIndexOf('/') + 1); - await this.file.createDir(destParent, destFolderName, true); + await File.createDir(destParent, destFolderName, true); const total = Object.keys(zip.files).length; let loaded = 0; @@ -107,7 +103,7 @@ export class ZipMock extends Zip { // File read and parent folder created, now write the file. const parentFolder = CoreText.concatenatePaths(destination, fileDir); - await this.file.writeFile(parentFolder, fileName, fileData, { replace: true }); + await File.writeFile(parentFolder, fileName, fileData, { replace: true }); } else { // It's a folder, create it if it doesn't exist. await this.createDir(destination, name); diff --git a/src/core/features/features.module.ts b/src/core/features/features.module.ts index b954b83d1..e5c8ee34f 100644 --- a/src/core/features/features.module.ts +++ b/src/core/features/features.module.ts @@ -41,6 +41,7 @@ import { CoreUserToursModule } from './usertours/user-tours.module'; import { CoreUserModule } from './user/user.module'; import { CoreViewerModule } from './viewer/viewer.module'; import { CoreXAPIModule } from './xapi/xapi.module'; +import { CoreNativeModule } from '@features/native/native.module'; @NgModule({ imports: [ @@ -50,13 +51,13 @@ import { CoreXAPIModule } from './xapi/xapi.module'; CoreCourseModule, CoreCoursesModule, CoreEditorModule, - CoreEmulatorModule, CoreFileUploaderModule, CoreFilterModule, CoreGradesModule, CoreH5PModule, CoreLoginModule, CoreMainMenuModule, + CoreNativeModule, CorePushNotificationsModule, CoreQuestionModule, CoreRatingModule, @@ -71,6 +72,9 @@ import { CoreXAPIModule } from './xapi/xapi.module'; CoreUserModule, CoreViewerModule, CoreXAPIModule, + + // Import last to allow overrides. + CoreEmulatorModule, ], }) export class CoreFeaturesModule {} diff --git a/src/core/features/native/native.module.ts b/src/core/features/native/native.module.ts new file mode 100644 index 000000000..3a8887ca0 --- /dev/null +++ b/src/core/features/native/native.module.ts @@ -0,0 +1,97 @@ +// (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 { NgModule } from '@angular/core'; + +import { Badge } from '@ionic-native/badge/ngx'; +import { Camera } from '@ionic-native/camera/ngx'; +import { Chooser } from '@ionic-native/chooser/ngx'; +import { Clipboard } from '@ionic-native/clipboard/ngx'; +import { Device } from '@ionic-native/device/ngx'; +import { Diagnostic } from '@ionic-native/diagnostic/ngx'; +import { File } from '@ionic-native/file/ngx'; +import { FileOpener } from '@ionic-native/file-opener/ngx'; +import { FileTransfer } from '@ionic-native/file-transfer/ngx'; +import { Geolocation } from '@ionic-native/geolocation/ngx'; +import { HTTP } from '@ionic-native/http/ngx'; +import { InAppBrowser } from '@ionic-native/in-app-browser/ngx'; +import { WebView } from '@ionic-native/ionic-webview/ngx'; +import { Keyboard } from '@ionic-native/keyboard/ngx'; +import { LocalNotifications } from '@ionic-native/local-notifications/ngx'; +import { Media } from '@ionic-native/media/ngx'; +import { MediaCapture } from '@ionic-native/media-capture/ngx'; +import { Push } from '@ionic-native/push/ngx'; +import { QRScanner } from '@ionic-native/qr-scanner/ngx'; +import { SplashScreen } from '@ionic-native/splash-screen/ngx'; +import { SQLite } from '@ionic-native/sqlite/ngx'; +import { StatusBar } from '@ionic-native/status-bar/ngx'; +import { WebIntent } from '@ionic-native/web-intent/ngx'; +import { Zip } from '@ionic-native/zip/ngx'; + +export const CORE_NATIVE_SERVICES = [ + Badge, + Camera, + Chooser, + Clipboard, + Device, + Diagnostic, + File, + FileOpener, + FileTransfer, + Geolocation, + HTTP, + InAppBrowser, + Keyboard, + LocalNotifications, + Media, + MediaCapture, + Push, + QRScanner, + SplashScreen, + StatusBar, + SQLite, + WebIntent, + WebView, + Zip, +]; + +@NgModule({ + providers: [ + Badge, + Camera, + Chooser, + Clipboard, + Device, + Diagnostic, + File, + FileOpener, + FileTransfer, + Geolocation, + HTTP, + InAppBrowser, + Keyboard, + LocalNotifications, + Media, + MediaCapture, + Push, + QRScanner, + SplashScreen, + SQLite, + StatusBar, + WebIntent, + WebView, + Zip, + ], +}) +export class CoreNativeModule {}