Merge pull request #6037 from gabrielbazan7/feat/changeFeeConfirm
Change fee on the confirm view
This commit is contained in:
commit
f32e564b99
12 changed files with 185 additions and 144 deletions
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $filter, $timeout, $ionicScrollDelegate, gettextCatalog, walletService, platformInfo, lodash, configService, rateService, $stateParams, $window, $state, $log, profileService, bitcore, txFormatService, ongoingProcess, $ionicModal, popupService, $ionicHistory, $ionicConfig, payproService, feeService, bwcError) {
|
angular.module('copayApp.controllers').controller('confirmController', function($rootScope, $scope, $interval, $filter, $timeout, $ionicScrollDelegate, gettextCatalog, walletService, platformInfo, lodash, configService, rateService, $stateParams, $window, $state, $log, profileService, bitcore, txFormatService, ongoingProcess, $ionicModal, popupService, $ionicHistory, $ionicConfig, payproService, feeService, bwcError) {
|
||||||
var cachedTxp = {};
|
var cachedTxp = {};
|
||||||
|
var feeLevel;
|
||||||
|
var feePerKb;
|
||||||
var toAmount;
|
var toAmount;
|
||||||
var isChromeApp = platformInfo.isChromeApp;
|
var isChromeApp = platformInfo.isChromeApp;
|
||||||
var countDown = null;
|
var countDown = null;
|
||||||
|
|
@ -20,7 +22,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
||||||
|
|
||||||
toAmount = data.stateParams.toAmount;
|
toAmount = data.stateParams.toAmount;
|
||||||
cachedSendMax = {};
|
cachedSendMax = {};
|
||||||
$scope.showFeeFiat = false;
|
|
||||||
$scope.showAddress = false;
|
$scope.showAddress = false;
|
||||||
$scope.useSendMax = data.stateParams.useSendMax == 'true' ? true : false;
|
$scope.useSendMax = data.stateParams.useSendMax == 'true' ? true : false;
|
||||||
$scope.recipientType = data.stateParams.recipientType || null;
|
$scope.recipientType = data.stateParams.recipientType || null;
|
||||||
|
|
@ -38,16 +39,29 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
||||||
$scope.remainingTimeStr = {
|
$scope.remainingTimeStr = {
|
||||||
value: null
|
value: null
|
||||||
};
|
};
|
||||||
|
|
||||||
var config = configService.getSync().wallet;
|
|
||||||
var feeLevel = config.settings && config.settings.feeLevel ? config.settings.feeLevel : 'normal';
|
|
||||||
$scope.feeLevel = feeService.feeOpts[feeLevel];
|
|
||||||
$scope.network = (new bitcore.Address($scope.toAddress)).network.name;
|
$scope.network = (new bitcore.Address($scope.toAddress)).network.name;
|
||||||
|
setFee();
|
||||||
resetValues();
|
resetValues();
|
||||||
setwallets();
|
setwallets();
|
||||||
applyButtonText();
|
applyButtonText();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function setFee(customFeeLevel, cb) {
|
||||||
|
feeService.getCurrentFeeValue($scope.network, customFeeLevel, function(err, feePerKb) {
|
||||||
|
var config = configService.getSync().wallet;
|
||||||
|
var configFeeLevel = (config.settings && config.settings.feeLevel) ? config.settings.feeLevel : 'normal';
|
||||||
|
feePerKb = feePerKb;
|
||||||
|
feeLevel = customFeeLevel ? customFeeLevel : configFeeLevel;
|
||||||
|
$scope.feeLevel = feeService.feeOpts[feeLevel];
|
||||||
|
if (cb) return cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function useSelectedWallet() {
|
||||||
|
if (!$scope.useSendMax) displayValues();
|
||||||
|
$scope.onWalletSelect($scope.wallet);
|
||||||
|
}
|
||||||
|
|
||||||
function applyButtonText(multisig) {
|
function applyButtonText(multisig) {
|
||||||
$scope.buttonText = $scope.isCordova ? gettextCatalog.getString('Slide') + ' ' : gettextCatalog.getString('Click') + ' ';
|
$scope.buttonText = $scope.isCordova ? gettextCatalog.getString('Slide') + ' ' : gettextCatalog.getString('Click') + ' ';
|
||||||
|
|
||||||
|
|
@ -95,7 +109,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++index == $scope.wallets.length) {
|
if (++index == $scope.wallets.length) {
|
||||||
|
|
||||||
if (!lodash.isEmpty(filteredWallets)) {
|
if (!lodash.isEmpty(filteredWallets)) {
|
||||||
$scope.wallets = lodash.clone(filteredWallets);
|
$scope.wallets = lodash.clone(filteredWallets);
|
||||||
if ($scope.useSendMax) {
|
if ($scope.useSendMax) {
|
||||||
|
|
@ -133,10 +146,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.toggleFeeValue = function() {
|
|
||||||
$scope.showFeeFiat = !$scope.showFeeFiat;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.toggleAddress = function() {
|
$scope.toggleAddress = function() {
|
||||||
$scope.showAddress = !$scope.showAddress;
|
$scope.showAddress = !$scope.showAddress;
|
||||||
};
|
};
|
||||||
|
|
@ -163,84 +172,75 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
||||||
};
|
};
|
||||||
|
|
||||||
function resetValues() {
|
function resetValues() {
|
||||||
$scope.displayAmount = $scope.displayUnit = $scope.fee = $scope.alternativeAmountStr = $scope.insufficientFunds = $scope.noMatchingWallet = null;
|
$scope.displayAmount = $scope.displayUnit = $scope.fee = $scope.feeFiat = $scope.feeRateStr = $scope.alternativeAmountStr = $scope.insufficientFunds = $scope.noMatchingWallet = null;
|
||||||
$scope.showFeeFiat = $scope.showAddress = false;
|
$scope.showAddress = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.getSendMaxInfo = function() {
|
$scope.getSendMaxInfo = function() {
|
||||||
resetValues();
|
resetValues();
|
||||||
|
var config = configService.getSync().wallet;
|
||||||
|
|
||||||
ongoingProcess.set('gettingFeeLevels', true);
|
ongoingProcess.set('retrievingInputs', true);
|
||||||
feeService.getCurrentFeeValue($scope.network, function(err, feePerKb) {
|
walletService.getSendMaxInfo($scope.wallet, {
|
||||||
ongoingProcess.set('gettingFeeLevels', false);
|
feePerKb: feePerKb,
|
||||||
|
excludeUnconfirmedUtxos: !config.spendUnconfirmed,
|
||||||
|
returnInputs: true,
|
||||||
|
}, function(err, resp) {
|
||||||
|
ongoingProcess.set('retrievingInputs', false);
|
||||||
if (err) {
|
if (err) {
|
||||||
popupService.showAlert(gettextCatalog.getString('Error'), err.message);
|
popupService.showAlert(gettextCatalog.getString('Error'), err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var config = configService.getSync().wallet;
|
|
||||||
|
|
||||||
ongoingProcess.set('retrievingInputs', true);
|
if (resp.amount == 0) {
|
||||||
walletService.getSendMaxInfo($scope.wallet, {
|
$scope.insufficientFunds = true;
|
||||||
|
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Not enough funds for fee'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.sendMaxInfo = {
|
||||||
|
sendMax: true,
|
||||||
|
amount: resp.amount,
|
||||||
|
inputs: resp.inputs,
|
||||||
|
fee: resp.fee,
|
||||||
feePerKb: feePerKb,
|
feePerKb: feePerKb,
|
||||||
excludeUnconfirmedUtxos: !config.spendUnconfirmed,
|
};
|
||||||
returnInputs: true,
|
|
||||||
}, function(err, resp) {
|
|
||||||
ongoingProcess.set('retrievingInputs', false);
|
|
||||||
if (err) {
|
|
||||||
popupService.showAlert(gettextCatalog.getString('Error'), err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resp.amount == 0) {
|
cachedSendMax[$scope.wallet.id] = $scope.sendMaxInfo;
|
||||||
$scope.insufficientFunds = true;
|
|
||||||
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Not enough funds for fee'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.sendMaxInfo = {
|
var msg = gettextCatalog.getString("{{fee}} will be deducted for bitcoin networking fees.", {
|
||||||
sendMax: true,
|
fee: txFormatService.formatAmountStr(resp.fee)
|
||||||
amount: resp.amount,
|
|
||||||
inputs: resp.inputs,
|
|
||||||
fee: resp.fee,
|
|
||||||
feePerKb: feePerKb,
|
|
||||||
};
|
|
||||||
|
|
||||||
cachedSendMax[$scope.wallet.id] = $scope.sendMaxInfo;
|
|
||||||
|
|
||||||
var msg = gettextCatalog.getString("{{fee}} will be deducted for bitcoin networking fees.", {
|
|
||||||
fee: txFormatService.formatAmountStr(resp.fee)
|
|
||||||
});
|
|
||||||
var warningMsg = verifyExcludedUtxos();
|
|
||||||
|
|
||||||
if (!lodash.isEmpty(warningMsg))
|
|
||||||
msg += '\n' + warningMsg;
|
|
||||||
|
|
||||||
popupService.showAlert(null, msg, function() {
|
|
||||||
setSendMaxValues(resp);
|
|
||||||
|
|
||||||
createTx($scope.wallet, true, function(err, txp) {
|
|
||||||
if (err) return;
|
|
||||||
cachedTxp[$scope.wallet.id] = txp;
|
|
||||||
apply(txp);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function verifyExcludedUtxos() {
|
|
||||||
var warningMsg = [];
|
|
||||||
if (resp.utxosBelowFee > 0) {
|
|
||||||
warningMsg.push(gettextCatalog.getString("A total of {{amountBelowFeeStr}} were excluded. These funds come from UTXOs smaller than the network fee provided.", {
|
|
||||||
amountBelowFeeStr: txFormatService.formatAmountStr(resp.amountBelowFee)
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resp.utxosAboveMaxSize > 0) {
|
|
||||||
warningMsg.push(gettextCatalog.getString("A total of {{amountAboveMaxSizeStr}} were excluded. The maximum size allowed for a transaction was exceeded.", {
|
|
||||||
amountAboveMaxSizeStr: txFormatService.formatAmountStr(resp.amountAboveMaxSize)
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
return warningMsg.join('\n');
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
var warningMsg = verifyExcludedUtxos();
|
||||||
|
|
||||||
|
if (!lodash.isEmpty(warningMsg))
|
||||||
|
msg += '\n' + warningMsg;
|
||||||
|
|
||||||
|
popupService.showAlert(null, msg, function() {
|
||||||
|
setSendMaxValues(resp);
|
||||||
|
|
||||||
|
createTx($scope.wallet, true, function(err, txp) {
|
||||||
|
if (err) return;
|
||||||
|
cachedTxp[$scope.wallet.id] = txp;
|
||||||
|
apply(txp);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function verifyExcludedUtxos() {
|
||||||
|
var warningMsg = [];
|
||||||
|
if (resp.utxosBelowFee > 0) {
|
||||||
|
warningMsg.push(gettextCatalog.getString("A total of {{amountBelowFeeStr}} were excluded. These funds come from UTXOs smaller than the network fee provided.", {
|
||||||
|
amountBelowFeeStr: txFormatService.formatAmountStr(resp.amountBelowFee)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp.utxosAboveMaxSize > 0) {
|
||||||
|
warningMsg.push(gettextCatalog.getString("A total of {{amountAboveMaxSizeStr}} were excluded. The maximum size allowed for a transaction was exceeded.", {
|
||||||
|
amountAboveMaxSizeStr: txFormatService.formatAmountStr(resp.amountAboveMaxSize)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return warningMsg.join('\n');
|
||||||
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -255,10 +255,14 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
||||||
$scope.displayAmount = getDisplayAmount($scope.amountStr);
|
$scope.displayAmount = getDisplayAmount($scope.amountStr);
|
||||||
$scope.displayUnit = getDisplayUnit($scope.amountStr);
|
$scope.displayUnit = getDisplayUnit($scope.amountStr);
|
||||||
$scope.fee = txFormatService.formatAmountStr(data.fee);
|
$scope.fee = txFormatService.formatAmountStr(data.fee);
|
||||||
|
txFormatService.formatAlternativeStr(data.fee, function(v) {
|
||||||
|
$scope.feeFiat = v;
|
||||||
|
});
|
||||||
toAmount = parseFloat((data.amount * satToUnit).toFixed(unitDecimals));
|
toAmount = parseFloat((data.amount * satToUnit).toFixed(unitDecimals));
|
||||||
txFormatService.formatAlternativeStr(data.amount, function(v) {
|
txFormatService.formatAlternativeStr(data.amount, function(v) {
|
||||||
$scope.alternativeAmountStr = v;
|
$scope.alternativeAmountStr = v;
|
||||||
});
|
});
|
||||||
|
$scope.feeRateStr = (data.fee / (data.amount + data.fee) * 100).toFixed(2) + '%';
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
});
|
});
|
||||||
|
|
@ -347,7 +351,6 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
||||||
var stop;
|
var stop;
|
||||||
$scope.wallet = wallet;
|
$scope.wallet = wallet;
|
||||||
$scope.fee = $scope.txp = null;
|
$scope.fee = $scope.txp = null;
|
||||||
|
|
||||||
if (stop) {
|
if (stop) {
|
||||||
$timeout.cancel(stop);
|
$timeout.cancel(stop);
|
||||||
stop = null;
|
stop = null;
|
||||||
|
|
@ -385,6 +388,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
||||||
$scope.feeFiat = v;
|
$scope.feeFiat = v;
|
||||||
});
|
});
|
||||||
$scope.txp = txp;
|
$scope.txp = txp;
|
||||||
|
$scope.feeRateStr = (txp.fee / (txp.amount + txp.fee) * 100).toFixed(2) + '%';
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
});
|
});
|
||||||
|
|
@ -428,7 +432,7 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
||||||
txp.inputs = $scope.sendMaxInfo.inputs;
|
txp.inputs = $scope.sendMaxInfo.inputs;
|
||||||
txp.fee = $scope.sendMaxInfo.fee;
|
txp.fee = $scope.sendMaxInfo.fee;
|
||||||
} else
|
} else
|
||||||
txp.feeLevel = config.settings && config.settings.feeLevel ? config.settings.feeLevel : 'normal';
|
txp.feeLevel = feeLevel;
|
||||||
|
|
||||||
txp.message = description;
|
txp.message = description;
|
||||||
|
|
||||||
|
|
@ -576,4 +580,31 @@ angular.module('copayApp.controllers').controller('confirmController', function(
|
||||||
if (err) return setSendError(err);
|
if (err) return setSendError(err);
|
||||||
}, onSendStatusChange);
|
}, onSendStatusChange);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.chooseFeeLevel = function() {
|
||||||
|
|
||||||
|
$scope.customFeeLevel = feeLevel;
|
||||||
|
$ionicModal.fromTemplateUrl('views/modals/chooseFeeLevel.html', {
|
||||||
|
scope: $scope,
|
||||||
|
}).then(function(modal) {
|
||||||
|
$scope.chooseFeeLevelModal = modal;
|
||||||
|
$scope.openModal();
|
||||||
|
});
|
||||||
|
$scope.openModal = function() {
|
||||||
|
$scope.chooseFeeLevelModal.show();
|
||||||
|
};
|
||||||
|
$scope.hideModal = function(customFeeLevel) {
|
||||||
|
if (customFeeLevel) {
|
||||||
|
cachedTxp = {};
|
||||||
|
ongoingProcess.set('gettingFeeLevels', true);
|
||||||
|
setFee(customFeeLevel, function() {
|
||||||
|
ongoingProcess.set('gettingFeeLevels', false);
|
||||||
|
resetValues();
|
||||||
|
if ($scope.wallet) useSelectedWallet();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$scope.chooseFeeLevelModal.hide();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ angular.module('copayApp.controllers').controller('paperWalletController',
|
||||||
$scope.wallet.buildTxFromPrivateKey($scope.privateKey, destinationAddress, null, function(err, testTx) {
|
$scope.wallet.buildTxFromPrivateKey($scope.privateKey, destinationAddress, null, function(err, testTx) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
var rawTxLength = testTx.serialize().length;
|
var rawTxLength = testTx.serialize().length;
|
||||||
feeService.getCurrentFeeValue('livenet', function(err, feePerKB) {
|
feeService.getCurrentFeeValue('livenet', null, function(err, feePerKB) {
|
||||||
var opts = {};
|
var opts = {};
|
||||||
opts.fee = Math.round((feePerKB * rawTxLength) / 2000);
|
opts.fee = Math.round((feePerKB * rawTxLength) / 2000);
|
||||||
$scope.wallet.buildTxFromPrivateKey($scope.privateKey, destinationAddress, opts, function(err, tx) {
|
$scope.wallet.buildTxFromPrivateKey($scope.privateKey, destinationAddress, opts, function(err, tx) {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,15 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('copayApp.controllers').controller('preferencesFeeController', function($scope, $timeout, $ionicHistory, lodash, gettextCatalog, configService, feeService, ongoingProcess, popupService) {
|
angular.module('copayApp.controllers').controller('preferencesFeeController', function($scope, $timeout, $ionicHistory, lodash, gettextCatalog, configService, feeService, ongoingProcess, popupService) {
|
||||||
|
|
||||||
$scope.save = function(newFee) {
|
$scope.save = function(newFee) {
|
||||||
|
|
||||||
|
if ($scope.customFeeLevel) {
|
||||||
|
$scope.currentFeeLevel = newFee;
|
||||||
|
updateCurrentValues();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var opts = {
|
var opts = {
|
||||||
wallet: {
|
wallet: {
|
||||||
settings: {
|
settings: {
|
||||||
|
|
@ -22,8 +29,12 @@ angular.module('copayApp.controllers').controller('preferencesFeeController', fu
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.$on("$ionicView.beforeEnter", function(event, data) {
|
$scope.$on("$ionicView.beforeEnter", function(event, data) {
|
||||||
|
$scope.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.init = function() {
|
||||||
$scope.feeOpts = feeService.feeOpts;
|
$scope.feeOpts = feeService.feeOpts;
|
||||||
$scope.currentFeeLevel = feeService.getCurrentFeeLevel();
|
$scope.currentFeeLevel = $scope.customFeeLevel ? $scope.customFeeLevel : feeService.getCurrentFeeLevel();
|
||||||
$scope.loadingFee = true;
|
$scope.loadingFee = true;
|
||||||
feeService.getFeeLevels(function(err, levels) {
|
feeService.getFeeLevels(function(err, levels) {
|
||||||
$scope.loadingFee = false;
|
$scope.loadingFee = false;
|
||||||
|
|
@ -36,7 +47,7 @@ angular.module('copayApp.controllers').controller('preferencesFeeController', fu
|
||||||
updateCurrentValues();
|
updateCurrentValues();
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
});
|
});
|
||||||
});
|
};
|
||||||
|
|
||||||
var updateCurrentValues = function() {
|
var updateCurrentValues = function() {
|
||||||
if (lodash.isEmpty($scope.feeLevels) || lodash.isEmpty($scope.currentFeeLevel)) return;
|
if (lodash.isEmpty($scope.feeLevels) || lodash.isEmpty($scope.currentFeeLevel)) return;
|
||||||
|
|
@ -44,11 +55,15 @@ angular.module('copayApp.controllers').controller('preferencesFeeController', fu
|
||||||
level: $scope.currentFeeLevel
|
level: $scope.currentFeeLevel
|
||||||
});
|
});
|
||||||
if (lodash.isEmpty(feeLevelValue)) {
|
if (lodash.isEmpty(feeLevelValue)) {
|
||||||
$scope.feePerKBUnit = null;
|
$scope.feePerSatByte = null;
|
||||||
$scope.avgConfirmationTime = null;
|
$scope.avgConfirmationTime = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$scope.feePerKBUnit = feeLevelValue.feePerKBUnit;
|
$scope.feePerSatByte = (feeLevelValue.feePerKB / 1000).toFixed();
|
||||||
$scope.avgConfirmationTime = feeLevelValue.nbBlocks * 10;
|
$scope.avgConfirmationTime = feeLevelValue.nbBlocks * 10;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.chooseNewFee = function() {
|
||||||
|
$scope.hideModal($scope.currentFeeLevel);
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@ angular.module('copayApp.services').factory('feeService', function($log, $stateP
|
||||||
return configService.getSync().wallet.settings.feeLevel || 'normal';
|
return configService.getSync().wallet.settings.feeLevel || 'normal';
|
||||||
};
|
};
|
||||||
|
|
||||||
root.getCurrentFeeValue = function(network, cb) {
|
root.getCurrentFeeValue = function(network, customFeeLevel, cb) {
|
||||||
network = network || 'livenet';
|
network = network || 'livenet';
|
||||||
var feeLevel = root.getCurrentFeeLevel();
|
var feeLevel = customFeeLevel || root.getCurrentFeeLevel();
|
||||||
|
|
||||||
root.getFeeLevels(function(err, levels) {
|
root.getFeeLevels(function(err, levels) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
@ -50,12 +50,7 @@ angular.module('copayApp.services').factory('feeService', function($log, $stateP
|
||||||
walletClient.getFeeLevels('testnet', function(errTestnet, levelsTestnet) {
|
walletClient.getFeeLevels('testnet', function(errTestnet, levelsTestnet) {
|
||||||
if (errLivenet || errTestnet) {
|
if (errLivenet || errTestnet) {
|
||||||
return cb(gettextCatalog.getString('Could not get dynamic fee'));
|
return cb(gettextCatalog.getString('Could not get dynamic fee'));
|
||||||
} else {
|
|
||||||
lodash.each(lodash.union(levelsLivenet, levelsTestnet), function(level) {
|
|
||||||
level.feePerKBUnit = txFormatService.formatAmount(level.feePerKB) + ' ' + unitName;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cb(null, {
|
return cb(null, {
|
||||||
'livenet': levelsLivenet,
|
'livenet': levelsLivenet,
|
||||||
'testnet': levelsTestnet
|
'testnet': levelsTestnet
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
var tmpl;
|
var tmpl;
|
||||||
if (isWP) tmpl = '<div>' + showName +'</div>';
|
if (isWP) tmpl = '<div>' + showName + '</div>';
|
||||||
else tmpl = '<div class="item-icon-left">' + showName + '<ion-spinner class="spinner-stable" icon="lines"></ion-spinner></div>';
|
else tmpl = '<div class="item-icon-left">' + showName + '<ion-spinner class="spinner-stable" icon="lines"></ion-spinner></div>';
|
||||||
$ionicLoading.show({
|
$ionicLoading.show({
|
||||||
template: tmpl
|
template: tmpl
|
||||||
|
|
@ -95,8 +95,8 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
|
||||||
if (isCordova && !isWP) {
|
if (isCordova && !isWP) {
|
||||||
window.plugins.spinnerDialog.hide();
|
window.plugins.spinnerDialog.hide();
|
||||||
} else {
|
} else {
|
||||||
$ionicLoading.hide();
|
$ionicLoading.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ angular.module('copayApp.services').service('sendMaxService', function(feeServic
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
this.getInfo = function(wallet, cb) {
|
this.getInfo = function(wallet, cb) {
|
||||||
feeService.getCurrentFeeValue(wallet.credentials.network, function(err, feePerKb) {
|
feeService.getCurrentFeeValue(wallet.credentials.network, null, function(err, feePerKb) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
var config = configService.getSync().wallet;
|
var config = configService.getSync().wallet;
|
||||||
|
|
||||||
walletService.getSendMaxInfo(wallet, {
|
walletService.getSendMaxInfo(wallet, {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
#view-confirm {
|
#view-confirm {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
@extend .deflash-blue;
|
@extend .deflash-blue;
|
||||||
|
.item-note {
|
||||||
|
float: none;
|
||||||
|
.fee-rate {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
.icon-amazon {
|
.icon-amazon {
|
||||||
background-image: url("../img/icon-amazon.svg");
|
background-image: url("../img/icon-amazon.svg");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,10 +142,6 @@
|
||||||
padding: .2rem 0;
|
padding: .2rem 0;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
|
|
||||||
~ .bp-arrow-right {
|
|
||||||
top: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> i {
|
> i {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
position: static;
|
position: static;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@
|
||||||
</span>
|
</span>
|
||||||
<div class="wallet" ng-if="recipientType == 'wallet'">
|
<div class="wallet" ng-if="recipientType == 'wallet'">
|
||||||
<i class="icon big-icon-svg">
|
<i class="icon big-icon-svg">
|
||||||
<img src="img/icon-wallet.svg" ng-style="{'background-color': toColor}" class="bg"/>
|
<img src="img/icon-wallet.svg" ng-class="{'wallet-background-color-default': !toColor}" ng-style="{'background-color': toColor}" class="bg"/>
|
||||||
</i>
|
</i>
|
||||||
<div copy-to-clipboard="toAddress" class="ellipsis">
|
<div copy-to-clipboard="toAddress" class="ellipsis">
|
||||||
<contact ng-if="!toName" address="{{toAddress}}"></contact>
|
<contact ng-if="!toName" address="{{toAddress}}"></contact>
|
||||||
|
|
@ -77,18 +77,21 @@
|
||||||
</div>
|
</div>
|
||||||
<i class="icon bp-arrow-right"></i>
|
<i class="icon bp-arrow-right"></i>
|
||||||
</a>
|
</a>
|
||||||
<a class="item single-line item-icon-right" ng-if="!insufficientFunds && !noMatchingWallet" ng-click="showDescriptionPopup()">
|
<div class="item item-icon-right" ng-if="!insufficientFunds && !noMatchingWallet" ng-click="chooseFeeLevel()">
|
||||||
|
<span class="label">{{'Fee:' | translate}} {{feeLevel | translate}}</span>
|
||||||
|
<span class="m10l">{{fee || '...'}}</span>
|
||||||
|
<span class="item-note m10l">
|
||||||
|
<span>{{feeFiat || '...'}} <span class="fee-rate" ng-if="feeRateStr" translate>- {{feeRateStr}} of the transaction</span></span>
|
||||||
|
</span>
|
||||||
|
<i class="icon bp-arrow-right"></i>
|
||||||
|
</div>
|
||||||
|
<a class="item item-icon-right" ng-if="!insufficientFunds && !noMatchingWallet" ng-click="showDescriptionPopup()">
|
||||||
<span class="label" translate>Add Memo</span>
|
<span class="label" translate>Add Memo</span>
|
||||||
<span class="item-note m10l">
|
<span class="item-note m10l">
|
||||||
{{description}}
|
{{description}}
|
||||||
</span>
|
</span>
|
||||||
<i class="icon bp-arrow-right"></i>
|
<i class="icon bp-arrow-right"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="item single-line toggle" ng-if="!insufficientFunds && !noMatchingWallet">
|
|
||||||
<span class="label">{{'Fee' | translate}}: {{feeLevel | translate}}</span>
|
|
||||||
<span ng-if="!showFeeFiat" class="item-note" ng-click="toggleFeeValue()">{{fee || '...'}}</span>
|
|
||||||
<span ng-if="showFeeFiat" class="item-note" ng-click="toggleFeeValue()">{{feeFiat || '...'}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="text-center" ng-show="noMatchingWallet">
|
<div class="text-center" ng-show="noMatchingWallet">
|
||||||
<span class="badge badge-energized" translate>No wallets available</span>
|
<span class="badge badge-energized" translate>No wallets available</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
<div class="m20t">
|
|
||||||
<label class="size-14 text-center">
|
|
||||||
<span translate>Send bitcoin</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="size-36">{{tx.amountStr}}</div>
|
|
||||||
<div class="size-12 label gray radius" ng-show="tx.alternativeAmountStr">{{tx.alternativeAmountStr}}</div>
|
|
||||||
<i class="db fi-arrow-down size-24 m10v"></i>
|
|
||||||
<div class="payment-proposal-to" copy-to-clipboard="tx.toAddress">
|
|
||||||
<i class="fi-bitcoin left m10l"></i>
|
|
||||||
<contact ng-if="!tx.hasMultiplesOutputs" class="dib enable_text_select ellipsis m5t m5b m15l size-14" address="{{tx.toAddress}}"></contact>
|
|
||||||
<span ng-if="tx.hasMultiplesOutputs" translate>
|
|
||||||
Multiple recipients
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="m10t size-12" ng-init="processFee(tx.amount, tx.fee)">
|
|
||||||
<div ng-show="!showPercentage" ng-click="showPercentage = true">
|
|
||||||
<span translate>Fee</span> <span class="tl">({{feeLevel|translate}})</span>:
|
|
||||||
<span class="text-bold">{{tx.feeStr}}</span>
|
|
||||||
<span class="label gray radius">{{feeAlternativeStr}}</span>
|
|
||||||
</div>
|
|
||||||
<div ng-show="showPercentage" ng-click="showPercentage = false" translate>
|
|
||||||
{{feeRateStr}} of the transaction
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row m20t dib">
|
|
||||||
<div class="half-row left">
|
|
||||||
<button ng-click="cancel()" class="round outline dark-gray expand">
|
|
||||||
<span class="size-12" translate>Cancel</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="half-row left">
|
|
||||||
<button ng-click="accept()" class="round expand" ng-class="{'wallet-background-color-default': !color}" ng-style="{'background-color': color}" autofocus>
|
|
||||||
<span class="size-12" translate>Confirm</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
34
www/views/modals/chooseFeeLevel.html
Normal file
34
www/views/modals/chooseFeeLevel.html
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
<ion-modal-view id="settings-fee" class="settings" ng-controller="preferencesFeeController" ng-init="init()">
|
||||||
|
<ion-header-bar align-title="center" class="bar-royal">
|
||||||
|
<button class="button button-clear" ng-click="hideModal()">
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
<div class="title">
|
||||||
|
{{'Bitcoin Network Fee Policy'|translate}}
|
||||||
|
</div>
|
||||||
|
</ion-header-bar>
|
||||||
|
<ion-content>
|
||||||
|
<div class="settings-explanation">
|
||||||
|
<div class="estimates">
|
||||||
|
<div>
|
||||||
|
<span translate>Average confirmation time</span>:
|
||||||
|
<span class="fee-minutes" ng-if="avgConfirmationTime">{{avgConfirmationTime | amDurationFormat: 'minute'}}</span>
|
||||||
|
<span ng-if="loadingFee">...</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span translate>Current fee rate for this policy</span>:
|
||||||
|
<span class="fee-rate" ng-if="feePerSatByte">{{feePerSatByte}} sat/byte</span>
|
||||||
|
<span ng-if="loadingFee">...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="fee-policies">
|
||||||
|
<ion-radio ng-repeat="(fee, level) in feeOpts" ng-value="fee" ng-model="currentFeeLevel" ng-click="save(fee)">
|
||||||
|
{{level|translate}}
|
||||||
|
</ion-radio>
|
||||||
|
</div>
|
||||||
|
<div class="m20t">
|
||||||
|
<button class="button button-standard button-primary" ng-click="chooseNewFee()" translate>Save</button>
|
||||||
|
</div>
|
||||||
|
</ion-content>
|
||||||
|
</ion-modal-view>
|
||||||
|
|
@ -12,13 +12,13 @@
|
||||||
<div class="settings-description" translate>The higher the fee, the greater the incentive a miner has to include that transaction in a block. Current fees are determined based on network load and the selected policy.</div>
|
<div class="settings-description" translate>The higher the fee, the greater the incentive a miner has to include that transaction in a block. Current fees are determined based on network load and the selected policy.</div>
|
||||||
<div class="estimates">
|
<div class="estimates">
|
||||||
<div>
|
<div>
|
||||||
<span translate>Average confirmation time</span>:
|
<span translate>Average confirmation time</span>:
|
||||||
<span class="fee-minutes" ng-if="avgConfirmationTime">{{avgConfirmationTime | amDurationFormat: 'minute'}}</span>
|
<span class="fee-minutes" ng-if="avgConfirmationTime">{{avgConfirmationTime | amDurationFormat: 'minute'}}</span>
|
||||||
<span ng-if="loadingFee">...</span>
|
<span ng-if="loadingFee">...</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span translate>Current fee rate for this policy</span>:
|
<span translate>Current fee rate for this policy</span>:
|
||||||
<span class="fee-rate" ng-if="feePerKBUnit">{{feePerKBUnit}}/kiB</span>
|
<span class="fee-rate" ng-if="feePerSatByte">{{feePerSatByte}} sat/byte</span>
|
||||||
<span ng-if="loadingFee">...</span>
|
<span ng-if="loadingFee">...</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue