fix amount.js for fiat/config

This commit is contained in:
matias 2017-08-31 17:13:54 -03:00
commit f96f0bb037
2 changed files with 346 additions and 358 deletions

View file

@ -1,13 +1,3 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# http://editorconfig.org
## Plugins
# Atom (https://github.com/sindresorhus/atom-editorconfig)
# Vim (https://github.com/editorconfig/editorconfig-vim)
# Sublime (https://github.com/sindresorhus/editorconfig-sublime)
;
root = true
[*]
@ -27,4 +17,3 @@ indent_style = tab
[**.html]
max_char = 78
brace_style = expand

View file

@ -1,384 +1,383 @@
'use strict';
angular.module('copayApp.controllers').controller('amountController', function($scope, $filter, $timeout, $ionicScrollDelegate, $ionicHistory, gettextCatalog, platformInfo, lodash, configService, rateService, $stateParams, $window, $state, $log, txFormatService, ongoingProcess, popupService, bwcError, payproService, profileService, bitcore, amazonService, nodeWebkitService) {
var _id;
var unitToSatoshi;
var satToUnit;
var unitDecimals;
var satToBtc;
var SMALL_FONT_SIZE_LIMIT = 10;
var LENGTH_EXPRESSION_LIMIT = 19;
var isNW = platformInfo.isNW;
var _id;
var unitToSatoshi;
var satToUnit;
var unitDecimals;
var satToBtc;
var SMALL_FONT_SIZE_LIMIT = 10;
var LENGTH_EXPRESSION_LIMIT = 19;
var isNW = platformInfo.isNW;
var unitIndex = 0;
var altUnitIndex = 0;
var availableUnits = [];
var fiatCode;
var unitIndex = 0;
var altUnitIndex = 0;
var availableUnits = [];
var fiatCode;
var fixedUnit;
var fixedUnit;
$scope.isChromeApp = platformInfo.isChromeApp;
$scope.isChromeApp = platformInfo.isChromeApp;
$scope.$on('$ionicView.leave', function() {
angular.element($window).off('keydown');
});
$scope.$on('$ionicView.leave', function() {
angular.element($window).off('keydown');
});
$scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.$on("$ionicView.beforeEnter", function(event, data) {
var config = configService.getSync().wallet.settings;
var config = configService.getSync().wallet.settings;
function setAvailableUnits() {
function setAvailableUnits() {
availableUnits = [{
name: 'Bitcoin',
id: 'btc',
shortName: 'BTC',
}];
availableUnits = [{
name: 'Bitcoin',
id: 'btc',
shortName: 'BTC',
}];
var anyCashWallet = true; // TODO!!
if (anyCashWallet) {
availableUnits.push({
name: 'Bitcoin Cash',
id: 'bch',
shortName: 'BCH',
});
};
var anyCashWallet = true; // TODO!!
if (anyCashWallet) {
availableUnits.push({
name: 'Bitcoin Cash',
id: 'bch',
shortName: 'BCH',
});
};
unitIndex = 0;
unitIndex = 0;
if (data.stateParams.coin) {
var coins = data.stateParams.coin.split(',');
var newAvailableUnits = [];
if (data.stateParams.coin) {
var coins = data.stateParams.coin.split(',');
var newAvailableUnits = [];
lodash.each(coins, function(c) {
var coin = lodash.find(availableUnits, {
id: c
});
if (!coin) {
$log.warn('Could not find desired coin:' + data.stateParams.coin)
} else {
newAvailableUnits.push(coin);
}
});
lodash.each(coins, function(c) {
var coin = lodash.find(availableUnits, {
id: c
});
if (!coin) {
$log.warn('Could not find desired coin:' + data.stateParams.coin)
} else {
newAvailableUnits.push(coin);
}
});
if (newAvailableUnits.length>0) {
availableUnits = newAvailableUnits;
if (newAvailableUnits.length > 0) {
availableUnits = newAvailableUnits;
}
}
// currency have preference
var fiatName;
if (data.stateParams.currency) {
fiatCode = data.stateParams.currency;
altUnitIndex = unitIndex
unitIndex = availableUnits.length;
} else {
fiatCode = config.alternativeIsoCode || 'USD';
fiatName = config.alternanativeName || fiatCode;
altUnitIndex = availableUnits.length;
}
availableUnits.push({
name: fiatName || fiatCode, // TODO
id: fiatCode,
shortName: fiatCode,
isFiat: true,
});
if (data.stateParams.fixedUnit) {
fixedUnit = true;
}
};
// Go to...
_id = data.stateParams.id; // Optional (BitPay Card ID or Wallet ID)
$scope.nextStep = data.stateParams.nextStep;
setAvailableUnits();
updateUnitUI();
$scope.showMenu = $ionicHistory.backView() && ($ionicHistory.backView().stateName == 'tabs.send' ||
$ionicHistory.backView().stateName == 'tabs.bitpayCard');
$scope.recipientType = data.stateParams.recipientType || null;
$scope.toAddress = data.stateParams.toAddress;
$scope.toName = data.stateParams.toName;
$scope.toEmail = data.stateParams.toEmail;
$scope.toColor = data.stateParams.toColor;
$scope.showSendMax = false;
if (!$scope.nextStep && !data.stateParams.toAddress) {
$log.error('Bad params at amount')
throw ('bad params');
}
}
var reNr = /^[1234567890\.]$/;
var reOp = /^[\*\+\-\/]$/;
// currency have preference
var fiat;
if (data.stateParams.currency) {
fiat = data.stateParams.currency;
altUnitIndex = unitIndex
unitIndex = availableUnits.length;
} else {
fiat = config.fiat || 'USD';
altUnitIndex = availableUnits.length;
}
var disableKeys = angular.element($window).on('keydown', function(e) {
if (!e.key) return;
if (e.which === 8) { // you can add others here inside brackets.
e.preventDefault();
$scope.removeDigit();
}
availableUnits.push({
name: fiat, // TODO
id: fiat,
shortName: fiat,
isFiat: true,
});
if (e.key.match(reNr)) {
$scope.pushDigit(e.key);
} else if (e.key.match(reOp)) {
$scope.pushOperator(e.key);
} else if (e.keyCode === 86) {
if (e.ctrlKey || e.metaKey)
processClipboard();
} else if (e.keyCode === 13)
$scope.finish();
fiatCode = fiat;
$timeout(function() {
$scope.$apply();
});
});
$scope.specificAmount = $scope.specificAlternativeAmount = '';
$scope.isCordova = platformInfo.isCordova;
unitToSatoshi = config.unitToSatoshi;
satToUnit = 1 / unitToSatoshi;
satToBtc = 1 / 100000000;
unitDecimals = config.unitDecimals;
if (data.stateParams.fixedUnit) {
fixedUnit = true;
}
$scope.resetAmount();
// in SAT ALWAYS
if ($stateParams.toAmount) {
$scope.amount = (($stateParams.toAmount) * satToUnit).toFixed(unitDecimals);
}
processAmount();
$timeout(function() {
$ionicScrollDelegate.resize();
}, 10);
});
function paste(value) {
$scope.amount = value;
processAmount();
$timeout(function() {
$scope.$apply();
});
};
// Go to...
_id = data.stateParams.id; // Optional (BitPay Card ID or Wallet ID)
$scope.nextStep = data.stateParams.nextStep;
function processClipboard() {
if (!isNW) return;
var value = nodeWebkitService.readFromClipboard();
if (value && evaluate(value) > 0) paste(evaluate(value));
};
$scope.showSendMaxMenu = function() {
$scope.showSendMax = true;
};
setAvailableUnits();
updateUnitUI();
$scope.showMenu = $ionicHistory.backView() && ($ionicHistory.backView().stateName == 'tabs.send' ||
$ionicHistory.backView().stateName == 'tabs.bitpayCard');
$scope.recipientType = data.stateParams.recipientType || null;
$scope.toAddress = data.stateParams.toAddress;
$scope.toName = data.stateParams.toName;
$scope.toEmail = data.stateParams.toEmail;
$scope.toColor = data.stateParams.toColor;
$scope.showSendMax = false;
if (!$scope.nextStep && !data.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.key) return;
if (e.which === 8) { // you can add others here inside brackets.
e.preventDefault();
$scope.removeDigit();
}
if (e.key.match(reNr)) {
$scope.pushDigit(e.key);
} else if (e.key.match(reOp)) {
$scope.pushOperator(e.key);
} else if (e.keyCode === 86) {
if (e.ctrlKey || e.metaKey)
processClipboard();
} else if (e.keyCode === 13)
$scope.sendMax = function() {
$scope.showSendMax = false;
$scope.useSendMax = true;
$scope.finish();
$timeout(function() {
$scope.$apply();
});
});
$scope.specificAmount = $scope.specificAlternativeAmount = '';
$scope.isCordova = platformInfo.isCordova;
unitToSatoshi = config.unitToSatoshi;
satToUnit = 1 / unitToSatoshi;
satToBtc = 1 / 100000000;
unitDecimals = config.unitDecimals;
$scope.resetAmount();
// in SAT ALWAYS
if ($stateParams.toAmount) {
$scope.amount = (($stateParams.toAmount) * satToUnit).toFixed(unitDecimals);
}
processAmount();
$timeout(function() {
$ionicScrollDelegate.resize();
}, 10);
});
function paste(value) {
$scope.amount = value;
processAmount();
$timeout(function() {
$scope.$apply();
});
};
function processClipboard() {
if (!isNW) return;
var value = nodeWebkitService.readFromClipboard();
if (value && evaluate(value) > 0) paste(evaluate(value));
};
$scope.showSendMaxMenu = function() {
$scope.showSendMax = true;
};
$scope.sendMax = function() {
$scope.showSendMax = false;
$scope.useSendMax = true;
$scope.finish();
};
$scope.toggleAlternative = function() {
if ($scope.amount && isExpression($scope.amount)) {
var amount = evaluate(format($scope.amount));
$scope.globalResult = '= ' + processResult(amount);
}
};
function updateUnitUI() {
$scope.unit = availableUnits[unitIndex].shortName;
$scope.alternativeUnit = availableUnits[altUnitIndex].shortName;
processAmount();
$log.debug('Update unit coin @amount unit:' + $scope.unit + " alternativeUnit:" + $scope.alternativeUnit);
};
$scope.changeUnit = function() {
if (fixedUnit) return;
unitIndex++;
if (unitIndex >= availableUnits.length) unitIndex = 0;
if (availableUnits[unitIndex].isFiat) {
// Always return to BTC... TODO?
altUnitIndex = 0;
} else {
altUnitIndex = lodash.findIndex(availableUnits, {
isFiat: true
});
}
updateUnitUI();
};
$scope.changeAlternativeUnit = function() {
// Do nothing is fiat is not main unit
if (!availableUnits[unitIndex].isFiat) return;
var nextCoin = lodash.findIndex(availableUnits, function(x) {
if (x.isFiat) return false;
if (x.id == availableUnits[altUnitIndex].id) return false;
return true;
});
if (nextCoin >= 0) {
altUnitIndex = nextCoin;
updateUnitUI();
}
};
function checkFontSize() {
if ($scope.amount && $scope.amount.length >= SMALL_FONT_SIZE_LIMIT) $scope.smallFont = true;
else $scope.smallFont = false;
};
$scope.pushDigit = function(digit) {
if ($scope.amount && $scope.amount.length >= LENGTH_EXPRESSION_LIMIT) return;
if ($scope.amount.indexOf('.') > -1 && digit == '.') return;
if (availableUnits[unitIndex].isFiat && $scope.amount.indexOf('.') > -1 && $scope.amount[$scope.amount.indexOf('.') + 2]) return;
$scope.amount = ($scope.amount + digit).replace('..', '.');
checkFontSize();
processAmount();
};
$scope.pushOperator = function(operator) {
if (!$scope.amount || $scope.amount.length == 0) return;
$scope.amount = _pushOperator($scope.amount);
function _pushOperator(val) {
if (!isOperator(lodash.last(val))) {
return val + operator;
} else {
return val.slice(0, -1) + operator;
}
};
};
function isOperator(val) {
var regex = /[\/\-\+\x\*]/;
return regex.test(val);
};
function isExpression(val) {
var regex = /^\.?\d+(\.?\d+)?([\/\-\+\*x]\d?\.?\d+)+$/;
return regex.test(val);
};
$scope.removeDigit = function() {
$scope.amount = ($scope.amount).toString().slice(0, -1);
processAmount();
checkFontSize();
};
$scope.resetAmount = function() {
$scope.amount = $scope.alternativeAmount = $scope.globalResult = '';
$scope.allowSend = false;
checkFontSize();
};
function processAmount() {
var formatedValue = format($scope.amount);
var result = evaluate(formatedValue);
$scope.allowSend = lodash.isNumber(result) && +result > 0;
if (lodash.isNumber(result)) {
$scope.globalResult = isExpression($scope.amount) ? '= ' + processResult(result) : '';
if (availableUnits[unitIndex].isFiat) {
$scope.alternativeAmount = txFormatService.formatAmount(fromFiat(result) * unitToSatoshi, true);
} else {
$scope.alternativeAmount = $filter('formatFiatAmount')(toFiat(result));
}
}
};
function processResult(val) {
if (availableUnits[unitIndex].isFiat)
return $filter('formatFiatAmount')(val);
else
return txFormatService.formatAmount(val.toFixed(unitDecimals) * unitToSatoshi, true);
};
function fromFiat(val) {
return parseFloat((rateService.fromFiat(val, fiatCode, availableUnits[altUnitIndex].id) * satToUnit).toFixed(unitDecimals));
};
function toFiat(val) {
return parseFloat((rateService.toFiat(val * unitToSatoshi, fiatCode, availableUnits[unitIndex].id)).toFixed(2));
};
function evaluate(val) {
var result;
try {
result = $scope.$eval(val);
} catch (e) {
return 0;
}
if (!lodash.isFinite(result)) return 0;
return result;
};
function format(val) {
if (!val) return;
var result = val.toString();
if (isOperator(lodash.last(val)))
result = result.slice(0, -1);
return result.replace('x', '*');
};
$scope.finish = function() {
var unit = availableUnits[unitIndex];
var _amount = evaluate(format($scope.amount));
if ($scope.nextStep) {
var coin = unit.id;
if (unit.isFiat) {
coin = availableUnits[altUnitIndex].id;
}
$state.transitionTo($scope.nextStep, {
id: _id,
amount: $scope.useSendMax ? null : _amount,
currency: unit.id.toUpperCase(),
coin: coin,
useSendMax: $scope.useSendMax
});
} else {
var amount = _amount;
if (unit.isFiat) {
amount = fromFiat(_amount);
} else {
amount = (amount * unitToSatoshi).toFixed(0);
}
$state.transitionTo('tabs.send.confirm', {
recipientType: $scope.recipientType,
toAmount: amount,
toAddress: $scope.toAddress,
toName: $scope.toName,
toEmail: $scope.toEmail,
toColor: $scope.toColor,
coin: unit.id,
useSendMax: $scope.useSendMax
});
}
$scope.useSendMax = null;
};
$scope.toggleAlternative = function() {
if ($scope.amount && isExpression($scope.amount)) {
var amount = evaluate(format($scope.amount));
$scope.globalResult = '= ' + processResult(amount);
}
};
function updateUnitUI() {
$scope.unit = availableUnits[unitIndex].shortName;
$scope.alternativeUnit = availableUnits[altUnitIndex].shortName;
processAmount();
$log.debug('Update unit coin @amount unit:' + $scope.unit + " alternativeUnit:" + $scope.alternativeUnit);
};
$scope.changeUnit = function() {
if (fixedUnit) return;
unitIndex++;
if (unitIndex >= availableUnits.length) unitIndex = 0;
if (availableUnits[unitIndex].isFiat) {
// Always return to BTC... TODO?
altUnitIndex = 0;
} else {
altUnitIndex = lodash.findIndex(availableUnits, {
isFiat: true
});
}
updateUnitUI();
};
$scope.changeAlternativeUnit = function() {
// Do nothing is fiat is not main unit
if (!availableUnits[unitIndex].isFiat) return;
var nextCoin = lodash.findIndex(availableUnits, function(x) {
if (x.isFiat) return false;
if (x.id == availableUnits[altUnitIndex].id) return false;
return true;
});
if (nextCoin >= 0) {
altUnitIndex = nextCoin;
updateUnitUI();
}
};
function checkFontSize() {
if ($scope.amount && $scope.amount.length >= SMALL_FONT_SIZE_LIMIT) $scope.smallFont = true;
else $scope.smallFont = false;
};
$scope.pushDigit = function(digit) {
if ($scope.amount && $scope.amount.length >= LENGTH_EXPRESSION_LIMIT) return;
if ($scope.amount.indexOf('.') > -1 && digit == '.') return;
if (availableUnits[unitIndex].isFiat && $scope.amount.indexOf('.') > -1 && $scope.amount[$scope.amount.indexOf('.') + 2]) return;
$scope.amount = ($scope.amount + digit).replace('..', '.');
checkFontSize();
processAmount();
};
$scope.pushOperator = function(operator) {
if (!$scope.amount || $scope.amount.length == 0) return;
$scope.amount = _pushOperator($scope.amount);
function _pushOperator(val) {
if (!isOperator(lodash.last(val))) {
return val + operator;
} else {
return val.slice(0, -1) + operator;
}
};
};
function isOperator(val) {
var regex = /[\/\-\+\x\*]/;
return regex.test(val);
};
function isExpression(val) {
var regex = /^\.?\d+(\.?\d+)?([\/\-\+\*x]\d?\.?\d+)+$/;
return regex.test(val);
};
$scope.removeDigit = function() {
$scope.amount = ($scope.amount).toString().slice(0, -1);
processAmount();
checkFontSize();
};
$scope.resetAmount = function() {
$scope.amount = $scope.alternativeAmount = $scope.globalResult = '';
$scope.allowSend = false;
checkFontSize();
};
function processAmount() {
var formatedValue = format($scope.amount);
var result = evaluate(formatedValue);
$scope.allowSend = lodash.isNumber(result) && +result > 0;
if (lodash.isNumber(result)) {
$scope.globalResult = isExpression($scope.amount) ? '= ' + processResult(result) : '';
if (availableUnits[unitIndex].isFiat) {
$scope.alternativeAmount = txFormatService.formatAmount(fromFiat(result) * unitToSatoshi, true);
} else {
$scope.alternativeAmount = $filter('formatFiatAmount')(toFiat(result));
}
}
};
function processResult(val) {
if (availableUnits[unitIndex].isFiat)
return $filter('formatFiatAmount')(val);
else
return txFormatService.formatAmount(val.toFixed(unitDecimals) * unitToSatoshi, true);
};
function fromFiat(val) {
return parseFloat((rateService.fromFiat(val, fiatCode, availableUnits[altUnitIndex].id) * satToUnit).toFixed(unitDecimals));
};
function toFiat(val) {
return parseFloat((rateService.toFiat(val * unitToSatoshi, fiatCode, availableUnits[unitIndex].id)).toFixed(2));
};
function evaluate(val) {
var result;
try {
result = $scope.$eval(val);
} catch (e) {
return 0;
}
if (!lodash.isFinite(result)) return 0;
return result;
};
function format(val) {
if (!val) return;
var result = val.toString();
if (isOperator(lodash.last(val)))
result = result.slice(0, -1);
return result.replace('x', '*');
};
$scope.finish = function() {
var unit = availableUnits[unitIndex];
var _amount = evaluate(format($scope.amount));
if ($scope.nextStep) {
var coin = unit.id;
if (unit.isFiat) {
coin = availableUnits[altUnitIndex].id;
}
$state.transitionTo($scope.nextStep, {
id: _id,
amount: $scope.useSendMax ? null : _amount,
currency: unit.id.toUpperCase(),
coin: coin,
useSendMax: $scope.useSendMax
});
} else {
var amount = _amount;
if (unit.isFiat) {
amount = fromFiat(_amount);
} else {
amount = (amount * unitToSatoshi).toFixed(0);
}
$state.transitionTo('tabs.send.confirm', {
recipientType: $scope.recipientType,
toAmount: amount,
toAddress: $scope.toAddress,
toName: $scope.toName,
toEmail: $scope.toEmail,
toColor: $scope.toColor,
coin: unit.id,
useSendMax: $scope.useSendMax
});
}
$scope.useSendMax = null;
};
});