Merged sprint 21.

This commit is contained in:
Brendon Duncan 2018-09-21 17:16:18 -07:00
commit 4d623d51d7
11 changed files with 1121 additions and 1039 deletions

View file

@ -366,13 +366,13 @@ module.exports = function(grunt) {
grunt.registerTask('build-mobile-release', ['build-ios-release', 'build-android-release']); grunt.registerTask('build-mobile-release', ['build-ios-release', 'build-android-release']);
// Build ios // Build ios
grunt.registerTask('start-ios', ['exec:build_ios_debug', 'exec:xcode']); grunt.registerTask('start-ios', ['default', 'exec:build_ios_debug', 'exec:xcode']);
grunt.registerTask('build-ios-debug', ['exec:build_ios_debug']); grunt.registerTask('build-ios-debug', ['default', 'exec:build_ios_debug']);
grunt.registerTask('build-ios-release', ['prod', 'exec:build_ios_release']); grunt.registerTask('build-ios-release', ['prod', 'exec:build_ios_release']);
// Build android // Build android
grunt.registerTask('start-android', ['build-android-debug', 'exec:run_android']); grunt.registerTask('start-android', ['build-android-debug', 'exec:run_android']);
grunt.registerTask('build-android-debug', ['exec:build_android_debug']); grunt.registerTask('build-android-debug', ['default', 'exec:build_android_debug']);
grunt.registerTask('start-android-emulator', ['build-android-debug', 'exec:run_android_emulator']); grunt.registerTask('start-android-emulator', ['build-android-debug', 'exec:run_android_emulator']);
grunt.registerTask('build-android-release', ['prod', 'exec:build_android_release', 'sign-android']); grunt.registerTask('build-android-release', ['prod', 'exec:build_android_release', 'sign-android']);
grunt.registerTask('sign-android', ['exec:sign_android']); grunt.registerTask('sign-android', ['exec:sign_android']);

View file

@ -1,10 +1,12 @@
'use strict'; 'use strict';
(function () {
angular angular
.module('copayApp.controllers') .module('copayApp.controllers')
.controller('reviewController', reviewController); .controller('reviewController', reviewController);
function reviewController(addressbookService, bitcoinCashJsService, bitcore, bitcoreCash, bwcError, clipboardService, configService, feeService, gettextCatalog, $interval, $ionicHistory, $ionicModal, ionicToast, lodash, $log, ongoingProcess, platformInfo, popupService, profileService, $scope, sendFlowService, shapeshiftService, soundService, $state, $timeout, txConfirmNotification, txFormatService, walletService) { function reviewController(addressbookService, bitcoinCashJsService, bitcore, bitcoreCash, bwcError, clipboardService, configService, feeService, gettextCatalog, $interval, $ionicHistory, $ionicModal, ionicToast, lodash, $log, ongoingProcess, platformInfo, popupService, profileService, $scope, sendFlowService, shapeshiftService, soundService, $state, $timeout, txConfirmNotification, txFormatService, walletService) {
var vm = this; var vm = this;
vm.buttonText = ''; vm.buttonText = '';
@ -26,6 +28,7 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
vm.feeIsHigh = false; vm.feeIsHigh = false;
vm.feeLessThanACent = false; vm.feeLessThanACent = false;
vm.isCordova = platformInfo.isCordova; vm.isCordova = platformInfo.isCordova;
vm.memo = '';
vm.notReadyMessage = ''; vm.notReadyMessage = '';
vm.origin = { vm.origin = {
balanceAmount: '', balanceAmount: '',
@ -79,6 +82,9 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
function onBeforeEnter(event, data) { function onBeforeEnter(event, data) {
console.log('review onBeforeEnter sendflow ', sendFlowService.state); console.log('review onBeforeEnter sendflow ', sendFlowService.state);
// Reset from last time
vm.memo = '';
defaults = configService.getDefaults(); defaults = configService.getDefaults();
sendFlowData = sendFlowService.state.getClone(); sendFlowData = sendFlowService.state.getClone();
originWalletId = sendFlowData.fromWalletId; originWalletId = sendFlowData.fromWalletId;
@ -392,12 +398,12 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
var balanceCryptoAmount = ''; var balanceCryptoAmount = '';
var balanceCryptoCurrencyCode = ''; var balanceCryptoCurrencyCode = '';
var balanceFiatAmount = ''; var balanceFiatAmount = '';
var balanceFiatCurrency = '' var balanceFiatCurrency = '';
var displayAmount = ''; var displayAmount = '';
var displayCurrency = ''; var displayCurrency = '';
var walletStatus = null; var walletStatus = null;
if (wallet.status.isValid) { if (wallet.status && wallet.status.isValid) {
walletStatus = wallet.status; walletStatus = wallet.status;
} else if (wallet.cachedStatus.isValid) { } else if (wallet.cachedStatus.isValid) {
walletStatus = wallet.cachedStatus; walletStatus = wallet.cachedStatus;
@ -948,5 +954,5 @@ function reviewController(addressbookService, bitcoinCashJsService, bitcore, bit
}); });
}); });
} }
}
} })();

View file

@ -10,7 +10,7 @@ angular.module('copayApp.controllers').controller('shapeshiftController', functi
walletsBtc = profileService.getWallets({coin: 'btc'}); walletsBtc = profileService.getWallets({coin: 'btc'});
walletsBch = profileService.getWallets({coin: 'bch'}); walletsBch = profileService.getWallets({coin: 'bch'});
$scope.fromWallets = lodash.filter(walletsBtc.concat(walletsBch), function(w) { $scope.fromWallets = lodash.filter(walletsBtc.concat(walletsBch), function(w) {
return w.status.balance.availableAmount > 0; return (w.status && w.status.balance && w.status.balance.availableAmount > 0);
}); });
$scope.singleFromWallet = $scope.fromWallets.length === 1; $scope.singleFromWallet = $scope.fromWallets.length === 1;

View file

@ -2,6 +2,7 @@
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) { 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 CLOSE_NORMAL = 1000;
var listeners = []; var listeners = [];
$scope.bchAddressType = { type: 'cashaddr' }; $scope.bchAddressType = { type: 'cashaddr' };
var bchAddresses = {}; var bchAddresses = {};
@ -10,12 +11,11 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
$scope.isCordova = platformInfo.isCordova; $scope.isCordova = platformInfo.isCordova;
$scope.isNW = platformInfo.isNW; $scope.isNW = platformInfo.isNW;
var currentAddressSocket = {}; var currentAddressSocket = null;
var paymentSubscriptionObj = { op:"addr_sub" } var paymentSubscriptionObj = { op:'addr_sub' };
var config;
$scope.displayBalanceAsFiat = true; $scope.displayBalanceAsFiat = true;
$scope.$on('$ionicView.beforeLeave', onBeforeLeave);
$scope.requestSpecificAmount = function() { $scope.requestSpecificAmount = function() {
sendFlowService.start({ sendFlowService.start({
@ -24,6 +24,50 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
}); });
}; };
function connectSocket() {
// Close existing socket if not connected with current address
if (currentAddressSocket) {
currentAddressSocket.close([CLOSE_NORMAL]);
}
if ($scope.wallet.coin === 'bch') {
// listen to bch address
currentAddressSocket = new WebSocket('wss://ws.blockchain.info/bch/inv');
paymentSubscriptionObj.addr = $scope.addrBchLegacy;
} else {
// listen to btc address
currentAddressSocket = new WebSocket('wss://ws.blockchain.info/inv');
paymentSubscriptionObj.addr = $scope.addr;
}
// create subscription to address
var msg = JSON.stringify(paymentSubscriptionObj);
currentAddressSocket.onopen = function (event) {
currentAddressSocket.send(msg);
};
// listen for response
currentAddressSocket.onmessage = function (event) {
//console.log("message received:" + event.data);
receivedPayment(event.data);
};
currentAddressSocket.onclose = function(event) {
if (event.code !== CLOSE_NORMAL) {
$log.debug('Socket was closed abnormally. Reconnect will be attempted in 1 second.');
$timeout(function() {
connectSocket();
}, 1000);
}
};
currentAddressSocket.onerror = function(err) {
console.error('Socket encountered error: ', err, 'Closing socket');
currentAddressSocket.close();
};
}
$scope.setAddress = function(newAddr, copyAddress) { $scope.setAddress = function(newAddr, copyAddress) {
$scope.addr = null; $scope.addr = null;
if (!$scope.wallet || $scope.generatingAddress || !$scope.wallet.isComplete()) return; if (!$scope.wallet || $scope.generatingAddress || !$scope.wallet.isComplete()) return;
@ -36,49 +80,24 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
popupService.showAlert(err); popupService.showAlert(err);
} }
//close existing socket if ($scope.wallet.coin === 'bch') {
if (currentAddressSocket.close === 'function') {
currentAddressSocket.close();
}
if ($scope.wallet.coin == 'bch') {
bchAddresses = bitcoinCashJsService.translateAddresses(addr); bchAddresses = bitcoinCashJsService.translateAddresses(addr);
$scope.addr = bchAddresses[$scope.bchAddressType.type]; $scope.addr = bchAddresses[$scope.bchAddressType.type];
$scope.addrBchLegacy = bchAddresses['legacy']; $scope.addrBchLegacy = bchAddresses['legacy'];
// listen to bch address
currentAddressSocket = new WebSocket("wss://ws.blockchain.info/bch/inv");
paymentSubscriptionObj.addr = bchAddresses['legacy'];
} else { } else {
$scope.addr = addr; $scope.addr = addr;
// listen to btc address
currentAddressSocket = new WebSocket("wss://ws.blockchain.info/inv");
paymentSubscriptionObj.addr = $scope.addr
} }
connectSocket();
if (copyAddress === true) { if (copyAddress === true) {
try { try {
clipboardService.copyToClipboard($scope.wallet.coin == 'bch' && $scope.bchAddressType.type == 'cashaddr' ? 'bitcoincash:' + $scope.addr : $scope.addr); clipboardService.copyToClipboard($scope.wallet.coin == 'bch' && $scope.bchAddressType.type == 'cashaddr' ? 'bitcoincash:' + $scope.addr : $scope.addr);
} catch (error) { } catch (error) {
$log.debug("Error copying to clipboard:"); $log.debug('Error copying to clipboard:');
$log.debug(error); $log.debug(error);
} }
} }
// create subscription
var msg = JSON.stringify(paymentSubscriptionObj);
currentAddressSocket.onopen = function (event) {
//console.log("message sent: " + msg);
currentAddressSocket.send(msg);
}
// listen for response
currentAddressSocket.onmessage = function (event) {
//console.log("message received:" + event.data);
receivedPayment(event.data);
}
$timeout(function() { $timeout(function() {
$scope.$apply(); $scope.$apply();
@ -164,7 +183,6 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
// Notify new tx // Notify new tx
$scope.$emit('bwsEvent', $scope.wallet.id); $scope.$emit('bwsEvent', $scope.wallet.id);
$scope.$apply(function () { $scope.$apply(function () {
$scope.showingPaymentReceived = true; $scope.showingPaymentReceived = true;
}); });
@ -233,6 +251,10 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
} }
}; };
function onBeforeLeave() {
currentAddressSocket.close([CLOSE_NORMAL]);
}
$scope.$on("$ionicView.beforeEnter", function(event, data) { $scope.$on("$ionicView.beforeEnter", function(event, data) {
$scope.wallets = profileService.getWallets(); $scope.wallets = profileService.getWallets();
$scope.singleWallet = $scope.wallets.length == 1; $scope.singleWallet = $scope.wallets.length == 1;
@ -258,7 +280,6 @@ angular.module('copayApp.controllers').controller('tabReceiveController', functi
configService.whenAvailable(function(_config) { configService.whenAvailable(function(_config) {
$scope.displayBalanceAsFiat = _config.wallet.settings.priceDisplay === 'fiat'; $scope.displayBalanceAsFiat = _config.wallet.settings.priceDisplay === 'fiat';
config = _config;
}); });
}); });

View file

@ -203,6 +203,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
function updateTxHistoryFromCachedData() { function updateTxHistoryFromCachedData() {
$scope.vm.gettingCachedHistory = true;
walletHistoryService.getCachedTxHistory($scope.wallet.id, function onGetCachedTxHistory(err, txHistory){ walletHistoryService.getCachedTxHistory($scope.wallet.id, function onGetCachedTxHistory(err, txHistory){
$scope.vm.gettingCachedHistory = false; $scope.vm.gettingCachedHistory = false;
if (err) { if (err) {
@ -400,8 +401,9 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
var refreshInterval; var refreshInterval;
$scope.$on("$ionicView.afterEnter", function(event, data) { $scope.$on("$ionicView.afterEnter", function onAfterEnter(event, data) {
$scope.updateAll(); updateTxHistoryFromCachedData();
$scope.updateAll(true, true);
// refreshAmountSection(); // refreshAmountSection();
refreshInterval = $interval($scope.onRefresh, 10 * 1000); refreshInterval = $interval($scope.onRefresh, 10 * 1000);
$timeout(function() { $timeout(function() {

View file

@ -1,7 +1,12 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('walletSelectorController', function($scope, $state, sendFlowService, configService, gettextCatalog, profileService, txFormatService) { (function () {
angular
.module('copayApp.controllers')
.controller('walletSelectorController', walletSelectorController);
function walletSelectorController ($scope, $state, sendFlowService, configService, gettextCatalog, ongoingProcess, profileService, walletService, txFormatService) {
var fromWalletId = ''; var fromWalletId = '';
var priceDisplayAsFiat = false; var priceDisplayAsFiat = false;
var unitDecimals = 0; var unitDecimals = 0;
@ -116,32 +121,41 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
if ($scope.type === 'origin') { if ($scope.type === 'origin') {
$scope.headerTitle = gettextCatalog.getString('Choose a wallet to send from'); $scope.headerTitle = gettextCatalog.getString('Choose a wallet to send from');
if ($scope.params.amount) { if ($scope.params.amount || $scope.coin) {
walletsAll = profileService.getWallets({coin: $scope.coin}); walletsAll = profileService.getWallets({coin: $scope.coin});
ongoingProcess.set('scanning', true);
walletsAll.forEach(function forWallet(wallet){ walletsAll.forEach(function forWallet(wallet) {
if (wallet.status.availableBalanceSat > $scope.params.amount) { if (!wallet.status && !wallet.cachedStatus) {
walletService.getStatus(wallet, {}, function(err, status) {
wallet.status = status;
if (status.availableBalanceSat > ($scope.params.amount ? $scope.params.amount : 0)) {
walletsSufficientFunds.push(wallet); walletsSufficientFunds.push(wallet);
} else { } else {
$scope.walletsInsufficientFunds.push(wallet); $scope.walletsInsufficientFunds.push(wallet);
} }
}); if ($scope.coin === 'btc') { // As this is a promise
if ($scope.coin === 'btc') {
$scope.walletsBtc = walletsSufficientFunds; $scope.walletsBtc = walletsSufficientFunds;
} else { } else {
$scope.walletsBch = walletsSufficientFunds; $scope.walletsBch = walletsSufficientFunds;
} }
ongoingProcess.set('scanning', false);
});
} else {
var walletStatus = null;
if (wallet.status && wallet.status.isValid) {
walletStatus = wallet.status;
} else if (wallet.cachedStatus && wallet.status.isValid) {
walletStatus = wallet.cachedStatus;
}
} else if ($scope.coin) { if (walletStatus && walletStatus.availableBalanceSat > ($scope.params.amount ? $scope.params.amount : 0)) {
walletsAll = profileService.getWallets({coin: $scope.coin});
walletsAll.forEach(function forWallet(wallet){
if (wallet.status.availableBalanceSat > 0) {
walletsSufficientFunds.push(wallet); walletsSufficientFunds.push(wallet);
} else { } else {
$scope.walletsInsufficientFunds.push(wallet); $scope.walletsInsufficientFunds.push(wallet);
} }
ongoingProcess.set('scanning', false);
}
}); });
if ($scope.coin === 'btc') { if ($scope.coin === 'btc') {
@ -186,4 +200,5 @@ angular.module('copayApp.controllers').controller('walletSelectorController', fu
sendFlowService.router.goBack(); sendFlowService.router.goBack();
} }
}); }
})();

View file

@ -12,6 +12,7 @@
totalBalanceSat: '@', totalBalanceSat: '@',
// The Wallet object is sometimes not stringify()-able, so not interpolatable, // The Wallet object is sometimes not stringify()-able, so not interpolatable,
// so can't be passed to a directive. // so can't be passed to a directive.
walletCoin: '@',
walletStatus: '@', walletStatus: '@',
walletCachedBalance: '@', walletCachedBalance: '@',
walletCachedBalanceUpdatedOn: '@', walletCachedBalanceUpdatedOn: '@',
@ -31,7 +32,6 @@
}); });
function displayCryptoBalance(walletStatus, walletCachedBalance, walletCachedBalanceUpdatedOn, walletCachedStatus) { function displayCryptoBalance(walletStatus, walletCachedBalance, walletCachedBalanceUpdatedOn, walletCachedStatus) {
console.log('displayCryptoBalance()');
if (walletStatus && walletStatus.isValid && walletStatus.totalBalanceStr) { if (walletStatus && walletStatus.isValid && walletStatus.totalBalanceStr) {
setDisplay(walletStatus.totalBalanceStr, ''); setDisplay(walletStatus.totalBalanceStr, '');
@ -52,7 +52,7 @@
setDisplay('', ''); setDisplay('', '');
} }
function displayFiatBalance(walletStatus, walletCachedStatus) { function displayFiatBalance(walletStatus, walletCachedStatus, walletCoin) {
var displayAmount = ''; var displayAmount = '';
if (walletStatus && walletStatus.isValid && walletStatus.alternativeBalanceAvailable) { if (walletStatus && walletStatus.isValid && walletStatus.alternativeBalanceAvailable) {
displayAmount = walletStatus.totalBalanceAlternative + ' ' + walletStatus.alternativeIsoCode; displayAmount = walletStatus.totalBalanceAlternative + ' ' + walletStatus.alternativeIsoCode;
@ -66,7 +66,7 @@
return; return;
} }
getFiatBalance(wallet); getFiatBalance(walletStatus, walletCachedStatus, walletCoin);
} }
function formatBalance() { function formatBalance() {
@ -94,19 +94,30 @@
} }
if (displayAsFiat) { if (displayAsFiat) {
displayFiatBalance(walletStatusObj, walletCachedStatusObj); displayFiatBalance(walletStatusObj, walletCachedStatusObj, $scope.walletCoin);
} }
} }
function getFiatBalance(wallet) { function getFiatBalance(walletStatus, walletCachedStatus, walletCoin) {
if (!(wallet.status && wallet.status.isValid)) { var totalBalanceSat = null;
$log.warn('Abandoning call to get fiat balance, because no valid wallet status.');
if (walletStatus && walletStatus.isValid) {
totalBalanceSat = walletStatus.totalBalanceSat
} else if (walletCachedStatus && walletCachedStatus.isValid) {
totalBalanceSat = walletCachedStatus.totalBalanceSat
}
// 0 is valid
if (totalBalanceSat === null) {
$log.warn('Abandoning call to get fiat balance, because no valid wallet status (cached or otherwise).');
return; return;
} }
txFormatService.formatAlternativeStr(wallet.coin, wallet.status.totalBalanceSat, function onFormatAlernativeStr(formatted) { txFormatService.formatAlternativeStr(walletCoin, totalBalanceSat, function onFormatAlernativeStr(formatted) {
if (formatted) { if (formatted) {
setDisplay(formatted, ''); setDisplay(formatted, '');
} else {
$log.error('Failed to format fiat balance of wallet.');
} }
}); });
} }

View file

@ -75,9 +75,7 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
var showName = $filter('translate')(processNames[name] || name); var showName = $filter('translate')(processNames[name] || name);
if (customHandler) { if (root.onGoingProcessName) {
customHandler(processName, showName, isOn);
} else if (root.onGoingProcessName) {
var tmpl; var tmpl;
if (isWindowsPhoneApp) tmpl = '<div>' + showName + '</div>'; if (isWindowsPhoneApp) 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>';
@ -87,6 +85,10 @@ angular.module('copayApp.services').factory('ongoingProcess', function($log, $ti
} else { } else {
$ionicLoading.hide(); $ionicLoading.hide();
} }
if (customHandler) {
customHandler(processName, showName, isOn);
}
}; };
return root; return root;

View file

@ -27,20 +27,23 @@
function addEarlyTransactions(walletId, cachedTxs, newTxs) { function addEarlyTransactions(walletId, cachedTxs, newTxs) {
var cachedTxIds = {}; var cachedTxIndexFromId = {};
cachedTxs.forEach(function forCachedTx(tx){ cachedTxs.forEach(function forCachedTx(tx){
cachedTxIds[tx.txid] = true; cachedTxIndexFromId[tx.txid] = true;
}); });
var confirmationsUpdated = false;
var someTransactionsWereNew = false; var someTransactionsWereNew = false;
var overlappingTxsCount = 0; var overlappingTxsCount = 0;
newTxs.forEach(function forNewTx(tx){ newTxs.forEach(function forNewTx(tx){
if (cachedTxIds[tx.txid]) { if (typeof cachedTxIndexFromId[tx.txid] === "undefined") {
overlappingTxsCount++;
} else {
someTransactionsWereNew = true; someTransactionsWereNew = true;
cachedTxs.push(tx); cachedTxs.push(tx);
} else {
var txUpdated = updateCachedTx(cachedTxs, cachedTxIndexFromId, tx);
confirmationsUpdated = confirmationsUpdated || txUpdated;
overlappingTxsCount++;
} }
}); });
@ -50,6 +53,8 @@
if (overlappingTxFraction >= MIN_KNOWN_TX_OVERLAP_FRACTION) { // We are good if (overlappingTxFraction >= MIN_KNOWN_TX_OVERLAP_FRACTION) { // We are good
if (someTransactionsWereNew) { if (someTransactionsWereNew) {
saveTxHistory(walletId, cachedTxs); saveTxHistory(walletId, cachedTxs);
} else if (confirmationsUpdated) {
saveTxHistory(walletId, cachedTxs);
} else if (overlappingTxsCount === newTxs.length) { } else if (overlappingTxsCount === newTxs.length) {
allTransactionsFetched = true; allTransactionsFetched = true;
} }
@ -65,21 +70,24 @@
} }
function addLatestTransactions(walletId, cachedTxs, newTxs) { function addLatestTransactions(walletId, cachedTxs, newTxs) {
var cachedTxIds = {}; var cachedTxIndexFromId = {};
cachedTxs.forEach(function forCachedTx(tx){ cachedTxs.forEach(function forCachedTx(tx, txIndex){
cachedTxIds[tx.txid] = true; cachedTxIndexFromId[tx.txid] = txIndex;
}); });
var someTransactionsWereNew = false; var someTransactionsWereNew = false;
var confirmationsUpdated = false;
var overlappingTxsCount = 0; var overlappingTxsCount = 0;
var uniqueNewTxs = []; var uniqueNewTxs = [];
newTxs.forEach(function forNewTx(tx){ newTxs.forEach(function forNewTx(tx){
if (cachedTxIds[tx.txid]) { if (typeof cachedTxIndexFromId[tx.txid] === "undefined") {
overlappingTxsCount++;
} else {
someTransactionsWereNew = true; someTransactionsWereNew = true;
uniqueNewTxs.push(tx); uniqueNewTxs.push(tx);
} else {
var txUpdated = updateCachedTx(cachedTxs, cachedTxIndexFromId, tx);
confirmationsUpdated = confirmationsUpdated || txUpdated;
overlappingTxsCount++;
} }
}); });
@ -91,6 +99,9 @@
saveTxHistory(walletId, allTxs); saveTxHistory(walletId, allTxs);
return allTxs; return allTxs;
} else { } else {
if (confirmationsUpdated) {
saveTxHistory(walletId, cachedTxs);
}
return cachedTxs; return cachedTxs;
} }
} else { } else {
@ -104,6 +115,8 @@
// Only clear the cache once we have received new transactions from the server. // Only clear the cache once we have received new transactions from the server.
/** /**
* @param wallet
* @param start
* @param {function(err, txs)} cb - transactions is always an array, may be empty * @param {function(err, txs)} cb - transactions is always an array, may be empty
*/ */
function fetchTxHistoryByPage(wallet, start, cb) { function fetchTxHistoryByPage(wallet, start, cb) {
@ -134,6 +147,7 @@
* @param {function(error, txs)} cb - txs is always an array, may be empty * @param {function(error, txs)} cb - txs is always an array, may be empty
*/ */
function getCachedTxHistory(walletId, cb) { function getCachedTxHistory(walletId, cb) {
console.log('txhistory updateLocalTxHistoryByPage()');
storageService.getTxHistory(walletId, function onGetTxHistory(err, txHistoryString){ storageService.getTxHistory(walletId, function onGetTxHistory(err, txHistoryString){
if (err) { if (err) {
return cb(err, []); return cb(err, []);
@ -187,7 +201,7 @@
}); });
return processedTxs; return processedTxs;
}; }
function saveTxHistory(walletId, processedTxs) { function saveTxHistory(walletId, processedTxs) {
storageService.setTxHistory(processedTxs, walletId, function onSetTxHistory(error){ storageService.setTxHistory(processedTxs, walletId, function onSetTxHistory(error){
@ -197,9 +211,26 @@
}); });
} }
/**
* Returns true if the cached tx was updated
* @param {*} cachedTxs
* @param {*} cachedTxIndexFromId - Indices for cachedTxs, based on txid
* @param {*} tx - The most recent tx info
*/
function updateCachedTx(cachedTxs, cachedTxIndexFromId, tx) {
var updated = false;
var txIndex = cachedTxIndexFromId[tx.txid];
var cachedTx = cachedTxs[txIndex];
if (cachedTx.confirmations < SAFE_CONFIRMATIONS && tx.confirmations > cachedTx.confirmations) {
cachedTxs[txIndex].confirmations = tx.confirmations;
updated = true;
}
return updated;
}
function updateLocalTxHistoryByPage(wallet, getLatest, flushCacheOnNew, cb) { function updateLocalTxHistoryByPage(wallet, getLatest, flushCacheOnNew, cb) {
console.log('txhistory updaetLocalTxHistoryByPage()');
if (flushCacheOnNew) { if (flushCacheOnNew) {
fetchTxHistoryByPage(wallet, 0, function onFetchTxHistory(err, txs){ fetchTxHistoryByPage(wallet, 0, function onFetchTxHistory(err, txs){
if (err) { if (err) {
@ -240,10 +271,5 @@
}); });
} }
} }
} }
})(); })();

View file

@ -18,13 +18,12 @@
<h2>{{fromWallet.name}}</h2> <h2>{{fromWallet.name}}</h2>
<wallet-balance <wallet-balance
display-as-fiat="{{displayBalanceAsFiat}}" display-as-fiat="{{displayBalanceAsFiat}}"
wallet-coin="{{fromWallet.coin}}"
wallet-status="{{fromWallet.status}}" wallet-status="{{fromWallet.status}}"
wallet-cached-balance="{{fromWallet.cachedBalance}}" wallet-cached-balance="{{fromWallet.cachedBalance}}"
wallet-cached-balance-updated-on="{{fromWallet.cachedBalanceUpdatedOn}}" wallet-cached-balance-updated-on="{{fromWallet.cachedBalanceUpdatedOn}}"
wallet-cached-status="{{fromWallet.cachedStatus}}" wallet-cached-status="{{fromWallet.cachedStatus}}"
total-balance-sat="{{fromWallet.status.totalBalanceSat}}"></wallet-balance> total-balance-sat="{{fromWallet.status.totalBalanceSat}}"></wallet-balance>
<!--<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>-->
</div> </div>
</div> </div>
</div> </div>

View file

@ -13,7 +13,7 @@
<div class="header--request__amount-alt" ng-show="requestAmountSecondary" translate>{{requestAmountSecondary}} {{requestCurrencySecondary}}</div> <div class="header--request__amount-alt" ng-show="requestAmountSecondary" translate>{{requestAmountSecondary}} {{requestCurrencySecondary}}</div>
</div> </div>
<div class="wallets-header"> <div class="wallets-header">
<div class="title"> <div class="title" ng-if="walletsBch.length > 0 || walletsBtc.length > 0 || walletsInsufficientFunds.length > 0">
{{headerTitle}} {{headerTitle}}
</div> </div>
</div> </div>