Merged fancy decimals.

# Conflicts:
#	www/views/walletDetails.html
This commit is contained in:
Brendon Duncan 2018-08-08 20:42:49 +12:00
commit b8de811fbe
12 changed files with 188 additions and 132 deletions

View file

@ -1,92 +0,0 @@
'use strict';
/**
* @desc amount directive that can be used to display formatted financial values
* size-equal attribute is optional, defaults to false.
* @example fee = {
* value: 12.49382901,
* currency: 'BCH'
* }
* @example <amount value="fee.value" currency="fee.currency"></amount>
* @example <amount value="fee.value" currency="fee.currency" size-equal="true"></amount>
*/
angular.module('bitcoincom.directives')
.directive('amount', [
'$timeout',
function($timeout) {
return {
restrict: 'E',
scope: {
value: '=',
currency: '=',
sizeEqual: '='
},
templateUrl: 'views/includes/amount.html',
controller: ['$scope', function($scope) {
$scope.displaySizeEqual = typeof $scope.sizeEqual == 'undefined' ? false : true;
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 numberWithCommas = function(x) {
return parseFloat(x).toLocaleString();
};
var buildAmount = function(start, middle, end) {
$scope.start = start;
$scope.middle = middle;
$scope.end = end;
};
var getDecimalPlaces = function(currency) {
if (decimalPlaces['0'].indexOf($scope.currency.toUpperCase()) > -1) return '0';
if (decimalPlaces['3'].indexOf($scope.currency.toUpperCase()) > -1) return '3';
if (decimalPlaces['8'].indexOf($scope.currency.toUpperCase()) > -1) return '8';
return '2';
};
var formatNumbers = function(currency, value) {
switch (getDecimalPlaces(currency)) {
case '0':
var valueFormatted = numberWithCommas(Math.round(parseFloat(value)));
buildAmount(valueFormatted, '', '');
break;
case '2':
var valueProcessing = parseFloat(parseFloat(value).toFixed(2));
var valueFormatted = numberWithCommas(valueProcessing);
buildAmount(valueFormatted, '', '');
break;
case '3':
var valueProcessing = parseFloat(parseFloat(value).toFixed(3));
var valueFormatted = numberWithCommas(valueProcessing);
buildAmount(valueFormatted, '', '');
break;
case '8':
var valueFormatted = parseFloat(value).toFixed(8);
if (parseFloat(value) == 0) {
buildAmount('0', '', '');
} else {
buildAmount(valueFormatted, '', '');
var start = numberWithCommas(valueFormatted.slice(0, -5));
var middle = valueFormatted.slice(-5, -2);
var end = valueFormatted.substr(valueFormatted.length - 2);
buildAmount(start, middle, end);
}
break;
}
}
formatNumbers($scope.currency, $scope.value);
$scope.$watchGroup(['currency', 'value'], function() {
formatNumbers($scope.currency, $scope.value);
});
}]
};
}
]);

View file

@ -0,0 +1,136 @@
'use strict';
/**
* @desc amount directive that can be used to display formatted financial values
* size-equal attribute is optional, defaults to false.
* @example fee = {
* value: 12.49382901,
* currency: 'BCH'
* }
* @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>
*/
angular.module('bitcoincom.directives')
.directive('formattedAmount', function(configService, uxLanguage) {
return {
restrict: 'E',
scope: {
value: '@',
currency: '@',
sizeEqual: '@'
},
templateUrl: 'views/includes/formatted-amount.html',
controller: function($scope, $timeout) {
$scope.canShow = false;
$scope.displaySizeEqual = !!$scope.sizeEqual;
configService.whenAvailable(function onConfigServiceAvailable(config) {
$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 = 0, useGrouping = true) {
return parseFloat(x).toLocaleString(uxLanguage.getCurrentLanguage(), {
minimumFractionDigits: minimumFractionDigits,
useGrouping: useGrouping
});
};
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() {
if (!$scope.currency && $scope.value) { // If there is no currency available..
// Try to extract currency from value..
var currencySplit = $scope.value.split(" ");
if (currencySplit.length === 2) {
$scope.currency = currencySplit[1];
}
}
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));
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();
});
});
});
}
};
}
);

View file

@ -8,4 +8,4 @@
@import "action-minor";
@import "expand-content";
@import "fee-summary";
@import "amount.scss";
@import "formatted-amount";

View file

@ -1,4 +1,6 @@
.amount {
.formatted-amount {
display: inline-block;
.start,
.middle,
.end,

View file

@ -15,11 +15,13 @@
<div class="send-amount-tool-input amount">
<div class="primary-amount"
ng-class="{long: vm.amount.length > 5, 'very-long': vm.amount.length > 10}">
<span class="primary-amount-display text-selectable">{{vm.amount || '0'}} {{vm.unit}}</span>
<span class="primary-amount-display text-selectable">
<formatted-amount value="{{vm.amount || '0'}}" currency="{{vm.unit}}"></formatted-amount>
</span>
</div>
<span ng-show="vm.globalResult">{{vm.globalResult}} {{vm.unit}}</span>
<span ng-show="vm.globalResult"><formatted-amount value="{{vm.globalResult}}" currency="{{vm.unit}}"></formatted-amount></span>
<div class="alternative-amount">
<span class="text-selectable">{{vm.alternativeAmount || '0.00'}}</span> <span>{{vm.alternativeUnit}}</span>
<span class="text-selectable"><formatted-amount value="{{vm.alternativeAmount || '0.00'}}" currency="{{vm.alternativeUnit}}"></formatted-amount></span>
</div>
<div class="switch-currencies" ng-click="vm.changeUnit()"><img src="img/icon-convert.svg"></div>
</div>
@ -42,7 +44,7 @@
<div class="extra available-funds"
ng-class="{warning: vm.fundsAreInsufficient}"
ng-if="!vm.isRequestingSpecificAmount" translate>
<span>Available Funds:</span>&ensp;<span>{{vm.availableFunds}}</span>
<span>Available Funds:</span>&ensp;<span><formatted-amount value="{{vm.availableFunds}}"></formatted-amount></span>
</div>
</div>
</div>
@ -52,7 +54,7 @@
<button class="button button-sendmax" ng-click="vm.sendMax()">
<span>
<span translate>Use All Available Funds</span>&ensp;
<span class="available-funds-amount">({{vm.availableFunds}})</span>
<span class="available-funds-amount">(<formatted-amount value="{{vm.availableFunds}}"></formatted-amount>)</span>
</span>
</button>
</div>

View file

@ -1,4 +1,4 @@
<div class="amount"
ng-class="{ 'size-equal': displaySizeEqual }">
<div class="formatted-amount"
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>
</div>

View file

@ -64,17 +64,16 @@
<span class="item-note text-right wallet-details__tx-amount">
<span class="wallet-details__tx-amount" ng-class="{'wallet-details__tx-amount--recent': btx.recent, 'wallet-details__tx-amount--received': btx.action == 'received', 'wallet-details__tx-amount--sent': btx.action == 'sent'}">
<span ng-if="btx.action == 'sent'"></span>
<span class="size-12" ng-if="btx.action == 'invalid'" translate>
(possible double spend)
</span>
<span ng-if="btx.action != 'invalid'">
{{btx.amountValueStr}} {{btx.amountUnitStr}}
<formatted-amount value="{{btx.action == 'sent'?'-':''}}{{btx.amountValueStr}}" currency="{{btx.amountUnitStr}}"></formatted-amount>
</span>
</span>
<div>
<span class="size-12 wallet-details__tx-amount" ng-class="{'wallet-details__tx-amount--recent': btx.recent, 'wallet-details__tx-amount--received': btx.action == 'received', 'wallet-details__tx-amount--sent': btx.action == 'sent'}">
{{btx.alternativeAmountStr}}
<formatted-amount value="{{btx.alternativeAmountStr}}"></formatted-amount>
</span>
</div>
</span>

View file

@ -7,8 +7,12 @@
Incomplete
</span>
<span ng-if="wallet.isComplete()">
<span ng-if="selectedPriceDisplay == 'crypto' && !wallet.balanceHidden && !wallet.scanning"> {{wallet.status.totalBalanceStr ? wallet.status.totalBalanceStr : ( wallet.cachedBalance ? wallet.cachedBalance + (wallet.cachedBalanceUpdatedOn ? ' &middot; ' + ( wallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo) : '') : '' ) }} </span>
<span ng-if="selectedPriceDisplay == 'fiat' && !wallet.balanceHidden && !wallet.scanning"> {{wallet.status.totalBalanceAlternative ? wallet.status.totalBalanceAlternative : ( wallet.cachedBalance ? wallet.cachedBalance + (wallet.cachedBalanceUpdatedOn ? ' &middot; ' + ( wallet.cachedBalanceUpdatedOn * 1000 | amTimeAgo) : '') : '' ) }} {{wallet.status.alternativeIsoCode}}</span>
<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>
</span>
<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>
</span>
<span ng-if="wallet.scanning" translate> Scanning funds... </span>
<span ng-if="wallet.balanceHidden && !wallet.scanning" translate>[Balance Hidden]</span>

View file

@ -27,8 +27,8 @@
Incomplete
</span>
<span ng-if="wallet.isComplete()">
<span ng-if="displayBalanceAsFiat && !wallet.balanceHidden">{{wallet.status.totalBalanceAlternative}} {{wallet.status.alternativeIsoCode}}</span>
<span ng-if="!displayBalanceAsFiat && !wallet.balanceHidden">{{wallet.status.availableBalanceStr}}</span>
<span ng-if="displayBalanceAsFiat && !wallet.balanceHidden"><formatted-amount value="{{wallet.status.totalBalanceAlternative}}" currency="{{wallet.status.alternativeIsoCode}}"></formatted-amount></span>
<span ng-if="!displayBalanceAsFiat && !wallet.balanceHidden"><formatted-amount value="{{wallet.status.availableBalanceStr}}"></formatted-amount></span>
<span ng-if="wallet.balanceHidden" translate>[Balance Hidden]</span>
</span>
</span>
@ -58,8 +58,8 @@
Incomplete
</span>
<span ng-if="wallet.isComplete()">
<span ng-if="displayBalanceAsFiat && !wallet.balanceHidden">{{wallet.status.totalBalanceAlternative}} {{wallet.status.alternativeIsoCode}}</span>
<span ng-if="!displayBalanceAsFiat && !wallet.balanceHidden">{{wallet.status.availableBalanceStr}}</span>
<span ng-if="displayBalanceAsFiat && !wallet.balanceHidden"><formatted-amount value="{{wallet.status.totalBalanceAlternative}}" currency="{{wallet.status.alternativeIsoCode}}"></formatted-amount></span>
<span ng-if="!displayBalanceAsFiat && !wallet.balanceHidden"><formatted-amount value="{{wallet.status.availableBalanceStr}}"></formatted-amount></span>
<span ng-if="wallet.balanceHidden" translate>[Balance Hidden]</span>
</span>
</span>

View file

@ -61,8 +61,8 @@
</svg>
<p class="success animated fadeIn">
<br/>Payment Received!
<span ng-if="!(displayBalanceAsFiat && paymentReceivedAlternativeAmount)" class="payment-received-amount">{{ paymentReceivedAmount }} <span class="payment-received-currency">{{ paymentReceivedCoin }}</span></span>
<span ng-if="displayBalanceAsFiat && paymentReceivedAlternativeAmount" class="payment-received-amount">{{ paymentReceivedAlternativeAmount }}</span></span>
<span ng-if="!(displayBalanceAsFiat && paymentReceivedAlternativeAmount)" class="payment-received-amount"><formatted-amount value="{{ paymentReceivedAmount }}" currency="{{paymentReceivedCoin}}"></formatted-amount></span>
<span ng-if="displayBalanceAsFiat && paymentReceivedAlternativeAmount" class="payment-received-amount"><formatted-amount value="{{ paymentReceivedAlternativeAmount }}"></formatted-amount></span></span>
Return To Address<br/>
</p>
</div>
@ -95,8 +95,8 @@
{{wallet.name || wallet.id}}
</span>
<p>
<span ng-if="displayBalanceAsFiat && !wallet.balanceHidden" translate> {{wallet.status.totalBalanceAlternative}} {{wallet.status.alternativeIsoCode}} </span>
<span ng-if="!displayBalanceAsFiat && !wallet.balanceHidden"> {{wallet.status.totalBalanceStr}} </span>
<span ng-if="displayBalanceAsFiat && !wallet.balanceHidden" translate> <formatted-amount value="{{wallet.status.totalBalanceAlternative}}" currency="{{wallet.status.alternativeIsoCode}}"></formatted-amount></span>
<span ng-if="!displayBalanceAsFiat && !wallet.balanceHidden"> <formatted-amount value="{{wallet.status.totalBalanceStr}}"></formatted-amount> </span>
<span ng-if="wallet.balanceHidden" translate>[Balance Hidden]</span>
<span class="tab-home__wallet__multisig-number" ng-if="wallet.n > 1">

View file

@ -24,13 +24,13 @@
<span ng-if="btx.action == 'received'" translate>Receiving</span>
</div>
<div class="amount-label">
<div class="amount">{{btx.amountValueStr}} <span class="unit">{{btx.amountUnitStr}}</span></div>
<div class="amount"><formatted-amount value="{{btx.amountValueStr}}" currency="{{btx.amountUnitStr}}"></formatted-amount></div>
<div class="alternative" ng-click="showRate = !showRate">
<span ng-if="!showRate">{{btx.alternativeAmountStr}}</span>
<span ng-if="!showRate"><formatted-amount value="{{btx.alternativeAmountStr}}"></formatted-amount></span>
<span ng-if="showRate">
<span ng-if="!rate">...</span>
<span ng-if="rate">
{{rate| currency:'':2}} {{alternativeIsoCode}} ({{rateDate | amDateFormat:'MM/DD/YYYY HH:mm a'}})
<formatted-amount value="{{rate| currency:'':2}}" currency="{{alternativeIsoCode}}"></formatted-amount> ({{rateDate | amDateFormat:'MM/DD/YYYY HH:mm a'}})
</span>
</span>
</div>
@ -115,7 +115,7 @@
<span class="label" translate>Fee</span>
<span class="m10l">{{btx.feeStr || '...'}}</span>
<span class="item-note m10l">
<span>{{btx.feeFiatStr || '...'}}&nbsp;<span class="fee-rate" ng-if="btx.feeRateStr" translate>- {{btx.feeRateStr}} of the transaction</span></span>
<span><span ng-if="btx.feeFiatStr"><formatted-amount value="{{btx.feeFiatStr}}"></formatted-amount></span><span ng-if="!btx.feeFiatStr">...</span><span class="fee-rate" ng-if="btx.feeRateStr" translate>- {{btx.feeRateStr}} of the transaction</span></span>
</span>
</div>
<div class="item low-fees" ng-if="btx.action == 'received' && btx.lowFees">

View file

@ -34,12 +34,14 @@
on-hold="hideToggle()"
ng-style="{'transform': amountScale}"
ng-class="{amount__balance: amountIsCollapsible}">
<strong class="size-25">{{status.totalBalanceAlternative}} {{status.alternativeIsoCode}}</strong>
<strong class="size-36" ng-show="status.totalBalanceAlternative">
<formatted-amount value="{{status.totalBalanceAlternative}}" currency="{{status.alternativeIsoCode}}"></formatted-amount>
</strong>
<div
class="size-14 amount-alternative"
ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'"
ng-if="status.totalBalanceStr && wallet.network == 'livenet'"
ng-style="{opacity: altAmountOpacity}">
{{status.totalBalanceStr}}
<formatted-amount value="{{status.totalBalanceStr}}"></formatted-amount>
</div>
</div>
@ -47,13 +49,16 @@
ng-show="selectedPriceDisplay=='crypto' && !updateStatusError && !wallet.balanceHidden && !wallet.scanning"
on-hold="hideToggle()"
ng-style="{'transform': amountScale}"
ng-if="status.totalBalanceStr"
ng-class="{amount__balance: amountIsCollapsible}">
<strong class="size-25">{{status.totalBalanceStr}}</strong>
<strong class="size-36">
<formatted-amount value="{{status.totalBalanceStr}}"></formatted-amount>
</strong>
<div
class="size-14 amount-alternative"
ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'"
ng-style="{opacity: altAmountOpacity}">
{{status.totalBalanceAlternative}} {{status.alternativeIsoCode}}
<formatted-amount value="{{status.totalBalanceAlternative}}" currency="{{status.alternativeIsoCode}}"></formatted-amount>
</div>
</div>
@ -86,7 +91,7 @@
</strong>
&nbsp;
<span>
{{status.spendableBalanceAlternative}} {{status.alternativeIsoCode}}
<formatted-amount value="{{status.spendableBalanceAlternative}}" currency="{{status.alternativeIsoCode}}"></formatted-amount>
</span>
</button>
</div>
@ -143,12 +148,12 @@
on-hold="hideToggle()"
ng-style="{'transform': amountScale}"
ng-class="{amount__balance: amountIsCollapsible}">
<strong class="size-25">{{status.totalBalanceStr}}</strong>
<strong ng-if="status.totalBalanceStr" class="size-36"><formatted-amount value="{{status.totalBalanceStr}}"></formatted-amount></strong>
<div
class="size-14 amount-alternative"
ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'"
ng-style="{opacity: altAmountOpacity}">
{{status.totalBalanceAlternative}} {{status.alternativeIsoCode}}
<formatted-amount value="{{status.totalBalanceAlternative}}" currency="{{status.alternativeIsoCode}}"></formatted-amount>
</div>
</div>
@ -158,12 +163,12 @@
on-hold="hideToggle()"
ng-style="{'transform': amountScale}"
ng-class="{amount__balance: amountIsCollapsible}">
<strong class="size-25">{{status.totalBalanceAlternative}} {{status.alternativeIsoCode}}</strong>
<strong class="size-36"><formatted-amount value="{{status.totalBalanceAlternative}}" currency="{{status.alternativeIsoCode}}"></formatted-amount></strong>
<div
class="size-16 amount-alternative"
ng-if="status.totalBalanceAlternative && wallet.network == 'livenet'"
class="size-14 amount-alternative"
ng-if="status.totalBalanceStr && wallet.network == 'livenet'"
ng-style="{opacity: altAmountOpacity}">
{{status.totalBalanceStr}}
<formatted-amount value="{{status.totalBalanceStr}}"></formatted-amount>
</div>
</div>
@ -196,7 +201,7 @@
</strong>
&nbsp;
<span>
{{status.spendableBalanceAlternative}} {{status.alternativeIsoCode}}
<formatted-amount value="{{status.spendableBalanceAlternative}}" currency="{{status.alternativeIsoCode}}"></formatted-amount>
</span>
</button>
</div>
@ -205,7 +210,7 @@
<button class="button button-standard button-primary amount__button-balance size-14" ng-click="openBalanceModal()">
<i class="icon ion-ios-checkmark-outline"></i>
<strong>
{{status.spendableBalanceAlternative}} {{status.alternativeIsoCode}}
<formatted-amount value="{{status.spendableBalanceAlternative}}" currency="{{status.alternativeIsoCode}}"></formatted-amount>
</strong>
&nbsp;
<span>