diff --git a/blue_modules/storage-context.js b/blue_modules/storage-context.js index db0523500..3e226f5d8 100644 --- a/blue_modules/storage-context.js +++ b/blue_modules/storage-context.js @@ -7,11 +7,13 @@ const BlueElectrum = require('./BlueElectrum'); const _lastTimeTriedToRefetchWallet = {}; // hashmap of timestamps we _started_ refetching some wallet +export const WalletTransactionsStatus = { NONE: false, ALL: true }; export const BlueStorageContext = createContext(); export const BlueStorageProvider = ({ children }) => { const [wallets, setWallets] = useState([]); const [pendingWallets, setPendingWallets] = useState([]); const [selectedWallet, setSelectedWallet] = useState(''); + const [walletTransactionUpdateStatus, setWalletTransactionUpdateStatus] = useState(WalletTransactionsStatus.NONE); const [walletsInitialized, setWalletsInitialized] = useState(false); const [preferredFiatCurrency, _setPreferredFiatCurrency] = useState(); const [language, _setLanguage] = useState(); @@ -80,9 +82,12 @@ export const BlueStorageProvider = ({ children }) => { saveToDisk(); }; - const refreshAllWalletTransactions = async lastSnappedTo => { + const refreshAllWalletTransactions = async (lastSnappedTo, showUpdateStatusIndicator = true) => { let noErr = true; try { + if (showUpdateStatusIndicator) { + setWalletTransactionUpdateStatus(WalletTransactionsStatus.ALL); + } await BlueElectrum.waitTillConnected(); const balanceStart = +new Date(); await fetchWalletBalances(lastSnappedTo); @@ -95,6 +100,8 @@ export const BlueStorageProvider = ({ children }) => { } catch (err) { noErr = false; console.warn(err); + } finally { + setWalletTransactionUpdateStatus(WalletTransactionsStatus.NONE); } if (noErr) await saveToDisk(); // caching }; @@ -104,6 +111,7 @@ export const BlueStorageProvider = ({ children }) => { let noErr = true; try { // 5sec debounce: + setWalletTransactionUpdateStatus(walletID); if (+new Date() - _lastTimeTriedToRefetchWallet[walletID] < 5000) { console.log('re-fetch wallet happens too fast; NOP'); return; @@ -122,6 +130,8 @@ export const BlueStorageProvider = ({ children }) => { } catch (err) { noErr = false; console.warn(err); + } finally { + setWalletTransactionUpdateStatus(WalletTransactionsStatus.NONE); } if (noErr) await saveToDisk(); // caching }; @@ -207,6 +217,8 @@ export const BlueStorageProvider = ({ children }) => { language, isHandOffUseEnabled, setIsHandOffUseEnabledAsyncStorage, + walletTransactionUpdateStatus, + setWalletTransactionUpdateStatus, }} > {children} diff --git a/components/WalletsCarousel.js b/components/WalletsCarousel.js index d1a5b0e7f..20eeb8503 100644 --- a/components/WalletsCarousel.js +++ b/components/WalletsCarousel.js @@ -127,6 +127,7 @@ const iStyles = StyleSheet.create({ const WalletCarouselItem = ({ item, index, onPress, handleLongPress, isSelectedWallet }) => { const scaleValue = new Animated.Value(1.0); const { colors } = useTheme(); + const { walletTransactionUpdateStatus } = useContext(BlueStorageContext); const onPressedIn = () => { const props = { duration: 50 }; @@ -203,6 +204,15 @@ const WalletCarouselItem = ({ item, index, onPress, handleLongPress, isSelectedW image = require('../img/btc-shape.png'); } + const latestTransactionText = + walletTransactionUpdateStatus === true || walletTransactionUpdateStatus === item.getID() + ? loc.transactions.updating + : item.getBalance() !== 0 && item.getLatestTransactionTime() === 0 + ? loc.wallets.pull_to_refresh + : item.getTransactions().find(tx => tx.confirmations === 0) + ? loc.transactions.pending + : transactionTimeToReadable(item.getLatestTransactionTime()); + return ( {loc.wallets.list_latest_transaction} + - {item.getBalance() !== 0 && item.getLatestTransactionTime() === 0 - ? loc.wallets.pull_to_refresh - : item.getTransactions().find(tx => tx.confirmations === 0) - ? loc.transactions.pending.toLowerCase() - : transactionTimeToReadable(item.getLatestTransactionTime())} + {latestTransactionText} diff --git a/loc/en.json b/loc/en.json index 471a80db3..b28c75104 100644 --- a/loc/en.json +++ b/loc/en.json @@ -355,7 +355,8 @@ "status_bump": "Bump Fee", "status_cancel": "Cancel Transaction", "transactions_count": "Transactions Count", - "txid": "Txid" + "txid": "Txid", + "updating": "Updating..." }, "wallets": { "add_bitcoin": "Bitcoin", diff --git a/screen/wallets/list.js b/screen/wallets/list.js index 21564b929..c9740be09 100644 --- a/screen/wallets/list.js +++ b/screen/wallets/list.js @@ -139,13 +139,13 @@ const WalletsList = () => { * Forcefully fetches TXs and balance for ALL wallets. * Triggered manually by user on pull-to-refresh. */ - const refreshTransactions = (showLoadingIndicator = true) => { + const refreshTransactions = (showLoadingIndicator = true, showUpdateStatusIndicator = false) => { setIsLoading(showLoadingIndicator); - refreshAllWalletTransactions().finally(() => setIsLoading(false)); + refreshAllWalletTransactions(showLoadingIndicator, showUpdateStatusIndicator).finally(() => setIsLoading(false)); }; useEffect(() => { - refreshTransactions(false); + refreshTransactions(false, true); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // call refreshTransactions() only once, when screen mounts @@ -194,7 +194,7 @@ const WalletsList = () => { console.log('onSnapToItem', index); if (wallets[index] && (wallets[index].timeToRefreshBalance() || wallets[index].timeToRefreshTransaction())) { console.log(wallets[index].getLabel(), 'thinks its time to refresh either balance or transactions. refetching both'); - refreshAllWalletTransactions(index).finally(() => setIsLoading(false)); + refreshAllWalletTransactions(index, false).finally(() => setIsLoading(false)); } }; @@ -432,12 +432,16 @@ const WalletsList = () => { setItemWidth(width * 0.82 > 375 ? 375 : width * 0.82); }; + const onRefresh = () => { + refreshTransactions(true, false); + }; + return ( { - const { wallets, saveToDisk, setSelectedWallet } = useContext(BlueStorageContext); + const { wallets, saveToDisk, setSelectedWallet, walletTransactionUpdateStatus } = useContext(BlueStorageContext); const [isLoading, setIsLoading] = useState(false); const [isManageFundsModalVisible, setIsManageFundsModalVisible] = useState(false); const { walletID } = useRoute().params; @@ -112,6 +112,11 @@ const WalletTransactions = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + useEffect(() => { + setOptions({ headerTitle: walletTransactionUpdateStatus === walletID ? loc.transactions.updating : '' }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [walletTransactionUpdateStatus]); + useEffect(() => { setIsLoading(true); setLimit(15);