Revert "Revert "Scan handling""

This reverts commit 641091e7d9.
This commit is contained in:
Marty Alcala 2016-10-26 14:00:43 -04:00
parent 1f64c5adaa
commit 22d4a92f7d
25 changed files with 510 additions and 128 deletions

View File

@ -20,7 +20,9 @@
autocomplete="address-level4" />
</div>
<ion-nav-view></ion-nav-view>
<ion-nav-view>
<incoming-data-menu></incoming-data-menu>
</ion-nav-view>
<script src="lib/ionic.bundle.min.js"></script>
<script src="lib/angular.js"></script>

View File

@ -15,6 +15,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.toEmail = data.stateParams.toEmail;
$scope.description = data.stateParams.description;
$scope.paypro = data.stateParams.paypro;
$scope._paypro = $scope.paypro;
$scope.paymentExpired = {
value: false
};
@ -25,13 +26,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
});
var initConfirm = function() {
if ($scope.paypro) {
return setFromPayPro($scope.paypro, function(err) {
if (err && !isChromeApp) {
popupService.showAlert(gettext('Could not fetch payment'));
}
});
}
// TODO (URL , etc)
if (!$scope.toAddress || !$scope.toAmount) {
$log.error('Bad params at amount');
@ -100,6 +94,10 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$scope.alternativeAmountStr = v;
});
if($scope.paypro) {
_paymentTimeControl($scope.paypro.expires);
}
$timeout(function() {
$scope.$apply();
}, 100);
@ -149,56 +147,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
return amountStr.split(' ')[1];
}
var setFromPayPro = function(uri, cb) {
if (!cb) cb = function() {};
var wallet = profileService.getWallets({
onlyComplete: true
})[0];
if (!wallet) return cb();
if (isChromeApp) {
popupService.showAlert(gettextCatalog.getString('Payment Protocol not supported on Chrome App'));
return cb(true);
}
$log.debug('Fetch PayPro Request...', uri);
ongoingProcess.set('fetchingPayPro', true);
wallet.fetchPayPro({
payProUrl: uri,
}, function(err, paypro) {
ongoingProcess.set('fetchingPayPro', false);
if (err) {
$log.warn('Could not fetch payment request:', err);
var msg = err.toString();
if (msg.match('HTTP')) {
msg = gettextCatalog.getString('Could not fetch payment information');
}
popupService.showAlert(msg);
return cb(true);
}
if (!paypro.verified) {
$log.warn('Failed to verify payment protocol signatures');
popupService.showAlert(gettextCatalog.getString('Payment Protocol Invalid'));
return cb(true);
}
$scope.toAmount = paypro.amount;
$scope.toAddress = paypro.toAddress;
$scope.description = paypro.memo;
$scope.paypro = null;
$scope._paypro = paypro;
_paymentTimeControl(paypro.expires);
return initConfirm();
});
};
function _paymentTimeControl(expirationTime) {
$scope.paymentExpired.value = false;
setExpirationTime();
@ -219,7 +167,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
var m = Math.floor(totalSecs / 60);
var s = totalSecs % 60;
$scope.remainingTimeStr.value = ('0' + m).slice(-2) + ":" + ('0' + s).slice(-2);
};
}
function setExpiredValues() {
$scope.paymentExpired.value = true;
@ -228,8 +176,8 @@ angular.module('copayApp.controllers').controller('confirmController', function(
$timeout(function() {
$scope.$apply();
});
};
};
}
}
function setWallet(wallet, delayed) {
var stop;
@ -257,7 +205,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
});
}, delayed ? 2000 : 1);
}
};
}
var setSendError = function(msg) {
$scope.sendStatus = '';
@ -294,7 +242,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
var msg = 'Amount too big';
$log.warn(msg);
return setSendError(msg);
};
}
outputs.push({
'toAddress': toAddress,
@ -313,7 +261,9 @@ angular.module('copayApp.controllers').controller('confirmController', function(
txp.outputs = outputs;
txp.message = description;
txp.payProUrl = paypro;
if(paypro) {
txp.payProUrl = paypro.url;
}
txp.excludeUnconfirmedUtxos = config.spendUnconfirmed ? false : true;
txp.feeLevel = config.settings && config.settings.feeLevel ? config.settings.feeLevel : 'normal';
txp.dryRun = dryRun;
@ -349,7 +299,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
var wallet = $scope.wallet;
if (!wallet) {
return setSendError(gettextCatalog.getString('No wallet selected'));
};
}
if (!wallet.canSign() && !wallet.isPrivKeyExternal()) {
$log.info('No signing proposal: No private key');

View File

@ -58,6 +58,7 @@ angular.module('copayApp.controllers').controller('tabScanController', function(
$scope.$on("$ionicView.afterEnter", function() {
// try initializing and refreshing status any time the view is entered
scannerService.gentleInitialize();
scannerService.resumePreview();
});
function activate(){
@ -95,9 +96,15 @@ angular.module('copayApp.controllers').controller('tabScanController', function(
function handleSuccessfulScan(contents){
$log.debug('Scan returned: "' + contents + '"');
scannerService.pausePreview();
incomingData.redir(contents);
}
$rootScope.$on('incomingDataMenu.menuHidden', function() {
scannerService.resumePreview();
activate();
});
$scope.openSettings = function(){
scannerService.openSettings();
};
@ -126,7 +133,7 @@ angular.module('copayApp.controllers').controller('tabScanController', function(
$scope.canGoBack = function(){
return $state.params.passthroughMode;
}
};
function goBack(){
$ionicHistory.nextViewOptions({
disableAnimate: true

View File

@ -61,7 +61,7 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
$scope.openScanner = function() {
$state.go('tabs.scan');
}
};
$scope.showMore = function() {
currentContactsPage++;

View File

@ -1,7 +1,7 @@
'use strict';
angular.module('copayApp.directives')
.directive('actionSheet', function() {
.directive('actionSheet', function($rootScope, $timeout) {
return {
restrict: 'E',
templateUrl: 'views/includes/actionSheet.html',
@ -10,8 +10,16 @@ angular.module('copayApp.directives')
show: '=actionSheetShow',
},
link: function(scope, element, attrs) {
scope.$watch('show', function() {
if(scope.show) {
$timeout(function() { scope.revealMenu = true; }, 100);
} else {
scope.revealMenu = false;
}
});
scope.hide = function() {
scope.show = false;
$rootScope.$broadcast('incomingDataMenu.menuHidden');
};
}
};

View File

@ -0,0 +1,50 @@
'use strict';
angular.module('copayApp.directives')
.directive('incomingDataMenu', function($timeout, $rootScope, $state, externalLinkService) {
return {
restrict: 'E',
templateUrl: 'views/includes/incomingDataMenu.html',
link: function(scope, element, attrs) {
$rootScope.$on('incomingDataMenu.showMenu', function(event, data) {
$timeout(function() {
scope.data = data.data;
scope.type = data.type;
scope.showMenu = true;
scope.https = false;
if(scope.type === 'url') {
if(scope.data.indexOf('https://') === 0) {
scope.https = true;
}
}
});
});
scope.hide = function() {
scope.showMenu = false;
$rootScope.$broadcast('incomingDataMenu.menuHidden');
};
scope.goToUrl = function(url){
externalLinkService.open(url);
};
scope.sendPaymentToAddress = function(bitcoinAddress) {
scope.showMenu = false;
$state.go('tabs.send').then(function() {
$timeout(function() {
$state.transitionTo('tabs.send.amount', {toAddress: bitcoinAddress});
}, 50);
});
};
scope.addToAddressBook = function(bitcoinAddress) {
scope.showMenu = false;
$timeout(function() {
$state.go('tabs.send').then(function() {
$timeout(function() {
$state.transitionTo('tabs.send.addressbook', {addressbookEntry: bitcoinAddress});
});
});
}, 100);
};
}
};
});

View File

@ -269,13 +269,14 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}
})
.state('tabs.send.confirm', {
url: '/confirm/:isWallet/:toAddress/:toName/:toAmount/:toEmail/:description/:paypro',
url: '/confirm/:isWallet/:toAddress/:toName/:toAmount/:toEmail/:description',
views: {
'tab-send@tabs': {
controller: 'confirmController',
templateUrl: 'views/confirm.html'
}
}
},
params: { paypro: null }
})
.state('tabs.send.addressbook', {
url: '/addressbook/add/:fromSendTab/:addressbookEntry',

View File

@ -1,9 +1,13 @@
'use strict';
angular.module('copayApp.services').factory('incomingData', function($log, $state, $window, $timeout, bitcore, lodash) {
angular.module('copayApp.services').factory('incomingData', function($log, $state, $window, $timeout, bitcore, profileService, popupService, ongoingProcess, platformInfo, gettextCatalog, $rootScope) {
var root = {};
root.showMenu = function(data) {
$rootScope.$broadcast('incomingDataMenu.showMenu', data);
};
root.redir = function(data) {
$log.debug('Processing incoming data: ' + data);
@ -21,7 +25,7 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
newUri.replace('://', ':');
return newUri;
};
}
function getParameterByName(name, url) {
if (!url) return;
@ -53,59 +57,59 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
var amount = parsed.amount ? parsed.amount : '';
$state.go('tabs.send');
// Timeout is required to enable the "Back" button
$timeout(function() {
if (parsed.r) {
$state.transitionTo('tabs.send.confirm', {paypro: parsed.r});
} else {
if (parsed.r) {
getPayProDetails(parsed.r, function(err, details) {
handlePayPro(details);
});
} else {
$state.go('tabs.send');
// Timeout is required to enable the "Back" button
$timeout(function() {
if (amount) {
$state.transitionTo('tabs.send.confirm', {toAmount: amount, toAddress: addr, description:message});
} else {
$state.transitionTo('tabs.send.amount', {toAddress: addr});
}
}
});
});
}
return true;
// Plain URL
} else if (/^https?:\/\//.test(data)) {
$state.go('tabs.send').then(function() {
$state.transitionTo('tabs.send.confirm', {paypro: data});
});
return true;
// Plain Address
} else if (bitcore.Address.isValid(data, 'livenet')) {
$state.go('tabs.send').then(function() {
$state.transitionTo('tabs.send.amount', {toAddress: data});
getPayProDetails(data, function(err, details) {
if(err) {
root.showMenu({data: data, type: 'url'});
return;
}
handlePayPro(details);
return true;
});
return true;
} else if (bitcore.Address.isValid(data, 'testnet')) {
$state.go('tabs.send').then(function() {
$state.transitionTo('tabs.send.amount', {toAddress: data});
});
return true;
// Plain Address
} else if (bitcore.Address.isValid(data, 'livenet') || bitcore.Address.isValid(data, 'testnet')) {
if($state.includes('tabs.scan')) {
root.showMenu({data: data, type: 'bitcoinAddress'});
} else {
goToAmountPage(data);
}
} else if (data && data.indexOf($window.appConfig.name + '://glidera') === 0) {
return $state.go('uriglidera', {url: data});
} else if (data && data.indexOf($window.appConfig.name + '://coinbase') === 0) {
return $state.go('uricoinbase', {url: data});
// Protocol
} else if (data && data.indexOf($window.appConfig.name + '://glidera')==0) {
return $state.go('uriglidera', {url: data});
} else if (data && data.indexOf($window.appConfig.name + '://coinbase')==0) {
return $state.go('uricoinbase', {url: data});
// BitPayCard Authentication
} else if (data && data.indexOf($window.appConfig.name + '://')==0) {
var secret = getParameterByName('secret', data);
var email = getParameterByName('email', data);
var otp = getParameterByName('otp', data);
$state.go('tabs.home').then(function() {
$state.transitionTo('tabs.bitpayCardIntro', {
secret: secret,
email: email,
otp: otp
// BitPayCard Authentication
} else if (data && data.indexOf($window.appConfig.name + '://') === 0) {
var secret = getParameterByName('secret', data);
var email = getParameterByName('email', data);
var otp = getParameterByName('otp', data);
$state.go('tabs.home').then(function() {
$state.transitionTo('tabs.bitpayCardIntro', {
secret: secret,
email: email,
otp: otp
});
});
});
return true;
return true;
// Join
} else if (data && data.match(/^copay:[0-9A-HJ-NP-Za-km-z]{70,80}$/)) {
@ -120,11 +124,74 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
$state.transitionTo('tabs.add.join', {url: data});
});
return true;
} else {
if($state.includes('tabs.scan')) {
root.showMenu({data: data, type: 'text'});
}
}
return false;
};
function getPayProDetails(uri, cb) {
if (!cb) cb = function() {};
var wallet = profileService.getWallets({
onlyComplete: true
})[0];
if (!wallet) return cb();
if (platformInfo.isChromeApp) {
popupService.showAlert(gettextCatalog.getString('Payment Protocol not supported on Chrome App'));
return cb(true);
}
$log.debug('Fetch PayPro Request...', uri);
ongoingProcess.set('fetchingPayPro', true);
wallet.fetchPayPro({
payProUrl: uri,
}, function(err, paypro) {
ongoingProcess.set('fetchingPayPro', false);
if (err) {
return cb(true);
}
if (!paypro.verified) {
$log.warn('Failed to verify payment protocol signatures');
popupService.showAlert(gettextCatalog.getString('Payment Protocol Invalid'));
return cb(true);
}
cb(null, paypro);
});
}
function goToAmountPage(toAddress) {
$state.go('tabs.send');
$timeout(function() {
$state.transitionTo('tabs.send.amount', {toAddress: toAddress});
}, 100);
}
function handlePayPro(payProDetails){
var stateParams = {
toAmount: payProDetails.amount,
toAddress: payProDetails.toAddress,
description: payProDetails.memo,
paypro: payProDetails
};
$state.go('tabs.send').then(function() {
$timeout(function() {
$state.transitionTo('tabs.send.confirm', stateParams);
});
});
}
return root;
});

View File

@ -1,9 +1,9 @@
'use strict';
angular.module('copayApp.services').service('scannerService', function($log, $timeout, platformInfo, $rootScope) {
angular.module('copayApp.services').service('scannerService', function($log, $timeout, platformInfo, $rootScope, $window) {
var isDesktop = !platformInfo.isCordova;
var QRScanner = window.QRScanner;
var QRScanner = $window.QRScanner;
var lightEnabled = false;
var backCamera = true; // the plugin defaults to the back camera
@ -55,8 +55,8 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
canEnableLight: canEnableLight,
canChangeCamera: canChangeCamera,
canOpenSettings: canOpenSettings
}
}
};
};
var initializeStarted = false;
/**
@ -123,10 +123,10 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
}
this.isInitialized = function(){
return initializeCompleted;
}
};
this.initializeStarted = function(){
return initializeStarted;
}
};
var nextHide = null;
var nextDestroy = null;
@ -167,6 +167,14 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
QRScanner.scan(callback);
};
this.pausePreview = function() {
QRScanner.pausePreview();
};
this.resumePreview = function() {
QRScanner.resumePreview();
};
/**
* Deactivate the QRScanner. To balance user-perceived performance and power
* consumption, this kicks off a countdown which will "sleep" the scanner
@ -177,7 +185,7 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
*/
this.deactivate = function(callback) {
$log.debug('Deactivating scanner...');
// QRScanner.cancelScan();
QRScanner.cancelScan();
nextHide = $timeout(_hide, hideAfterSeconds * 1000);
nextDestroy = $timeout(_destroy, destroyAfterSeconds * 1000);
};
@ -200,7 +208,7 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
initializeCompleted = false;
QRScanner.destroy();
initialize(callback);
}
};
/**
* Toggle the device light (if available).
@ -236,7 +244,7 @@ angular.module('copayApp.services').service('scannerService', function($log, $ti
var nextCamera = backCamera? 1 : 0;
function cameraToString(index){
return index === 1? 'front' : 'back'; // front = 1, back = 0
};
}
$log.debug('Toggling to the ' + cameraToString(nextCamera) + ' camera...');
QRScanner.useCamera(nextCamera, function(err, status){
if(err){

View File

@ -12,8 +12,8 @@ action-sheet {
transition: transform 250ms cubic-bezier(0.4, 0.0, 0.2, 1);
z-index: 100;
padding-top: 1.75rem;
padding-left: 2rem;
padding-right: .75rem;
padding-left: 1.25rem;
padding-right: 1.25rem;
color: #2f2f2f;
padding-bottom: 3.5rem;
max-width: 550px;

View File

@ -0,0 +1,81 @@
incoming-data-menu {
.bp-action-sheet__sheet {
padding-left: 0;
padding-right: 0;
padding-top: 0;
padding: 0;
}
.incoming-data-menu {
&__header {
padding-bottom: 1rem;
font-size: 16px;
}
&__item {
border-top: 1px solid #f7f4f4;
font-size: 14px;
padding: 1rem 1.25rem;
color: #4A4A4A;
display: flex;
align-items: center;
&.head {
display: block;
padding-top: 1.5rem;
}
&:first-child {
border: 0;
}
> img {
margin-left: .2rem;
position: absolute;
}
&__text {
padding-left: 2.7rem;
}
}
&__cancel {
background: #EDEDED;
font-size: 18px;
height: 66px;
display: flex;
align-items: center;
justify-content: center;
color: #3A3A3A;
border-top: 1px solid #e4e4e4;
&:active {
background: #dadada;
}
}
&__url {
background: rgba(203, 203, 203, .13);
padding: .5rem;
padding-left: 0;
border-radius: 4px;
display: flex;
align-items: center;
margin-bottom: .5rem;
&__icon {
padding: 0 9px 0 10px;
display: flex;
align-items: center;
}
&__text {
color: #4A4A4A;
font-size: 14px;
border-left: 1px solid #E4E4E4;
padding-left: .7rem;//1rem;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
}
}

View File

@ -1,7 +1,12 @@
wallet-selector {
$border-color: #EFEFEF;
.bp-action-sheet__sheet {
padding-left: 2rem;
padding-right: .75rem;
}
.wallet-selector {
.wallet {
border: 0;

View File

@ -24,6 +24,7 @@
@import "includes/wallets";
@import "includes/modals/modals";
@import "includes/clickToAccept";
@import "includes/incomingDataMenu";
@import "includes/slideToAccept";
@import "includes/slideToAcceptSuccess";
@import "includes/tx-details";

22
www/img/icon-contacts.svg Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="17px" height="18px" viewBox="0 0 17 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 40.1 (33804) - http://www.bohemiancoding.com/sketch -->
<title>icons/list items/sync</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Scan" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2.2---Scan-Address" transform="translate(-21.000000, -454.000000)" stroke="#8F8F90">
<g id="Group-2" transform="translate(0.000000, 336.000000)">
<g id="icons/list-items/sync" transform="translate(22.000000, 119.000000)">
<g id="Group">
<path d="M0,16.3112128 L0,1.77635684e-15 L12.3636364,1.77635684e-15 C13.2136364,1.77635684e-15 13.9090909,0.667276888 13.9090909,1.48283753 L13.9090909,14.8283753 C13.9090909,15.6439359 13.2136364,16.3112128 12.3636364,16.3112128 L0,16.3112128 L0,16.3112128 Z" id="Shape"></path>
<path d="M15.4545455,2.22425629 L15.4545455,3.70709382" id="Shape"></path>
<path d="M15.4545455,5.93135011 L15.4545455,7.41418764" id="Shape"></path>
<path d="M7.72727273,7.93318078 L9.42727273,9.19359268 C9.81363636,9.49016018 10.0454545,9.93501144 10.0454545,10.3798627 L10.0454545,11.1212815 L3.86363636,11.1212815 L3.86363636,10.3798627 C3.86363636,9.93501144 4.09545455,9.49016018 4.48181818,9.19359268 L6.18181818,8.00732265" id="Shape"></path>
<path d="M6.95454545,8.15560641 L6.95454545,8.15560641 C6.10454545,8.15560641 5.40909091,7.48832952 5.40909091,6.67276888 L5.40909091,5.93135011 C5.40909091,5.11578947 6.10454545,4.44851259 6.95454545,4.44851259 L6.95454545,4.44851259 C7.80454545,4.44851259 8.5,5.11578947 8.5,5.93135011 L8.5,6.67276888 C8.5,7.48832952 7.80454545,8.15560641 6.95454545,8.15560641 L6.95454545,8.15560641 Z" id="Shape"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 40.1 (33804) - http://www.bohemiancoding.com/sketch -->
<title>arrows-24px-outline-4_launch-47</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Scan" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2.2---Scan-URL" transform="translate(-24.000000, -564.000000)" stroke="#8F8F90">
<g id="Group-2" transform="translate(0.000000, 448.000000)">
<g id="Group-3" transform="translate(0.000000, 98.000000)">
<g id="arrows-24px-outline-4_launch-47" transform="translate(25.000000, 19.000000)">
<g id="Group">
<path d="M8,8 L16,0" id="Shape"></path>
<polyline id="Shape" points="10.1818182 0 16 0 16 5.81818182"></polyline>
<polyline id="Shape" points="5.81818182 2.90909091 0 2.90909091 0 16 13.0909091 16 13.0909091 10.1818182"></polyline>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="bitpay-lock" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 15 20" style="enable-background:new 0 0 15 20;" xml:space="preserve">
<style type="text/css">
.st0{fill:#12E5B6;}
</style>
<path class="st0" d="M12.2,6.7V5.4c0-2.7-2-4.7-4.7-4.7s-4.7,2-4.7,4.7v1.4H0.5v12.5h13.9V6.7H12.2z M4.6,5.4c0-1.6,1.3-2.9,2.9-2.9
s2.9,1.3,2.9,2.9v1.4H4.6V5.4z M12.6,17.4H2.4V8.6h0.4h9.4h0.5V17.4z"/>
<path class="st0" d="M7.5,9.8c-1.3,0-2.4,1.1-2.4,2.4c0,1,0.7,1.9,1.5,2.2v0.7h1.9v-0.7c0.9-0.4,1.5-1.2,1.5-2.2
C9.9,10.9,8.8,9.8,7.5,9.8z M7.5,11.7c0.3,0,0.6,0.3,0.6,0.6c0,0.4-0.3,0.6-0.6,0.6s-0.6-0.3-0.6-0.6C6.9,12,7.2,11.7,7.5,11.7z"/>
</svg>

After

Width:  |  Height:  |  Size: 753 B

27
www/img/icon-lock-x.svg Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="19px" height="20px" viewBox="0 0 19 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 40.1 (33804) - http://www.bohemiancoding.com/sketch -->
<title>Group</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Addresss-(Unsecure-URL)" transform="translate(-9.000000, -9.000000)" stroke-width="2">
<g id="Items/Bitcoin-Address">
<g id="Items/Bitcoin-Address-Copy">
<g id="ui-24px-outline-1_lock" transform="translate(10.955302, 10.000000)">
<g id="Group">
<path d="M6.5,0 L6.5,0 C4.225,0 2.4375,1.8 2.4375,4.09090909 L2.4375,6.54545455 L10.5625,6.54545455 L10.5625,4.09090909 C10.5625,1.8 8.775,0 6.5,0 L6.5,0 Z" id="Shape" stroke="#CACACA" fill="#EEEEEE" opacity="0.800000012"></path>
<rect id="Rectangle-path" stroke="#CACACA" fill="#EEEEEE" opacity="0.800000012" x="0" y="6.54545455" width="13" height="11.4545455"></rect>
<g id="ui-24px-outline-2_small-remove" transform="translate(8.000000, 7.000000)" stroke="#E14F61">
<g id="Group">
<path d="M8,0 L0,8" id="Shape"></path>
<path d="M8,8 L0,0" id="Shape"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 40.1 (33804) - http://www.bohemiancoding.com/sketch -->
<title>Shape</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Scan" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2.2---Scan-Address" transform="translate(-20.000000, -565.000000)" stroke="#8F8F90">
<g id="Group-2" transform="translate(0.000000, 336.000000)">
<g id="ui-24px-outline-1_attach-87" transform="translate(21.000000, 230.000000)">
<g id="Group">
<path d="M17.6885043,8.49938195 L9.8566131,16.3312732 C7.631644,18.5562423 3.89369592,18.5562423 1.66872682,16.3312732 L1.66872682,16.3312732 C-0.556242274,14.1063041 -0.556242274,10.368356 1.66872682,8.1433869 L8.61063041,1.20148331 C10.2126082,-0.400494438 12.7045735,-0.400494438 14.3065513,1.20148331 L14.3065513,1.20148331 C15.908529,2.80346106 15.908529,5.29542645 14.3065513,6.8974042 L7.8986403,13.2163164 C7.00865266,14.1063041 5.58467244,14.1063041 4.78368356,13.2163164 L4.78368356,13.2163164 C3.89369592,12.3263288 3.89369592,10.9023486 4.78368356,10.1013597 L10.1236094,4.76143387" id="Shape"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

21
www/img/icon-send-alt.svg Normal file
View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="20px" height="16px" viewBox="0 0 20 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 40.1 (33804) - http://www.bohemiancoding.com/sketch -->
<title>Group</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Scan" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="2.2---Scan-Address" transform="translate(-20.000000, -511.000000)" stroke="#8F8F90">
<g id="Group-2" transform="translate(0.000000, 336.000000)">
<g id="Icons/Tabs/Send" transform="translate(19.000000, 172.000000)">
<g id="ui-24px-outline-1_send" transform="translate(10.498463, 10.316139) rotate(10.000000) translate(-10.498463, -10.316139) translate(1.998463, 2.316139)">
<g id="Group" transform="translate(0.000000, -0.000000)">
<polyline id="Shape" points="16.5 2.40696352e-13 4.125 9.6 4.125 15.2 7.095 11.76"></polyline>
<polygon id="Shape" points="2.30038211e-13 6.4 16.5 1.19015908e-13 13.2 16"></polygon>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="116.6 16.8 86.8 30.5"><path d="M203.4 24h-4.5l-2.6 11-.4 1.5c-.3.1-.5.1-.8.2-.5.1-.9.1-1.4.1-.6 0-1-.1-1.4-.3-.3-.2-.6-.4-.7-.7-.1-.3-.2-.7-.2-1.1 0-.4.1-.9.2-1.3l1.4-5.7.9-3.8h-4.6l-2.1 8.8c-.3 1.1-.4 2.1-.4 3 0 1 .1 1.8.4 2.5.3.7.9 1.3 1.7 1.7.8.4 1.9.6 3.3.6 1 0 1.9-.1 2.6-.3h.1c-.2.9-.6 1.6-1.3 2.2-.7.6-1.6.9-2.9.9-.5 0-1.1 0-1.5-.1l-.9 3.7c.6.1 1.3.1 2 .1 1.4 0 2.6-.2 3.6-.5s1.9-.8 2.7-1.4c.7-.6 1.4-1.4 1.9-2.4s.9-2.1 1.2-3.4l3.1-13.1.6-2.2zm-18.9 9.4c-.3 1.1-.4 2.3-.3 3.5.1 1.2.6 2.9 1 3.8h-4.4c-.5-.9-.5-1.3-.6-1.6-.6.5-1.2.8-1.9 1.1-.7.3-1.4.5-2.3.5-1 0-1.9-.2-2.6-.5-.7-.3-1.3-.8-1.8-1.4-.5-.6-.8-1.3-1-2.1-.2-.8-.3-1.6-.3-2.6 0-1.4.3-2.7.7-3.9.5-1.2 1.2-2.3 2.1-3.2.9-.9 3-3 6.5-3h7l-2.1 9.4zm-3.2-5.6c-2.1 0-2.5 0-3.4.4-.6.3-1.1.8-1.6 1.4-.4.5-.8 1.2-1.1 1.9-.3.7-.4 1.5-.4 2.3 0 1 .2 1.7.5 2.3s.9.8 1.8.8c.5 0 .9-.1 1.3-.3.4-.2.8-.5 1.2-.9 0-.5.1-1 .2-1.6s.2-1.1.3-1.5l1.2-4.8m-12.1 2.8c0 1.5-.3 2.8-.7 4.1-.5 1.2-1.2 2.3-2 3.2-.9.9-1.9 1.6-3.1 2.1-1.2.5-2.5.8-3.9.8-.7 0-1.4-.1-2.1-.2l-1.4 5.5h-4.5l5.2-22h6c1.1 0 2.1.2 2.9.5.8.3 1.5.8 2 1.4.5.6.9 1.3 1.2 2.1.3.7.4 1.6.4 2.5zm-11.1 6.2c.3.1.8.1 1.3.1.8 0 1.5-.1 2.2-.4.6-.3 1.2-.7 1.7-1.2s.8-1.2 1.1-1.9c.3-.7.4-1.6.4-2.5 0-.9-.2-1.6-.6-2.2-.4-.6-1.1-.9-2-.9h-1.8l-2.3 9zm-9.4 0c-.6 0-1-.1-1.4-.3-.3-.2-.6-.4-.7-.7-.1-.3-.2-.7-.2-1.1s.1-.9.2-1.3l1.4-5.7h5.1l.9-3.8h-5.2l1.2-4.8-4.8.8-3 12.9c-.3 1.1-.4 2.1-.4 3 0 1 .1 1.8.4 2.5.3.7.9 1.3 1.7 1.7.8.4 1.9.6 3.3.6 1 0 1.9-.1 2.6-.3.1 0 .2 0 .3-.1l.9-3.9c-.3.1-.6.2-.9.2-.5.3-.9.3-1.4.3zM137.2 24l-4 16.7h4.5l4-16.7zm4.9-2l.7-2.9h-4.5l-.7 2.9zm-14.9 2c1 0 1.8.2 2.5.5s1.3.8 1.8 1.4c.5.6.8 1.3 1 2.1s.3 1.6.3 2.5c0 1.4-.3 2.7-.8 4-.5 1.2-1.2 2.3-2.1 3.3s-1.9 1.6-3.2 2.2c-1.2.5-2.5.8-3.9.8h-1c-.5 0-1 0-1.6-.1-.6-.1-1.2-.2-1.9-.4s-1.3-.4-1.9-.7l5.2-22 4.7-.7-1.9 7.8c.4-.2.8-.3 1.2-.4.7-.3 1.1-.3 1.6-.3zm-4 13c.7 0 1.4-.2 2-.5.6-.3 1.2-.8 1.6-1.4.5-.6.8-1.2 1.1-1.9.3-.7.4-1.5.4-2.3 0-1-.2-1.7-.5-2.3-.3-.5-1-.8-1.9-.8-.3 0-.6 0-1 .1-.5.1-.8.3-1.2.6l-2 8.3c.6.1.8.1.9.1.2.1.4.1.6.1z" fill="#FFF"/></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

1
www/img/logo.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="252.5 17 185 64"><path d="M437.6 32.1H428l-5.6 23.4-.8 3.1c-.6.2-1 .2-1.7.4-1 .2-1.9.2-2.9.2-1.3 0-2.1-.2-2.9-.6-.6-.4-1.3-.8-1.5-1.5-.2-.6-.4-1.5-.4-2.3s.2-1.9.4-2.7l2.9-12.2 1.9-8.1h-9.8l-4.5 18.7c-.6 2.3-.8 4.5-.8 6.4 0 2.1.2 3.8.8 5.3.6 1.5 1.9 2.7 3.6 3.6 1.7.8 4.1 1.3 7 1.3 2.1 0 4.1-.2 5.6-.6h.2c-.4 1.9-1.3 3.4-2.7 4.7-1.5 1.3-3.4 1.9-6.2 1.9-1 0-2.3 0-3.1-.2l-2 7.9c1.3.2 2.7.2 4.3.2 2.9 0 5.6-.4 7.7-1 2.1-.6 4.1-1.7 5.8-2.9 1.5-1.3 2.9-2.9 4.1-5.1 1-2.1 1.9-4.5 2.5-7.2l6.6-27.8 1.1-4.9zM397.4 52c-.6 2.3-.8 4.9-.6 7.4.2 2.5 1.3 6.2 2.1 8.1h-9.3c-1-1.9-1-2.7-1.3-3.4-1.3 1-2.5 1.7-4.1 2.3-1.5.6-2.9 1-4.9 1-2.1 0-4.1-.4-5.6-1s-2.7-1.7-3.8-2.9c-1-1.3-1.7-2.7-2.1-4.5s-.6-3.4-.6-5.6c0-2.9.6-5.8 1.5-8.3 1-2.5 2.5-4.9 4.5-6.8 1.9-1.9 6.4-6.4 13.8-6.4h14.9L397.4 52zm-6.8-11.8c-4.5 0-5.3 0-7.2.8-1.3.6-2.3 1.7-3.4 2.9-.8 1-1.7 2.5-2.3 4.1-.6 1.5-.8 3.1-.8 4.9 0 2.1.4 3.6 1 4.9.6 1.2 1.9 1.7 3.8 1.7 1 0 1.9-.2 2.7-.6.8-.4 1.7-1 2.5-1.9 0-1 .2-2.1.4-3.4.2-1.3.4-2.3.6-3.1l2.7-10.3m-25.8 6c0 3.1-.6 6-1.5 8.7-1 2.5-2.5 4.9-4.3 6.8-1.9 1.9-4.1 3.4-6.6 4.5s-5.3 1.7-8.3 1.7c-1.5 0-2.9-.2-4.5-.4l-2.9 11.6h-9.5l11-46.8H351c2.3 0 4.5.4 6.2 1s3.1 1.7 4.3 2.9c1 1.3 1.9 2.7 2.5 4.5.6 1.6.8 3.5.8 5.5zm-23.5 13.1c.6.2 1.7.2 2.7.2 1.7 0 3.1-.2 4.7-.8 1.3-.6 2.5-1.5 3.6-2.5 1-1 1.7-2.5 2.3-4.1.6-1.5.8-3.4.8-5.3s-.4-3.4-1.3-4.7c-.8-1.3-2.3-1.9-4.3-1.9H346l-4.7 19.1zm-20 0c-1.3 0-2.1-.2-2.9-.6-.6-.4-1.3-.8-1.5-1.5-.2-.6-.4-1.5-.4-2.3 0-.8.2-1.9.4-2.7l2.9-12.2h10.8l1.9-8.1h-11l2.5-10.2-10.2 1.7-6.4 27.4c-.6 2.3-.8 4.5-.8 6.4 0 2.1.2 3.8.8 5.3.6 1.5 1.9 2.7 3.6 3.6 1.7.9 4.1 1.3 7 1.3 2.1 0 4.1-.2 5.6-.6.2 0 .4 0 .6-.2l1.9-8.3c-.6.2-1.3.4-1.9.4-1 .6-1.9.6-2.9.6zm-24.4-27.2l-8.5 35.5h9.5l8.5-35.5zm10.3-4.3l1.5-6.1h-9.5l-1.5 6.1zm-31.6 4.3c2.1 0 3.8.4 5.3 1s2.7 1.7 3.8 2.9c1 1.3 1.7 2.7 2.1 4.5s.6 3.4.6 5.3c0 2.9-.6 5.8-1.7 8.5-1 2.5-2.5 4.9-4.5 7-1.9 2.1-4.1 3.4-6.8 4.7-2.5 1-5.3 1.7-8.3 1.7H264c-1.1 0-2.1 0-3.4-.2-1.3-.2-2.5-.4-4.1-.8-1.5-.4-2.7-.8-4.1-1.5l11.1-46.6 10-1.5-4.1 16.6c.8-.4 1.7-.6 2.5-.8 1.8-.8 2.6-.8 3.7-.8zm-8.5 27.6c1.5 0 2.9-.4 4.3-1s2.5-1.7 3.4-2.9c1-1.3 1.7-2.5 2.3-4.1s.8-3.1.8-4.9c0-2.1-.4-3.6-1-4.9-.6-1-2.1-1.7-4.1-1.7-.6 0-1.3 0-2.1.2-1 .2-1.7.6-2.5 1.3L264 59.4c1.3.2 1.7.2 1.9.2.3.1.8.1 1.2.1z" fill="#002855"/></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,10 +1,8 @@
<div
class="bp-action-sheet__backdrop"
ng-class="{'fade-in': show}"
ng-class="{'fade-in': revealMenu}"
ng-click="hide()">
</div>
<div class="bp-action-sheet__sheet" ng-class="{'slide-up': show}">
<img class="back-arrow" src="img/icon-back-arrow.svg" ng-click="hide()">
<div class="header">Send from</div>
<div class="bp-action-sheet__sheet" ng-class="{'slide-up': revealMenu}">
<ng-transclude></ng-transclude>
</div>

View File

@ -0,0 +1,78 @@
<action-sheet
action-sheet-show="showMenu">
<div ng-if="type === 'url'">
<div class="incoming-data-menu__item head">
<div class="incoming-data-menu__header">Website</div>
<div class="incoming-data-menu__url">
<div class="incoming-data-menu__url__icon">
<img ng-hide="https" src="img/icon-lock-x.svg" style="height: 22px;">
<img ng-show="https" src="img/icon-lock-green.svg" style="height: 22px;">
</div>
<div class="incoming-data-menu__url__text">
{{data}}
</div>
</div>
</div>
<a class="incoming-data-menu__item item item-icon-right" ng-click="goToUrl(data)">
<img src="img/icon-link-external.svg">
<div class="incoming-data-menu__item__text">Open website</div>
<i class="icon bp-arrow-right"></i>
</a>
<a class="incoming-data-menu__cancel item" ng-click="hide()">
Cancel
</a>
</div>
<div ng-if="type === 'bitcoinAddress'">
<div class="incoming-data-menu__item head">
<div class="incoming-data-menu__header">Bitcoin Address</div>
<div class="incoming-data-menu__url">
<div class="incoming-data-menu__url__icon">
<img src="img/icon-bitcoin-small.svg">
</div>
<div class="incoming-data-menu__url__text">
{{data}}
</div>
</div>
</div>
<a class="incoming-data-menu__item item item-icon-right" ng-click="addToAddressBook(data)">
<img src="img/icon-contacts.svg">
<div class="incoming-data-menu__item__text">Add as a contact</div>
<i class="icon bp-arrow-right"></i>
</a>
<a class="incoming-data-menu__item item item-icon-right" ng-click="sendPaymentToAddress(data)">
<img src="img/icon-send-alt.svg">
<div class="incoming-data-menu__item__text">Send payment to this address</div>
<i class="icon bp-arrow-right"></i>
</a>
<a class="incoming-data-menu__item item item-icon-right" copy-to-clipboard="data">
<img src="img/icon-paperclip.svg">
<div class="incoming-data-menu__item__text">Copy to clipboard</div>
<i class="icon bp-arrow-right"></i>
</a>
<a class="incoming-data-menu__cancel item" ng-click="hide()">
Cancel
</a>
</div>
<div ng-if="type === 'text'">
<div class="incoming-data-menu__item head">
<div class="incoming-data-menu__header">Text</div>
<div class="incoming-data-menu__url">
<div class="incoming-data-menu__url__text" style="border: 0;">
{{data}}
</div>
</div>
</div>
<a class="incoming-data-menu__item item item-icon-right" copy-to-clipboard="data">
<img src="img/icon-paperclip.svg">
<div class="incoming-data-menu__item__text">Copy to clipboard</div>
<i class="icon bp-arrow-right"></i>
</a>
<a class="incoming-data-menu__cancel item" ng-click="hide()">
Cancel
</a>
</div>
</action-sheet>

View File

@ -1,4 +1,6 @@
<action-sheet action-sheet-show="show" class="wallet-selector">
<img class="back-arrow" src="img/icon-back-arrow.svg" ng-click="hide()">
<div class="header">Send from</div>
<a
ng-repeat="w in wallets track by $index"
class="item item-icon-left item-big-icon-left item-icon-right wallet"

View File

@ -42,4 +42,5 @@
</div>
</div>
</ion-content>
</ion-view>