mirror of https://github.com/BTCPrivate/copay.git
feat(scan): first iteration of full scan view implementation
This commit is contained in:
parent
845534c727
commit
c0d4fbe5bb
|
@ -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;
|
||||
|
|
|
@ -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: '<a on-tap="openScanner()"><i class="icon ion-qr-scanner"></i></a>',
|
||||
template: '<a on-tap="openScanner()" nav-transition="none"><i class="icon ion-qr-scanner"></i></a>',
|
||||
link: function(scope, el, attrs) {
|
||||
|
||||
scope.openScanner = function() {
|
||||
$log.debug('Opening scanner by directive...');
|
||||
$ionicHistory.nextViewOptions({
|
||||
disableAnimate: true
|
||||
});
|
||||
$state.go('scanner', { passthroughMode: 1 });
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
});
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<ion-content scroll="false">
|
||||
<div class="ng-hide" id="tab-scan-has-problems" ng-show="currentState === scannerStates.unauthorized || currentState === scannerStates.denied || currentState === scannerStates.unavailable">
|
||||
<i class="icon zero-state-icon">
|
||||
<img src="img/tab-icons/ico-receive.svg" />
|
||||
<img src="img/tab-icons/ico-receive.svg"/>
|
||||
</i>
|
||||
<div class="zero-state-heading" translate>Scan QR Codes</div>
|
||||
<div class="zero-state-description" translate>You can scan bitcoin addresses, payment requests, paper wallets, and more.</div>
|
||||
|
@ -18,9 +18,9 @@
|
|||
<div class="ng-hide zero-state-tldr" ng-show="currentState === scannerStates.unauthorized" translate>Enable the camera to get started.</div>
|
||||
<div class="ng-hide zero-state-tldr" ng-show="currentState === scannerStates.denied" translate>Enable camera access in your device settings to get started.</div>
|
||||
<div class="ng-hide zero-state-tldr" ng-show="currentState === scannerStates.unavailable" translate>Please connect a camera to get started.</div>
|
||||
<button ng-show="currentState === scannerStates.unauthorized" class="ng-hide button button-standard button-primary" ng-click="attemptActivate">Allow Camera Access</button>
|
||||
<button ng-show="currentState === scannerStates.denied && canOpenSettings" class="ng-hide button button-standard button-primary" ng-click="openSettings">Open Settings</button>
|
||||
<button ng-show="currentState === scannerStates.unavailable" class="ng-hide button button-standard button-primary">Retry Camera</button>
|
||||
<button ng-show="currentState === scannerStates.unauthorized" class="ng-hide button button-standard button-primary" ng-click="authorize()">Allow Camera Access</button>
|
||||
<button ng-show="currentState === scannerStates.denied && canOpenSettings" class="ng-hide button button-standard button-primary" ng-click="openSettings()">Open Settings</button>
|
||||
<button ng-show="currentState === scannerStates.unavailable" class="ng-hide button button-standard button-primary" ng-click="attemptToReactivate()">Retry Camera</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ng-show" id="tab-scan-loading-camera" ng-show="currentState === scannerStates.loading"></div>
|
||||
|
|
Loading…
Reference in New Issue