Merge pull request #268 from Bitcoin-com/wallet/sprint/20

Wallet/sprint/20
This commit is contained in:
Jean-Baptiste Dominguez 2018-08-13 15:33:24 +09:00 committed by GitHub
commit b25879b251
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 503 additions and 301 deletions

View file

@ -29,6 +29,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
vm.finish = finish; vm.finish = finish;
vm.goBack = goBack; vm.goBack = goBack;
vm.loadMore = loadMore; vm.loadMore = loadMore;
vm.next = next;
vm.openPopup = openPopup; vm.openPopup = openPopup;
vm.pushDigit = pushDigit; vm.pushDigit = pushDigit;
vm.removeDigit = removeDigit; vm.removeDigit = removeDigit;
@ -66,15 +67,14 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
} }
function onBeforeEnter(event, data) { function onBeforeEnter(event, data) {
console.log('amount onBeforeEnter sendflow ', sendFlowService.getState());
if (data.direction == "back") { if (data.direction == "back") {
sendFlowService.popState(); sendFlowService.popState();
} }
console.log('amount onBeforeEnter after back sendflow ', sendFlowService.state);
initCurrencies(); initCurrencies();
passthroughParams = sendFlowService; passthroughParams = sendFlowService.getStateClone();
vm.fromWalletId = passthroughParams.fromWalletId; vm.fromWalletId = passthroughParams.fromWalletId;
vm.toWalletId = passthroughParams.toWalletId; vm.toWalletId = passthroughParams.toWalletId;
@ -463,7 +463,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
}; };
if (vm.thirdParty) { if (vm.thirdParty) {
confirmData['thirdParty'] = this.thirdParty; confirmData.thirdParty = vm.thirdParty;
} }
sendFlowService.pushState(confirmData); sendFlowService.pushState(confirmData);
@ -478,7 +478,7 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
// Currency // Currency
var next = 10; var nextCurrencies = 10;
var completeAlternativeList = []; var completeAlternativeList = [];
var popularCurrencyList = [ var popularCurrencyList = [
@ -537,12 +537,17 @@ function amountController(configService, $filter, gettextCatalog, $ionicHistory,
function loadMore() { function loadMore() {
$timeout(function() { $timeout(function() {
vm.altCurrencyList = completeAlternativeList.slice(0, next); vm.altCurrencyList = completeAlternativeList.slice(0, nextCurrencies);
next += 10; nextCurrencies += 10;
vm.listComplete = vm.altCurrencyList.length >= completeAlternativeList.length; vm.listComplete = vm.altCurrencyList.length >= completeAlternativeList.length;
$scope.$broadcast('scroll.infiniteScrollComplete'); $scope.$broadcast('scroll.infiniteScrollComplete');
}, 100); }, 100);
}; }
function next() {
useSendMax = false;
vm.finish();
}
function findCurrency(search) { function findCurrency(search) {
if (!search) initCurrencies(); if (!search) initCurrencies();

View file

@ -75,9 +75,9 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
function onBeforeEnter(event, data) { function onBeforeEnter(event, data) {
console.log('walletSelector onBeforeEnter sendflow ', sendFlowService.getState()); console.log('walletSelector onBeforeEnter sendflow ', sendFlowService.state);
defaults = configService.getDefaults(); defaults = configService.getDefaults();
sendFlowData = sendFlowService.getState(); sendFlowData = sendFlowService.getStateClone();
originWalletId = sendFlowData.fromWalletId; originWalletId = sendFlowData.fromWalletId;
satoshis = parseInt(sendFlowData.amount, 10); satoshis = parseInt(sendFlowData.amount, 10);
toAddress = sendFlowData.toAddress; toAddress = sendFlowData.toAddress;
@ -116,7 +116,9 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
if (!tx || !vm.originWallet) return; if (!tx || !vm.originWallet) return;
if (vm.paymentExpired) { if (vm.paymentExpired) {
popupService.showAlert(null, gettextCatalog.getString('This bitcoin payment request has expired.')); popupService.showAlert(null, gettextCatalog.getString('This bitcoin payment request has expired.', function () {
$ionicHistory.goBack();
}));
vm.sendStatus = ''; vm.sendStatus = '';
$timeout(function() { $timeout(function() {
$scope.$apply(); $scope.$apply();
@ -223,7 +225,7 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
// Grab stateParams // Grab stateParams
tx = { tx = {
amount: parseInt(sendFlowData.amount), amount: parseInt(sendFlowData.amount),
sendMax: sendFlowData.sendMax === 'true' ? true : false, sendMax: sendFlowData.sendMax,
fromWalletId: sendFlowData.fromWalletId, fromWalletId: sendFlowData.fromWalletId,
toAddress: sendFlowData.toAddress, toAddress: sendFlowData.toAddress,
paypro: txPayproData, paypro: txPayproData,
@ -486,20 +488,26 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
walletService.getAddress(vm.originWallet, false, function onReturnWalletAddress(err, returnAddr) { walletService.getAddress(vm.originWallet, false, function onReturnWalletAddress(err, returnAddr) {
if (err) { if (err) {
ongoingProcess.set('connectingShapeshift', false); ongoingProcess.set('connectingShapeshift', false);
popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString()); popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString(), function () {
$ionicHistory.goBack();
});
return; return;
} }
walletService.getAddress(toWallet, false, function onWithdrawalWalletAddress(err, withdrawalAddr) { walletService.getAddress(toWallet, false, function onWithdrawalWalletAddress(err, withdrawalAddr) {
if (err) { if (err) {
ongoingProcess.set('connectingShapeshift', false); ongoingProcess.set('connectingShapeshift', false);
popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString()); popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString(), function () {
$ionicHistory.goBack();
});
return; return;
} }
shapeshiftService.shiftIt(vm.originWallet.coin, toWallet.coin, withdrawalAddr, returnAddr, function onShiftIt(err, shapeshiftData) { shapeshiftService.shiftIt(vm.originWallet.coin, toWallet.coin, withdrawalAddr, returnAddr, function onShiftIt(err, shapeshiftData) {
if (err && err != null) { if (err && err != null) {
ongoingProcess.set('connectingShapeshift', false); ongoingProcess.set('connectingShapeshift', false);
popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString()); popupService.showAlert(gettextCatalog.getString('Shapeshift Error'), err.toString(), function () {
$ionicHistory.goBack();
});
} else { } else {
vm.memo = 'ShapeShift Order:\nhttps://www.shapeshift.io/#/status/' + shapeshiftData.orderId; vm.memo = 'ShapeShift Order:\nhttps://www.shapeshift.io/#/status/' + shapeshiftData.orderId;
vm.memoExpanded = !!vm.memo; vm.memoExpanded = !!vm.memo;
@ -640,7 +648,9 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
$timeout(function() { $timeout(function() {
$scope.$apply(); $scope.$apply();
}); });
popupService.showAlert(gettextCatalog.getString('Error at confirm'), bwcError.msg(msg)); popupService.showAlert(gettextCatalog.getString('Error at confirm'), bwcError.msg(msg), function () {
$ionicHistory.goBack();
});
}; };
function setupTx(tx) { function setupTx(tx) {
@ -825,7 +835,9 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
if (tx.sendMax && sendMaxInfo.amount == 0) { if (tx.sendMax && sendMaxInfo.amount == 0) {
ongoingProcess.set('calculatingFee', false); ongoingProcess.set('calculatingFee', false);
setNotReady(gettextCatalog.getString('Insufficient confirmed funds')); setNotReady(gettextCatalog.getString('Insufficient confirmed funds'));
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Not enough funds for fee')); popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Not enough funds for fee'), function () {
$ionicHistory.goBack();
});
return cb('no_funds'); return cb('no_funds');
} }

View file

@ -1,7 +1,7 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('tabHomeController', angular.module('copayApp.controllers').controller('tabHomeController',
function($rootScope, sendFlowService, $timeout, $scope, $state, $stateParams, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, bannerService, externalLinkService, latestReleaseService, profileService, walletService, configService, $log, platformInfo, storageService, txpModalService, appConfigService, startupService, addressbookService, bwcError, nextStepsService, buyAndSellService, homeIntegrationsService, bitpayCardService, pushNotificationsService, timeService, $ionicNavBarDelegate) { function($rootScope, $timeout, $scope, $state, $stateParams, $ionicModal, $ionicScrollDelegate, $window, gettextCatalog, lodash, popupService, ongoingProcess, bannerService, communityService, externalLinkService, latestReleaseService, profileService, walletService, configService, $log, platformInfo, sendFlowService, storageService, txpModalService, appConfigService, startupService, addressbookService, bwcError, nextStepsService, buyAndSellService, homeIntegrationsService, bitpayCardService, pushNotificationsService, timeService, bitcoincomService, pricechartService, firebaseEventsService, servicesService, shapeshiftService, $ionicNavBarDelegate, signVerifyMessageService) {
var wallet; var wallet;
var listeners = []; var listeners = [];
var notifications = []; var notifications = [];
@ -214,6 +214,7 @@ angular.module('copayApp.controllers').controller('tabHomeController',
var j = 0; var j = 0;
lodash.each(wallets, function(wallet) { lodash.each(wallets, function(wallet) {
walletService.invalidateCache(wallet); // Temporary solution, to have the good balance, when we ask to reload the wallets.
walletService.getStatus(wallet, {}, function(err, status) { walletService.getStatus(wallet, {}, function(err, status) {
if (err) { if (err) {

View file

@ -1,6 +1,6 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('tabReceiveController', function($rootScope, $scope, $timeout, $log, $ionicModal, $state, $ionicHistory, $ionicPopover, storageService, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService, bwcError, bitcoinCashJsService, $ionicNavBarDelegate, txFormatService, soundService, clipboardService) { angular.module('copayApp.controllers').controller('tabReceiveController', function($rootScope, $scope, $timeout, $log, $ionicModal, $state, $ionicHistory, $ionicPopover, storageService, platformInfo, walletService, profileService, configService, lodash, gettextCatalog, popupService, bwcError, bitcoinCashJsService, $ionicNavBarDelegate, sendFlowService, txFormatService, soundService, clipboardService) {
var listeners = []; var listeners = [];
$scope.bchAddressType = { type: 'cashaddr' }; $scope.bchAddressType = { type: 'cashaddr' };
@ -18,9 +18,10 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
$scope.displayBalanceAsFiat = true; $scope.displayBalanceAsFiat = true;
$scope.requestSpecificAmount = function() { $scope.requestSpecificAmount = function() {
$state.go('tabs.paymentRequest.amount', { sendFlowService.pushState({
toWalletId: $scope.wallet.credentials.walletId toWalletId: $scope.wallet.credentials.walletId
}); });
$state.go('tabs.paymentRequest.amount');
}; };
$scope.setAddress = function(newAddr, copyAddress) { $scope.setAddress = function(newAddr, copyAddress) {
@ -158,6 +159,10 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
soundService.play('misc/payment_received.mp3'); soundService.play('misc/payment_received.mp3');
} }
// Notify new tx
$scope.$emit('bwsEvent', $scope.wallet.id);
$scope.$apply(function () { $scope.$apply(function () {
$scope.showingPaymentReceived = true; $scope.showingPaymentReceived = true;
}); });

View file

@ -28,14 +28,15 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
}; };
$scope.$on("$ionicView.enter", function(event, data) { $scope.$on("$ionicView.enter", function(event, data) {
var stateParams = sendFlowService.getStateClone();
$scope.fromWallet = profileService.getWallet(stateParams.fromWalletId);
clipboardService.readFromClipboard(function(text) { clipboardService.readFromClipboard(function(text) {
if (text.length > 200) { if (text.length > 200) {
text = text.substring(0, 200); text = text.substring(0, 200);
} }
var stateParams = sendFlowService.getState();
$scope.fromWallet = profileService.getWallet(stateParams.fromWalletId);
$scope.clipboardHasAddress = false; $scope.clipboardHasAddress = false;
$scope.clipboardHasContent = false; $scope.clipboardHasContent = false;
if ((text.indexOf('bitcoincash:') === 0 || text[0] === 'C' || text[0] === 'H' || text[0] === 'p' || text[0] === 'q') && text.replace('bitcoincash:', '').length === 42) { // CashAddr if ((text.indexOf('bitcoincash:') === 0 || text[0] === 'C' || text[0] === 'H' || text[0] === 'p' || text[0] === 'q') && text.replace('bitcoincash:', '').length === 42) { // CashAddr
@ -183,7 +184,7 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
$log.debug('Got toAddress:' + toAddress + ' | ' + item.name); $log.debug('Got toAddress:' + toAddress + ' | ' + item.name);
var stateParams = sendFlowService.getState(); var stateParams = sendFlowService.getStateClone();
stateParams.toAddress = toAddress, stateParams.toAddress = toAddress,
stateParams.coin = item.coin; stateParams.coin = item.coin;
sendFlowService.pushState(stateParams); sendFlowService.pushState(stateParams);
@ -199,7 +200,7 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
$scope.startWalletToWalletTransfer = function() { $scope.startWalletToWalletTransfer = function() {
console.log('startWalletToWalletTransfer()'); console.log('startWalletToWalletTransfer()');
var params = sendFlowService.getState(); var params = sendFlowService.getStateClone();
sendFlowService.pushState(params); sendFlowService.pushState(params);
$state.transitionTo('tabs.send.wallet-to-wallet', { $state.transitionTo('tabs.send.wallet-to-wallet', {
fromWalletId: sendFlowService.fromWalletId fromWalletId: sendFlowService.fromWalletId
@ -221,7 +222,7 @@ angular.module('copayApp.controllers').controller('tabSendController', function(
$scope.$on("$ionicView.beforeEnter", function(event, data) { $scope.$on("$ionicView.beforeEnter", function(event, data) {
console.log(data); console.log(data);
console.log('tab-send onBeforeEnter sendflow ', sendFlowService.getState()); console.log('tab-send onBeforeEnter sendflow ', sendFlowService.state);
$scope.isIOS = platformInfo.isIOS && platformInfo.isCordova; $scope.isIOS = platformInfo.isIOS && platformInfo.isCordova;
$scope.showWalletsBch = $scope.showWalletsBtc = $scope.showWallets = false; $scope.showWalletsBch = $scope.showWalletsBtc = $scope.showWallets = false;

View file

@ -304,6 +304,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
}; };
function refreshAmountSection(scrollPos) { function refreshAmountSection(scrollPos) {
var AMOUNT_HEIGHT_BASE = 270;
$scope.showBalanceButton = false; $scope.showBalanceButton = false;
if ($scope.status) { if ($scope.status) {
$scope.showBalanceButton = ($scope.status.totalBalanceSat != $scope.status.spendableAmount); $scope.showBalanceButton = ($scope.status.totalBalanceSat != $scope.status.spendableAmount);
@ -315,16 +316,16 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
} }
scrollPos = scrollPos || 0; scrollPos = scrollPos || 0;
var amountHeight = 210 - scrollPos; var amountHeight = AMOUNT_HEIGHT_BASE - scrollPos;
if (amountHeight < 80) { if (amountHeight < 80) {
amountHeight = 80; amountHeight = 80;
} }
var contentMargin = amountHeight; var contentMargin = amountHeight;
if (contentMargin > 210) { if (contentMargin > AMOUNT_HEIGHT_BASE) {
contentMargin = 210; contentMargin = AMOUNT_HEIGHT_BASE;
} }
var amountScale = (amountHeight / 210); var amountScale = (amountHeight / AMOUNT_HEIGHT_BASE);
if (amountScale < 0.5) { if (amountScale < 0.5) {
amountScale = 0.5; amountScale = 0.5;
} }

View file

@ -11,13 +11,12 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
$scope.$on("$ionicView.enter", onEnter); $scope.$on("$ionicView.enter", onEnter);
function onBeforeEnter(event, data) { function onBeforeEnter(event, data) {
console.log('walletSelector onBeforeEnter sendflow', sendFlowService.getState());
if (data.direction == "back") { if (data.direction == "back") {
sendFlowService.popState(); sendFlowService.popState();
} }
console.log('walletSelector onBeforeEnter after back sendflow', sendFlowService.state);
var stateParams = sendFlowService.getState(); $scope.params = sendFlowService.getStateClone();
var config = configService.getSync().wallet.settings; var config = configService.getSync().wallet.settings;
priceDisplayAsFiat = config.priceDisplay === 'fiat'; priceDisplayAsFiat = config.priceDisplay === 'fiat';
@ -29,21 +28,23 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
$scope.sendFlowTitle = gettextCatalog.getString('Wallet to Wallet Transfer'); $scope.sendFlowTitle = gettextCatalog.getString('Wallet to Wallet Transfer');
break; break;
case 'tabs.send.destination': case 'tabs.send.destination':
if (stateParams.fromWalletId) { if ($scope.params.fromWalletId && !$scope.params.thirdParty) {
$scope.sendFlowTitle = gettextCatalog.getString('Wallet to Wallet Transfer'); $scope.sendFlowTitle = gettextCatalog.getString('Wallet to Wallet Transfer');
} }
break; break;
default: default:
if (!$scope.params.thirdParty) {
$scope.sendFlowTitle = gettextCatalog.getString('Send');
}
// nop // nop
} }
$scope.params = sendFlowService;
$scope.coin = false; // Wallets to show (for destination screen or contacts) $scope.coin = false; // Wallets to show (for destination screen or contacts)
$scope.type = $scope.params['fromWalletId'] ? 'destination' : 'origin'; // origin || destination $scope.type = $scope.params['fromWalletId'] ? 'destination' : 'origin'; // origin || destination
fromWalletId = $scope.params['fromWalletId']; fromWalletId = $scope.params['fromWalletId'];
if ($scope.type === 'destination' && $scope.params.toAddress) { if ($scope.type === 'destination' && $scope.params.toAddress) {
$state.transitionTo(getNextStep()); $state.transitionTo(getNextStep($scope.params));
} }
if ($scope.params.coin) { if ($scope.params.coin) {
@ -103,13 +104,10 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
} }
} }
function getNextStep() { function getNextStep(params) {
if ($scope.thirdParty) { if (!params.toWalletId && !params.toAddress) { // If we have no toAddress or fromWallet
$scope.params.thirdParty = $scope.thirdParty
}
if (!$scope.params.toWalletId && !$scope.params.toAddress) { // If we have no toAddress or fromWallet
return 'tabs.send.destination'; return 'tabs.send.destination';
} else if (!$scope.params.amount) { // If we have no amount } else if (!params.amount) { // If we have no amount
return 'tabs.send.amount'; return 'tabs.send.amount';
} else { // If we do have them } else { // If we do have them
return 'tabs.send.review'; return 'tabs.send.review';
@ -193,14 +191,16 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
$scope.useWallet = function(wallet) { $scope.useWallet = function(wallet) {
var params = sendFlowService.getState(); var params = sendFlowService.getStateClone();
if ($scope.type === 'origin') { // we're on the origin screen, set wallet to send from if ($scope.type === 'origin') { // we're on the origin screen, set wallet to send from
params.fromWalletId = wallet.id; params.fromWalletId = wallet.id;
} else { // we're on the destination screen, set wallet to send to } else { // we're on the destination screen, set wallet to send to
params.toWalletId = wallet.id; params.toWalletId = wallet.id;
} }
sendFlowService.pushState(params); sendFlowService.pushState(params);
$state.transitionTo(getNextStep(), $scope.params); var nextStep = getNextStep(params);
console.log('walletSelector nextStep', nextStep);
$state.transitionTo(nextStep, $scope.params);
}; };
$scope.goBack = function() { $scope.goBack = function() {

View file

@ -1,5 +1,6 @@
'use strict'; 'use strict';
(function(){
/** /**
* @desc amount directive that can be used to display formatted financial values * @desc amount directive that can be used to display formatted financial values
* size-equal attribute is optional, defaults to false. * size-equal attribute is optional, defaults to false.
@ -10,168 +11,189 @@
* @example <formatted-amount value="fee.value" currency="fee.currency"></formatted-amount> * @example <formatted-amount value="fee.value" currency="fee.currency"></formatted-amount>
* @example <formatted-amount value="fee.value" currency="fee.currency" size-equal="true"></formatted-amount> * @example <formatted-amount value="fee.value" currency="fee.currency" size-equal="true"></formatted-amount>
*/ */
angular.module('bitcoincom.directives') angular
.directive('formattedAmount', function(uxLanguage) { .module('bitcoincom.directives')
return { .directive('formattedAmount', function() {
restrict: 'E', return {
scope: { restrict: 'E',
value: '@', scope: {
currency: '@', value: '@',
sizeEqual: '@' currency: '@',
}, sizeEqual: '@'
templateUrl: 'views/includes/formatted-amount.html', },
controller: function($scope, $timeout) { templateUrl: 'views/includes/formatted-amount.html',
$scope.canShow = false; controller: formattedAmountController
$scope.displaySizeEqual = !!$scope.sizeEqual;
$timeout(function onFormattedAmountTimeout() {
var decimalPlaces = {
'0': ['BIF', 'CLP', 'DJF', 'GNF', 'ILS', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'],
'3': ['BHD', 'IQD', 'JOD', 'KWD', 'OMR', 'TND'],
'8': ['BCH', 'BTC']
};
var localizeNumbers = function(x, minimumFractionDigits) {
var parsed = parseFloat(x);
var opts = {
minimumFractionDigits: minimumFractionDigits,
useGrouping: true
};
var lang = uxLanguage.getCurrentLanguage();
var localized = parsed.toLocaleString(lang, opts);
var corrected = ensureEnoughFractionalDigits(localized, x, minimumFractionDigits);
return corrected;
};
var buildAmount = function(start, middle, end) {
$scope.start = start;
$scope.middle = middle;
$scope.end = end;
};
var getDecimalPlaces = function(currency) {
if (decimalPlaces['0'].indexOf(currency.toUpperCase()) > -1) return '0';
if (decimalPlaces['3'].indexOf(currency.toUpperCase()) > -1) return '3';
if (decimalPlaces['8'].indexOf(currency.toUpperCase()) > -1) return '8';
return '2';
};
var getDecimalSeparator = function() {
var testNum = 1.5;
var testString = testNum.toLocaleString(uxLanguage.getCurrentLanguage());
// Some environments let you set decimal separators that are more than one character
var separator = /^1(.+)5$/.exec(testString)[1]
return separator;
};
var formatNumbers = function() {
// During watch, may be changed from having a separate currency value,
// to both being in value. Don't want to use previous currency value.
// Try to extract currency from value..
var currencySplit = $scope.value.split(" ");
if (currencySplit.length === 2) {
$scope.currency = currencySplit[1];
}
$scope.currency = $scope.currency || '';
var parsed = parseFloat($scope.value);
var valueFormatted = '';
var valueProcessing = '';
switch (getDecimalPlaces($scope.currency)) {
case '0':
if (isNaN(parsed)) {
buildAmount('-', '', '');
} else {
valueFormatted = localizeNumbers(Math.round(parsed), 0);
buildAmount(valueFormatted, '', '');
}
break;
case '3':
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '---', '', '');
} else {
valueProcessing = parsed.toFixed(3);
valueFormatted = localizeNumbers(valueProcessing, 3);
buildAmount(valueFormatted, '', '');
}
break;
case '8':
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '---', '', '');
} else if (parsed === 0) {
buildAmount('0', '', '');
} else {
valueFormatted = parsed.toFixed(8);
valueFormatted = localizeNumbers(valueFormatted, 8);
var start = valueFormatted.slice(0, -5);
var middle = valueFormatted.slice(-5, -2);
var end = valueFormatted.substr(valueFormatted.length - 2);
buildAmount(start, middle, end);
}
break;
default: // 2
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '--', '', '');
} else {
valueProcessing = parseFloat(parsed.toFixed(2));
valueFormatted = localizeNumbers(valueProcessing, 2);
buildAmount(valueFormatted, '', '');
}
break;
}
$scope.canShow = true;
};
formatNumbers();
$scope.$watchGroup(['currency', 'value'], function onFormattedAmountWatch() {
formatNumbers();
});
/**
* On Android 4.4, toLocaleString() only returns 3 fractional digits when 8 is specified.
*/
function ensureEnoughFractionalDigits(localizedString, number, desiredFractionDigits) {
if (desiredFractionDigits === 0) {
// Assume it is OK
return localizedString;
}
var fractionalRe = /^(\d*\D)(\d+)$/;
var match = fractionalRe.exec(localizedString);
if (match.length !== 3) {
// Don't know what's happening, just return what we have
return localizedString;
}
var decimals = match[2];
var decimalCount = decimals.length;
if (decimalCount >= desiredFractionDigits) {
// Everything is OK.
return localizedString;
}
if (typeof number !== 'number') {
number = parseFloat(number);
}
var fixed = number.toFixed(desiredFractionDigits);
var fixedMatch = fractionalRe.exec(fixed);
if (fixedMatch.length !== 3) {
// Don't know what's happening, just return what we have
return localizedString;
}
// Keeps locale decimal separator.
var enough = match[1] + fixedMatch[2];
return enough;
}
});
} }
});
function formattedAmountController($scope, uxLanguage) {
$scope.vm = {};
var vm = $scope.vm;
vm.currency = '';
vm.value = '';
$scope.canShow = false
$scope.displaySizeEqual = !!$scope.sizeEqual;
var decimalPlaces = {
'0': ['BIF', 'CLP', 'DJF', 'GNF', 'ILS', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'],
'3': ['BHD', 'IQD', 'JOD', 'KWD', 'OMR', 'TND'],
'8': ['BCH', 'BTC']
};
$scope.$watch('value', function onFormattedAmountWatch() {
formatNumbers();
});
function buildAmount(start, middle, end) {
$scope.start = start;
$scope.middle = middle;
$scope.end = end;
};
/**
* On Android 4.4, toLocaleString() only returns 3 fractional digits when 8 is specified.
*/
function ensureEnoughFractionDigits(localizedString, number, desiredFractionDigits) {
if (desiredFractionDigits === 0) {
// Assume it is OK
return localizedString;
}
var fractionalRe = /^-*(\d*\D)(\d+)$/;
var match = fractionalRe.exec(localizedString);
if (!match || match.length !== 3) {
// Don't know what's happening, just return what we have
return localizedString;
}
var decimals = match[2];
var decimalCount = decimals.length;
if (decimalCount >= desiredFractionDigits) {
// Everything is OK.
return localizedString;
}
if (typeof number !== 'number') {
number = parseFloat(number);
}
var fixed = number.toFixed(desiredFractionDigits);
var fixedMatch = fractionalRe.exec(fixed);
if (!fixedMatch || fixedMatch.length !== 3) {
// Don't know what's happening, just return what we have
return localizedString;
}
// Keeps locale decimal separator.
var enough = match[1] + fixedMatch[2];
return enough;
}
function formatNumbers() {
// Might get "< 0.01 USD" being passed in.
// During watch, may be changed from having a separate currency value,
// to both being in value. Don't want to use previous currency value.
// Try to extract currency from value..
if (!$scope.currency || $scope.currency.length === 0) {
var currencySplit = $scope.value.split(" ");
if (currencySplit.length >= 2) {
vm.currency = currencySplit[currencySplit.length - 1];
}
} else {
vm.currency = $scope.currency;
}
// Redo this when we have proper formatting for low fees
if ($scope.value.indexOf("<") === 0) {
buildAmount($scope.value, '', '');
vm.currency = '';
$scope.canShow = true;
return;
}
// Remove thousands separators for parseFloat()
$scope.value = $scope.value.replace(',', '');
var parsed = parseFloat($scope.value);
var valueFormatted = '';
var valueProcessing = '';
switch (getDecimalPlaces(vm.currency)) {
case '0':
if (isNaN(parsed)) {
buildAmount('-', '', '');
} else {
valueFormatted = localizeNumbers(Math.round(parsed), 0);
buildAmount(valueFormatted, '', '');
}
break;
case '3':
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '---', '', '');
} else {
valueProcessing = parsed.toFixed(3);
valueFormatted = localizeNumbers(valueProcessing, 3);
buildAmount(valueFormatted, '', '');
}
break;
case '8':
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '---', '', '');
} else if (parsed === 0) {
buildAmount('0', '', '');
} else {
valueFormatted = parsed.toFixed(8);
valueFormatted = localizeNumbers(valueFormatted, 8);
var start = valueFormatted.slice(0, -5);
var middle = valueFormatted.slice(-5, -2);
var end = valueFormatted.substr(valueFormatted.length - 2);
buildAmount(start, middle, end);
}
break;
default: // 2
if (isNaN(parsed)) {
buildAmount('-' + getDecimalSeparator() + '--', '', '');
} else {
valueProcessing = parseFloat(parsed.toFixed(2));
valueFormatted = localizeNumbers(valueProcessing, 2);
buildAmount(valueFormatted, '', '');
}
break;
}
$scope.canShow = true;
$scope.$apply();
};
function getDecimalPlaces(currency) {
if (decimalPlaces['0'].indexOf(currency.toUpperCase()) > -1) return '0';
if (decimalPlaces['3'].indexOf(currency.toUpperCase()) > -1) return '3';
if (decimalPlaces['8'].indexOf(currency.toUpperCase()) > -1) return '8';
return '2';
};
function getDecimalSeparator() {
var testNum = 1.5;
var testString = testNum.toLocaleString(uxLanguage.getCurrentLanguage());
// Some environments let you set decimal separators that are more than one character
var separator = /^1(.+)5$/.exec(testString)[1]
return separator;
};
function localizeNumbers(x, minimumFractionDigits) {
var parsed = parseFloat(x);
var opts = {
minimumFractionDigits: minimumFractionDigits,
useGrouping: true
};
var lang = uxLanguage.getCurrentLanguage();
var localized = parsed.toLocaleString(lang, opts);
var corrected = ensureEnoughFractionDigits(localized, x, minimumFractionDigits);
return corrected;
}; };
} }
);
})();

View file

@ -0,0 +1,120 @@
'use strict';
(function(){
angular
.module('bitcoincom.directives')
.directive('walletBalance', function() {
return {
restrict: 'E',
scope: {
displayAsFiat: '@',
totalBalanceSat: '@',
// The Wallet object is sometimes not stringify()-able, so not interpolatable,
// so can't be passed to a directive.
walletStatus: '@',
walletCachedBalance: '@',
walletCachedBalanceUpdatedOn: '@',
walletCachedStatus: '@'
},
templateUrl: 'views/includes/wallet-balance.html',
controller: walletBalanceController
}
});
function walletBalanceController($log, $scope, txFormatService) {
var cryptoBalanceHasBeenDisplayed = false;
formatBalance();
$scope.$watchGroup(['displayAsFiat', 'totalBalanceSat'], function onWalletBalanceWatch() {
formatBalance();
});
function displayCryptoBalance(walletStatus, walletCachedBalance, walletCachedBalanceUpdatedOn, walletCachedStatus) {
console.log('displayCryptoBalance()');
if (walletStatus && walletStatus.isValid && walletStatus.totalBalanceStr) {
setDisplay(walletStatus.totalBalanceStr, '');
cryptoBalanceHasBeenDisplayed = true;
return;
}
if (walletCachedBalance) {
setDisplay(walletCachedBalance, walletCachedBalanceUpdatedOn);
return;
}
if (walletCachedStatus && walletCachedStatus.isValid && walletCachedStatus.totalBalanceStr) {
setDisplay(walletCachedStatus.totalBalanceStr, '');
return;
}
setDisplay('', '');
}
function displayFiatBalance(walletStatus, walletCachedStatus) {
var displayAmount = '';
if (walletStatus && walletStatus.isValid && walletStatus.alternativeBalanceAvailable) {
displayAmount = walletStatus.totalBalanceAlternative + ' ' + walletStatus.alternativeIsoCode;
setDisplay(displayAmount, '');
return;
}
if (walletCachedStatus && walletCachedStatus.isValid && walletCachedStatus.alternativeBalanceAvailable) {
displayAmount = walletCachedStatus.totalBalanceAlternative + ' ' + walletCachedStatus.alternativeIsoCode;
setDisplay(displayAmount, '');
return;
}
getFiatBalance(wallet);
}
function formatBalance() {
var displayAsFiat = $scope.displayAsFiat === 'true';
var walletStatusObj = null;
var walletCachedBalance = null;
var walletCachedBalanceUpdatedOn = null;
var walletCachedStatusObj = null;
try {
walletStatusObj = JSON.parse($scope.walletStatus);
} catch (e) {
$log.warn('Failed to parse walletStatus.', e);
}
try {
walletCachedStatusObj = JSON.parse($scope.walletCachedStatus);
} catch (e) {
$log.warn('Failed to parse walletCachedStatus.', e);
}
if (!displayAsFiat || displayAsFiat && !cryptoBalanceHasBeenDisplayed) {
displayCryptoBalance(walletStatusObj, walletCachedBalance, walletCachedBalanceUpdatedOn, walletCachedStatusObj);
}
if (displayAsFiat) {
displayFiatBalance(walletStatusObj, walletCachedStatusObj);
}
}
function getFiatBalance(wallet) {
if (!(wallet.status && wallet.status.isValid)) {
$log.warn('Abandoning call to get fiat balance, because no valid wallet status.');
return;
}
txFormatService.formatAlternativeStr(wallet.coin, wallet.status.totalBalanceSat, function onFormatAlernativeStr(formatted) {
if (formatted) {
setDisplay(formatted, '');
}
});
}
function setDisplay(amount, cachedBalanceUpdatedOn) {
$scope.displayAmount = amount;
$scope.cachedBalanceUpdatedOn = cachedBalanceUpdatedOn;
}
}
})();

View file

@ -1277,6 +1277,13 @@ angular.module('copayApp').config(function(historicLogProvider, $provide, $logPr
}); });
window.BitAnalytics.ActionHandlers.trackAction(actionTabOpen); window.BitAnalytics.ActionHandlers.trackAction(actionTabOpen);
var actionShapeShiftStart = new window.BitAnalytics.ActionFactory.createAction('click', {
name: 'shapeshift_start_click',
class: 'track_shapeshift_start_click',
channels: [channel]
});
window.BitAnalytics.ActionHandlers.trackAction(actionShapeShiftStart);
// Init language // Init language
uxLanguage.init(function (lang) { uxLanguage.init(function (lang) {

View file

@ -82,7 +82,7 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
}); });
// Timeout is required to enable the "Back" button // Timeout is required to enable the "Back" button
$timeout(function() { $timeout(function() {
var params = sendFlowService.getState(); var params = sendFlowService.getStateClone();
if (amount) { if (amount) {
params.amount = amount; params.amount = amount;
@ -447,7 +447,7 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
amount: thirdPartyData.amount, amount: thirdPartyData.amount,
toAddress: thirdPartyData.toAddress, toAddress: thirdPartyData.toAddress,
coin: coin, coin: coin,
thirdParty: JSON.stringify(thirdPartyData) thirdParty: thirdPartyData
}; };
// fee // fee
@ -455,6 +455,9 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
stateParams.requiredFeeRate = thirdPartyData.requiredFeeRate * 1024; stateParams.requiredFeeRate = thirdPartyData.requiredFeeRate * 1024;
} }
// This does not make sense, thirdPartyData gets added by stateParams below
//sendFlowService.pushState(thirdPartyData);
scannerService.pausePreview(); scannerService.pausePreview();
$state.go('tabs.send', {}, { $state.go('tabs.send', {}, {
'reload': true, 'reload': true,

View file

@ -9,17 +9,21 @@ angular
function sendFlowService($log) { function sendFlowService($log) {
var service = { var service = {
amount: '', // A separate state variable so we can ensure it is cleared of everything,
fromWalletId: '', // even other properties added that this service does not know about. (such as "coin")
sendMax: false, state: {
thirdParty: null, amount: '',
toAddress: '', fromWalletId: '',
toWalletId: '', sendMax: false,
thirdParty: null,
toAddress: '',
toWalletId: ''
},
previousStates: [], previousStates: [],
// Functions // Functions
clear: clear, clear: clear,
getState: getState, getStateClone: getStateClone,
map: map, map: map,
popState: popState, popState: popState,
pushState: pushState, pushState: pushState,
@ -36,22 +40,24 @@ angular
function clearCurrent() { function clearCurrent() {
console.log("sendFlow clearCurrent()"); console.log("sendFlow clearCurrent()");
service.amount = ''; service.state = {
service.fromWalletId = ''; amount: '',
service.sendMax = false; fromWalletId: '',
service.thirdParty = null; sendMax: false,
service.toAddress = ''; thirdParty: null,
service.toWalletId = ''; toAddress: '',
toWalletId: ''
}
} }
/** /**
* Handy for debugging * Handy for debugging
*/ */
function getState() { function getStateClone() {
var currentState = {}; var currentState = {};
Object.keys(service).forEach(function forCurrentParam(key) { Object.keys(service.state).forEach(function forCurrentParam(key) {
if (typeof service[key] !== 'function' && key !== 'previousStates') { if (typeof service.state[key] !== 'function' && key !== 'previousStates') {
currentState[key] = service[key]; currentState[key] = service.state[key];
} }
}); });
return currentState; return currentState;
@ -68,7 +74,7 @@ angular
function map(params) { function map(params) {
Object.keys(params).forEach(function forNewParam(key) { Object.keys(params).forEach(function forNewParam(key) {
service[key] = params[key]; service.state[key] = params[key];
}); });
}; };
@ -85,7 +91,7 @@ angular
function pushState(params) { function pushState(params) {
console.log('sendFlow push'); console.log('sendFlow push');
var currentParams = getState(); var currentParams = getStateClone();
service.previousStates.push(currentParams); service.previousStates.push(currentParams);
clearCurrent(); clearCurrent();
map(params); map(params);

View file

@ -1,7 +1,12 @@
'use strict' 'use strict'
angular.module('copayApp.services').factory('servicesService', function(configService, $log, lodash) { angular.module('copayApp.services').factory('servicesService', function(configService, $log, lodash) {
var root = {}; var root = {};
var services = []; var services = [{
name: 'shapeshift',
title: 'Shapeshift',
icon: 'icon-shapeshift',
sref: 'tabs.shapeshift',
}];
root.register = function(serviceInfo) { root.register = function(serviceInfo) {
$log.info('Adding Services entry:' + serviceInfo.name); $log.info('Adding Services entry:' + serviceInfo.name);

View file

@ -137,17 +137,5 @@ angular.module('copayApp.services').factory('shapeshiftService', function ($http
}); });
}; };
var servicesItem = {
name: 'shapeshift',
title: 'Shapeshift',
icon: 'icon-shapeshift',
sref: 'tabs.shapeshift',
};
var register = function() {
servicesService.register(servicesItem);
};
register();
return root; return root;
}); });

View file

@ -74,7 +74,7 @@
color: #FFF; color: #FFF;
} }
&-outline { &-outline {
@include button-style(transparent, #FFFFFF, #FAFAFA, #FFF, #FFFFFF); @include button-style(transparent, #FFFFFF, #FFFFFF, #FFFFFF, #FFFFFF);
@include button-outline(#FFFFFF); @include button-outline(#FFFFFF);
background: none; background: none;
box-shadow: none; box-shadow: none;

View file

@ -9,3 +9,4 @@
@import "expand-content"; @import "expand-content";
@import "fee-summary"; @import "fee-summary";
@import "formatted-amount"; @import "formatted-amount";
@import "wallet-balance";

View file

@ -0,0 +1,3 @@
.wallet-balance-directive {
display: inline-block;
}

View file

@ -305,7 +305,8 @@
&.very-long { &.very-long {
input, .unit, .primary-amount-display { input, .unit, .primary-amount-display {
font-size: 0.9em; font-size: 1.2em; // OK for iPhone 5 / SE with BCH to 8dp
@media (min-width: 375px) { @media (min-width: 375px) {
font-size: 1.3em; font-size: 1.3em;
@ -382,41 +383,46 @@
.available-funds { .available-funds {
color: #6F6F70; color: #6F6F70;
text-align: left;
}
.change-currency {
text-align: right;
} }
.warning { .warning {
color: $v-warning-color-2; color: $v-warning-color-2;
} }
.extra, .extra {
button.extra { flex: 1;
/*display: flex;*/
flex: 0 1 auto;
}
button.extra {
background: none;
border: none;
color: #000;
font-family: 'ProximaNova';
font-size: 14px;
line-height: normal; line-height: normal;
min-height: auto;
min-width: auto;
padding: 0;
}
.button .icon:before { .button {
font-size: 14px; background: none;
line-height: normal; border: none;
} border-radius: 0;
color: #000;
font-family: 'ProximaNova';
font-size: 14px;
line-height: normal;
min-height: auto;
min-width: auto;
padding: 0;
}
.button .icon:before {
font-size: 14px;
line-height: normal;
}
.button { .button {
span { span {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
}
} }
} }
} }

View file

@ -1,5 +1,4 @@
#view-review { #view-review {
background-color: #494949;
slide-to-accept, slide-to-accept-success { slide-to-accept, slide-to-accept-success {
margin-bottom: constant(safe-area-inset-bottom); /* iOS 11.0 */ margin-bottom: constant(safe-area-inset-bottom); /* iOS 11.0 */

View file

@ -261,6 +261,7 @@
.no-alternative { .no-alternative {
padding-top: 45px; padding-top: 45px;
} }
.item.item-footer { .item.item-footer {
font-weight: lighter; font-weight: lighter;
} }

View file

@ -15359,8 +15359,6 @@ log-options #check-bar .checkbox-icon {
#view-review .fee-summary { #view-review .fee-summary {
position: absolute; position: absolute;
bottom: 92px; } bottom: 92px; }
#view-review .fee-summary-spacer {
height: 15px; }
#view-review .shapeshift-banner, #view-review .bitpay-banner, #view-review .egifter-banner { #view-review .shapeshift-banner, #view-review .bitpay-banner, #view-review .egifter-banner {
box-shadow: none; } box-shadow: none; }
#view-review .warning { #view-review .warning {

View file

@ -14,14 +14,14 @@
<div class="send-amount-tool"> <div class="send-amount-tool">
<div class="send-amount-tool-input amount"> <div class="send-amount-tool-input amount">
<div class="primary-amount" <div class="primary-amount"
ng-class="{long: vm.amount.length > 5, 'very-long': vm.amount.length > 10}"> ng-class="{long: vm.amount.length > 5, 'very-long': vm.amount.length > 8}">
<span class="primary-amount-display text-selectable"> <span class="primary-amount-display text-selectable">
<formatted-amount value="{{vm.amount || '0'}}" currency="{{vm.unit}}"></formatted-amount> {{vm.amount || '0'}} {{vm.unit}}
</span> </span>
</div> </div>
<span ng-show="vm.globalResult"><formatted-amount value="{{vm.globalResult}}" currency="{{vm.unit}}"></formatted-amount></span> <span ng-show="vm.globalResult"><formatted-amount value="{{vm.globalResult}}" currency="{{vm.unit}}"></formatted-amount></span>
<div class="alternative-amount"> <div class="alternative-amount">
<span class="text-selectable"><formatted-amount value="{{vm.alternativeAmount || '0.00'}}" currency="{{vm.alternativeUnit}}"></formatted-amount></span> <span class="text-selectable">{{vm.alternativeAmount || '0.00'}} {{vm.alternativeUnit}}</span>
</div> </div>
<div class="switch-currencies" ng-click="vm.changeUnit()"><img src="img/icon-convert.svg"></div> <div class="switch-currencies" ng-click="vm.changeUnit()"><img src="img/icon-convert.svg"></div>
</div> </div>
@ -34,17 +34,20 @@
</div> </div>
<div class="send-amount-extras text-center"> <div class="send-amount-extras text-center">
<button class="extra button" ng-click="vm.openPopup()"> <div class="extra change-currency">
<span> <button class="button" ng-click="vm.openPopup()">
<img src="img/icon-alternative-currency-black.svg"/> <span>
&ensp; <img src="img/icon-alternative-currency-black.svg"/>
<span translate>Change Currency</span> <pre> </pre>
</span> <span translate>Change Currency</span>
</button> </span>
</button>
</div>
<div class="extra available-funds" <div class="extra available-funds"
ng-class="{warning: vm.fundsAreInsufficient}" ng-class="{warning: vm.fundsAreInsufficient}"
ng-if="!vm.isRequestingSpecificAmount" translate> ng-if="!vm.isRequestingSpecificAmount" translate>
<span>Available Funds:</span>&ensp;<span><formatted-amount value="{{vm.availableFunds}}" size-equal="true"></formatted-amount></span> <span>Available Funds: </span><span><formatted-amount value="{{vm.availableFunds}}" size-equal="true"></formatted-amount></span>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -90,7 +93,7 @@
<button <button
class="button button-full button-primary no-margin" class="button button-full button-primary no-margin"
ng-disabled="!vm.allowSend" ng-disabled="!vm.allowSend"
ng-click="vm.finish()" ng-click="vm.next()"
style="position: absolute; bottom: 0;" style="position: absolute; bottom: 0;"
translate> translate>
Next Next

View file

@ -32,15 +32,15 @@
</div> </div>
<div ng-show="!showingPaymentReceived" class="amount"> <div ng-show="!showingPaymentReceived" class="amount">
<div ng-show="selectedPriceDisplay=='fiat'"> <div ng-show="selectedPriceDisplay=='fiat'">
<span class="size-36">{{amountUnitStr}}</span> <span class="size-36"><formatted-amount value="{{amountUnitStr}}"></formatted-amount></span>
<div class="size-14 amount-alternative"> <div class="size-14 amount-alternative">
{{altAmountStr | uppercase}} <formatted-amount value="{{altAmountStr | uppercase}}"></formatted-amount>
</div> </div>
</div> </div>
<div ng-show="selectedPriceDisplay=='crypto'"> <div ng-show="selectedPriceDisplay=='crypto'">
<span class="size-36">{{altAmountStr | uppercase}}</span> <span class="size-36"><formatted-amount value="{{altAmountStr | uppercase}}"></formatted-amount></span>
<div class="size-14 amount-alternative"> <div class="size-14 amount-alternative">
{{amountUnitStr}} <formatted-amount value="{{amountUnitStr}}"></formatted-amount>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,4 +1,4 @@
<div class="formatted-amount" <div class="formatted-amount"
ng-class="{ 'size-equal': displaySizeEqual }" ng-show="canShow"> ng-class="{ 'size-equal': displaySizeEqual }" ng-show="canShow">
<span ng-if="start.length > 0" class="start">{{start}}</span><span ng-if="middle.length > 0" class="middle">{{middle}}</span><span ng-if="end.length > 0" class="end">{{end}}</span><span ng-if="currency.length > 0" class="currency">{{currency}}</span> <span ng-if="start.length > 0" class="start">{{start}}</span><span ng-if="middle.length > 0" class="middle">{{middle}}</span><span ng-if="end.length > 0" class="end">{{end}}</span><span ng-if="vm.currency.length > 0" class="currency">{{vm.currency}}</span>
</div> </div>

View file

@ -24,7 +24,7 @@
(possible double spend) (possible double spend)
</span> </span>
<span ng-if="tx.action != 'invalid'"> <span ng-if="tx.action != 'invalid'">
{{tx.amountStr}} <formatted-amount value={{tx.amountStr}}></formatted-amount>
</span> </span>
</span> </span>
<div> <div>

View file

@ -0,0 +1,3 @@
<div class="wallet-balance-directive">
<formatted-amount value="{{displayAmount}}"></formatted-amount><span ng-if="age">{{&middot; (cachedBalanceUpdatedOn * 1000 | amTimeAgo)}}</span>
</div>

View file

@ -10,7 +10,7 @@
<div ng-if="notification.type == 'NewOutgoingTx'"> <div ng-if="notification.type == 'NewOutgoingTx'">
<span translate>Payment Sent </span> <span translate>Payment Sent </span>
<div class="wallet-activity-amount"> <div class="wallet-activity-amount">
{{notification.amountStr}} <formatted-amount value={{notification.amountStr}}
</div> </div>
</div> </div>
@ -19,7 +19,7 @@
<div ng-if="notification.type == 'NewIncomingTx'"> <div ng-if="notification.type == 'NewIncomingTx'">
<span translate>Payment Received</span> <span translate>Payment Received</span>
<div class="wallet-activity-amount"> <div class="wallet-activity-amount">
{{notification.amountStr}} <formatted-amount value={{notification.amountStr}}></formatted-amount>
</div> </div>
</div> </div>
@ -27,7 +27,7 @@
<span translate>Proposal Deleted</span>: <span translate>Proposal Deleted</span>:
<b>{{notification.message}}</b> <b>{{notification.message}}</b>
<div class="wallet-activity-amount"> <div class="wallet-activity-amount">
{{notification.amountStr}}: <formatted-amount value={{notification.amountStr}}></formatted-amount>:
</div> </div>
</div> </div>
@ -35,7 +35,7 @@
<span translate>Proposal Rejected</span>: <span translate>Proposal Rejected</span>:
<b>{{notification.message}}</b> <b>{{notification.message}}</b>
<div class="wallet-activity-amount"> <div class="wallet-activity-amount">
{{notification.amountStr}}: <formatted-amount value={{notification.amountStr}}></formatted-amount>:
</div> </div>
</div> </div>
@ -43,7 +43,7 @@
<span translate>New Proposal</span>: <span translate>New Proposal</span>:
<b>{{notification.message}}</b> <b>{{notification.message}}</b>
<div class="wallet-activity-amount"> <div class="wallet-activity-amount">
{{notification.amountStr}} <formatted-amount value={{notification.amountStr}}></formatted-amount>
</div> </div>
</span> </span>
@ -51,7 +51,7 @@
<span translate>Proposal Accepted</span>: <span translate>Proposal Accepted</span>:
<b>{{notification.message}}</b> <b>{{notification.message}}</b>
<div class="wallet-activity-amount"> <div class="wallet-activity-amount">
{{notification.amountStr}} <formatted-amount value={{notification.amountStr}}></formatted-amount>
</div> </div>
</span> </span>

View file

@ -8,10 +8,10 @@
</span> </span>
<span ng-if="wallet.isComplete()"> <span ng-if="wallet.isComplete()">
<span ng-if="selectedPriceDisplay == 'crypto' && !wallet.balanceHidden && !wallet.scanning"> <span ng-if="selectedPriceDisplay == 'crypto' && !wallet.balanceHidden && !wallet.scanning">
<formatted-amount value="{{wallet.status.totalBalanceStr ? wallet.status.totalBalanceStr : ( wallet.cachedBalance ? wallet.cachedBalance + (wallet.cachedBalanceUpdatedOn ? ' &middot; ' + ( wallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo) : '') : '' ) }}"></formatted-amount> <formatted-amount value="{{wallet.status.totalBalanceStr ? wallet.status.totalBalanceStr : ( wallet.cachedBalance ? wallet.cachedBalance : '' ) }}"></formatted-amount> {{(!wallet.status.totalBalanceStr && wallet.cachedBalanceUpdatedOn ? ' &middot; ' + ( wallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo) : '')}}
</span> </span>
<span ng-if="selectedPriceDisplay == 'fiat' && !wallet.balanceHidden && !wallet.scanning"> <span ng-if="selectedPriceDisplay == 'fiat' && !wallet.balanceHidden && !wallet.scanning">
<formatted-amount value="{{wallet.status.totalBalanceAlternative ? wallet.status.totalBalanceAlternative : ( wallet.cachedBalance ? wallet.cachedBalance + (wallet.cachedBalanceUpdatedOn ? ' &middot; ' + ( wallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo) : '') : '' ) }}" currency="{{wallet.status.alternativeIsoCode}}"></formatted-amount> <formatted-amount value="{{wallet.status.totalBalanceAlternative ? wallet.status.totalBalanceAlternative : (wallet.cachedBalance ? wallet.cachedBalance : '') }}" currency="{{wallet.status.alternativeIsoCode}}"></formatted-amount> {{( !wallet.status.totalBalanceAlternative && wallet.cachedBalance ? (wallet.cachedBalanceUpdatedOn ? ' &middot; ' + ( wallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo) : '') : '' )}}
</span> </span>
<span ng-if="wallet.scanning" translate> Scanning funds... </span> <span ng-if="wallet.scanning" translate> Scanning funds... </span>

View file

@ -11,8 +11,8 @@
<div class="header {{vm.origin.currency.toLowerCase()}}" ng-class="vm.thirdParty.id"> <div class="header {{vm.origin.currency.toLowerCase()}}" ng-class="vm.thirdParty.id">
<div class="content"> <div class="content">
<p>{{vm.sendingTitle}}</p> <p>{{vm.sendingTitle}}</p>
<p class="large">{{vm.primaryAmount}} {{vm.primaryCurrency}}</p> <p class="large"><formatted-amount value="{{vm.primaryAmount}}" currency="{{vm.primaryCurrency}}"></formatted-amount></p>
<p ng-show="vm.secondaryAmount">{{vm.secondaryAmount}} {{vm.secondaryCurrency}}</p> <p ng-show="vm.secondaryAmount"><formatted-amount value="{{vm.secondaryAmount}}" currency="{{vm.secondaryCurrency}}"></formatted-amount></p>
</div> </div>
</div> </div>
@ -89,7 +89,7 @@
<div class="fee-fiat positive" ng-if="vm.feeLessThanACent">Fee: Less than 1 cent</div> <div class="fee-fiat positive" ng-if="vm.feeLessThanACent">Fee: Less than 1 cent</div>
<div class="fee-fiat" ng-class="vm.feeIsHigh ? 'negative' : 'positive'" ng-if="!vm.feeLessThanACent">Fee: {{vm.feeFiat}} {{vm.feeCurrency}}</div> <div class="fee-fiat" ng-class="vm.feeIsHigh ? 'negative' : 'positive'" ng-if="!vm.feeLessThanACent">Fee: {{vm.feeFiat}} {{vm.feeCurrency}}</div>
<div class="fee-crypto" ng-if="vm.feeCrypto"> <div class="fee-crypto" ng-if="vm.feeCrypto">
{{vm.feeCrypto}} {{vm.origin.currency}} <formatted-amount value="{{vm.feeCrypto}}" currency="{{vm.origin.currency}}"></formatted-amount>
</div> </div>
</div> </div>
</div> </div>

View file

@ -16,8 +16,15 @@
></div> ></div>
</i> </i>
<h2>{{fromWallet.name}}</h2> <h2>{{fromWallet.name}}</h2>
<wallet-balance
display-as-fiat="{{displayBalanceAsFiat}}"
wallet-status="{{fromWallet.status}}"
wallet-cached-balance="{{fromWallet.cachedBalance}}"
wallet-cached-balance-updated-on="{{fromWallet.cachedBalanceUpdatedOn}}"
wallet-cached-status="{{fromWallet.cachedStatus}}"
total-balance-sat="{{fromWallet.status.totalBalanceSat}}"></wallet-balance>
<!--<p ng-show="vm.origin.balanceAmount">{{vm.origin.balanceAmount}} {{vm.origin.balanceCurrency}}</p>--> <!--<p ng-show="vm.origin.balanceAmount">{{vm.origin.balanceAmount}} {{vm.origin.balanceCurrency}}</p>-->
<formatted-amount value="{{fromWallet.status.totalBalanceStr ? fromWallet.status.totalBalanceStr : ( fromWallet.cachedBalance ? fromWallet.cachedBalance + (fromWallet.cachedBalanceUpdatedOn ? ' &middot; ' + ( fromWallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo) : '') : '' ) }}"></formatted-amount> <!--<formatted-amount value="{{fromWallet.status.totalBalanceStr ? fromWallet.status.totalBalanceStr : ( fromWallet.cachedBalance ? fromWallet.cachedBalance + (fromWallet.cachedBalanceUpdatedOn ? ' &middot; ' + ( fromWallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo) : '') : '' ) }}"></formatted-amount>-->
</div> </div>
</div> </div>
</div> </div>

View file

@ -10,6 +10,11 @@
</button> </button>
</ion-nav-buttons> </ion-nav-buttons>
</ion-nav-bar> </ion-nav-bar>
<style type="text/css">
.button-white-outline.button-outline.active, .button-white-outline.button-outline.activated {
color: {{ wallet.color }};
}
</style>
<div class="bp-content" ng-class="{'status-bar': isCordova}"> <div class="bp-content" ng-class="{'status-bar': isCordova}">
@ -41,7 +46,7 @@
class="size-14 amount-alternative" class="size-14 amount-alternative"
ng-if="status.totalBalanceStr && wallet.network == 'livenet'" ng-if="status.totalBalanceStr && wallet.network == 'livenet'"
ng-style="{opacity: altAmountOpacity}"> ng-style="{opacity: altAmountOpacity}">
<formatted-amount value="{{status.totalBalanceStr}}"></formatted-amount> <formatted-amount value="{{status.totalBalanceStr}}" size-equal="true"></formatted-amount>
</div> </div>
</div> </div>