send
This commit is contained in:
parent
8072082f4f
commit
b5023ae9e7
10 changed files with 547 additions and 251 deletions
88
public/views/amount.html
Normal file
88
public/views/amount.html
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<ion-view>
|
||||
|
||||
<ion-nav-title>Enter Amount</ion-nav-title>
|
||||
|
||||
<ion-pane>
|
||||
<ion-content class="calculator" scroll="false" class="amount" ng-controller="amountController" ng-init="init()">
|
||||
|
||||
<ion-nav-buttons side="primary">
|
||||
<button class="button" href ui-sref="tabs.send">
|
||||
<i class="ion-arrow-left-c"></i> Back
|
||||
</button>
|
||||
</ion-nav-buttons>
|
||||
|
||||
|
||||
<div class="list card">
|
||||
|
||||
<div class="item item-divider">
|
||||
Recipient
|
||||
</div>
|
||||
|
||||
<div class="item item-text-wrap item-icon-left">
|
||||
<i class="icon ion-ios-person-outline"></i>
|
||||
{{toName || toAddress}}
|
||||
</div>
|
||||
|
||||
<div class="item item-divider">
|
||||
Amount
|
||||
</div>
|
||||
|
||||
|
||||
<div class="item item-text-wrap item-button-right">
|
||||
|
||||
<button class="button black" ng-click="toggleAlternative()" ng-show="showAlternativeAmount">{{alternativeIsoCode}}</button>
|
||||
<button class="button transform-none" ng-click="toggleAlternative()" ng-show="!showAlternativeAmount">{{unitName}}</button>
|
||||
|
||||
<div class="text-light text-black m15b" ng-class="{'size-28': smallFont, 'size-36': !smallFont}"> <span> {{amount || "0.00" }}</div>
|
||||
<div class="text-light text-black" ng-class="{'size-16': smallFont, 'size-17': !smallFont}" ng-show="!showAlternativeAmount">
|
||||
{{globalResult}} <span class="label gray text-white radius">{{amountResult || '0.00'}} {{alternativeIsoCode}}</span>
|
||||
</div>
|
||||
<div class="text-light text-black size-17" ng-show="showAlternativeAmount">
|
||||
{{globalResult}} <span class="label gray text-white radius">{{alternativeResult || '0.00'}} {{unitName}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="button-calc">
|
||||
<div class="row m5b">
|
||||
<button class="col columns col-25 text-center m0 operator" ng-click="resetAmount()">
|
||||
AC
|
||||
</button>
|
||||
<button class="col columns text-center text-white m0"
|
||||
ng-style="{'background-color':recipientColor || '#4b6178'}"
|
||||
ng-disabled="alternativeResult <= 0 && amountResult <= 0" ng-click="finish()">
|
||||
OK
|
||||
</button>
|
||||
</div>
|
||||
<div class="row text-center">
|
||||
<div class="col columns" ng-click="pushDigit('7')">7</div>
|
||||
<div class="col columns" ng-click="pushDigit('8')">8</div>
|
||||
<div class="col columns" ng-click="pushDigit('9')">9</div>
|
||||
<div class="col columns operator" ng-click="pushOperator('/')">/</div>
|
||||
</div>
|
||||
|
||||
<div class="row text-center">
|
||||
<div class="col columns" ng-click="pushDigit('4')">4</div>
|
||||
<div class="col columns" ng-click="pushDigit('5')">5</div>
|
||||
<div class="col columns" ng-click="pushDigit('6')">6</div>
|
||||
<div class="col columns operator" ng-click="pushOperator('x')">x</div>
|
||||
</div>
|
||||
|
||||
<div class="row text-center">
|
||||
<div class="col columns" ng-click="pushDigit('1')">1</div>
|
||||
<div class="col columns" ng-click="pushDigit('2')">2</div>
|
||||
<div class="col columns" ng-click="pushDigit('3')">3</div>
|
||||
<div class="col columns operator" ng-click="pushOperator('+')">+</div>
|
||||
</div>
|
||||
|
||||
<div class="row text-center">
|
||||
<div class="col columns operator" ng-click="pushDigit('.')">.</div>
|
||||
<div class="col columns" ng-click="pushDigit('0')">0</div>
|
||||
<div class="col columns operator icon ion-arrow-left-a" ng-click="removeDigit()"></div>
|
||||
<div class="col columns operator" ng-click="pushOperator('-')">-</div>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-pane>
|
||||
</ion-view>
|
||||
81
public/views/confirm.html
Normal file
81
public/views/confirm.html
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<ion-view>
|
||||
|
||||
<ion-nav-title>Send confirmation</ion-nav-title>
|
||||
|
||||
<ion-pane>
|
||||
<ion-content scroll="false" ng-controller="confirmController" ng-init="init()">
|
||||
|
||||
|
||||
<ion-nav-buttons side="primary">
|
||||
<button class="button" href ui-sref="amount({toAddress: toAddress, toName: toName, toAmount: toAmount})">
|
||||
<i class="ion-arrow-left-c"></i> Back
|
||||
</button>
|
||||
</ion-nav-buttons>
|
||||
|
||||
|
||||
|
||||
<ion-content ng-style="{'background-color':'#f6f7f9'}">
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="card">
|
||||
<div class="item item-text-wrap">
|
||||
<i class="icon ion-arrow-up-c"></i> <span class="text-bold size-16">Sending</span>
|
||||
<div class="text-bold size-28 m15t">{{amount}} {{unitName}}</div>
|
||||
<div class="text-light size-20 m5t">{{alternativeAmount}} {{alternativeIsoCode}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list card">
|
||||
<div class="item">Fee: Economy (97 bits)</div>
|
||||
|
||||
<div class="item item-icon-left">
|
||||
<i class="icon ion-ios-person-outline"></i>
|
||||
<label translate>To</label>
|
||||
<p>{{toName || toAddress}}</p>
|
||||
</div>
|
||||
|
||||
<div class="item item-icon-left">
|
||||
<i class="icon icon-wallet size-21" ng-style="{'color':recipientColor}"></i>
|
||||
<label translate>From</label>
|
||||
</div>
|
||||
|
||||
<div class="item item-text-wrap" ng-style="{'height' : '200px'}">
|
||||
<ion-slides class="slides" options="options" slider="data.slider">
|
||||
<ion-slide-page ng-repeat="item in wallets track by $index" >
|
||||
<div class="list card">
|
||||
<ul class="pr">
|
||||
<li ng-show="wallets[0]" class="item item-icon-left">
|
||||
<i class="icon ion-briefcase size-21" ng-style="{'color':item.color}"></i>
|
||||
{{item.name || item.id}}
|
||||
<span class="item-note" ng-show="item.n > 1 && item.isComplete()">
|
||||
{{item.m}}-of-{{item.n}}
|
||||
</span>
|
||||
<span class="badge badge-assertive" ng-show="!item.isComplete()" translate>
|
||||
Incomplete
|
||||
</span>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</ion-slide-page>
|
||||
</ion-slides>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="item item-icon-right">
|
||||
Add Memo
|
||||
<i class="icon ion-ios-arrow-right size-21"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="item item-text-wrap item-icon-right" ng-click="cancel()">
|
||||
Slide to complete
|
||||
<i class="icon ion-ios-arrow-thin-right size-21"></i>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
|
||||
</ion-view>
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<ion-view cache-view="false">
|
||||
<ion-nav-bar class="bar-stable">
|
||||
<ion-nav-title>feedback</ion-nav-title>
|
||||
<ion-nav-buttons side="primary">
|
||||
<button class="button" href ui-sref="tabs.settings">
|
||||
<i class="ion-arrow-left-c"></i> Back
|
||||
</button>
|
||||
</ion-nav-buttons>
|
||||
</ion-nav-bar>
|
||||
<ion-content>
|
||||
</ion-content>
|
||||
</ion-view>
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
<ion-modal-view ng-controller="inputAmountController" ng-style="{'background-color':'#F6F7F9'}" ng-init=init()>
|
||||
<ion-header-bar align-title="center" class="tab-bar" ng-style="{'background-color':recipientColor}">
|
||||
<div class="buttons m3t" ng-click="cancel()">
|
||||
<button class="button text-white transform-none" ng-style="{'background-color':'transparent'}" translate>Close</button>
|
||||
</div>
|
||||
|
||||
<h1 class="title ellipsis text-white" translate>Enter amount</h1>
|
||||
|
||||
<div class="buttons m5r m3t" ng-if="!specificAmount && !sending" ng-click="toggleAlternative()">
|
||||
<button class="button black" ng-show="showAlternativeAmount">{{alternativeIsoCode}}</button>
|
||||
<button class="button text-whit transform-none" ng-show="!showAlternativeAmount">{{unitName}}</button>
|
||||
</div>
|
||||
|
||||
<div class="right-small m10r" ng-if="specificAmount">
|
||||
<a ng-click="init()">
|
||||
<span class="text-close" translate>Cancel</span>
|
||||
</a>
|
||||
</div>
|
||||
</ion-header-bar>
|
||||
|
||||
<ion-pane>
|
||||
<ion-content class="calculator" scroll="false" ng-show="!specificAmount && !sending">
|
||||
<div class="m5t">
|
||||
<label class="m15l">Recipient</label>
|
||||
<a class="item item-icon-left item-icon-right">
|
||||
<i class="icon ion-ios-person-outline"></i>
|
||||
{{recipientName}}
|
||||
<i class="icon ion-ios-close-empty"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="header-calc">
|
||||
<div class="text-light text-black m15b" ng-class="{'size-28': smallFont, 'size-36': !smallFont}">{{amount || '-'}}</div>
|
||||
<div class="text-light text-black" ng-class="{'size-16': smallFont, 'size-17': !smallFont}" ng-show="!showAlternativeAmount">
|
||||
{{globalResult}} <span class="label gray text-white radius">{{amountResult || '0.00'}} {{alternativeIsoCode}}</span>
|
||||
</div>
|
||||
<div class="text-light text-black size-17" ng-show="showAlternativeAmount">
|
||||
{{globalResult}} <span class="label gray text-white radius">{{alternativeResult || '0.00'}} {{unitName}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="button-calc">
|
||||
<div class="row m5b">
|
||||
<button class="col columns col-25 text-center m0 operator" ng-click="resetAmount()">
|
||||
AC
|
||||
</button>
|
||||
<button class="col columns text-center text-white m0"
|
||||
ng-style="{'background-color':recipientColor || '#4b6178'}"
|
||||
ng-disabled="alternativeResult <= 0 && amountResult <= 0" ng-click="finish()" ng-show="!specificAmount">
|
||||
OK
|
||||
</button>
|
||||
</div>
|
||||
<div class="row text-center">
|
||||
<div class="col columns" ng-click="pushDigit('7')">7</div>
|
||||
<div class="col columns" ng-click="pushDigit('8')">8</div>
|
||||
<div class="col columns" ng-click="pushDigit('9')">9</div>
|
||||
<div class="col columns operator" ng-click="pushOperator('/')">/</div>
|
||||
</div>
|
||||
|
||||
<div class="row text-center">
|
||||
<div class="col columns" ng-click="pushDigit('4')">4</div>
|
||||
<div class="col columns" ng-click="pushDigit('5')">5</div>
|
||||
<div class="col columns" ng-click="pushDigit('6')">6</div>
|
||||
<div class="col columns operator" ng-click="pushOperator('x')">x</div>
|
||||
</div>
|
||||
|
||||
<div class="row text-center">
|
||||
<div class="col columns" ng-click="pushDigit('1')">1</div>
|
||||
<div class="col columns" ng-click="pushDigit('2')">2</div>
|
||||
<div class="col columns" ng-click="pushDigit('3')">3</div>
|
||||
<div class="col columns operator" ng-click="pushOperator('+')">+</div>
|
||||
</div>
|
||||
|
||||
<div class="row text-center">
|
||||
<div class="col columns operator" ng-click="pushDigit('.')">.</div>
|
||||
<div class="col columns" ng-click="pushDigit('0')">0</div>
|
||||
<div class="col columns operator icon ion-arrow-left-a" ng-click="removeDigit()"></div>
|
||||
<div class="col columns operator" ng-click="pushOperator('-')">-</div>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
|
||||
<ion-content ng-show="specificAmount && !sending" ng-style="{'background-color':'#f6f7f9'}">
|
||||
<section class="modal-content m20b">
|
||||
<h4 class="title m10l" translate>QR Code</h4>
|
||||
<ul class="no-bullet size-14 m0">
|
||||
<li class="line-b p10 oh text-center">
|
||||
<qrcode size="220" data="bitcoin:{{addr + '?amount=' + customizedAmountBtc}}"></qrcode>
|
||||
<div class="m10t text-center" ng-show="isCordova">
|
||||
<span class="button outline dark-gray tiny round"
|
||||
ng-click="shareAddress('bitcoin:' + addr + '?amount=' + customizedAmountBtc)">
|
||||
<i class="fi-share"></i>
|
||||
<span translate>Share address</span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4 class="title m10l" translate>Details</h4>
|
||||
<ul class="no-bullet size-14 m0">
|
||||
<li class="line-b p10 oh">
|
||||
<span class="text-gray" translate>Address</span>:
|
||||
<span class="right">
|
||||
<span class="text-gray enable_text_select">{{addr}}</span>
|
||||
</span>
|
||||
</li>
|
||||
<li class="line-b p10 oh">
|
||||
<span class="text-gray" translate>Amount</span>:
|
||||
<span class="right">
|
||||
{{specificAmount}} {{unitName}}
|
||||
<span class="label gray radius">{{specificAlternativeAmount}} {{alternativeIsoCode}}</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="extra-margin-bottom"></div>
|
||||
</section>
|
||||
</ion-content>
|
||||
|
||||
<ion-content ng-show="sending">
|
||||
<div class="card">
|
||||
<div class="item item-text-wrap">
|
||||
<i class="icon ion-arrow-up-c"></i> <span class="text-bold size-16">Sending</span>
|
||||
<div class="text-bold size-28 m15t">{{sendingAmount}} {{unitName}}</div>
|
||||
<div class="text-light size-20 m5t">{{sendingAlternativeAmount}} {{alternativeIsoCode}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list card">
|
||||
<span class="item">Fee: Economy (97 bits)</span>
|
||||
|
||||
<span class="item item-icon-left">
|
||||
<i class="icon ion-ios-person-outline"></i>
|
||||
<label translate>To</label>
|
||||
<p>{{recipientName}}</p>
|
||||
</span>
|
||||
|
||||
<span class="item item-icon-left">
|
||||
<i class="icon icon-wallet size-21" ng-style="{'color':recipientColor}"></i>
|
||||
<label translate>From</label>
|
||||
<p>Focused Wallet (Default Wallet)</p>
|
||||
</span>
|
||||
|
||||
<span class="item item-icon-right">
|
||||
Add Memo
|
||||
<i class="icon ion-ios-arrow-right size-21"></i>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="item item-text-wrap item-icon-right" ng-click="cancel()">
|
||||
Slide to complete
|
||||
<i class="icon ion-ios-arrow-thin-right size-21"></i>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-pane>
|
||||
</ion-modal-view>
|
||||
|
|
@ -12,11 +12,11 @@
|
|||
<input type="text" placeholder="Search" ng-model="search" ng-change="findContact()">
|
||||
</label>
|
||||
|
||||
<h2>Contacts & Wallets</h2>
|
||||
<h3>Contacts & Wallets</h3>
|
||||
|
||||
<div class="list card">
|
||||
<ul class="pr">
|
||||
<li class="item item-icon-left" ng-repeat="item in list" ng-click="openInputAmountModal(item)">
|
||||
<li class="item item-icon-left" ng-repeat="item in list" ng-click="goToAmount(item)">
|
||||
|
||||
<i ng-show="item.isWallet" class="icon ion-briefcase size-21" ng-style="{'color':item.color}"></i>
|
||||
<i ng-show="!item.isWallet" class="icon ion-ios-person-outline"></i>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('inputAmountController', function($rootScope, $scope, $filter, $timeout, $ionicScrollDelegate, profileService, platformInfo, lodash, configService, go, rateService) {
|
||||
angular.module('copayApp.controllers').controller('amountController', function($rootScope, $scope, $filter, $timeout, $ionicScrollDelegate, walletService, platformInfo, lodash, configService, go, rateService, $stateParams, $window, $state, $log) {
|
||||
|
||||
|
||||
var unitToSatoshi;
|
||||
var satToUnit;
|
||||
var unitDecimals;
|
||||
|
|
@ -10,6 +12,45 @@ angular.module('copayApp.controllers').controller('inputAmountController', funct
|
|||
var LENGTH_EXPRESSION_LIMIT = 19;
|
||||
|
||||
$scope.init = function() {
|
||||
|
||||
if (!$stateParams.toAddress) {
|
||||
$log.error('Bad params at amount')
|
||||
throw ('bad params');
|
||||
}
|
||||
|
||||
var reNr = /^[1234567890\.]$/;
|
||||
var reOp = /^[\*\+\-\/]$/;
|
||||
|
||||
|
||||
var disableKeys = angular.element($window).on('keydown', function(e) {
|
||||
if (e.which === 8) { // you can add others here inside brackets.
|
||||
e.preventDefault();
|
||||
$scope.removeDigit();
|
||||
}
|
||||
|
||||
if (e.key && e.key.match(reNr))
|
||||
$scope.pushDigit(e.key);
|
||||
|
||||
else if (e.key && e.key.match(reOp))
|
||||
$scope.pushOperator(e.key);
|
||||
|
||||
else if (e.key && e.key == 'Enter')
|
||||
$scope.finish();
|
||||
|
||||
$timeout(function() {
|
||||
$scope.$apply();
|
||||
}, 10);
|
||||
|
||||
});
|
||||
|
||||
$scope.$on('$destroy', function() {
|
||||
angular.element($window).off('keydown');
|
||||
});
|
||||
|
||||
|
||||
$scope.toAddress = $stateParams.toAddress;
|
||||
$scope.toName = $stateParams.toName;
|
||||
|
||||
var config = configService.getSync().wallet.settings;
|
||||
$scope.unitName = config.unitName;
|
||||
$scope.alternativeIsoCode = config.alternativeIsoCode;
|
||||
|
|
@ -19,18 +60,20 @@ angular.module('copayApp.controllers').controller('inputAmountController', funct
|
|||
satToUnit = 1 / unitToSatoshi;
|
||||
satToBtc = 1 / 100000000;
|
||||
unitDecimals = config.unitDecimals;
|
||||
|
||||
// in SAT ALWAYS
|
||||
if ($stateParams.toAmount) {
|
||||
$scope.amount = (($stateParams.toAmount) * satToUnit).toFixed(unitDecimals) ;
|
||||
}
|
||||
|
||||
|
||||
processAmount($scope.amount);
|
||||
|
||||
$timeout(function() {
|
||||
$ionicScrollDelegate.resize();
|
||||
}, 100);
|
||||
};
|
||||
|
||||
$scope.shareAddress = function(uri) {
|
||||
if ($scope.isCordova) {
|
||||
window.plugins.socialsharing.share(uri, null, null, null);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleAlternative = function() {
|
||||
$scope.showAlternativeAmount = !$scope.showAlternativeAmount;
|
||||
|
||||
|
|
@ -54,6 +97,7 @@ angular.module('copayApp.controllers').controller('inputAmountController', funct
|
|||
};
|
||||
|
||||
$scope.pushOperator = function(operator) {
|
||||
console.log('[amount.js.90:operator:]', operator); //TODO
|
||||
if (!$scope.amount || $scope.amount.length == 0) return;
|
||||
$scope.amount = _pushOperator($scope.amount);
|
||||
|
||||
|
|
@ -100,7 +144,7 @@ angular.module('copayApp.controllers').controller('inputAmountController', funct
|
|||
if (lodash.isNumber(result)) {
|
||||
$scope.globalResult = isExpression(val) ? '= ' + processResult(result) : '';
|
||||
$scope.amountResult = $filter('formatFiatAmount')(toFiat(result));
|
||||
$scope.alternativeResult = profileService.formatAmount(fromFiat(result) * unitToSatoshi, true);
|
||||
$scope.alternativeResult = walletService.formatAmount(fromFiat(result) * unitToSatoshi, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -108,7 +152,7 @@ angular.module('copayApp.controllers').controller('inputAmountController', funct
|
|||
if ($scope.showAlternativeAmount)
|
||||
return $filter('formatFiatAmount')(val);
|
||||
else
|
||||
return profileService.formatAmount(val.toFixed(unitDecimals) * unitToSatoshi, true);
|
||||
return walletService.formatAmount(val.toFixed(unitDecimals) * unitToSatoshi, true);
|
||||
};
|
||||
|
||||
function fromFiat(val) {
|
||||
|
|
@ -142,31 +186,15 @@ angular.module('copayApp.controllers').controller('inputAmountController', funct
|
|||
$scope.finish = function() {
|
||||
var _amount = evaluate(format($scope.amount));
|
||||
var amount = $scope.showAlternativeAmount ? fromFiat(_amount).toFixed(unitDecimals) : _amount.toFixed(unitDecimals);
|
||||
var alternativeAmount = $scope.showAlternativeAmount ? _amount : toFiat(_amount);
|
||||
|
||||
if (amount % 1 == 0) amount = parseInt(amount);
|
||||
|
||||
if ($scope.addr) {
|
||||
$scope.specificAmount = profileService.formatAmount(amount * unitToSatoshi, true);
|
||||
$scope.specificAlternativeAmount = $filter('formatFiatAmount')(alternativeAmount);
|
||||
|
||||
if ($scope.unitName == 'bits') {
|
||||
var amountSat = parseInt((amount * unitToSatoshi).toFixed(0));
|
||||
amount = (amountSat * satToBtc).toFixed(8);
|
||||
}
|
||||
$scope.customizedAmountBtc = amount;
|
||||
|
||||
$timeout(function() {
|
||||
$ionicScrollDelegate.resize();
|
||||
}, 100);
|
||||
} else {
|
||||
$scope.sending = true;
|
||||
$scope.sendingAmount = profileService.formatAmount(amount * unitToSatoshi, true);
|
||||
$scope.sendingAlternativeAmount = $filter('formatFiatAmount')(alternativeAmount);
|
||||
}
|
||||
$state.transitionTo('confirm', {
|
||||
toAmount:amount * unitToSatoshi,
|
||||
toAddress: $scope.toAddress,
|
||||
toName: $scope.toName,
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cancel = function() {
|
||||
$scope.inputAmountModal.hide();
|
||||
$state.transitionTo('tabs.send');
|
||||
};
|
||||
});
|
||||
172
src/js/controllers/confirm.js
Normal file
172
src/js/controllers/confirm.js
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $filter, $timeout, $ionicScrollDelegate, walletService, platformInfo, lodash, configService, go, rateService, $stateParams, $window, $state, $log, profileService, bitcore) {
|
||||
|
||||
|
||||
var unitToSatoshi;
|
||||
var satToUnit;
|
||||
var unitDecimals;
|
||||
var satToBtc;
|
||||
var self = $scope.self;
|
||||
var SMALL_FONT_SIZE_LIMIT = 13;
|
||||
var LENGTH_EXPRESSION_LIMIT = 19;
|
||||
|
||||
$scope.init = function() {
|
||||
console.log('[confirm.js.23:$scope:]',$stateParams); //TODO
|
||||
|
||||
// TODO (URL , etc)
|
||||
if (!$stateParams.toAddress || !$stateParams.toAmount) {
|
||||
$log.error('Bad params at amount')
|
||||
throw ('bad params');
|
||||
}
|
||||
|
||||
$scope.isCordova = platformInfo.isCordova;
|
||||
|
||||
var config = configService.getSync().wallet.settings;
|
||||
$scope.unitName = config.unitName;
|
||||
$scope.alternativeIsoCode = config.alternativeIsoCode;
|
||||
|
||||
unitToSatoshi = config.unitToSatoshi;
|
||||
satToUnit = 1 / unitToSatoshi;
|
||||
satToBtc = 1 / 100000000;
|
||||
|
||||
$scope.toAmount = $stateParams.toAmount;
|
||||
$scope.amount = (($stateParams.toAmount) * satToUnit).toFixed(unitDecimals) ;
|
||||
$scope.toAddress = $stateParams.toAddress;
|
||||
$scope.toName = $stateParams.toName;
|
||||
|
||||
var network = (new bitcore.Address($scope.toAddress)).network.name;
|
||||
$scope.setWallets(network);
|
||||
|
||||
$scope.alternativeAmount = toFiat($scope.toAmount);
|
||||
unitDecimals = config.unitDecimals;
|
||||
$timeout(function() {
|
||||
$ionicScrollDelegate.resize();
|
||||
}, 100);
|
||||
};
|
||||
|
||||
|
||||
|
||||
var send = function() {
|
||||
if (!$scope._amount || !$scope._address) return;
|
||||
var unitToSat = this.unitToSatoshi;
|
||||
var currentSpendUnconfirmed = configWallet.spendUnconfirmed;
|
||||
|
||||
var outputs = [];
|
||||
|
||||
this.resetError();
|
||||
|
||||
if (isCordova && this.isWindowsPhoneApp)
|
||||
$rootScope.shouldHideMenuBar = true;
|
||||
|
||||
var form = $scope.sendForm;
|
||||
var comment = form.comment.$modelValue;
|
||||
|
||||
// ToDo: use a credential's (or fc's) function for this
|
||||
if (comment && !client.credentials.sharedEncryptingKey) {
|
||||
var msg = 'Could not add message to imported wallet without shared encrypting key';
|
||||
$log.warn(msg);
|
||||
return self.setSendError(gettext(msg));
|
||||
}
|
||||
|
||||
if (form.amount.$modelValue * unitToSat > Number.MAX_SAFE_INTEGER) {
|
||||
var msg = 'Amount too big';
|
||||
$log.warn(msg);
|
||||
return self.setSendError(gettext(msg));
|
||||
};
|
||||
|
||||
$timeout(function() {
|
||||
var paypro = self._paypro;
|
||||
var address, amount;
|
||||
|
||||
address = form.address.$modelValue;
|
||||
amount = parseInt((form.amount.$modelValue * unitToSat).toFixed(0));
|
||||
|
||||
outputs.push({
|
||||
'toAddress': address,
|
||||
'amount': amount,
|
||||
'message': comment
|
||||
});
|
||||
|
||||
var txp = {};
|
||||
|
||||
if (!lodash.isEmpty(self.sendMaxInfo)) {
|
||||
txp.sendMax = true;
|
||||
txp.inputs = self.sendMaxInfo.inputs;
|
||||
txp.fee = self.sendMaxInfo.fee;
|
||||
} else {
|
||||
txp.amount = amount;
|
||||
}
|
||||
|
||||
txp.toAddress = address;
|
||||
txp.outputs = outputs;
|
||||
txp.message = comment;
|
||||
txp.payProUrl = paypro ? paypro.url : null;
|
||||
txp.excludeUnconfirmedUtxos = configWallet.spendUnconfirmed ? false : true;
|
||||
txp.feeLevel = walletSettings.feeLevel || 'normal';
|
||||
|
||||
ongoingProcess.set('creatingTx', true);
|
||||
walletService.createTx(client, txp, function(err, createdTxp) {
|
||||
ongoingProcess.set('creatingTx', false);
|
||||
if (err) {
|
||||
return self.setSendError(err);
|
||||
}
|
||||
|
||||
if (!client.canSign() && !client.isPrivKeyExternal()) {
|
||||
$log.info('No signing proposal: No private key');
|
||||
ongoingProcess.set('sendingTx', true);
|
||||
walletService.publishTx(client, createdTxp, function(err, publishedTxp) {
|
||||
ongoingProcess.set('sendingTx', false);
|
||||
if (err) {
|
||||
return self.setSendError(err);
|
||||
}
|
||||
self.resetForm();
|
||||
go.walletHome();
|
||||
var type = txStatus.notify(createdTxp);
|
||||
$scope.openStatusModal(type, createdTxp, function() {
|
||||
return $scope.$emit('Local/TxProposalAction');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
$rootScope.$emit('Local/NeedsConfirmation', createdTxp, function(accept) {
|
||||
if (accept) self.confirmTx(createdTxp);
|
||||
else self.resetForm();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}, 100);
|
||||
};
|
||||
|
||||
|
||||
|
||||
function fromFiat(val) {
|
||||
return parseFloat((rateService.fromFiat(val, $scope.alternativeIsoCode) * satToUnit).toFixed(unitDecimals), 10);
|
||||
};
|
||||
|
||||
function toFiat(val) {
|
||||
return parseFloat((rateService.toFiat(val * unitToSatoshi, $scope.alternativeIsoCode)).toFixed(2), 10);
|
||||
};
|
||||
|
||||
$scope.finish = function() {
|
||||
var _amount = evaluate(format($scope.amount));
|
||||
var amount = $scope.showAlternativeAmount ? fromFiat(_amount).toFixed(unitDecimals) : _amount.toFixed(unitDecimals);
|
||||
|
||||
$state.transitionTo('confirm', {
|
||||
toAmount:walletService.formatAmount(amount * unitToSatoshi, true),
|
||||
toAddress: $scope.toAddress,
|
||||
toName: $scope.toName,
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cancel = function() {
|
||||
$state.transitionTo('tabs.send');
|
||||
};
|
||||
|
||||
$scope.setWallets = function(network) {
|
||||
$scope.wallets = profileService.getWallets({onlyComplete:true, network: network});
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
72
src/js/controllers/search.js
Normal file
72
src/js/controllers/search.js
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
|
||||
//
|
||||
// self.startSearch = function() {
|
||||
// self.isSearching = true;
|
||||
// self.txHistorySearchResults = [];
|
||||
// self.result = [];
|
||||
// self.historyShowMore = false;
|
||||
// self.nextTxHistory = self.historyShowMoreLimit;
|
||||
// }
|
||||
//
|
||||
// self.cancelSearch = function() {
|
||||
// self.isSearching = false;
|
||||
// self.result = [];
|
||||
// self.setCompactTxHistory();
|
||||
// }
|
||||
//
|
||||
// self.updateSearchInput = function(search) {
|
||||
// self.search = search;
|
||||
// if (isCordova)
|
||||
// window.plugins.toast.hide();
|
||||
// self.throttleSearch();
|
||||
// $ionicScrollDelegate.resize();
|
||||
// }
|
||||
//
|
||||
// self.throttleSearch = lodash.throttle(function() {
|
||||
//
|
||||
// function filter(search) {
|
||||
// self.result = [];
|
||||
//
|
||||
// function computeSearchableString(tx) {
|
||||
// var addrbook = '';
|
||||
// if (tx.addressTo && self.addressbook && self.addressbook[tx.addressTo]) addrbook = self.addressbook[tx.addressTo] || '';
|
||||
// var searchableDate = computeSearchableDate(new Date(tx.time * 1000));
|
||||
// var message = tx.message ? tx.message : '';
|
||||
// var comment = tx.note ? tx.note.body : '';
|
||||
// var addressTo = tx.addressTo ? tx.addressTo : '';
|
||||
// return ((tx.amountStr + message + addressTo + addrbook + searchableDate + comment).toString()).toLowerCase();
|
||||
// }
|
||||
//
|
||||
// function computeSearchableDate(date) {
|
||||
// var day = ('0' + date.getDate()).slice(-2).toString();
|
||||
// var month = ('0' + (date.getMonth() + 1)).slice(-2).toString();
|
||||
// var year = date.getFullYear();
|
||||
// return [month, day, year].join('/');
|
||||
// };
|
||||
//
|
||||
// if (lodash.isEmpty(search)) {
|
||||
// self.historyShowMore = false;
|
||||
// return [];
|
||||
// }
|
||||
// self.result = lodash.filter(self.completeHistory, function(tx) {
|
||||
// if (!tx.searcheableString) tx.searcheableString = computeSearchableString(tx);
|
||||
// return lodash.includes(tx.searcheableString, search.toLowerCase());
|
||||
// });
|
||||
//
|
||||
// if (self.result.length > self.historyShowLimit) self.historyShowMore = true;
|
||||
// else self.historyShowMore = false;
|
||||
//
|
||||
// return self.result;
|
||||
// };
|
||||
//
|
||||
// self.txHistorySearchResults = filter(self.search).slice(0, self.historyShowLimit);
|
||||
// if (isCordova)
|
||||
// window.plugins.toast.showShortBottom(gettextCatalog.getString('Matches: ' + self.result.length));
|
||||
//
|
||||
// $timeout(function() {
|
||||
// $rootScope.$apply();
|
||||
// });
|
||||
//
|
||||
// }, 1000);
|
||||
//
|
||||
|
|
@ -1,21 +1,25 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('copayApp.controllers').controller('tabSendController', function($scope, $ionicModal, $log, $timeout, addressbookService, profileService, configService, lodash) {
|
||||
angular.module('copayApp.controllers').controller('tabSendController', function($scope, $ionicModal, $log, $timeout, addressbookService, profileService, configService, lodash, $state, walletService) {
|
||||
|
||||
|
||||
var originalList = [];
|
||||
|
||||
$scope.search = '';
|
||||
|
||||
|
||||
$scope.init = function() {
|
||||
|
||||
var wallets = profileService.getWallets();
|
||||
var wallets = profileService.getWallets({onlyComplete: true});
|
||||
|
||||
lodash.each(wallets, function(v) {
|
||||
originalList.push({
|
||||
color: v.color,
|
||||
label: v.name,
|
||||
isWallet: true,
|
||||
getAddress: function(cb) {
|
||||
console.log('[tab-send.js.20] get ADDRESS at wallet!!!', v.name); //TODO
|
||||
walletService.getAddress(v, false, cb);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -26,7 +30,9 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
|
|||
lodash.each(ab, function(v, k) {
|
||||
contacts.push({
|
||||
label: k,
|
||||
address: v,
|
||||
getAddress: function(cb) {
|
||||
return cb(null,v);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -37,11 +43,11 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
|
|||
|
||||
$scope.findContact = function() {
|
||||
|
||||
if (!$scope.search || $scope.search.length<2){
|
||||
if (!$scope.search || $scope.search.length < 2) {
|
||||
$scope.list = originalList;
|
||||
$timeout(function() {
|
||||
$scope.$apply();
|
||||
},10);
|
||||
}, 10);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -53,15 +59,14 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
|
|||
$scope.list = result;
|
||||
};
|
||||
|
||||
$scope.openInputAmountModal = function(recipient) {
|
||||
$scope.recipientName = recipient.name || recipient.label;
|
||||
$scope.recipientColor = recipient.color;
|
||||
|
||||
$ionicModal.fromTemplateUrl('views/modals/inputAmount.html', {
|
||||
scope: $scope
|
||||
}).then(function(modal) {
|
||||
$scope.inputAmountModal = modal;
|
||||
$scope.inputAmountModal.show();
|
||||
$scope.goToAmount = function(item) {
|
||||
item.getAddress(function(err,addr){
|
||||
if (err|| !addr) {
|
||||
$log.error(err);
|
||||
return;
|
||||
}
|
||||
$log.debug('Got toAddress:' + addr + ' | ' + item.label)
|
||||
return $state.transitionTo('amount', { toAddress: addr, toName: item.label})
|
||||
});
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ if (window && window.navigator) {
|
|||
|
||||
//Setting up route
|
||||
angular.module('copayApp').config(function(historicLogProvider, $provide, $logProvider, $stateProvider, $urlRouterProvider, $compileProvider) {
|
||||
$urlRouterProvider.otherwise('/tabs');
|
||||
$urlRouterProvider.otherwise('/tabs.home');
|
||||
|
||||
$logProvider.debugEnabled(true);
|
||||
$provide.decorator('$log', ['$delegate', 'platformInfo',
|
||||
|
|
@ -116,6 +116,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
|
|||
})
|
||||
.state('tabs', {
|
||||
url: '/tabs',
|
||||
cache: false,
|
||||
needProfile: true,
|
||||
abstract: true,
|
||||
views: {
|
||||
|
|
@ -126,6 +127,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
|
|||
})
|
||||
.state('tabs.home', {
|
||||
url: '/home',
|
||||
cache: false,
|
||||
needProfile: true,
|
||||
views: {
|
||||
'tab-home': {
|
||||
|
|
@ -135,6 +137,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
|
|||
})
|
||||
.state('tabs.receive', {
|
||||
url: '/receive',
|
||||
cache: false,
|
||||
needProfile: true,
|
||||
views: {
|
||||
'tab-receive': {
|
||||
|
|
@ -144,6 +147,7 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
|
|||
})
|
||||
.state('tabs.send', {
|
||||
url: '/send',
|
||||
cache: false,
|
||||
needProfile: true,
|
||||
views: {
|
||||
'tab-send': {
|
||||
|
|
@ -160,15 +164,36 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
|
|||
},
|
||||
}
|
||||
})
|
||||
.state('feedback', {
|
||||
url: '/feedback',
|
||||
.state('amount', {
|
||||
cache: false,
|
||||
url: '/amount',
|
||||
needProfile: true,
|
||||
views: {
|
||||
'main': {
|
||||
templateUrl: 'views/feedback.html',
|
||||
templateUrl: 'views/amount.html',
|
||||
},
|
||||
}
|
||||
},
|
||||
params: {
|
||||
toAddress: null,
|
||||
toName: null,
|
||||
},
|
||||
})
|
||||
.state('confirm', {
|
||||
cache: false,
|
||||
url: '/confirm',
|
||||
needProfile: true,
|
||||
views: {
|
||||
'main': {
|
||||
templateUrl: 'views/confirm.html',
|
||||
},
|
||||
},
|
||||
params: {
|
||||
toAddress: null,
|
||||
toName: null,
|
||||
toAmount: null,
|
||||
},
|
||||
})
|
||||
|
||||
.state('unsupported', {
|
||||
url: '/unsupported',
|
||||
needProfile: false,
|
||||
|
|
@ -701,6 +726,29 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
|
|||
navigator.splashscreen.hide();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
|
||||
$log.info('Init profile...');
|
||||
// Try to open local profile
|
||||
profileService.loadAndBindProfile(function(err) {
|
||||
if (err) {
|
||||
if (err.message && err.message.match('NOPROFILE')) {
|
||||
$log.debug('No profile... redirecting');
|
||||
$state.transitionTo('disclaimer');
|
||||
} else if (err.message && err.message.match('NONAGREEDDISCLAIMER')) {
|
||||
$log.debug('Display disclaimer... redirecting');
|
||||
$state.transitionTo('disclaimer');
|
||||
} else {
|
||||
throw new Error(err); // TODO
|
||||
}
|
||||
} else {
|
||||
profileService.storeProfileIfDirty();
|
||||
$log.debug('Profile loaded ... Starting UX.');
|
||||
$state.transitionTo('tabs.home');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
uxLanguage.init();
|
||||
|
|
@ -724,34 +772,5 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
|
|||
$log.debug(' toParams:' + JSON.stringify(toParams || {}));
|
||||
$log.debug(' fromParams:' + JSON.stringify(fromParams || {}));
|
||||
|
||||
if (!profileService.profile && toState.needProfile) {
|
||||
|
||||
// Give us time to open / create the profile
|
||||
event.preventDefault();
|
||||
// Try to open local profile
|
||||
profileService.loadAndBindProfile(function(err) {
|
||||
if (err) {
|
||||
if (err.message && err.message.match('NOPROFILE')) {
|
||||
$log.debug('No profile... redirecting');
|
||||
$state.transitionTo('disclaimer');
|
||||
} else if (err.message && err.message.match('NONAGREEDDISCLAIMER')) {
|
||||
$log.debug('Display disclaimer... redirecting');
|
||||
$state.transitionTo('disclaimer');
|
||||
} else {
|
||||
throw new Error(err); // TODO
|
||||
}
|
||||
} else {
|
||||
profileService.storeProfileIfDirty();
|
||||
$log.debug('Profile loaded ... Starting UX.');
|
||||
$state.transitionTo(toState.name || toState, toParams);
|
||||
}
|
||||
});
|
||||
}
|
||||
// else {
|
||||
// if (profileService.focusedClient && !profileService.focusedClient.isComplete() && toState.walletShouldBeComplete) {
|
||||
//
|
||||
// $state.transitionTo('copayers');
|
||||
// }
|
||||
// }
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue