diff --git a/config.xml b/config.xml index 1282a7a65..cd9f0ab61 100644 --- a/config.xml +++ b/config.xml @@ -170,6 +170,7 @@ + diff --git a/package-lock.json b/package-lock.json index 956c7923b..074dd3600 100644 --- a/package-lock.json +++ b/package-lock.json @@ -182,6 +182,11 @@ "resolved": "https://registry.npmjs.org/@ionic-native/push/-/push-4.20.0.tgz", "integrity": "sha512-IgzaZd8KSPLwyLX1emRijlQ0Vfa3RlPPBx370lVH32c8zG3DFH1xfQQbb39KF3qmX5b6so0pGGA2holSUwVm2w==" }, + "@ionic-native/qr-scanner": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@ionic-native/qr-scanner/-/qr-scanner-4.20.0.tgz", + "integrity": "sha512-eLeJQq49/x5bdCVLotuMHZZ3YGEpSzuEnuX2vno2ugdGSygBm+wxIVSa9Nuz8HozYwC6oyii+zH/pg4SZ+4V9Q==" + }, "@ionic-native/screen-orientation": { "version": "4.20.0", "resolved": "https://registry.npmjs.org/@ionic-native/screen-orientation/-/screen-orientation-4.20.0.tgz", @@ -2705,6 +2710,14 @@ "resolved": "https://registry.npmjs.org/cordova-plugin-network-information/-/cordova-plugin-network-information-2.0.2.tgz", "integrity": "sha512-NwO3qDBNL/vJxUxBTPNOA1HvkDf9eTeGH8JSZiwy1jq2W2mJKQEDBwqWkaEQS19Yd/MQTiw0cykxg5D7u4J6cQ==" }, + "cordova-plugin-qrscanner": { + "version": "git+https://github.com/moodlemobile/cordova-plugin-qrscanner.git#43952839ce97887d1c6cad53c7d668fe3370aedd", + "from": "git+https://github.com/moodlemobile/cordova-plugin-qrscanner.git#dist", + "requires": { + "qrcode-reader": "^1.0.4", + "webrtc-adapter": "^3.1.4" + } + }, "cordova-plugin-screen-orientation": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/cordova-plugin-screen-orientation/-/cordova-plugin-screen-orientation-3.0.2.tgz", @@ -10224,6 +10237,11 @@ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" }, + "qrcode-reader": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/qrcode-reader/-/qrcode-reader-1.0.4.tgz", + "integrity": "sha512-rRjALGNh9zVqvweg1j5OKIQKNsw3bLC+7qwlnead5K/9cb1cEIAGkwikt/09U0K+2IDWGD9CC6SP7tHAjUeqvQ==" + }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", @@ -11127,6 +11145,11 @@ } } }, + "sdp": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/sdp/-/sdp-1.5.4.tgz", + "integrity": "sha1-jgOPbdsUvXZa4fS1IW4SCUUR4NA=" + }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", @@ -13864,6 +13887,14 @@ "source-map": "~0.6.1" } }, + "webrtc-adapter": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-3.4.3.tgz", + "integrity": "sha1-tjYGLu6abvFYrNDYUBtnhDS1bxY=", + "requires": { + "sdp": "^1.5.0" + } + }, "websocket-driver": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", diff --git a/package.json b/package.json index 941127fae..d1b669d91 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "@ionic-native/media-capture": "4.20.0", "@ionic-native/network": "4.20.0", "@ionic-native/push": "4.20.0", + "@ionic-native/qr-scanner": "4.20.0", "@ionic-native/screen-orientation": "4.20.0", "@ionic-native/splash-screen": "4.20.0", "@ionic-native/sqlite": "4.20.0", @@ -98,6 +99,7 @@ "cordova-plugin-local-notification": "git+https://github.com/moodlemobile/cordova-plugin-local-notification.git#moodle", "cordova-plugin-media-capture": "3.0.3", "cordova-plugin-network-information": "2.0.2", + "cordova-plugin-qrscanner": "git+https://github.com/moodlemobile/cordova-plugin-qrscanner.git#dist", "cordova-plugin-screen-orientation": "3.0.2", "cordova-plugin-splashscreen": "5.0.3", "cordova-plugin-statusbar": "2.4.3", @@ -194,7 +196,8 @@ "cordova-plugin-advanced-http": { "OKHTTP_VERSION": "3.10.0" }, - "cordova-plugin-wkwebview-cookies": {} + "cordova-plugin-wkwebview-cookies": {}, + "cordova-plugin-qrscanner": {} } }, "main": "desktop/electron.js", @@ -254,4 +257,4 @@ "deleteAppDataOnUninstall": true } } -} +} \ No newline at end of file diff --git a/src/core/emulator/emulator.module.ts b/src/core/emulator/emulator.module.ts index a24a2b08e..5f9886c9a 100644 --- a/src/core/emulator/emulator.module.ts +++ b/src/core/emulator/emulator.module.ts @@ -31,6 +31,7 @@ import { LocalNotifications } from '@ionic-native/local-notifications'; import { MediaCapture } from '@ionic-native/media-capture'; import { Network } from '@ionic-native/network'; import { Push } from '@ionic-native/push'; +import { QRScanner } from '@ionic-native/qr-scanner'; import { SplashScreen } from '@ionic-native/splash-screen'; import { StatusBar } from '@ionic-native/status-bar'; import { SQLite } from '@ionic-native/sqlite'; @@ -51,12 +52,14 @@ import { LocalNotificationsMock } from './providers/local-notifications'; import { MediaCaptureMock } from './providers/media-capture'; import { NetworkMock } from './providers/network'; import { PushMock } from './providers/push'; +import { QRScannerMock } from './providers/qr-scanner'; import { ZipMock } from './providers/zip'; import { CoreEmulatorHelperProvider } from './providers/helper'; import { CoreEmulatorCaptureHelperProvider } from './providers/capture-helper'; import { CoreAppProvider } from '@providers/app'; import { CoreFileProvider } from '@providers/file'; +import { CoreLoggerProvider } from '@providers/logger'; import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype'; import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreUrlUtilsProvider } from '@providers/utils/url'; @@ -80,6 +83,7 @@ export const IONIC_NATIVE_PROVIDERS = [ MediaCapture, Network, Push, + QRScanner, SplashScreen, StatusBar, SQLite, @@ -206,6 +210,13 @@ export const IONIC_NATIVE_PROVIDERS = [ return appProvider.isMobile() ? new Push() : new PushMock(appProvider); } }, + { + provide: QRScanner, + deps: [CoreAppProvider, CoreLoggerProvider], + useFactory: (appProvider: CoreAppProvider, loggerProvider: CoreLoggerProvider): QRScanner => { + return appProvider.isMobile() ? new QRScanner() : new QRScannerMock(loggerProvider); + } + }, SplashScreen, StatusBar, SQLite, diff --git a/src/core/emulator/providers/qr-scanner.ts b/src/core/emulator/providers/qr-scanner.ts new file mode 100644 index 000000000..668a74f5c --- /dev/null +++ b/src/core/emulator/providers/qr-scanner.ts @@ -0,0 +1,160 @@ +// (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 { Injectable } from '@angular/core'; +import { QRScanner, QRScannerStatus } from '@ionic-native/qr-scanner'; +import { Observable } from 'rxjs'; +import { CoreLoggerProvider } from '@providers/logger'; + +/** + * Emulates the Cordova QR Scanner plugin in desktop apps and in browser. + */ +@Injectable() +export class QRScannerMock extends QRScanner { + protected logger; + + constructor(logger: CoreLoggerProvider) { + super(); + + this.logger = logger.getInstance('QRScannerMock'); + } + + /** + * Request permission to use QR scanner. + * + * @return Promise. + */ + prepare(): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Call this method to enable scanning. You must then call the `show` method to make the camera preview visible. + * + * @return Observable that emits the scanned text. Unsubscribe from the observable to stop scanning. + */ + scan(): Observable { + this.logger.error('QRScanner isn\'t available in desktop apps.'); + + return null; + } + + /** + * Configures the native webview to have a transparent background, then sets the background of the and DOM + * elements to transparent, allowing the webview to re-render with the transparent background. + * + * @return Promise. + */ + show(): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Configures the native webview to be opaque with a white background, covering the video preview. + * + * @return Promise. + */ + hide(): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Enable the device's light (for scanning in low-light environments). + * + * @return Promise. + */ + enableLight(): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Destroy the scanner instance. + * + * @return Promise. + */ + destroy(): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Disable the device's light. + * + * @return Promise. + */ + disableLight(): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Use front camera + * + * @return Promise. + */ + useFrontCamera(): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Use back camera + * + * @return Promise. + */ + useBackCamera(): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Set camera to be used. + * + * @param camera Provide `0` for back camera, and `1` for front camera. + * @return Promise. + */ + useCamera(camera: number): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Pauses the video preview on the current frame and pauses scanning. + * + * @return Promise. + */ + pausePreview(): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Resumse the video preview and resumes scanning. + * + * @return Promise. + */ + resumePreview(): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Returns permission status + * + * @return Promise. + */ + getStatus(): Promise { + return Promise.reject('QRScanner isn\'t available in desktop apps.'); + } + + /** + * Opens settings to edit app permissions. + */ + openSettings(): void { + this.logger.error('QRScanner isn\'t available in desktop apps.'); + } +}