diff --git a/Gruntfile.js b/Gruntfile.js index 160db85d5..7968f2510 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -65,6 +65,9 @@ module.exports = function(grunt) { run_android: { command: 'cordova run android --device', }, + run_android_emulator: { + command: 'cordova run android --emulator', + }, sign_android: { // When the build log outputs "Built the following apk(s):", it seems to need the filename to start with "android-release". // It looks like it simply lists all apk files starting with "android-release" @@ -363,13 +366,14 @@ module.exports = function(grunt) { grunt.registerTask('build-mobile-release', ['build-ios-release', 'build-android-release']); // Build ios - grunt.registerTask('start-ios', ['exec:build_ios_debug', 'exec:xcode']); - grunt.registerTask('build-ios-debug', ['exec:build_ios_debug']); + grunt.registerTask('start-ios', ['default', 'exec:build_ios_debug', 'exec:xcode']); + grunt.registerTask('build-ios-debug', ['default', 'exec:build_ios_debug']); grunt.registerTask('build-ios-release', ['prod', 'exec:build_ios_release']); // Build 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('build-android-release', ['prod', 'exec:build_android_release', 'sign-android']); grunt.registerTask('sign-android', ['exec:sign_android']); diff --git a/app-template/package-template.json b/app-template/package-template.json index 200c269f6..11b15bfcd 100644 --- a/app-template/package-template.json +++ b/app-template/package-template.json @@ -126,6 +126,7 @@ "start": "npm run build:www && ionic serve --nolivereload --nogulp -s --address 0.0.0.0", "start:chrome": "npm run build:www && ionic serve --nolivereload --nogulp -s --address 0.0.0.0 --browser \"google chrome\"", "start:android": "grunt start-android", + "start:android-emulator": "grunt start-android", "start:android-log": "grunt start-android && npm run log:android", "start:ios": "grunt start-ios", "start:windows": "npm run build:www && npm run build:windows", diff --git a/src/js/controllers/wallet-details.controller.js b/src/js/controllers/wallet-details.controller.js index f3109db8b..cef57925e 100644 --- a/src/js/controllers/wallet-details.controller.js +++ b/src/js/controllers/wallet-details.controller.js @@ -400,8 +400,8 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun var refreshInterval; - $scope.$on("$ionicView.afterEnter", function(event, data) { - $scope.updateAll(); + $scope.$on("$ionicView.afterEnter", function onAfterEnter(event, data) { + $scope.updateAll(true, true); // refreshAmountSection(); refreshInterval = $interval($scope.onRefresh, 10 * 1000); $timeout(function() { diff --git a/src/js/services/bitcoincomService.js b/src/js/services/bitcoincomService.js index 68fd51a8a..62a75b4d1 100644 --- a/src/js/services/bitcoincomService.js +++ b/src/js/services/bitcoincomService.js @@ -85,7 +85,9 @@ angular.module('copayApp.services').factory('bitcoincomService', function(gettex }; var register = function() { - nextStepsService.register(cashGamesItem); + if (!platformInfo.isAndroid) { // To comply with Google Play policies + nextStepsService.register(cashGamesItem); + } nextStepsService.register(newsItem); nextStepsService.register(poolItem); nextStepsService.register(toolsItem); diff --git a/src/js/services/uxLanguage.js b/src/js/services/uxLanguage.js index 1fa446f01..b8e7c3b09 100644 --- a/src/js/services/uxLanguage.js +++ b/src/js/services/uxLanguage.js @@ -10,7 +10,7 @@ angular.module('copayApp.services') isoCode: 'en', rateCode: 'USD' }, { - name: 'català', + name: 'Català', isoCode: 'ca', rateCode: 'EUR' },{ @@ -59,10 +59,6 @@ angular.module('copayApp.services') name: 'Português', isoCode: 'pt', rateCode: 'EUR' - }, { - name: 'русский язык', - isoCode: 'ru', - rateCode: 'RUB' }, { name: '한국어', isoCode: 'ko', diff --git a/src/js/services/wallet-history.service.js b/src/js/services/wallet-history.service.js index e10e763e9..13fc8d636 100644 --- a/src/js/services/wallet-history.service.js +++ b/src/js/services/wallet-history.service.js @@ -12,9 +12,9 @@ // How much to overlap on each end of the page, for mitigating inconsistent sort order. 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. + // The fraction 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 MIN_KNOWN_TX_OVERLAP_FRACTION = 0.5; var SAFE_CONFIRMATIONS = 6; @@ -27,26 +27,34 @@ function addEarlyTransactions(walletId, cachedTxs, newTxs) { - var cachedTxIds = {}; + var cachedTxIndexFromId = {}; cachedTxs.forEach(function forCachedTx(tx){ - cachedTxIds[tx.txid] = true; + cachedTxIndexFromId[tx.txid] = true; }); + var confirmationsUpdated = false; var someTransactionsWereNew = false; var overlappingTxsCount = 0; newTxs.forEach(function forNewTx(tx){ - if (cachedTxIds[tx.txid]) { - overlappingTxsCount++; - } else { + if (typeof cachedTxIndexFromId[tx.txid] === "undefined") { someTransactionsWereNew = true; cachedTxs.push(tx); + } else { + var txUpdated = updateCachedTx(cachedTxs, cachedTxIndexFromId, tx); + confirmationsUpdated = confirmationsUpdated || txUpdated; + overlappingTxsCount++; } }); - if (overlappingTxsCount >= MIN_KNOWN_TX_OVERLAP) { // We are good + var overlappingTxFraction = overlappingTxsCount / Math.min(cachedTxs.length, PAGE_OVERLAP); + console.log('overlappingTxFraction:', overlappingTxFraction); + + if (overlappingTxFraction >= MIN_KNOWN_TX_OVERLAP_FRACTION) { // We are good if (someTransactionsWereNew) { saveTxHistory(walletId, cachedTxs); + } else if (confirmationsUpdated) { + saveTxHistory(walletId, cachedTxs); } else if (overlappingTxsCount === newTxs.length) { allTransactionsFetched = true; } @@ -62,30 +70,38 @@ } function addLatestTransactions(walletId, cachedTxs, newTxs) { - var cachedTxIds = {}; - cachedTxs.forEach(function forCachedTx(tx){ - cachedTxIds[tx.txid] = true; + var cachedTxIndexFromId = {}; + cachedTxs.forEach(function forCachedTx(tx, txIndex){ + cachedTxIndexFromId[tx.txid] = txIndex; }); var someTransactionsWereNew = false; + var confirmationsUpdated = false; var overlappingTxsCount = 0; var uniqueNewTxs = []; newTxs.forEach(function forNewTx(tx){ - if (cachedTxIds[tx.txid]) { - overlappingTxsCount++; - } else { + if (typeof cachedTxIndexFromId[tx.txid] === "undefined") { someTransactionsWereNew = true; uniqueNewTxs.push(tx); + } else { + var txUpdated = updateCachedTx(cachedTxs, cachedTxIndexFromId, tx); + confirmationsUpdated = confirmationsUpdated || txUpdated; + overlappingTxsCount++; } }); - if (overlappingTxsCount >= MIN_KNOWN_TX_OVERLAP) { // We are good + var overlappingTxFraction = overlappingTxsCount / Math.min(cachedTxs.length, PAGE_OVERLAP); + + if (overlappingTxFraction >= MIN_KNOWN_TX_OVERLAP_FRACTION) { // We are good if (someTransactionsWereNew) { var allTxs = uniqueNewTxs.concat(cachedTxs); saveTxHistory(walletId, allTxs); return allTxs; } else { + if (confirmationsUpdated) { + saveTxHistory(walletId, cachedTxs); + } return cachedTxs; } } else { @@ -99,6 +115,8 @@ // 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 */ function fetchTxHistoryByPage(wallet, start, cb) { @@ -182,7 +200,7 @@ }); return processedTxs; - }; + } function saveTxHistory(walletId, processedTxs) { storageService.setTxHistory(processedTxs, walletId, function onSetTxHistory(error){ @@ -192,9 +210,25 @@ }); } + /** + * 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) { - if (flushCacheOnNew) { fetchTxHistoryByPage(wallet, 0, function onFetchTxHistory(err, txs){ if (err) { @@ -235,10 +269,5 @@ }); } } - - - } - - })(); \ No newline at end of file