From 86f356bca3acfd4dad3aeae643b951b83eae24b6 Mon Sep 17 00:00:00 2001 From: Javier Date: Thu, 8 Oct 2015 14:29:35 -0300 Subject: [PATCH 01/10] loading history from bwc and local --- public/views/walletHome.html | 10 +- src/js/controllers/index.js | 457 +++++++++++++++++++++--------- src/js/services/storageService.js | 15 + 3 files changed, 340 insertions(+), 142 deletions(-) diff --git a/public/views/walletHome.html b/public/views/walletHome.html index faf16d9ef..2482d093f 100644 --- a/public/views/walletHome.html +++ b/public/views/walletHome.html @@ -513,12 +513,18 @@ -
+ +
- + Download CSV file + + + + READ CSV file +
diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 988228bd5..6a68e177f 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -404,48 +404,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); }; - self.updateTxHistory = function(skip) { - var fc = profileService.focusedClient; - if (!fc || !fc.isComplete()) return; - if (!skip) { - self.txHistory = []; - self.txHistoryUnique = {}; - } - self.skipHistory = skip || 0; - $log.debug('Updating Transaction History'); - self.txHistoryError = false; - self.updatingTxHistory = true; - self.txHistoryPaging = false; - - $timeout(function() { - fc.getTxHistory({ - skip: self.skipHistory, - limit: self.limitHistory + 1 - }, function(err, txs) { - self.updatingTxHistory = false; - if (err) { - $log.debug('TxHistory ERROR:', err); - // We do not should errors here, since history is usually - // fetched AFTER others requests (if skip=0) - if (skip) - self.handleError(err); - - self.txHistoryError = true; - } else { - $log.debug('Wallet Transaction History:', txs); - self.skipHistory = self.skipHistory + self.limitHistory; - self.setTxHistory(txs); - } - $rootScope.$apply(); - }); - }); - }; - - self.debouncedUpdateHistory = lodash.throttle(function() { - self.updateTxHistory(); - }, 5000); - - // This handles errors from BWS/index with are nomally // trigger from async events (like updates) self.handleError = function(err) { @@ -551,7 +509,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.txHistoryUnique[tx.txid] = true; c++; } else { - $log.debug('Ignoring duplicate TX in history: '+ tx.txid) + $log.debug('Ignoring duplicate TX in history: ' + tx.txid) } } }); @@ -648,51 +606,141 @@ angular.module('copayApp.controllers').controller('indexController', function($r } }; + // this.csvHistory = function() { + + // function saveFile(name, data) { + // var chooser = document.querySelector(name); + // chooser.addEventListener("change", function(evt) { + // var fs = require('fs'); + // fs.writeFile(this.value, data, function(err) { + // if (err) { + // $log.debug(err); + // } + // }); + // }, false); + // chooser.click(); + // } + + // function formatDate(date) { + // var dateObj = new Date(date); + // if (!dateObj) { + // $log.debug('Error formating a date'); + // return 'DateError' + // } + // if (!dateObj.toJSON()) { + // return ''; + // } + + // return dateObj.toJSON(); + // } + + // function formatString(str) { + // if (!str) return ''; + + // if (str.indexOf('"') !== -1) { + // //replace all + // str = str.replace(new RegExp('"', 'g'), '\''); + // } + + // //escaping commas + // str = '\"' + str + '\"'; + + // return str; + // } + + // var step = 6; + + // function getHistory(skip, cb) { + // skip = skip || 0; + // fc.getTxHistory({ + // skip: skip, + // limit: step, + // }, function(err, txs) { + // if (err) return cb(err); + // if (txs && txs.length > 0) { + // allTxs.push(txs); + // return getHistory(skip + step, cb); + // } else { + // return cb(null, lodash.flatten(allTxs)); + // } + // }); + // }; + + // if (isCordova) { + // $log.info('Not available on mobile'); + // return; + // } + // var isNode = nodeWebkit.isDefined(); + // var fc = profileService.focusedClient; + // if (!fc.isComplete()) return; + // var self = this; + // var allTxs = []; + // $log.debug('Generating CSV from History'); + // self.setOngoingProcess('generatingCSV', true); + // $timeout(function() { + // getHistory(null, function(err, txs) { + // self.setOngoingProcess('generatingCSV', false); + // if (err) { + // self.handleError(err); + // } else { + // $log.debug('Wallet Transaction History:', txs); + + // self.satToUnit = 1 / self.unitToSatoshi; + // var data = txs; + // var satToBtc = 1 / 100000000; + // var filename = 'Copay-' + (self.alias || self.walletName) + '.csv'; + // var csvContent = ''; + // if (!isNode) csvContent = 'data:text/csv;charset=utf-8,'; + // csvContent += 'Date,Destination,Note,Amount,Currency,Spot Value,Total Value,Tax Type,Category\n'; + + // var _amount, _note; + // var dataString; + // data.forEach(function(it, index) { + // var amount = it.amount; + + // if (it.action == 'moved') + // amount = 0; + + // _amount = (it.action == 'sent' ? '-' : '') + (amount * satToBtc).toFixed(8); + // _note = formatString((it.message ? it.message : '') + ' TxId: ' + it.txid + ' Fee:' + (it.fees * satToBtc).toFixed(8)); + + // if (it.action == 'moved') + // _note += ' Moved:' + (it.amount * satToBtc).toFixed(8) + + // dataString = formatDate(it.time * 1000) + ',' + formatString(it.addressTo) + ',' + _note + ',' + _amount + ',BTC,,,,'; + // csvContent += dataString + "\n"; + + // if (it.fees && (it.action == 'moved' || it.action == 'sent')) { + // var _fee = (it.fees * satToBtc).toFixed(8) + // csvContent += formatDate(it.time * 1000) + ',Bitcoin Network Fees,, -' + _fee + ',BTC,,,,' + "\n"; + // } + // }); + + // if (isNode) { + // saveFile('#export_file', csvContent); + // } else { + // var encodedUri = encodeURI(csvContent); + // var link = document.createElement("a"); + // link.setAttribute("href", encodedUri); + // link.setAttribute("download", filename); + // link.click(); + // } + // } + // $rootScope.$apply(); + // }); + // }); + // }; + this.csvHistory = function() { + if (isCordova) return $log.info('Not available on mobile'); - function saveFile(name, data) { - var chooser = document.querySelector(name); - chooser.addEventListener("change", function(evt) { - var fs = require('fs'); - fs.writeFile(this.value, data, function(err) { - if (err) { - $log.debug(err); - } - }); - }, false); - chooser.click(); - } - - function formatDate(date) { - var dateObj = new Date(date); - if (!dateObj) { - $log.debug('Error formating a date'); - return 'DateError' - } - if (!dateObj.toJSON()) { - return ''; - } - - return dateObj.toJSON(); - } - - function formatString(str) { - if (!str) return ''; - - if (str.indexOf('"') !== -1) { - //replace all - str = str.replace(new RegExp('"', 'g'), '\''); - } - - //escaping commas - str = '\"' + str + '\"'; - - return str; - } + var fc = profileService.focusedClient; + if (!fc.isComplete()) return; var step = 6; var unique = {}; + function getHistory(skip, cb) { skip = skip || 0; fc.getTxHistory({ @@ -700,88 +748,217 @@ angular.module('copayApp.controllers').controller('indexController', function($r limit: step, }, function(err, txs) { if (err) return cb(err); + if (txs && txs.length > 0) { lodash.each(txs, function(tx) { - if (!unique[tx.txid]){ + if (!unique[tx.txid]) { allTxs.push(tx); unique[tx.txid] = 1; console.log("Got:" + lodash.keys(unique).length + " txs"); } else { - console.log("Ignoring duplicate TX in CSV: "+ tx.txid); + console.log("Ignoring duplicate TX in CSV: " + tx.txid); } }); return getHistory(skip + step, cb); - } else { + } else return cb(null, lodash.flatten(allTxs)); - } }); }; - if (isCordova) { - $log.info('Not available on mobile'); - return; - } - var isNode = nodeWebkit.isDefined(); - var fc = profileService.focusedClient; - if (!fc.isComplete()) return; var self = this; var allTxs = []; - $log.debug('Generating CSV from History'); - self.setOngoingProcess('generatingCSV', true); + $log.debug('Fetching transactions from History'); + self.setOngoingProcess('generatingCSV', true); // cambiar esto + $timeout(function() { getHistory(null, function(err, txs) { - self.setOngoingProcess('generatingCSV', false); - if (err) { + self.setOngoingProcess('generatingCSV', false); // cambiar esto + + if (err) self.handleError(err); - } else { + else $log.debug('Wallet Transaction History:', txs); - self.satToUnit = 1 / self.unitToSatoshi; - var data = txs; - var satToBtc = 1 / 100000000; - var filename = 'Copay-' + (self.alias || self.walletName) + '.csv'; - var csvContent = ''; - if (!isNode) csvContent = 'data:text/csv;charset=utf-8,'; - csvContent += 'Date,Destination,Note,Amount,Currency,Spot Value,Total Value,Tax Type,Category\n'; - - var _amount, _note; - var dataString; - data.forEach(function(it, index) { - var amount = it.amount; - - if (it.action == 'moved') - amount = 0; - - _amount = (it.action == 'sent' ? '-' : '') + (amount * satToBtc).toFixed(8); - _note = formatString((it.message ? it.message : '') + ' TxId: ' + it.txid + ' Fee:' + (it.fees * satToBtc).toFixed(8)); - - if (it.action == 'moved') - _note += ' Moved:' + (it.amount * satToBtc).toFixed(8) - - dataString = formatDate(it.time * 1000) + ',' + formatString(it.addressTo) + ',' + _note + ',' + _amount + ',BTC,,,,'; - csvContent += dataString + "\n"; - - if (it.fees && (it.action == 'moved' || it.action == 'sent')) { - var _fee = (it.fees * satToBtc).toFixed(8) - csvContent += formatDate(it.time * 1000) + ',Bitcoin Network Fees,, -' + _fee + ',BTC,,,,' + "\n"; - } - }); - - if (isNode) { - saveFile('#export_file', csvContent); - } else { - var encodedUri = encodeURI(csvContent); - var link = document.createElement("a"); - link.setAttribute("href", encodedUri); - link.setAttribute("download", filename); - link.click(); - } - } - $rootScope.$apply(); + // verificar wallets sin transacciones (pendiente) + storageService.setTxHistory(JSON.stringify(txs), fc.credentials.walletId, function() { + return; + }); }); }); }; + self.getLocalHistory = function(walletId, cb) { + storageService.getTxHistory(walletId, function(err, txH) { + if (err) return cb(err); + if (!txH) return cb($log.debug('There is not transactions stored')); + + var txHistory; + try { + txHistory = JSON.parse(txH); + } catch (ex) { + return cb(ex); + } + + // console.log('From getLocalHistory: ', txHistory); + // lodash.each(txHistory, function(tx) { + // console.log(tx); + // }); + + return cb(null, txHistory); + }); + } + + // self.updateTxHistory = function(skip) { + // var fc = profileService.focusedClient; + // if (!fc || !fc.isComplete()) return; + // if (!skip) { + // self.txHistory = []; + // } + // self.skipHistory = skip || 0; + // $log.debug('Updating Transaction History'); + // self.txHistoryError = false; + // self.updatingTxHistory = true; + // self.txHistoryPaging = false; + + // $timeout(function() { + // fc.getTxHistory({ + // skip: self.skipHistory, + // limit: self.limitHistory + 1 + // }, function(err, txs) { + // self.updatingTxHistory = false; + // if (err) { + // $log.debug('TxHistory ERROR:', err); + // // We do not should errors here, since history is usually + // // fetched AFTER others requests (if skip=0) + // if (skip) + // self.handleError(err); + + // self.txHistoryError = true; + // } else { + // $log.debug('Wallet Transaction History:', txs); + // self.skipHistory = self.skipHistory + self.limitHistory; + // self.setTxHistory(txs); + // } + // $rootScope.$apply(); + // }); + // }); + // }; + + // self.debouncedUpdateHistory = lodash.throttle(function() { + // self.updateTxHistory(); + // }, 5000); + + self.updateTxHistory = function(skip) { + var fc = profileService.focusedClient; + if (!fc || !fc.isComplete()) return; + if (!skip) self.txHistory = []; + + $log.debug('Updating Transaction History'); + self.skipHistory = skip || 0; + self.txHistoryError = false; + self.updatingTxHistory = true; + self.txHistoryPaging = false; + + $timeout(function() { + storageService.getTxHistoryFlag(fc.credentials.walletId, function(err, historyFlag) { + if (err) { + $log.debug('TxHistory ERROR:', err); + if (skip) self.handleError(err); + self.txHistoryError = true; + return; + } + + if (historyFlag) { + // history from local storage + self.getLocalHistory(fc.credentials.walletId, function(err, txsFromLocal) { + self.updatingTxHistory = false; + if (err) { + $log.debug('TxHistory ERROR:', err); + if (skip) self.handleError(err); + self.txHistoryError = true; + return; + } + + self.setTxHistory(txsFromLocal); + console.log('Loaded from local.'); + $log.debug('Wallet Transaction History:', txsFromLocal); + storageService.setTxHistoryFlag(true, fc.credentials.walletId, function() { + return; + }); + }); + } else { + // history from BWC + fc.getTxHistory({ + skip: self.skipHistory, + limit: self.limitHistory + 1 + }, function(err, txsFromBWC) { + self.updatingTxHistory = false; + if (err) { + $log.debug('TxHistory ERROR:', err); + + if (skip) self.handleError(err); + self.txHistoryError = true; + return; + } else { + if (!txsFromBWC[0]) + return $log.debug('There is not transactions stored'); + + self.setTxHistory(txsFromBWC); + $log.debug('Wallet Transaction History:', txsFromBWC); + storageService.setTxHistory(JSON.stringify(txsFromBWC), fc.credentials.walletId, function() { + storageService.setTxHistoryFlag(true, fc.credentials.walletId, function() { + return; + }); + }); + console.log('Loaded from BWC.'); + // // Check if the last tx on server is equal to the last tx in local storage + // // console.log('Last tx from BWC: ', txsFromBWC[0]); + // self.getLocalHistory(function(err, txsFromLocal) { + // // console.log('Last tx from LocalStorage: ', txsFromLocal[0]); + // if (err) { + // $log.debug('TxHistory ERROR:', err); + // if (skip) self.handleError(err); + // self.txHistoryError = true; + // } + + // if (self.areEqualsTxs(txsFromBWC[0], txsFromLocal[0])) { + // self.setTxHistory(txsFromLocal); + // $log.debug('Wallet Transaction History:', txsFromLocal); + // storageService.setTxHistoryFlag(true, function() { + // return; + // }); + // } else { + // self.setTxHistory(txsFromBWC); + // $log.debug('Wallet Transaction History:', txsFromBWC); + // storageService.setTxHistory(JSON.stringify(txsFromBWC), function() { + // return; + // }); + // storageService.setTxHistoryFlag(false, function() { + // return; + // }); + // } + // }); + } + }); + } + }); + self.skipHistory = self.skipHistory + self.limitHistory; + self.updatingTxHistory = false; + $rootScope.$apply(); + }); + }; + + self.debouncedUpdateHistory = lodash.throttle(function() { + self.updateTxHistory(); + }, 5000); + + self.areEqualsTxs = function(firstTx, secondTx) { + if (firstTx.txid == secondTx.txid) // enough to determinate it? + return true; + else + return false; + } + self.showErrorPopup = function(msg, cb) { $log.warn('Showing err popup:' + msg); self.showAlert = { diff --git a/src/js/services/storageService.js b/src/js/services/storageService.js index b19db8779..13de88221 100644 --- a/src/js/services/storageService.js +++ b/src/js/services/storageService.js @@ -216,5 +216,20 @@ angular.module('copayApp.services') storage.remove('addressbook-' + network, cb); }; + root.setTxHistory = function(txs, walletId, cb) { + storage.set('txsHistory-' + walletId, txs, cb); + } + + root.getTxHistory = function(walletId, cb) { + storage.get('txsHistory-' + walletId, cb); + } + + root.setTxHistoryFlag = function(value, walletId, cb) { + storage.set('txsHistoryFlag-' + walletId, value, cb); + } + + root.getTxHistoryFlag = function(walletId, cb) { + storage.get('txsHistoryFlag-' + walletId, cb); + } return root; }); From 5cbf808dc0c0a84ff71ae957fd07414275c4850d Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 9 Oct 2015 15:23:04 -0300 Subject: [PATCH 02/10] fetch history and load it from local --- public/views/walletHome.html | 10 +- src/js/controllers/index.js | 219 +++++++++++++++-------------------- 2 files changed, 93 insertions(+), 136 deletions(-) diff --git a/public/views/walletHome.html b/public/views/walletHome.html index 2482d093f..faf16d9ef 100644 --- a/public/views/walletHome.html +++ b/public/views/walletHome.html @@ -513,18 +513,12 @@ - -
+
diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 6a68e177f..13a18b4ed 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -6,7 +6,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.isChromeApp = isChromeApp; self.isSafari = isMobile.Safari(); self.onGoingProcess = {}; - self.limitHistory = 5; + self.limitHistory = 6; function strip(number) { return (parseFloat(number.toPrecision(12))); @@ -487,7 +487,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r var config = configService.getSync().wallet.settings; var now = Math.floor(Date.now() / 1000); var c = 0; - self.txHistoryPaging = txs[self.limitHistory] ? true : false; + self.hasUnsafeConfirmed = false; lodash.each(txs, function(tx) { tx = txFormatService.processTx(tx); @@ -738,6 +738,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r if (!fc.isComplete()) return; var step = 6; + self._getHistory(); var unique = {}; @@ -768,46 +769,119 @@ angular.module('copayApp.controllers').controller('indexController', function($r var self = this; var allTxs = []; $log.debug('Fetching transactions from History'); - self.setOngoingProcess('generatingCSV', true); // cambiar esto + self.setOngoingProcess('generatingCSV', true); // change this $timeout(function() { getHistory(null, function(err, txs) { - self.setOngoingProcess('generatingCSV', false); // cambiar esto + self.setOngoingProcess('generatingCSV', false); // change this if (err) self.handleError(err); else $log.debug('Wallet Transaction History:', txs); - // verificar wallets sin transacciones (pendiente) - storageService.setTxHistory(JSON.stringify(txs), fc.credentials.walletId, function() { + storageService.setTxHistory(JSON.stringify(txs), walletId, function() { return; }); }); }); }; - self.getLocalHistory = function(walletId, cb) { - storageService.getTxHistory(walletId, function(err, txH) { - if (err) return cb(err); - if (!txH) return cb($log.debug('There is not transactions stored')); + self.areEqualsTxs = function(firstTx, secondTx) { + if (firstTx.txid == secondTx.txid) + return true; + else + return false; + } - var txHistory; + self.updateLocalTxHistory = function(cb) { + var fc = profileService.focusedClient; + var c = fc.credentials; + var txsToPush = []; + + storageService.getTxHistory(c.walletId, function(err, txs) { + if (err) return cb(err); + + var txsFromLocal; try { - txHistory = JSON.parse(txH); + txsFromLocal = JSON.parse(txs); } catch (ex) { return cb(ex); } - // console.log('From getLocalHistory: ', txHistory); - // lodash.each(txHistory, function(tx) { - // console.log(tx); - // }); + if (!txsFromLocal) + txsFromLocal = []; - return cb(null, txHistory); + var count = 0; + fillTxsObject(txsToPush); + + function fillTxsObject(txsToPush) { + self.makeTxHistoryRequest(txsToPush, txsFromLocal, function(err, skipLoop, txsResult) { + if (err) return cb(err); + if (skipLoop) { + self.txHistory = []; + self.setTxHistory(lodash.compact(txsResult.concat(txsFromLocal))); + storageService.setTxHistory(JSON.stringify(self.txHistory), c.walletId, function() { + return cb(null); + }); + } else + fillTxsObject(txsResult); + }); + }; }); } + self.makeTxHistoryRequest = function(txsToPush, localTx, cb) { + var fc = profileService.focusedClient; + var c = fc.credentials; + var skipLoop = false; + + fc.getTxHistory({ + skip: self.skipHistory, + limit: self.limitHistory + 1 + }, function(err, txsFromBWC) { + if (err) return cb(err); + + if (!txsFromBWC[0]) { + skipLoop = true; + $log.debug('There is not transactions stored'); + } + + lodash.each(txsFromBWC, function(t) { + if (!localTx[0]) txsToPush.push(t); + else { + if (!self.areEqualsTxs(t, localTx[0]) && !skipLoop) { + txsToPush.push(t); + } else { + skipLoop = true; + } + } + }); + self.skipHistory = self.skipHistory + self.limitHistory; + return cb(null, skipLoop, txsToPush); + }); + } + + self.updateTxHistory = function(skip) { + $log.debug('Updating Transaction History'); + self.skipHistory = skip || 0; + self.txHistoryError = false; + self.updatingTxHistory = true; + self.txHistoryPaging = false; + + $timeout(function() { + self.updateLocalTxHistory(function(err) { + if (err) self.txHistoryError = true; + self.updatingTxHistory = false; + $rootScope.$apply(); + }); + }); + }; + + self.debouncedUpdateHistory = lodash.throttle(function() { + self.updateTxHistory(); + }, 5000); + // self.updateTxHistory = function(skip) { // var fc = profileService.focusedClient; // if (!fc || !fc.isComplete()) return; @@ -848,117 +922,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r // self.updateTxHistory(); // }, 5000); - self.updateTxHistory = function(skip) { - var fc = profileService.focusedClient; - if (!fc || !fc.isComplete()) return; - if (!skip) self.txHistory = []; - - $log.debug('Updating Transaction History'); - self.skipHistory = skip || 0; - self.txHistoryError = false; - self.updatingTxHistory = true; - self.txHistoryPaging = false; - - $timeout(function() { - storageService.getTxHistoryFlag(fc.credentials.walletId, function(err, historyFlag) { - if (err) { - $log.debug('TxHistory ERROR:', err); - if (skip) self.handleError(err); - self.txHistoryError = true; - return; - } - - if (historyFlag) { - // history from local storage - self.getLocalHistory(fc.credentials.walletId, function(err, txsFromLocal) { - self.updatingTxHistory = false; - if (err) { - $log.debug('TxHistory ERROR:', err); - if (skip) self.handleError(err); - self.txHistoryError = true; - return; - } - - self.setTxHistory(txsFromLocal); - console.log('Loaded from local.'); - $log.debug('Wallet Transaction History:', txsFromLocal); - storageService.setTxHistoryFlag(true, fc.credentials.walletId, function() { - return; - }); - }); - } else { - // history from BWC - fc.getTxHistory({ - skip: self.skipHistory, - limit: self.limitHistory + 1 - }, function(err, txsFromBWC) { - self.updatingTxHistory = false; - if (err) { - $log.debug('TxHistory ERROR:', err); - - if (skip) self.handleError(err); - self.txHistoryError = true; - return; - } else { - if (!txsFromBWC[0]) - return $log.debug('There is not transactions stored'); - - self.setTxHistory(txsFromBWC); - $log.debug('Wallet Transaction History:', txsFromBWC); - storageService.setTxHistory(JSON.stringify(txsFromBWC), fc.credentials.walletId, function() { - storageService.setTxHistoryFlag(true, fc.credentials.walletId, function() { - return; - }); - }); - console.log('Loaded from BWC.'); - // // Check if the last tx on server is equal to the last tx in local storage - // // console.log('Last tx from BWC: ', txsFromBWC[0]); - // self.getLocalHistory(function(err, txsFromLocal) { - // // console.log('Last tx from LocalStorage: ', txsFromLocal[0]); - // if (err) { - // $log.debug('TxHistory ERROR:', err); - // if (skip) self.handleError(err); - // self.txHistoryError = true; - // } - - // if (self.areEqualsTxs(txsFromBWC[0], txsFromLocal[0])) { - // self.setTxHistory(txsFromLocal); - // $log.debug('Wallet Transaction History:', txsFromLocal); - // storageService.setTxHistoryFlag(true, function() { - // return; - // }); - // } else { - // self.setTxHistory(txsFromBWC); - // $log.debug('Wallet Transaction History:', txsFromBWC); - // storageService.setTxHistory(JSON.stringify(txsFromBWC), function() { - // return; - // }); - // storageService.setTxHistoryFlag(false, function() { - // return; - // }); - // } - // }); - } - }); - } - }); - self.skipHistory = self.skipHistory + self.limitHistory; - self.updatingTxHistory = false; - $rootScope.$apply(); - }); - }; - - self.debouncedUpdateHistory = lodash.throttle(function() { - self.updateTxHistory(); - }, 5000); - - self.areEqualsTxs = function(firstTx, secondTx) { - if (firstTx.txid == secondTx.txid) // enough to determinate it? - return true; - else - return false; - } - self.showErrorPopup = function(msg, cb) { $log.warn('Showing err popup:' + msg); self.showAlert = { From 51f2f7500aecf5afb2a5829f840e5c47de25c5a8 Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 9 Oct 2015 15:54:43 -0300 Subject: [PATCH 03/10] addapt download csv file to fetch transactions from local storage --- src/js/controllers/index.js | 266 +++++++++++++++--------------------- 1 file changed, 108 insertions(+), 158 deletions(-) diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 13a18b4ed..661f55a3e 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -606,183 +606,133 @@ angular.module('copayApp.controllers').controller('indexController', function($r } }; - // this.csvHistory = function() { - - // function saveFile(name, data) { - // var chooser = document.querySelector(name); - // chooser.addEventListener("change", function(evt) { - // var fs = require('fs'); - // fs.writeFile(this.value, data, function(err) { - // if (err) { - // $log.debug(err); - // } - // }); - // }, false); - // chooser.click(); - // } - - // function formatDate(date) { - // var dateObj = new Date(date); - // if (!dateObj) { - // $log.debug('Error formating a date'); - // return 'DateError' - // } - // if (!dateObj.toJSON()) { - // return ''; - // } - - // return dateObj.toJSON(); - // } - - // function formatString(str) { - // if (!str) return ''; - - // if (str.indexOf('"') !== -1) { - // //replace all - // str = str.replace(new RegExp('"', 'g'), '\''); - // } - - // //escaping commas - // str = '\"' + str + '\"'; - - // return str; - // } - - // var step = 6; - - // function getHistory(skip, cb) { - // skip = skip || 0; - // fc.getTxHistory({ - // skip: skip, - // limit: step, - // }, function(err, txs) { - // if (err) return cb(err); - // if (txs && txs.length > 0) { - // allTxs.push(txs); - // return getHistory(skip + step, cb); - // } else { - // return cb(null, lodash.flatten(allTxs)); - // } - // }); - // }; - - // if (isCordova) { - // $log.info('Not available on mobile'); - // return; - // } - // var isNode = nodeWebkit.isDefined(); - // var fc = profileService.focusedClient; - // if (!fc.isComplete()) return; - // var self = this; - // var allTxs = []; - // $log.debug('Generating CSV from History'); - // self.setOngoingProcess('generatingCSV', true); - // $timeout(function() { - // getHistory(null, function(err, txs) { - // self.setOngoingProcess('generatingCSV', false); - // if (err) { - // self.handleError(err); - // } else { - // $log.debug('Wallet Transaction History:', txs); - - // self.satToUnit = 1 / self.unitToSatoshi; - // var data = txs; - // var satToBtc = 1 / 100000000; - // var filename = 'Copay-' + (self.alias || self.walletName) + '.csv'; - // var csvContent = ''; - // if (!isNode) csvContent = 'data:text/csv;charset=utf-8,'; - // csvContent += 'Date,Destination,Note,Amount,Currency,Spot Value,Total Value,Tax Type,Category\n'; - - // var _amount, _note; - // var dataString; - // data.forEach(function(it, index) { - // var amount = it.amount; - - // if (it.action == 'moved') - // amount = 0; - - // _amount = (it.action == 'sent' ? '-' : '') + (amount * satToBtc).toFixed(8); - // _note = formatString((it.message ? it.message : '') + ' TxId: ' + it.txid + ' Fee:' + (it.fees * satToBtc).toFixed(8)); - - // if (it.action == 'moved') - // _note += ' Moved:' + (it.amount * satToBtc).toFixed(8) - - // dataString = formatDate(it.time * 1000) + ',' + formatString(it.addressTo) + ',' + _note + ',' + _amount + ',BTC,,,,'; - // csvContent += dataString + "\n"; - - // if (it.fees && (it.action == 'moved' || it.action == 'sent')) { - // var _fee = (it.fees * satToBtc).toFixed(8) - // csvContent += formatDate(it.time * 1000) + ',Bitcoin Network Fees,, -' + _fee + ',BTC,,,,' + "\n"; - // } - // }); - - // if (isNode) { - // saveFile('#export_file', csvContent); - // } else { - // var encodedUri = encodeURI(csvContent); - // var link = document.createElement("a"); - // link.setAttribute("href", encodedUri); - // link.setAttribute("download", filename); - // link.click(); - // } - // } - // $rootScope.$apply(); - // }); - // }); - // }; - this.csvHistory = function() { - if (isCordova) return $log.info('Not available on mobile'); - var fc = profileService.focusedClient; - if (!fc.isComplete()) return; + function saveFile(name, data) { + var chooser = document.querySelector(name); + chooser.addEventListener("change", function(evt) { + var fs = require('fs'); + fs.writeFile(this.value, data, function(err) { + if (err) { + $log.debug(err); + } + }); + }, false); + chooser.click(); + } + + function formatDate(date) { + var dateObj = new Date(date); + if (!dateObj) { + $log.debug('Error formating a date'); + return 'DateError' + } + if (!dateObj.toJSON()) { + return ''; + } + + return dateObj.toJSON(); + } + + function formatString(str) { + if (!str) return ''; + + if (str.indexOf('"') !== -1) { + //replace all + str = str.replace(new RegExp('"', 'g'), '\''); + } + + //escaping commas + str = '\"' + str + '\"'; + + return str; + } var step = 6; - self._getHistory(); var unique = {}; function getHistory(skip, cb) { - skip = skip || 0; - fc.getTxHistory({ - skip: skip, - limit: step, - }, function(err, txs) { + storageService.getTxHistory(c.walletId, function(err, txs) { if (err) return cb(err); - if (txs && txs.length > 0) { - lodash.each(txs, function(tx) { - if (!unique[tx.txid]) { - allTxs.push(tx); - unique[tx.txid] = 1; - console.log("Got:" + lodash.keys(unique).length + " txs"); - } else { - console.log("Ignoring duplicate TX in CSV: " + tx.txid); - } - }); - return getHistory(skip + step, cb); - } else - return cb(null, lodash.flatten(allTxs)); - }); - }; + var txsFromLocal; + try { + txsFromLocal = JSON.parse(txs); + } catch (ex) { + return cb(ex); + } + allTxs.push(txsFromLocal); + return cb(null, lodash.flatten(allTxs)); + }); + } + + if (isCordova) { + $log.info('Not available on mobile'); + return; + } + var isNode = nodeWebkit.isDefined(); + var fc = profileService.focusedClient; + var c = fc.credentials; + if (!fc.isComplete()) return; var self = this; var allTxs = []; - $log.debug('Fetching transactions from History'); - self.setOngoingProcess('generatingCSV', true); // change this + + $log.debug('Generating CSV from History'); + self.setOngoingProcess('generatingCSV', true); $timeout(function() { getHistory(null, function(err, txs) { - self.setOngoingProcess('generatingCSV', false); // change this - - if (err) + self.setOngoingProcess('generatingCSV', false); + if (err) { self.handleError(err); - else + } else { $log.debug('Wallet Transaction History:', txs); - storageService.setTxHistory(JSON.stringify(txs), walletId, function() { - return; - }); + self.satToUnit = 1 / self.unitToSatoshi; + var data = txs; + var satToBtc = 1 / 100000000; + var filename = 'Copay-' + (self.alias || self.walletName) + '.csv'; + var csvContent = ''; + + if (!isNode) csvContent = 'data:text/csv;charset=utf-8,'; + csvContent += 'Date,Destination,Note,Amount,Currency,Spot Value,Total Value,Tax Type,Category\n'; + + var _amount, _note; + var dataString; + data.forEach(function(it, index) { + var amount = it.amount; + + if (it.action == 'moved') + amount = 0; + + _amount = (it.action == 'sent' ? '-' : '') + (amount * satToBtc).toFixed(8); + _note = formatString((it.message ? it.message : '') + ' TxId: ' + it.txid + ' Fee:' + (it.fees * satToBtc).toFixed(8)); + + if (it.action == 'moved') + _note += ' Moved:' + (it.amount * satToBtc).toFixed(8) + + dataString = formatDate(it.time * 1000) + ',' + formatString(it.addressTo) + ',' + _note + ',' + _amount + ',BTC,,,,'; + csvContent += dataString + "\n"; + + if (it.fees && (it.action == 'moved' || it.action == 'sent')) { + var _fee = (it.fees * satToBtc).toFixed(8) + csvContent += formatDate(it.time * 1000) + ',Bitcoin Network Fees,, -' + _fee + ',BTC,,,,' + "\n"; + } + }); + + if (isNode) { + saveFile('#export_file', csvContent); + } else { + var encodedUri = encodeURI(csvContent); + var link = document.createElement("a"); + link.setAttribute("href", encodedUri); + link.setAttribute("download", filename); + link.click(); + } + } + $rootScope.$apply(); }); }); }; From 6e355bba3f0535bbf096c0b19c3e47bd518df87f Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 9 Oct 2015 15:58:09 -0300 Subject: [PATCH 04/10] delete comments --- src/js/controllers/index.js | 40 ------------------------------------- 1 file changed, 40 deletions(-) diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 661f55a3e..21c0891aa 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -832,46 +832,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.updateTxHistory(); }, 5000); - // self.updateTxHistory = function(skip) { - // var fc = profileService.focusedClient; - // if (!fc || !fc.isComplete()) return; - // if (!skip) { - // self.txHistory = []; - // } - // self.skipHistory = skip || 0; - // $log.debug('Updating Transaction History'); - // self.txHistoryError = false; - // self.updatingTxHistory = true; - // self.txHistoryPaging = false; - - // $timeout(function() { - // fc.getTxHistory({ - // skip: self.skipHistory, - // limit: self.limitHistory + 1 - // }, function(err, txs) { - // self.updatingTxHistory = false; - // if (err) { - // $log.debug('TxHistory ERROR:', err); - // // We do not should errors here, since history is usually - // // fetched AFTER others requests (if skip=0) - // if (skip) - // self.handleError(err); - - // self.txHistoryError = true; - // } else { - // $log.debug('Wallet Transaction History:', txs); - // self.skipHistory = self.skipHistory + self.limitHistory; - // self.setTxHistory(txs); - // } - // $rootScope.$apply(); - // }); - // }); - // }; - - // self.debouncedUpdateHistory = lodash.throttle(function() { - // self.updateTxHistory(); - // }, 5000); - self.showErrorPopup = function(msg, cb) { $log.warn('Showing err popup:' + msg); self.showAlert = { From 061ec1d1fd513d853ad693fb4cec3084d443298b Mon Sep 17 00:00:00 2001 From: Javier Date: Tue, 13 Oct 2015 16:11:07 -0300 Subject: [PATCH 05/10] update local storage when a wallet is deleted --- src/js/controllers/preferencesDelete.js | 11 ++++++++--- src/js/services/storageService.js | 7 ++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/js/controllers/preferencesDelete.js b/src/js/controllers/preferencesDelete.js index 7fbc0c4d2..7d30f4685 100644 --- a/src/js/controllers/preferencesDelete.js +++ b/src/js/controllers/preferencesDelete.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.controllers').controller('preferencesDeleteWalletController', - function($scope, $rootScope, $filter, $timeout, $modal, $log, notification, profileService, isCordova, go, gettext, gettextCatalog, animationService) { + function($scope, $rootScope, $filter, $timeout, $modal, $log, storageService, notification, profileService, isCordova, go, gettext, gettextCatalog, animationService) { this.isCordova = isCordova; this.error = null; @@ -46,14 +46,19 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWalletContro var _deleteWallet = function() { var fc = profileService.focusedClient; var name = fc.credentials.walletName; - var walletName = (fc.alias||'') + ' [' + name + ']'; + var walletName = (fc.alias || '') + ' [' + name + ']'; var self = this; profileService.deleteWalletFC({}, function(err) { if (err) { self.error = err.message || err; } else { - notification.success(gettextCatalog.getString('Success'), gettextCatalog.getString('The wallet "{{walletName}}" was deleted', {walletName: walletName})); + storageService.removeTxHistory(fc.credentials.walletId, function() { + notification.success(gettextCatalog.getString('Success'), gettextCatalog.getString('The wallet "{{walletName}}" was deleted', { + walletName: walletName + })); + return; + }); } }); }; diff --git a/src/js/services/storageService.js b/src/js/services/storageService.js index 13de88221..9673863ff 100644 --- a/src/js/services/storageService.js +++ b/src/js/services/storageService.js @@ -224,12 +224,9 @@ angular.module('copayApp.services') storage.get('txsHistory-' + walletId, cb); } - root.setTxHistoryFlag = function(value, walletId, cb) { - storage.set('txsHistoryFlag-' + walletId, value, cb); + root.removeTxHistory = function(walletId, cb) { + storage.remove('txsHistory-' + walletId, cb); } - root.getTxHistoryFlag = function(walletId, cb) { - storage.get('txsHistoryFlag-' + walletId, cb); - } return root; }); From 92a236e4dc08f95d03833de8ce4db876bca47389 Mon Sep 17 00:00:00 2001 From: Javier Date: Thu, 22 Oct 2015 10:14:57 -0300 Subject: [PATCH 06/10] add unique txs control --- src/js/controllers/index.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 21c0891aa..d136c74ed 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -486,7 +486,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.setTxHistory = function(txs) { var config = configService.getSync().wallet.settings; var now = Math.floor(Date.now() / 1000); - var c = 0; + self.txHistoryUnique = {}; self.hasUnsafeConfirmed = false; lodash.each(txs, function(tx) { @@ -503,14 +503,11 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.hasUnsafeConfirmed = true; } - if (c < self.limitHistory) { - if (!self.txHistoryUnique[tx.txid]) { - self.txHistory.push(tx); - self.txHistoryUnique[tx.txid] = true; - c++; - } else { - $log.debug('Ignoring duplicate TX in history: ' + tx.txid) - } + if (!self.txHistoryUnique[tx.txid]) { + self.txHistory.push(tx); + self.txHistoryUnique[tx.txid] = true; + } else { + $log.debug('Ignoring duplicate TX in history: ' + tx.txid) } }); }; From c34873c177c26e8fcb6f6eae81c45fb6af96eab8 Mon Sep 17 00:00:00 2001 From: Javier Date: Thu, 22 Oct 2015 11:43:30 -0300 Subject: [PATCH 07/10] fix local transaction sync with more than 6 confirmation --- src/js/controllers/index.js | 39 +++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index d136c74ed..85d734529 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -734,13 +734,20 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); }; - self.areEqualsTxs = function(firstTx, secondTx) { - if (firstTx.txid == secondTx.txid) + self.stopSync = function(remoteTx, localTx) { + if (remoteTx.txid == localTx.txid) return true; else return false; } + self.removeLessThanSixConfirmations = function(txs) { + return lodash.map(txs, function(tx) { + if (tx.confirmations >= 6) + return tx; + }); + } + self.updateLocalTxHistory = function(cb) { var fc = profileService.focusedClient; var c = fc.credentials; @@ -749,23 +756,25 @@ angular.module('copayApp.controllers').controller('indexController', function($r storageService.getTxHistory(c.walletId, function(err, txs) { if (err) return cb(err); - var txsFromLocal; + var localTxs; try { - txsFromLocal = JSON.parse(txs); + localTxs = JSON.parse(txs); } catch (ex) { return cb(ex); } - if (!txsFromLocal) - txsFromLocal = []; + if (!localTxs) + localTxs = []; + + var txsFromLocal = self.removeLessThanSixConfirmations(localTxs); var count = 0; fillTxsObject(txsToPush); function fillTxsObject(txsToPush) { - self.makeTxHistoryRequest(txsToPush, txsFromLocal, function(err, skipLoop, txsResult) { + self.makeTxHistoryRequest(txsToPush, txsFromLocal, function(err, exitLoop, txsResult) { if (err) return cb(err); - if (skipLoop) { + if (exitLoop) { self.txHistory = []; self.setTxHistory(lodash.compact(txsResult.concat(txsFromLocal))); storageService.setTxHistory(JSON.stringify(self.txHistory), c.walletId, function() { @@ -781,7 +790,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.makeTxHistoryRequest = function(txsToPush, localTx, cb) { var fc = profileService.focusedClient; var c = fc.credentials; - var skipLoop = false; + var exitLoop = false; fc.getTxHistory({ skip: self.skipHistory, @@ -790,28 +799,28 @@ angular.module('copayApp.controllers').controller('indexController', function($r if (err) return cb(err); if (!txsFromBWC[0]) { - skipLoop = true; + exitLoop = true; $log.debug('There is not transactions stored'); } lodash.each(txsFromBWC, function(t) { if (!localTx[0]) txsToPush.push(t); else { - if (!self.areEqualsTxs(t, localTx[0]) && !skipLoop) { + if (!self.stopSync(t, localTx[0]) && !exitLoop) { txsToPush.push(t); } else { - skipLoop = true; + exitLoop = true; } } }); self.skipHistory = self.skipHistory + self.limitHistory; - return cb(null, skipLoop, txsToPush); + return cb(null, exitLoop, txsToPush); }); } - self.updateTxHistory = function(skip) { + self.updateTxHistory = function() { $log.debug('Updating Transaction History'); - self.skipHistory = skip || 0; + self.skipHistory = 0; self.txHistoryError = false; self.updatingTxHistory = true; self.txHistoryPaging = false; From c674634a56d31537064904788294b9309558c6c0 Mon Sep 17 00:00:00 2001 From: Javier Date: Thu, 22 Oct 2015 12:31:54 -0300 Subject: [PATCH 08/10] debounced transaction history --- src/js/controllers/index.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 85d734529..972050670 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -818,7 +818,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); } - self.updateTxHistory = function() { + self.updateHistory = function() { $log.debug('Updating Transaction History'); self.skipHistory = 0; self.txHistoryError = false; @@ -834,8 +834,12 @@ angular.module('copayApp.controllers').controller('indexController', function($r }); }; - self.debouncedUpdateHistory = lodash.throttle(function() { - self.updateTxHistory(); + self.updateTxHistory = lodash.debounce(function() { + self.updateHistory(); + }, 1000); + + self.throttledUpdateHistory = lodash.throttle(function() { + self.updateHistory(); }, 5000); self.showErrorPopup = function(msg, cb) { @@ -1146,7 +1150,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r } else if (self.hasUnsafeConfirmed) { $log.debug('Wallet has transactions with few confirmations. Updating.') if (self.network == 'testnet') { - self.debouncedUpdateHistory(); + self.throttledUpdateHistory(); } else { self.updateTxHistory(); } From ce47cb0c650aef81ffa79068026741756ceedb78 Mon Sep 17 00:00:00 2001 From: Javier Date: Thu, 22 Oct 2015 17:11:37 -0300 Subject: [PATCH 09/10] spinner - csv download button --- public/views/walletHome.html | 46 ++++++++++++++++++------------------ src/js/controllers/index.js | 3 ++- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/public/views/walletHome.html b/public/views/walletHome.html index faf16d9ef..035b0a8d2 100644 --- a/public/views/walletHome.html +++ b/public/views/walletHome.html @@ -455,6 +455,29 @@ +
+
+ +
+
+
+
+
+
+
+
+
+
-
-
- -
-
-
-
-
-
-
-
-
- -
diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 972050670..7504a1f46 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -2,6 +2,7 @@ angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, lodash, go, profileService, configService, isCordova, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, nodeWebkit, addonManager, feeService, isChromeApp, bwsError, txFormatService, uxLanguage, $state, glideraService, isMobile) { var self = this; + var CONFIRMATIONS = 12; self.isCordova = isCordova; self.isChromeApp = isChromeApp; self.isSafari = isMobile.Safari(); @@ -743,7 +744,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.removeLessThanSixConfirmations = function(txs) { return lodash.map(txs, function(tx) { - if (tx.confirmations >= 6) + if (tx.confirmations >= CONFIRMATIONS) return tx; }); } From 0d022523b0de5d4021c75b1d54d898d9e2567278 Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 23 Oct 2015 13:26:59 -0300 Subject: [PATCH 10/10] refactor on local transactions methods --- public/views/walletHome.html | 7 +--- src/js/controllers/index.js | 72 ++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 42 deletions(-) diff --git a/public/views/walletHome.html b/public/views/walletHome.html index 035b0a8d2..7e98c2f5b 100644 --- a/public/views/walletHome.html +++ b/public/views/walletHome.html @@ -455,13 +455,8 @@ -
+
-
diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 7504a1f46..b37adad0e 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -2,7 +2,7 @@ angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, lodash, go, profileService, configService, isCordova, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, nodeWebkit, addonManager, feeService, isChromeApp, bwsError, txFormatService, uxLanguage, $state, glideraService, isMobile) { var self = this; - var CONFIRMATIONS = 12; + var SOFT_CONFIRMATION_LIMIT = 12; self.isCordova = isCordova; self.isChromeApp = isChromeApp; self.isSafari = isMobile.Safari(); @@ -85,7 +85,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.txHistory = []; self.txHistoryUnique = {}; self.balanceByAddress = null; - self.txHistoryPaging = false; self.pendingTxProposalsCountForUs = null; self.setSpendUnconfirmed(); @@ -647,18 +646,17 @@ angular.module('copayApp.controllers').controller('indexController', function($r } var step = 6; - var unique = {}; - function getHistory(skip, cb) { + function getHistory(cb) { storageService.getTxHistory(c.walletId, function(err, txs) { if (err) return cb(err); - var txsFromLocal; + var txsFromLocal = []; try { txsFromLocal = JSON.parse(txs); } catch (ex) { - return cb(ex); + $log.warn(ex); } allTxs.push(txsFromLocal); @@ -667,7 +665,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r } if (isCordova) { - $log.info('Not available on mobile'); + $log.info('CSV generation not available in mobile'); return; } var isNode = nodeWebkit.isDefined(); @@ -681,7 +679,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.setOngoingProcess('generatingCSV', true); $timeout(function() { - getHistory(null, function(err, txs) { + getHistory(function(err, txs) { self.setOngoingProcess('generatingCSV', false); if (err) { self.handleError(err); @@ -742,89 +740,91 @@ angular.module('copayApp.controllers').controller('indexController', function($r return false; } - self.removeLessThanSixConfirmations = function(txs) { + self.removeSoftConfirmedTx = function(txs) { return lodash.map(txs, function(tx) { - if (tx.confirmations >= CONFIRMATIONS) + if (tx.confirmations >= SOFT_CONFIRMATION_LIMIT) return tx; }); } - self.updateLocalTxHistory = function(cb) { + self.getConfirmedTxs = function(cb) { var fc = profileService.focusedClient; var c = fc.credentials; - var txsToPush = []; storageService.getTxHistory(c.walletId, function(err, txs) { if (err) return cb(err); - var localTxs; + var localTxs = []; try { localTxs = JSON.parse(txs); } catch (ex) { - return cb(ex); + $log.warn(ex); } - if (!localTxs) - localTxs = []; + return cb(null, self.removeSoftConfirmedTx(localTxs)); + }); + } - var txsFromLocal = self.removeLessThanSixConfirmations(localTxs); + self.updateLocalTxHistory = function(cb) { + self.getConfirmedTxs(function(err, txsFromLocal) { + if (err) return cb(err); - var count = 0; - fillTxsObject(txsToPush); + var fc = profileService.focusedClient; + var c = fc.credentials; + fillTxsObject(); - function fillTxsObject(txsToPush) { - self.makeTxHistoryRequest(txsToPush, txsFromLocal, function(err, exitLoop, txsResult) { + function fillTxsObject(txsResult, index) { + txsResult = txsResult || []; + index = index || 0; + + self.makeTxHistoryRequest(txsResult, index, txsFromLocal[0], function(err, newIndex, exitLoop) { if (err) return cb(err); if (exitLoop) { self.txHistory = []; self.setTxHistory(lodash.compact(txsResult.concat(txsFromLocal))); - storageService.setTxHistory(JSON.stringify(self.txHistory), c.walletId, function() { + return storageService.setTxHistory(JSON.stringify(self.txHistory), c.walletId, function() { return cb(null); }); - } else - fillTxsObject(txsResult); + } + fillTxsObject(txsResult, newIndex); }); }; }); } - self.makeTxHistoryRequest = function(txsToPush, localTx, cb) { + self.makeTxHistoryRequest = function(txsResult, index, endingTx, cb) { var fc = profileService.focusedClient; var c = fc.credentials; var exitLoop = false; fc.getTxHistory({ - skip: self.skipHistory, + skip: index, limit: self.limitHistory + 1 }, function(err, txsFromBWC) { if (err) return cb(err); - if (!txsFromBWC[0]) { + if (!txsFromBWC[0]) exitLoop = true; - $log.debug('There is not transactions stored'); - } lodash.each(txsFromBWC, function(t) { - if (!localTx[0]) txsToPush.push(t); + if (!endingTx) txsResult.push(t); else { - if (!self.stopSync(t, localTx[0]) && !exitLoop) { - txsToPush.push(t); + if (!self.stopSync(t, endingTx) && !exitLoop) { + txsResult.push(t); } else { exitLoop = true; } } }); - self.skipHistory = self.skipHistory + self.limitHistory; - return cb(null, exitLoop, txsToPush); + index = index + self.limitHistory; + return cb(null, index, exitLoop); }); } self.updateHistory = function() { $log.debug('Updating Transaction History'); - self.skipHistory = 0; self.txHistoryError = false; self.updatingTxHistory = true; - self.txHistoryPaging = false; $timeout(function() { self.updateLocalTxHistory(function(err) {