From cc4f6c8a9aee6316a522e246fc95fec3354f8248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Rodriguez=20V=C3=A9lez?= Date: Sat, 16 Feb 2019 20:22:14 -0500 Subject: [PATCH] REF: UI responsiveness improvements --- android/app/build.gradle | 2 +- class/abstract-hd-wallet.js | 3 - class/app-storage.js | 2 + ios/BlueWallet/Info.plist | 2 +- loc/index.js | 7 --- package.json | 2 +- screen/receive/details.js | 4 +- screen/send/success.js | 2 +- screen/wallets/list.js | 52 +++++++-------- screen/wallets/scanQrWif.js | 3 +- screen/wallets/transactions.js | 112 +++++++++++++++++---------------- 11 files changed, 94 insertions(+), 97 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index e845694d8..f48b1c264 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -102,7 +102,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 - versionName "3.7.2" + versionName "3.8.0" ndk { abiFilters "armeabi-v7a", "x86" } diff --git a/class/abstract-hd-wallet.js b/class/abstract-hd-wallet.js index 244a0c29c..32ccb338a 100644 --- a/class/abstract-hd-wallet.js +++ b/class/abstract-hd-wallet.js @@ -394,9 +394,6 @@ export class AbstractHDWallet extends LegacyWallet { } this.next_free_address_index = await binarySearchIterationForExternalAddress(100); - - this.balance = 0; - this.unconfirmed_balance = 0; this.usedAddresses = []; // generating all involved addresses: diff --git a/class/app-storage.js b/class/app-storage.js index 2d7dc24ac..62bd61a94 100644 --- a/class/app-storage.js +++ b/class/app-storage.js @@ -262,6 +262,7 @@ export class AppStorage { * @return {Promise.} */ async fetchWalletBalances(index) { + console.log('fetchWalletBalances for wallet#', index); if (index || index === 0) { let c = 0; for (let wallet of this.wallets) { @@ -287,6 +288,7 @@ export class AppStorage { * @return {Promise.} */ async fetchWalletTransactions(index) { + console.log('fetchWalletTransactions for wallet#', index); if (index || index === 0) { let c = 0; for (let wallet of this.wallets) { diff --git a/ios/BlueWallet/Info.plist b/ios/BlueWallet/Info.plist index 31e832c22..ab98c3c34 100644 --- a/ios/BlueWallet/Info.plist +++ b/ios/BlueWallet/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 3.7.2 + 3.8.0 CFBundleSignature ???? CFBundleURLTypes diff --git a/loc/index.js b/loc/index.js index 299af3ec9..324eba80e 100644 --- a/loc/index.js +++ b/loc/index.js @@ -164,13 +164,6 @@ strings.transactionTimeToReadable = time => { return dayjs(time).fromNow(); }; -strings.transactionTimeToReadableToFuture = time => { - if (time === 0) { - return strings._.never; - } - return dayjs(time).toNow(); -}; - function removeTrailingZeros(value) { value = value.toString(); diff --git a/package.json b/package.json index 20dfaf29e..db0dce4ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "BlueWallet", - "version": "3.7.2", + "version": "3.8.0", "devDependencies": { "babel-eslint": "^10.0.1", "babel-jest": "^24.0.0", diff --git a/screen/receive/details.js b/screen/receive/details.js index 87d2f85a1..a3f9a064b 100644 --- a/screen/receive/details.js +++ b/screen/receive/details.js @@ -36,10 +36,10 @@ export default class ReceiveDetails extends Component { addressText: '', }; - // EV(EV.enum.RECEIVE_ADDRESS_CHANGED, this.refreshFunction.bind(this)); + // EV(EV.enum.RECEIVE_ADDRESS_CHANGED, this.redrawScreen.bind(this)); } - /* refreshFunction(newAddress) { + /* redrawScreen(newAddress) { console.log('newAddress =', newAddress); this.setState({ address: newAddress, diff --git a/screen/send/success.js b/screen/send/success.js index f55527d8c..5bca848d1 100644 --- a/screen/send/success.js +++ b/screen/send/success.js @@ -121,7 +121,7 @@ Success.propTypes = { dismiss: PropTypes.func, state: PropTypes.shape({ params: PropTypes.shape({ - amount: PropTypes.string, + amount: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), fee: PropTypes.number, }), }), diff --git a/screen/wallets/list.js b/screen/wallets/list.js index b8ddfc104..a24ab386f 100644 --- a/screen/wallets/list.js +++ b/screen/wallets/list.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; -import { View, TouchableOpacity, Text, FlatList, RefreshControl, ScrollView } from 'react-native'; -import { BlueLoading, SafeBlueArea, WalletsCarousel, BlueList, BlueHeaderDefaultMain, BlueListTransactionItem } from '../../BlueComponents'; +import { View, TouchableOpacity, Text, FlatList, InteractionManager, RefreshControl, ScrollView } from 'react-native'; +import { BlueLoading, SafeBlueArea, WalletsCarousel, BlueList, BlueHeaderDefaultMain, BlueTransactionListItem } from '../../BlueComponents'; import { Icon } from 'react-native-elements'; import { NavigationEvents } from 'react-navigation'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; @@ -33,18 +33,19 @@ export default class WalletsList extends Component { super(props); this.state = { isLoading: true, + isFlatListRefreshControlHidden: true, wallets: BlueApp.getWallets().concat(false), lastSnappedTo: 0, }; - EV(EV.enum.WALLETS_COUNT_CHANGED, this.refreshFunction.bind(this)); + EV(EV.enum.WALLETS_COUNT_CHANGED, this.redrawScreen.bind(this)); // here, when we receive TRANSACTIONS_COUNT_CHANGED we do not query // remote server, we just redraw the screen - EV(EV.enum.TRANSACTIONS_COUNT_CHANGED, this.refreshFunction.bind(this)); + EV(EV.enum.TRANSACTIONS_COUNT_CHANGED, this.redrawScreen.bind(this)); } componentDidMount() { - this.refreshFunction(); + this.redrawScreen(); } /** @@ -52,28 +53,26 @@ export default class WalletsList extends Component { * Triggered manually by user on pull-to-refresh. */ refreshTransactions() { - if (!(this.lastSnappedTo < BlueApp.getWallets().length)) { + if (!(this.lastSnappedTo < BlueApp.getWallets().length) && this.lastSnappedTo !== undefined) { // last card, nop console.log('last card, nop'); return; } - this.setState( { - isTransactionsLoading: true, + isFlatListRefreshControlHidden: true, }, - async function() { - let that = this; - setTimeout(async function() { + () => { + InteractionManager.runAfterInteractions(async () => { // more responsive let noErr = true; try { let balanceStart = +new Date(); - await BlueApp.fetchWalletBalances(that.lastSnappedTo || 0); + await BlueApp.fetchWalletBalances(this.lastSnappedTo || 0); let balanceEnd = +new Date(); console.log('fetch balance took', (balanceEnd - balanceStart) / 1000, 'sec'); let start = +new Date(); - await BlueApp.fetchWalletTransactions(that.lastSnappedTo || 0); + await BlueApp.fetchWalletTransactions(this.lastSnappedTo || 0); let end = +new Date(); console.log('fetch tx took', (end - start) / 1000, 'sec'); } catch (err) { @@ -82,23 +81,21 @@ export default class WalletsList extends Component { } if (noErr) await BlueApp.saveToDisk(); // caching - that.refreshFunction(); - }, 1); + this.redrawScreen(); + }); }, ); } - /** - * Redraws the screen - */ - refreshFunction() { + redrawScreen() { + console.log('wallets/list redrawScreen()'); if (BlueApp.getBalance() !== 0) { A(A.ENUM.GOT_NONZERO_BALANCE); } this.setState({ isLoading: false, - isTransactionsLoading: false, + isFlatListRefreshControlHidden: true, dataSource: BlueApp.getTransactions(), wallets: BlueApp.getWallets().concat(false), }); @@ -163,7 +160,7 @@ export default class WalletsList extends Component { console.log('balance changed, thus txs too'); // balance changed, thus txs too await wallets[index].fetchTransactions(); - this.refreshFunction(); + this.redrawScreen(); didRefresh = true; } else if (wallets[index].timeToRefreshTransaction()) { console.log(wallets[index].getLabel(), 'thinks its time to refresh TXs'); @@ -174,7 +171,7 @@ export default class WalletsList extends Component { if (wallets[index].fetchUserInvoices) { await wallets[index].fetchUserInvoices(); } - this.refreshFunction(); + this.redrawScreen(); didRefresh = true; } else { console.log('balance not changed'); @@ -218,8 +215,9 @@ export default class WalletsList extends Component { } }; - _renderItem = data => ; - + _renderItem = data => { + return ; + }; render() { if (this.state.isLoading) { return ; @@ -228,11 +226,13 @@ export default class WalletsList extends Component { { - this.refreshFunction(); + this.redrawScreen(); }} /> this.refreshTransactions()} refreshing={this.state.isTransactionsLoading} />} + refreshControl={ + this.refreshTransactions()} refreshing={!this.state.isFlatListRefreshControlHidden} /> + } > this.props.navigation.navigate('AddWallet')} /> EV(EV.enum.WALLETS_COUNT_CHANGED), 500); } // end @@ -284,7 +284,6 @@ ScanQrWif.propTypes = { navigation: PropTypes.shape({ goBack: PropTypes.func, popToTop: PropTypes.func, - dismiss: PropTypes.func, navigate: PropTypes.func, }), }; diff --git a/screen/wallets/transactions.js b/screen/wallets/transactions.js index f7fccae65..56af6008b 100644 --- a/screen/wallets/transactions.js +++ b/screen/wallets/transactions.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { Text, View, Image, FlatList, RefreshControl, TouchableOpacity, StatusBar } from 'react-native'; +import { Text, View, InteractionManager, Image, FlatList, RefreshControl, TouchableOpacity, StatusBar } from 'react-native'; import LinearGradient from 'react-native-linear-gradient'; import PropTypes from 'prop-types'; import { NavigationEvents } from 'react-navigation'; @@ -47,15 +47,20 @@ export default class WalletTransactions extends Component { this.props.navigation.setParams({ wallet: wallet }); this.state = { isLoading: true, - isTransactionsLoading: false, + showShowFlatListRefreshControl: false, wallet: wallet, dataSource: wallet.getTransactions(), walletPreviousPreferredUnit: wallet.getPreferredBalanceUnit(), + walletHeaderLatestTransaction: '...', + showSendButton: + (wallet.allowSend() && wallet.type === LightningCustodianWallet.type && wallet.balance > 0) || + (wallet.allowSend() && wallet.type !== LightningCustodianWallet.type), + showReceiveButton: wallet.allowReceive(), }; } componentDidMount() { - this.refreshFunction(); + // nop } /** @@ -68,12 +73,9 @@ export default class WalletTransactions extends Component { }, 4000); // giving a chance to remote server to propagate } - /** - * Redraws the screen - */ - refreshFunction() { - setTimeout(() => { - console.log('wallets/transactions refreshFunction()'); + redrawScreen() { + InteractionManager.runAfterInteractions(async () => { + console.log('wallets/transactions redrawScreen()'); let showSend = false; let showReceive = false; const wallet = this.state.wallet; @@ -99,16 +101,18 @@ export default class WalletTransactions extends Component { return b.sort_ts - a.sort_ts; }); + const latestTXTime = loc.transactionTimeToReadable(wallet.getLatestTransactionTime()); this.setState({ isLoading: false, - isTransactionsLoading: false, + showShowFlatListRefreshControl: false, showReceiveButton: showReceive, showSendButton: showSend, showManageFundsBigButton, showManageFundsSmallButton, dataSource: txs, + walletHeaderLatestTransaction: latestTXTime, }); - }, 1); + }); } isLightning() { @@ -124,49 +128,50 @@ export default class WalletTransactions extends Component { * Forcefully fetches TXs and balance for wallet */ refreshTransactions() { + if (this.state.isLoading) return; this.setState( { - isTransactionsLoading: true, + showShowFlatListRefreshControl: true, + isLoading: true, }, - async function() { - let that = this; - setTimeout(async function() { - // more responsive - let noErr = true; - let smthChanged = false; - try { - /** @type {LegacyWallet} */ - let wallet = that.state.wallet; - let balanceStart = +new Date(); - const oldBalance = wallet.getBalance(); - await wallet.fetchBalance(); - if (oldBalance !== wallet.getBalance()) smthChanged = true; - let balanceEnd = +new Date(); - console.log(wallet.getLabel(), 'fetch balance took', (balanceEnd - balanceStart) / 1000, 'sec'); - let start = +new Date(); - const oldTxLen = wallet.getTransactions().length; - await wallet.fetchTransactions(); - if (oldTxLen !== wallet.getTransactions().length) smthChanged = true; - if (wallet.fetchPendingTransactions) { - await wallet.fetchPendingTransactions(); - } - if (wallet.fetchUserInvoices) { - await wallet.fetchUserInvoices(); - } - let end = +new Date(); - console.log(wallet.getLabel(), 'fetch tx took', (end - start) / 1000, 'sec'); - } catch (err) { - noErr = false; - console.warn(err); + async () => { + let noErr = true; + let smthChanged = false; + try { + /** @type {LegacyWallet} */ + let wallet = this.state.wallet; + let balanceStart = +new Date(); + const oldBalance = wallet.getBalance(); + await wallet.fetchBalance(); + if (oldBalance !== wallet.getBalance()) smthChanged = true; + let balanceEnd = +new Date(); + console.log(wallet.getLabel(), 'fetch balance took', (balanceEnd - balanceStart) / 1000, 'sec'); + let start = +new Date(); + const oldTxLen = wallet.getTransactions().length; + await wallet.fetchTransactions(); + if (oldTxLen !== wallet.getTransactions().length) smthChanged = true; + if (wallet.fetchPendingTransactions) { + await wallet.fetchPendingTransactions(); } - if (noErr && smthChanged) { - console.log('saving to disk'); - await BlueApp.saveToDisk(); // caching - EV(EV.enum.TRANSACTIONS_COUNT_CHANGED); // let other components know they should redraw + if (wallet.fetchUserInvoices) { + await wallet.fetchUserInvoices(); } - - that.refreshFunction(); // Redraws the screen - }, 1); + let end = +new Date(); + console.log(wallet.getLabel(), 'fetch tx took', (end - start) / 1000, 'sec'); + } catch (err) { + noErr = false; + console.warn(err); + this.setState({ + isLoading: false, + showShowFlatListRefreshControl: false, + }); + } + if (noErr && smthChanged) { + console.log('saving to disk'); + await BlueApp.saveToDisk(); // caching + EV(EV.enum.TRANSACTIONS_COUNT_CHANGED); // let other components know they should redraw + } + this.redrawScreen(); }, ); } @@ -253,7 +258,7 @@ export default class WalletTransactions extends Component { color: '#fff', }} > - {loc.transactionTimeToReadable(this.state.wallet.getLatestTransactionTime())} + {this.state.walletHeaderLatestTransaction} ); @@ -299,10 +304,9 @@ export default class WalletTransactions extends Component { { StatusBar.setBarStyle('light-content'); - this.refreshFunction(); + this.redrawScreen(); }} onWillBlur={() => this.onWillBlur()} - onDidFocus={() => StatusBar.setBarStyle('light-content')} /> {this.renderWalletHeader()} @@ -397,7 +401,9 @@ export default class WalletTransactions extends Component { )} } - refreshControl={ this.refreshTransactions()} refreshing={this.state.isTransactionsLoading} />} + refreshControl={ + this.refreshTransactions()} refreshing={this.state.showShowFlatListRefreshControl} /> + } data={this.state.dataSource} keyExtractor={this._keyExtractor} initialNumToRender={10}