From c0d4fbe5bb11a5c22c8d5f0e0ddc307c3589cdcb Mon Sep 17 00:00:00 2001 From: Jason Dreyzehner Date: Tue, 11 Oct 2016 02:59:21 -0400 Subject: [PATCH] feat(scan): first iteration of full scan view implementation --- src/js/controllers/tab-scan.js | 91 ++++++++++++++++++++----------- src/js/directives/qrScanner.js | 7 ++- src/js/services/scannerService.js | 48 ++++++++++++---- src/sass/views/tab-scan.scss | 6 +- www/views/tab-scan.html | 8 +-- 5 files changed, 108 insertions(+), 52 deletions(-) diff --git a/src/js/controllers/tab-scan.js b/src/js/controllers/tab-scan.js index 0f16ea580..3d95c3a25 100644 --- a/src/js/controllers/tab-scan.js +++ b/src/js/controllers/tab-scan.js @@ -23,57 +23,71 @@ angular.module('copayApp.controllers').controller('tabScanController', function( } function _handleCapabilities(){ - if(!$scope.scannerIsAvailable){ - $scope.currentState = scannerStates.unavailable; - } else if($scope.scannerIsDenied){ - $scope.currentState = scannerStates.denied; - } else if($scope.scannerIsRestricted){ - $scope.currentState = scannerStates.denied; - } else if(!$scope.scannerHasPermission){ - $scope.currentState = scannerStates.unauthorized; - } else if($scope.scannerHasPermission){ + // always update the view + $timeout(function(){ + if(!scannerService.isInitialized()){ + $scope.currentState = scannerStates.loading; + } else if(!$scope.scannerIsAvailable){ + $scope.currentState = scannerStates.unavailable; + } else if($scope.scannerIsDenied){ + $scope.currentState = scannerStates.denied; + } else if($scope.scannerIsRestricted){ + $scope.currentState = scannerStates.denied; + } else if(!$scope.scannerHasPermission){ + $scope.currentState = scannerStates.unauthorized; + } + $log.debug('Scan view state set to: ' + $scope.currentState); + }); + } + + function _refreshScanView(){ + _updateCapabilities(); + _handleCapabilities(); + if($scope.scannerHasPermission){ activate(); } } - function _initScanView(){ - _updateCapabilities(); - _handleCapabilities(); - } - - $scope.$on("$ionicView.beforeEnter", function() { - $scope.currentState = scannerStates.loading; - }); - // This could be much cleaner with a Promise API // (needs a polyfill for some platforms) $rootScope.$on('scannerServiceInitialized', function(){ $log.debug('Scanner initialization finished, reinitializing scan view...'); - _initScanView(); + _refreshScanView(); }); $scope.$on("$ionicView.afterEnter", function() { - if(scannerService.isInitialized()){ - _initScanView(); - } + // try initializing and refreshing status any time the view is entered + scannerService.gentleInitialize(); }); function activate(){ scannerService.activate(function(){ + _updateCapabilities(); + _handleCapabilities(); $log.debug('Scanner activated, setting to visible...'); $scope.currentState = scannerStates.visible; - scannerService.scan(function(err, contents){ - if(err){ - $log.debug('Scan canceled.'); - } else if ($state.params.passthroughMode) { - $rootScope.scanResult = contents; - goBack(); - } else { - handleSuccessfulScan(contents); - } - }); + // pause to update the view + $timeout(function(){ + scannerService.scan(function(err, contents){ + if(err){ + $log.debug('Scan canceled.'); + } else if ($state.params.passthroughMode) { + $rootScope.scanResult = contents; + goBack(); + } else { + handleSuccessfulScan(contents); + } + }); + }); }); } + $scope.activate = activate; + + $scope.authorize = function(){ + scannerService.initialize(function(){ + _refreshScanView(); + }); + }; $scope.$on("$ionicView.afterLeave", function() { scannerService.deactivate(); @@ -84,6 +98,14 @@ angular.module('copayApp.controllers').controller('tabScanController', function( incomingData.redir(contents); } + $scope.openSettings = function(){ + scannerService.openSettings(); + }; + + $scope.attemptToReactivate = function(){ + scannerService.reinitialize(); + }; + $scope.toggleLight = function(){ scannerService.toggleLight(function(lightEnabled){ $scope.lightActive = lightEnabled; @@ -98,7 +120,7 @@ angular.module('copayApp.controllers').controller('tabScanController', function( $timeout(function(){ $scope.cameraToggleActive = false; $log.debug('Camera toggle control deactivated.'); - }, 600); + }, 200); }); }; @@ -106,6 +128,9 @@ angular.module('copayApp.controllers').controller('tabScanController', function( return $state.params.passthroughMode; } function goBack(){ + $ionicHistory.nextViewOptions({ + disableAnimate: true + }); $ionicHistory.backView().go(); } $scope.goBack = goBack; diff --git a/src/js/directives/qrScanner.js b/src/js/directives/qrScanner.js index 0a23819a5..131e48fde 100644 --- a/src/js/directives/qrScanner.js +++ b/src/js/directives/qrScanner.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.directives') - .directive('qrScanner', function($state, $rootScope, $log) { + .directive('qrScanner', function($state, $rootScope, $log, $ionicHistory) { return { restrict: 'E', @@ -9,11 +9,14 @@ angular.module('copayApp.directives') onScan: "&" }, replace: true, - template: '', + template: '', link: function(scope, el, attrs) { scope.openScanner = function() { $log.debug('Opening scanner by directive...'); + $ionicHistory.nextViewOptions({ + disableAnimate: true + }); $state.go('scanner', { passthroughMode: 1 }); }; diff --git a/src/js/services/scannerService.js b/src/js/services/scannerService.js index 09df4dfee..3baff576a 100644 --- a/src/js/services/scannerService.js +++ b/src/js/services/scannerService.js @@ -8,9 +8,8 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti var backCamera = true; // the plugin defaults to the back camera // Initalize known capabilities - var isAvailable = false; - var hasPermission = isDesktop? true: false; - var isAuthorized = false; + var isAvailable = isDesktop? false: true; // assume camera exists on mobile + var hasPermission = isDesktop? true: false; // assume desktop has permission var isDenied = false; var isRestricted = false; var canEnableLight = false; @@ -59,6 +58,7 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti } } + var initializeStarted = false; /** * If camera access has been granted, pre-initialize the QRScanner. This method * can be safely called before the scanner is visible to improve perceived @@ -67,27 +67,32 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti * The `status` of QRScanner is returned to the callback. */ this.gentleInitialize = function(callback) { + if(initializeStarted){ + QRScanner.getStatus(function(status){ + _completeInitialization(status, callback); + }); + return; + } + initializeStarted = true; $log.debug('Trying to pre-initialize QRScanner.'); if(!isDesktop){ QRScanner.getStatus(function(status){ _checkCapabilities(status); if(status.authorized){ $log.debug('Camera permission already granted.'); - _initalize(callback); + initialize(callback); } else { $log.debug('QRScanner not authorized, waiting to initalize.'); - if(typeof callback === "function"){ - callback && callback(status); - } + _completeInitialization(status, callback); } }); } else { $log.debug('Camera permission assumed on desktop.'); - _initalize(callback); + initialize(callback); } }; - function _initalize(callback){ + function initialize(callback){ $log.debug('Initializing scanner...'); QRScanner.prepare(function(err, status){ if(err){ @@ -103,19 +108,25 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti } }); } + this.initialize = initialize; // This could be much cleaner with a Promise API // (needs a polyfill for some platforms) var initializeCompleted = false; function _completeInitialization(status, callback){ _checkCapabilities(status); - $rootScope.$emit('scannerServiceInitialized'); initializeCompleted = true; - callback && callback(status); + $rootScope.$emit('scannerServiceInitialized'); + if(typeof callback === "function"){ + callback(status); + } } this.isInitialized = function(){ return initializeCompleted; } + this.initializeStarted = function(){ + return initializeStarted; + } var nextHide = null; var nextDestroy = null; @@ -132,7 +143,9 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti $log.debug('Activating scanner...'); QRScanner.show(function(status){ _checkCapabilities(status); - callback(status); + if(typeof callback === "function"){ + callback(status); + } }); if(nextHide !== null){ $timeout.cancel(nextHide); @@ -183,6 +196,12 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti QRScanner.destroy(); } + this.reinitialize = function(callback){ + initializeCompleted = false; + QRScanner.destroy(); + initialize(callback); + } + /** * Toggle the device light (if available). * @@ -228,4 +247,9 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti callback(status); }); }; + + this.openSettings = function() { + $log.debug('Attempting to open device settings...'); + QRScanner.openSettings(); + }; }); diff --git a/src/sass/views/tab-scan.scss b/src/sass/views/tab-scan.scss index ad6898c02..9fe049233 100644 --- a/src/sass/views/tab-scan.scss +++ b/src/sass/views/tab-scan.scss @@ -4,6 +4,9 @@ $scannerBackgroundColor: #060d2d; color: #fff; text-align: center; background: transparent none; + .bar-header { + opacity: .9; + } &-has-problems, &-loading-camera { background-color: $scannerBackgroundColor; @@ -50,7 +53,8 @@ $scannerBackgroundColor: #060d2d; } } &-loading-camera { - + height: 100%; + width: 100% } &-camera-ready { // view background is transparent to show video preview diff --git a/www/views/tab-scan.html b/www/views/tab-scan.html index 288e15915..d75188b4d 100644 --- a/www/views/tab-scan.html +++ b/www/views/tab-scan.html @@ -10,7 +10,7 @@
- +
Scan QR Codes
You can scan bitcoin addresses, payment requests, paper wallets, and more.
@@ -18,9 +18,9 @@
Enable the camera to get started.
Enable camera access in your device settings to get started.
Please connect a camera to get started.
- - - + + +