Getting earlier transactions with pagination.
This commit is contained in:
parent
0bd94601ae
commit
78f0ff28cd
2 changed files with 161 additions and 62 deletions
|
|
@ -198,6 +198,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var updateTxHistory = function(cb) {
|
var updateTxHistory = function(cb) {
|
||||||
if (!cb) cb = function() {};
|
if (!cb) cb = function() {};
|
||||||
$scope.vm.updateTxHistoryFailed = false;
|
$scope.vm.updateTxHistoryFailed = false;
|
||||||
|
|
@ -234,6 +235,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function applyCurrencyAliases(txHistory) {
|
function applyCurrencyAliases(txHistory) {
|
||||||
var defaults = configService.getDefaults();
|
var defaults = configService.getDefaults();
|
||||||
var configCache = configService.getSync();
|
var configCache = configService.getSync();
|
||||||
|
|
@ -259,7 +261,7 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function updateTxHistoryUsingCachedData() {
|
function updateTxHistoryFromCachedData() {
|
||||||
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) {
|
||||||
|
|
@ -277,27 +279,24 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
|
||||||
formatTxHistoryForDisplay(txHistory);
|
formatTxHistoryForDisplay(txHistory);
|
||||||
|
|
||||||
completeTxHistory = txHistory;
|
completeTxHistory = txHistory;
|
||||||
showHistory();
|
showHistory(false);
|
||||||
console.log('pagination Showing tx history items:', $scope.txHistory.length);
|
console.log('pagination Showing tx history items:', $scope.txHistory.length);
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
console.log('pagination displayed cached history.');
|
console.log('pagination displayed cached history.');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTxHistoryFromSmallCache(getLatest) {
|
function fetchAndShowTxHistory(getLatest, flushCacheOnNew) {
|
||||||
if (completeTxHistory.length > $scope.txHistory.length) {
|
$scope.vm.updatingTxHistory = true;
|
||||||
console.log('pagination Showing history we already have.');
|
|
||||||
currentTxHistoryDisplayPage++;
|
|
||||||
showHistory();
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
walletHistoryService.updateTxHistoryByPage($scope.wallet, getLatest, true, function onUpdateTxHistoryByPage(err, txHistory) {
|
walletHistoryService.updateLocalTxHistoryByPage($scope.wallet, getLatest, flushCacheOnNew, function onUpdateLocalTxHistoryByPage(err, txHistory) {
|
||||||
console.log('pagination returned');
|
console.log('pagination returned');
|
||||||
$scope.vm.gettingInitialHistory = false;
|
$scope.vm.gettingInitialHistory = false;
|
||||||
|
$scope.vm.updatingTxHistory = false;
|
||||||
|
$scope.$broadcast('scroll.infiniteScrollComplete');
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('pagination Failed to get history.', err);
|
console.error('pagination Failed to get history.', err);
|
||||||
$scope.txHistory = null;
|
|
||||||
$scope.vm.updateTxHistoryFailed = true;
|
$scope.vm.updateTxHistoryFailed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -305,16 +304,17 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
|
||||||
formatTxHistoryForDisplay(txHistory);
|
formatTxHistoryForDisplay(txHistory);
|
||||||
|
|
||||||
completeTxHistory = txHistory;
|
completeTxHistory = txHistory;
|
||||||
showHistory();
|
showHistory(true);
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function showHistory() {
|
function showHistory(showAll) {
|
||||||
if (completeTxHistory) {
|
if (completeTxHistory) {
|
||||||
$scope.txHistory = completeTxHistory.slice(0, (currentTxHistoryDisplayPage + 1) * DISPLAY_PAGE_SIZE);
|
$scope.txHistory = showAll ? completeTxHistory : completeTxHistory.slice(0, (currentTxHistoryDisplayPage + 1) * DISPLAY_PAGE_SIZE);
|
||||||
$scope.vm.allowInfiniteScroll = completeTxHistory.length > $scope.txHistory.length || !$scope.vm.gettingInitialHistory;
|
$scope.vm.allowInfiniteScroll = completeTxHistory.length > $scope.txHistory.length || !$scope.vm.gettingInitialHistory;
|
||||||
|
console.log('pagination Showing txs: ', $scope.txHistory.length);
|
||||||
} else {
|
} else {
|
||||||
$scope.vm.allowInfiniteScroll = false;
|
$scope.vm.allowInfiniteScroll = false;
|
||||||
}
|
}
|
||||||
|
|
@ -372,6 +372,8 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
|
||||||
$scope.$broadcast('scroll.infiniteScrollComplete');
|
$scope.$broadcast('scroll.infiniteScrollComplete');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fetchAndShowTxHistory(false, false);
|
||||||
/*
|
/*
|
||||||
$scope.vm.updatingTxHistory = true;
|
$scope.vm.updatingTxHistory = true;
|
||||||
$timeout(function() {
|
$timeout(function() {
|
||||||
|
|
@ -393,10 +395,11 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
|
||||||
$scope.updateAll(true);
|
$scope.updateAll(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.updateAll = function(force, cb) {
|
$scope.updateAll = function(forceStatusUpdate, getLatestTx, flushTxCacheOnNew) {
|
||||||
updateStatus(force);
|
console.log('pagination updateAll()');
|
||||||
|
updateStatus(forceStatusUpdate);
|
||||||
//updateTxHistory(cb);
|
//updateTxHistory(cb);
|
||||||
//updateTxHistoryFromSmallCache();
|
fetchAndShowTxHistory(getLatestTx, flushTxCacheOnNew);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.hideToggle = function() {
|
$scope.hideToggle = function() {
|
||||||
|
|
@ -538,10 +541,11 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
|
||||||
var refreshInterval;
|
var refreshInterval;
|
||||||
|
|
||||||
$scope.$on("$ionicView.afterEnter", function(event, data) {
|
$scope.$on("$ionicView.afterEnter", function(event, data) {
|
||||||
updateTxHistoryUsingCachedData();
|
updateTxHistoryFromCachedData();
|
||||||
$scope.updateAll();
|
$scope.updateAll(false, true, true);
|
||||||
refreshAmountSection();
|
refreshAmountSection();
|
||||||
refreshInterval = $interval($scope.onRefresh, 10 * 1000);
|
//refreshInterval = $interval($scope.onRefresh, 10 * 1000);
|
||||||
|
//refreshInterval = $interval($scope.onRefresh, 120 * 1000); // For testing
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.$on("$ionicView.afterLeave", function(event, data) {
|
$scope.$on("$ionicView.afterLeave", function(event, data) {
|
||||||
|
|
|
||||||
|
|
@ -7,32 +7,109 @@
|
||||||
.factory('walletHistoryService', walletHistoryService);
|
.factory('walletHistoryService', walletHistoryService);
|
||||||
|
|
||||||
function walletHistoryService(configService, storageService, lodash, $log, txFormatService) {
|
function walletHistoryService(configService, storageService, lodash, $log, txFormatService) {
|
||||||
// 8 Transactions fit on an iPhone Plus screen when in Wallet Details.
|
//var PAGE_SIZE = 50;
|
||||||
// Make it a little bit bigger so it doesn't have to load more immediately
|
var PAGE_SIZE = 20; // For dev only
|
||||||
var PAGE_SIZE = 50 / 1.5;
|
|
||||||
// How much to overlap on each end of the page, for mitigating inconsistent sort order.
|
// How much to overlap on each end of the page, for mitigating inconsistent sort order.
|
||||||
var PAGE_OVERLAP_FRACTION = 0.5;
|
var PAGE_OVERLAP_FRACTION = 0.2;
|
||||||
|
var PAGE_OVERLAP = Math.floor(PAGE_SIZE * PAGE_OVERLAP_FRACTION);
|
||||||
|
// The amount of transactions in the new overlapping resultset that we already know about.
|
||||||
|
// If we know about at least this many, then there are probably no gaps.
|
||||||
|
var MIN_KNOWN_TX_OVERLAP = Math.floor(PAGE_OVERLAP * 0.5);
|
||||||
|
|
||||||
var SAFE_CONFIRMATIONS = 6;
|
var SAFE_CONFIRMATIONS = 6;
|
||||||
|
|
||||||
var service = {
|
var service = {
|
||||||
getCachedTxHistory: getCachedTxHistory,
|
getCachedTxHistory: getCachedTxHistory,
|
||||||
updateTxHistoryByPage: updateTxHistoryByPage
|
updateLocalTxHistoryByPage: updateLocalTxHistoryByPage,
|
||||||
};
|
};
|
||||||
return service;
|
return service;
|
||||||
|
|
||||||
|
function addEarlyTransactions(walletId, cachedTxs, newTxs) {
|
||||||
|
|
||||||
|
var cachedTxIds = {};
|
||||||
|
cachedTxs.forEach(function forCachedTx(tx){
|
||||||
|
cachedTxIds[tx.txid] = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
var someTransactionWereNew = false;
|
||||||
|
var overlappingTxsCount = 0;
|
||||||
|
|
||||||
|
newTxs.forEach(function forNewTx(tx){
|
||||||
|
if (cachedTxIds[tx.txid]) {
|
||||||
|
overlappingTxsCount++;
|
||||||
|
} else {
|
||||||
|
someTransactionWereNew = true;
|
||||||
|
cachedTxs.push(tx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('pagination Overlapping transactions:', overlappingTxsCount);
|
||||||
|
if (overlappingTxsCount >= MIN_KNOWN_TX_OVERLAP) { // We are good
|
||||||
|
if (someTransactionWereNew) {
|
||||||
|
console.log('pagination someTransactionsWereNew');
|
||||||
|
saveTxHistory(walletId, cachedTxs);
|
||||||
|
}
|
||||||
|
return cachedTxs;
|
||||||
|
} else {
|
||||||
|
// We might be missing some txs.
|
||||||
|
console.error('We might be missing some txs in the history.');
|
||||||
|
// Our history is wrong, so remove it - we could instead, try to fetch data that was not so early.
|
||||||
|
storageService.removeTxHistory(walletId, function onRemoveTxHistory(){});
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function addLatestTransactions(cachedTxs, newTxs) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only clear the cache once we have received new transactions from the server.
|
||||||
|
/**
|
||||||
|
* @param {function(err, txs)} cb - transactions is always an array, may be empty
|
||||||
|
*/
|
||||||
|
function fetchTxHistoryByPage(wallet, start, cb) {
|
||||||
|
var skip = Math.max(0, start - PAGE_OVERLAP);
|
||||||
|
var limit = PAGE_SIZE;
|
||||||
|
|
||||||
|
var opts = {
|
||||||
|
skip: skip,
|
||||||
|
limit: limit
|
||||||
|
};
|
||||||
|
wallet.getTxHistory(opts, function onTxHistory(err, txsFromServer) {
|
||||||
|
if (err) {
|
||||||
|
return cb(err, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txsFromServer.length === 0) {
|
||||||
|
return cb(null, []);
|
||||||
|
}
|
||||||
|
console.log('pagination Transactions fetched:', txsFromServer.length);
|
||||||
|
|
||||||
|
var processedTxs = processNewTxs(wallet, txsFromServer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (getLatest) {
|
||||||
|
console.log('pagination Saving retrieved txs.');
|
||||||
|
saveTxHistory(wallet, processedTxs);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return cb(null, processedTxs);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} walletId
|
* @param {string} walletId
|
||||||
* @param {function(error, txs)} cb
|
* @param {function(error, txs)} cb - txs is always an array, may be empty
|
||||||
*/
|
*/
|
||||||
function getCachedTxHistory(walletId, cb) {
|
function getCachedTxHistory(walletId, cb) {
|
||||||
storageService.getTxHistory(walletId, function onGetTxHistory(err, txHistoryString){
|
storageService.getTxHistory(walletId, function onGetTxHistory(err, txHistoryString){
|
||||||
if (err) {
|
if (err) {
|
||||||
return cb(err);
|
return cb(err, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!txHistoryString) {
|
if (!txHistoryString) {
|
||||||
return cb(null, txHistoryString);
|
return cb(null, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -40,7 +117,7 @@
|
||||||
return cb(null, txHistory);
|
return cb(null, txHistory);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
$log.error('Failed to parse tx history.', e);
|
$log.error('Failed to parse tx history.', e);
|
||||||
return cb(e);
|
return cb(e, []);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -83,46 +160,64 @@
|
||||||
return processedTxs;
|
return processedTxs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
function saveTxHistory(walletId, processedTxs) {
|
||||||
* A small cache of up to the 50 most recent transactions
|
console.log('pagination Saving transactions:', processedTxs.length);
|
||||||
*/
|
|
||||||
function saveTxHistory(processedTxs, walletId) {
|
|
||||||
storageService.setTxHistory(processedTxs, walletId, function onSetTxHistory(error){
|
storageService.setTxHistory(processedTxs, walletId, function onSetTxHistory(error){
|
||||||
// Looks like callback only gets called on error
|
if (error) {
|
||||||
$log.error('pagination Failed to save tx history.', error);
|
$log.error('pagination Failed to save tx history.', error);
|
||||||
});
|
} else {
|
||||||
|
console.log('pagination Save successful.');
|
||||||
}
|
|
||||||
|
|
||||||
// Only clear the cache once we have received new transactions from the server.
|
|
||||||
function updateTxHistoryByPage(wallet, getLatest, flushCacheOnNew, cb) {
|
|
||||||
var skip = 0;
|
|
||||||
var limit = Math.floor(PAGE_SIZE * (1 + PAGE_OVERLAP_FRACTION));
|
|
||||||
|
|
||||||
var opts = {
|
|
||||||
skip: skip,
|
|
||||||
limit: limit
|
|
||||||
};
|
|
||||||
wallet.getTxHistory(opts, function onTxHistory(err, txsFromServer) {
|
|
||||||
if (err) {
|
|
||||||
return cb(err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!txsFromServer.length) {
|
|
||||||
return cb(null, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
var processedTxs = processNewTxs(wallet, txsFromServer);
|
|
||||||
|
|
||||||
if (getLatest) {
|
|
||||||
console.log('pagination Saving retrieved txs.');
|
|
||||||
saveTxHistory(wallet, processedTxs);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cb(null, processedTxs);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateLocalTxHistoryByPage(wallet, getLatest, flushCacheOnNew, cb) {
|
||||||
|
|
||||||
|
if (flushCacheOnNew) {
|
||||||
|
console.log('pagination Getting latest txs.');
|
||||||
|
fetchTxHistoryByPage(wallet, 0, function onFetchTxHistory(err, txs){
|
||||||
|
if (err) {
|
||||||
|
return cb(err, txs);
|
||||||
|
}
|
||||||
|
saveTxHistory(wallet.id, txs);
|
||||||
|
return cb(null, txs);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('pagination Getting early txs.');
|
||||||
|
getCachedTxHistory(wallet.id, function onCachedHistory(err, cachedTxs){
|
||||||
|
if (err) {
|
||||||
|
$log.error('Failed to get cached tx history.', err);
|
||||||
|
return cb(err, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
var start = getLatest ? 0 : cachedTxs.length;
|
||||||
|
console.log('pagination Transaction fetch start:', start);
|
||||||
|
fetchTxHistoryByPage(wallet, start, function onFetchHistory(err, fetchedTxs){
|
||||||
|
if (err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fetchedTxs.length === 0) {
|
||||||
|
return cb(null, cachedTxs);
|
||||||
|
}
|
||||||
|
|
||||||
|
var txs = [];
|
||||||
|
if (getLatest) {
|
||||||
|
txs = addLatestTransactions(wallet.id, cachedTxs, fetchedTxs);
|
||||||
|
} else {
|
||||||
|
txs = addEarlyTransactions(wallet.id, cachedTxs, fetchedTxs);
|
||||||
|
}
|
||||||
|
return cb(null, txs);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue