From 4f67fa1b1b2c45b415745c234013d445604a350e Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Sun, 3 Nov 2024 19:25:07 -0400 Subject: [PATCH 1/4] REF: Cache the numberformatter --- blue_modules/currency.ts | 71 +++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/blue_modules/currency.ts b/blue_modules/currency.ts index 73320d181..6af141777 100644 --- a/blue_modules/currency.ts +++ b/blue_modules/currency.ts @@ -27,11 +27,48 @@ let exchangeRates: ExchangeRates = { LAST_UPDATED_ERROR: false }; let lastTimeUpdateExchangeRateWasCalled: number = 0; let skipUpdateExchangeRate: boolean = false; +let currencyFormatter: Intl.NumberFormat | null = null; +let btcFormatter: Intl.NumberFormat | null = null; + +function getCurrencyFormatter(): Intl.NumberFormat { + if ( + !currencyFormatter || + currencyFormatter.resolvedOptions().locale !== preferredFiatCurrency.locale || + currencyFormatter.resolvedOptions().currency !== preferredFiatCurrency.endPointKey + ) { + currencyFormatter = new Intl.NumberFormat(preferredFiatCurrency.locale, { + style: 'currency', + currency: preferredFiatCurrency.endPointKey, + minimumFractionDigits: 2, + maximumFractionDigits: 8, + }); + console.debug('Created new currency formatter'); + } else { + console.debug('Using cached currency formatter'); + } + return currencyFormatter; +} + +function getBTCFormatter(): Intl.NumberFormat { + if (!btcFormatter) { + btcFormatter = new Intl.NumberFormat(preferredFiatCurrency.locale, { + minimumFractionDigits: 8, + maximumFractionDigits: 8, + }); + console.debug('Created new BTC formatter'); + } else { + console.debug('Using cached BTC formatter'); + } + return btcFormatter; +} + async function setPreferredCurrency(item: FiatUnitType): Promise { await AsyncStorage.setItem(PREFERRED_CURRENCY_STORAGE_KEY, JSON.stringify(item)); await DefaultPreference.setName(GROUP_IO_BLUEWALLET); await DefaultPreference.set(PREFERRED_CURRENCY_STORAGE_KEY, item.endPointKey); await DefaultPreference.set(PREFERRED_CURRENCY_LOCALE_STORAGE_KEY, item.locale.replace('-', '_')); + currencyFormatter = null; + btcFormatter = null; } async function updateExchangeRate(): Promise { @@ -79,7 +116,10 @@ async function updateExchangeRate(): Promise { rate.LAST_UPDATED_ERROR = true; exchangeRates.LAST_UPDATED_ERROR = true; await AsyncStorage.setItem(EXCHANGE_RATES_STORAGE_KEY, JSON.stringify(rate)); - } catch (storageError) {} + } catch (storageError) { + exchangeRates = { LAST_UPDATED_ERROR: true }; + throw storageError; + } } } @@ -233,15 +273,9 @@ function satoshiToLocalCurrency(satoshi: number, format: boolean = true): string if (format === false) return formattedAmount; try { - const formatter = new Intl.NumberFormat(preferredFiatCurrency.locale, { - style: 'currency', - currency: preferredFiatCurrency.endPointKey, - minimumFractionDigits: 2, - maximumFractionDigits: 8, - }); - return formatter.format(Number(formattedAmount)); + return getCurrencyFormatter().format(Number(formattedAmount)); } catch (error) { - console.warn(error); + console.error(error); return formattedAmount; } } @@ -267,15 +301,10 @@ async function mostRecentFetchedRate(): Promise { currencyInformation = {}; } - const formatter = new Intl.NumberFormat(preferredFiatCurrency.locale, { - style: 'currency', - currency: preferredFiatCurrency.endPointKey, - }); - const rate = currencyInformation[BTC_PREFIX + preferredFiatCurrency.endPointKey]; return { - LastUpdated: currencyInformation[LAST_UPDATED], - Rate: rate ? formatter.format(rate) : '...', + LastUpdated: currencyInformation[LAST_UPDATED] ? new Date(currencyInformation[LAST_UPDATED]) : null, + Rate: rate ? getCurrencyFormatter().format(rate) : '...', }; } catch { return { @@ -309,6 +338,15 @@ function getCurrencySymbol(): string { return preferredFiatCurrency.symbol; } +function formatBTC(btc: BigNumber.Value): string { + try { + return getBTCFormatter().format(Number(btc)); + } catch (error) { + console.error(error); + return new BigNumber(btc).toFixed(8); + } +} + function _setPreferredFiatCurrency(currency: FiatUnitType): void { preferredFiatCurrency = currency; } @@ -341,4 +379,5 @@ export { satoshiToLocalCurrency, setPreferredCurrency, updateExchangeRate, + formatBTC, }; From 00bfe03a078f38cf4604e3f87aea55bd96933e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Rodriguez=20V=C3=A9lez?= Date: Sun, 3 Nov 2024 20:15:35 -0400 Subject: [PATCH 2/4] Update blue_modules/currency.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- blue_modules/currency.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blue_modules/currency.ts b/blue_modules/currency.ts index 6af141777..811b2a05f 100644 --- a/blue_modules/currency.ts +++ b/blue_modules/currency.ts @@ -50,7 +50,7 @@ function getCurrencyFormatter(): Intl.NumberFormat { } function getBTCFormatter(): Intl.NumberFormat { - if (!btcFormatter) { + if (!btcFormatter || btcFormatter.resolvedOptions().locale !== preferredFiatCurrency.locale) { btcFormatter = new Intl.NumberFormat(preferredFiatCurrency.locale, { minimumFractionDigits: 8, maximumFractionDigits: 8, From d94ac253f6273366295b283c2fb1cda31206a136 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Wed, 6 Nov 2024 21:25:47 -0400 Subject: [PATCH 3/4] REF: Optimize totalwalletsbalance view --- components/Context/SettingsProvider.tsx | 3 ++- components/TotalWalletsBalance.tsx | 19 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/components/Context/SettingsProvider.tsx b/components/Context/SettingsProvider.tsx index 9c5cfdeca..71a69499b 100644 --- a/components/Context/SettingsProvider.tsx +++ b/components/Context/SettingsProvider.tsx @@ -200,7 +200,8 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = React.m }; loadSettings(); - }, [languageStorage]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); useEffect(() => { if (walletsInitialized) { diff --git a/components/TotalWalletsBalance.tsx b/components/TotalWalletsBalance.tsx index bfd43d4b3..3cc65af04 100644 --- a/components/TotalWalletsBalance.tsx +++ b/components/TotalWalletsBalance.tsx @@ -31,20 +31,18 @@ const TotalWalletsBalance: React.FC = React.memo(() => { [colors.foregroundColor], ); - const totalBalance = useMemo(() => { - return wallets.reduce((prev, curr) => { - if (!curr.hideBalance) { - const balance = curr.getBalance(); - return prev + (typeof balance === 'number' ? balance : 0); - } - return prev; - }, 0); + const getVisibleWalletBalances = useCallback(() => { + return wallets.filter(wallet => !wallet.hideBalance).map(wallet => wallet.getBalance()); }, [wallets]); + const totalBalance = useMemo(() => { + const visibleBalances = getVisibleWalletBalances(); + return visibleBalances.reduce((acc, balance) => acc + balance, 0); + }, [getVisibleWalletBalances]); + const formattedBalance = useMemo(() => { return formatBalanceWithoutSuffix(totalBalance, totalBalancePreferredUnit, true); }, [totalBalance, totalBalancePreferredUnit]); - const toolTipActions = useMemo(() => { const viewInFiat = { ...CommonToolTipActions.ViewInFiat, @@ -95,7 +93,8 @@ const TotalWalletsBalance: React.FC = React.memo(() => { break; } }, - [setIsTotalBalanceEnabledStorage, formattedBalance, setTotalBalancePreferredUnitStorage], + // eslint-disable-next-line react-hooks/exhaustive-deps + [formattedBalance], ); const handleBalanceOnPress = useCallback(async () => { From 09defd31739c51cfe46cbb719bc494a56da1b518 Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Fri, 8 Nov 2024 00:01:49 -0400 Subject: [PATCH 4/4] REF: Reduce code --- components/TotalWalletsBalance.tsx | 103 +++++++++++------------------ ios/Localizable.xcstrings | 2 +- loc/cs_cz.json | 6 +- loc/de_de.json | 6 +- loc/en.json | 8 +-- loc/es_419.json | 6 +- loc/he.json | 6 +- loc/jp_jp.json | 6 +- loc/pl.json | 6 +- loc/pt_br.json | 6 +- loc/ru.json | 6 +- typings/CommonToolTipActions.ts | 15 +++-- 12 files changed, 78 insertions(+), 98 deletions(-) diff --git a/components/TotalWalletsBalance.tsx b/components/TotalWalletsBalance.tsx index 3cc65af04..a0066fe61 100644 --- a/components/TotalWalletsBalance.tsx +++ b/components/TotalWalletsBalance.tsx @@ -23,52 +23,34 @@ const TotalWalletsBalance: React.FC = React.memo(() => { } = useSettings(); const { colors } = useTheme(); - const styleHooks = useMemo( - () => ({ - balance: { color: colors.foregroundColor }, - currency: { color: colors.foregroundColor }, - }), - [colors.foregroundColor], - ); - - const getVisibleWalletBalances = useCallback(() => { - return wallets.filter(wallet => !wallet.hideBalance).map(wallet => wallet.getBalance()); - }, [wallets]); - - const totalBalance = useMemo(() => { - const visibleBalances = getVisibleWalletBalances(); - return visibleBalances.reduce((acc, balance) => acc + balance, 0); - }, [getVisibleWalletBalances]); - - const formattedBalance = useMemo(() => { + const totalBalanceFormatted = useMemo(() => { + const totalBalance = wallets.reduce((prev, curr) => { + return curr.hideBalance ? prev : prev + (curr.getBalance() || 0); + }, 0); return formatBalanceWithoutSuffix(totalBalance, totalBalancePreferredUnit, true); - }, [totalBalance, totalBalancePreferredUnit]); - const toolTipActions = useMemo(() => { - const viewInFiat = { - ...CommonToolTipActions.ViewInFiat, - text: loc.formatString(loc.total_balance_view.view_in_fiat, { currency: preferredFiatCurrency.endPointKey }), - hidden: totalBalancePreferredUnit === BitcoinUnit.LOCAL_CURRENCY, - }; + }, [wallets, totalBalancePreferredUnit]); - const viewInSats = { - ...CommonToolTipActions.ViewInSats, - hidden: totalBalancePreferredUnit === BitcoinUnit.SATS, - }; - - const viewInBitcoin = { - ...CommonToolTipActions.ViewInBitcoin, - hidden: totalBalancePreferredUnit === BitcoinUnit.BTC, - }; - - const viewInActions = { - id: 'viewInActions', - text: '', - subactions: [viewInFiat, viewInSats, viewInBitcoin], - displayInline: true, - }; - - return [viewInActions, CommonToolTipActions.CopyAmount, CommonToolTipActions.HideBalance]; - }, [preferredFiatCurrency, totalBalancePreferredUnit]); + const toolTipActions = useMemo( + () => [ + { + id: 'viewInActions', + text: '', + displayInline: true, + subactions: [ + { + ...CommonToolTipActions.ViewInFiat, + text: loc.formatString(loc.total_balance_view.display_in_fiat, { currency: preferredFiatCurrency.endPointKey }), + hidden: totalBalancePreferredUnit === BitcoinUnit.LOCAL_CURRENCY, + }, + { ...CommonToolTipActions.ViewInSats, hidden: totalBalancePreferredUnit === BitcoinUnit.SATS }, + { ...CommonToolTipActions.ViewInBitcoin, hidden: totalBalancePreferredUnit === BitcoinUnit.BTC }, + ], + }, + CommonToolTipActions.CopyAmount, + CommonToolTipActions.Hide, + ], + [preferredFiatCurrency, totalBalancePreferredUnit], + ); const onPressMenuItem = useCallback( async (id: string) => { @@ -83,37 +65,30 @@ const TotalWalletsBalance: React.FC = React.memo(() => { case CommonToolTipActions.ViewInBitcoin.id: await setTotalBalancePreferredUnitStorage(BitcoinUnit.BTC); break; - case CommonToolTipActions.HideBalance.id: + case CommonToolTipActions.Hide.id: await setIsTotalBalanceEnabledStorage(false); break; case CommonToolTipActions.CopyAmount.id: - Clipboard.setString(formattedBalance.toString()); + Clipboard.setString(totalBalanceFormatted.toString()); break; default: break; } }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [formattedBalance], + [setIsTotalBalanceEnabledStorage, totalBalanceFormatted, setTotalBalancePreferredUnitStorage], ); const handleBalanceOnPress = useCallback(async () => { LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); - let nextUnit: BitcoinUnit; - switch (totalBalancePreferredUnit) { - case BitcoinUnit.BTC: - nextUnit = BitcoinUnit.SATS; - break; - case BitcoinUnit.SATS: - nextUnit = BitcoinUnit.LOCAL_CURRENCY; - break; - default: - nextUnit = BitcoinUnit.BTC; - } + const nextUnit = + totalBalancePreferredUnit === BitcoinUnit.BTC + ? BitcoinUnit.SATS + : totalBalancePreferredUnit === BitcoinUnit.SATS + ? BitcoinUnit.LOCAL_CURRENCY + : BitcoinUnit.BTC; await setTotalBalancePreferredUnitStorage(nextUnit); }, [totalBalancePreferredUnit, setTotalBalancePreferredUnitStorage]); - // If there's only one wallet or total balance view is disabled, don't render if (wallets.length <= 1 || !isTotalBalanceEnabled) return null; return ( @@ -121,10 +96,10 @@ const TotalWalletsBalance: React.FC = React.memo(() => { {loc.wallets.total_balance} - - {formattedBalance}{' '} + + {totalBalanceFormatted}{' '} {totalBalancePreferredUnit !== BitcoinUnit.LOCAL_CURRENCY && ( - {totalBalancePreferredUnit} + {totalBalancePreferredUnit} )} @@ -147,12 +122,10 @@ const styles = StyleSheet.create({ balance: { fontSize: 32, fontWeight: 'bold', - color: '#1D2B53', }, currency: { fontSize: 18, fontWeight: 'bold', - color: '#1D2B53', }, }); diff --git a/ios/Localizable.xcstrings b/ios/Localizable.xcstrings index 99cfa3cdf..659ed9bd8 100644 --- a/ios/Localizable.xcstrings +++ b/ios/Localizable.xcstrings @@ -18,7 +18,7 @@ } } }, - "VIEW_IN_BROWSER_TITLE" : { + "display_in_BROWSER_TITLE" : { "localizations" : { "en_US" : { "stringUnit" : { diff --git a/loc/cs_cz.json b/loc/cs_cz.json index 9aba9f469..0720ebe1d 100644 --- a/loc/cs_cz.json +++ b/loc/cs_cz.json @@ -483,9 +483,9 @@ "more_info": "Další informace" }, "total_balance_view": { - "view_in_bitcoin": "Zobrazit v bitcoinech", - "view_in_sats": "Zobrazit v sat", - "view_in_fiat": "Zobrazit v {currency}", + "display_in_bitcoin": "Zobrazit v bitcoinech", + "display_in_sats": "Zobrazit v sat", + "display_in_fiat": "Zobrazit v {currency}", "title": "Celkový zůstatek", "explanation": "Zobrazit celkový zůstatek všech vašich peněženek na přehledové obrazovce." }, diff --git a/loc/de_de.json b/loc/de_de.json index fe1ad4aed..f4b0a3ddc 100644 --- a/loc/de_de.json +++ b/loc/de_de.json @@ -475,9 +475,9 @@ "more_info": "Mehr Infos" }, "total_balance_view": { - "view_in_bitcoin": "In bitcoin anzeigen", - "view_in_sats": "In sats anzeigen", - "view_in_fiat": "In {currency} anzeigen", + "display_in_bitcoin": "In bitcoin anzeigen", + "display_in_sats": "In sats anzeigen", + "display_in_fiat": "In {currency} anzeigen", "title": "Gesamtes Guthaben", "explanation": "Auf dem Übersichtsbildschirm den Gesamtsaldo aller Wallets anzeigen." }, diff --git a/loc/en.json b/loc/en.json index 3444431e8..3e51f23f7 100644 --- a/loc/en.json +++ b/loc/en.json @@ -336,7 +336,6 @@ "details_balance_hide": "Hide Balance", "details_balance_show": "Show Balance", "details_copy": "Copy", - "details_copy_amount": "Copy Amount", "details_copy_block_explorer_link": "Copy Block Explorer Link", "details_copy_note": "Copy Note", "details_copy_txid": "Copy Transaction ID", @@ -486,9 +485,10 @@ "more_info": "More Info" }, "total_balance_view": { - "view_in_bitcoin": "View in Bitcoin", - "view_in_sats": "View in sats", - "view_in_fiat": "View in {currency}", + "display_in_bitcoin": "Display in Bitcoin", + "hide": "Hide", + "display_in_sats": "Display in sats", + "display_in_fiat": "Display in {currency}", "title": "Total Balance", "explanation": "View the total balance of all your wallets in the overview screen." }, diff --git a/loc/es_419.json b/loc/es_419.json index 8d6266086..5587d1a1e 100644 --- a/loc/es_419.json +++ b/loc/es_419.json @@ -486,9 +486,9 @@ "more_info": "Más información" }, "total_balance_view": { - "view_in_bitcoin": "Ver en Bitcoin", - "view_in_sats": "Ver en sats", - "view_in_fiat": "Ver en {currency}", + "display_in_bitcoin": "Ver en Bitcoin", + "display_in_sats": "Ver en sats", + "display_in_fiat": "Ver en {currency}", "title": "Balance Total", "explanation": "Ve el saldo total de todas tus billeteras en la pantalla de descripción general." }, diff --git a/loc/he.json b/loc/he.json index 0ca7ee250..95a4bd275 100644 --- a/loc/he.json +++ b/loc/he.json @@ -471,9 +471,9 @@ "more_info": "מידע נוסף" }, "total_balance_view": { - "view_in_bitcoin": "הצגה בביטקוין", - "view_in_sats": "הצגה בסאטושי", - "view_in_fiat": "הצגה ב- {currency}", + "display_in_bitcoin": "הצגה בביטקוין", + "display_in_sats": "הצגה בסאטושי", + "display_in_fiat": "הצגה ב- {currency}", "title": "יתרה כוללת", "explanation": "הצגת המאזן הכולל של כל הארנקים שלך במסך הכללי." }, diff --git a/loc/jp_jp.json b/loc/jp_jp.json index 410aba3a1..ffccdc6ec 100644 --- a/loc/jp_jp.json +++ b/loc/jp_jp.json @@ -483,9 +483,9 @@ "more_info": "詳細情報" }, "total_balance_view": { - "view_in_bitcoin": "ビットコインで表示", - "view_in_sats": "satsで表示", - "view_in_fiat": "{currency}で表示", + "display_in_bitcoin": "ビットコインで表示", + "display_in_sats": "satsで表示", + "display_in_fiat": "{currency}で表示", "title": "合計残高", "explanation": "すべてのウォレットの合計残高を概要画面に表示" }, diff --git a/loc/pl.json b/loc/pl.json index ecf42c72d..1bd9f3394 100644 --- a/loc/pl.json +++ b/loc/pl.json @@ -463,9 +463,9 @@ "more_info": "Więcej informacji" }, "total_balance_view": { - "view_in_bitcoin": "Pokaż w Bitcoinach", - "view_in_sats": "Pokaż w satsach", - "view_in_fiat": "Pokaż w {currency}", + "display_in_bitcoin": "Pokaż w Bitcoinach", + "display_in_sats": "Pokaż w satsach", + "display_in_fiat": "Pokaż w {currency}", "title": "Saldo całkowite", "explanation": "Wyświetl saldo całkowite wszystkich swoich portfeli na ekranie podglądu." }, diff --git a/loc/pt_br.json b/loc/pt_br.json index f03eec5da..2e4bf1e3a 100644 --- a/loc/pt_br.json +++ b/loc/pt_br.json @@ -463,9 +463,9 @@ "more_info": "Mais informações" }, "total_balance_view": { - "view_in_bitcoin": "Ver em Bitcoin", - "view_in_sats": "Ver em sats", - "view_in_fiat": "Ver em {currency}", + "display_in_bitcoin": "Ver em Bitcoin", + "display_in_sats": "Ver em sats", + "display_in_fiat": "Ver em {currency}", "title": "Saldo total", "explanation": "Veja o saldo total de todas as suas carteiras na tela pricinpal." }, diff --git a/loc/ru.json b/loc/ru.json index 3ee68b3be..e25aa407c 100644 --- a/loc/ru.json +++ b/loc/ru.json @@ -474,9 +474,9 @@ "more_info": "Подробнее" }, "total_balance_view": { - "view_in_bitcoin": "Показать в Bitcoin", - "view_in_sats": "Показать в сатоши", - "view_in_fiat": "Показать в {currency}", + "display_in_bitcoin": "Показать в Bitcoin", + "display_in_sats": "Показать в сатоши", + "display_in_fiat": "Показать в {currency}", "title": "Общий баланс", "explanation": "Просмотр общего баланса всех ваших кошельков на обзорном экране." }, diff --git a/typings/CommonToolTipActions.ts b/typings/CommonToolTipActions.ts index bd14e2074..345a698b3 100644 --- a/typings/CommonToolTipActions.ts +++ b/typings/CommonToolTipActions.ts @@ -43,6 +43,7 @@ const keys = { SignVerify: 'signVerify', ExportPrivateKey: 'exportPrivateKey', PasteFromClipboard: 'pasteFromClipboard', + Hide: 'hide', }; const icons: { [key: string]: { iconValue: string } } = { @@ -83,6 +84,7 @@ const icons: { [key: string]: { iconValue: string } } = { Signature: { iconValue: 'signature' }, PasteFromClipboard: { iconValue: 'document.on.clipboard' }, ImportFile: { iconValue: 'document.viewfinder' }, + Hide: { iconValue: 'eye.slash' }, }; export const CommonToolTipActions: { [key: string]: Action } = { @@ -108,7 +110,7 @@ export const CommonToolTipActions: { [key: string]: Action } = { }, CopyAmount: { id: keys.CopyAmount, - text: loc.transactions.details_copy_amount, + text: loc.transactions.details_copy, icon: icons.Clipboard, }, AddRecipient: { @@ -141,21 +143,26 @@ export const CommonToolTipActions: { [key: string]: Action } = { text: loc.transactions.details_balance_hide, icon: icons.EyeSlash, }, + Hide: { + id: keys.Hide, + text: loc.total_balance_view.hide, + icon: icons.EyeSlash, + }, ViewInFiat: { id: keys.ViewInFiat, - text: loc.total_balance_view.view_in_fiat, + text: loc.total_balance_view.display_in_fiat, icon: icons.ViewInFiat, hidden: false, }, ViewInSats: { id: keys.ViewInSats, - text: loc.total_balance_view.view_in_sats, + text: loc.total_balance_view.display_in_sats, icon: icons.ViewInBitcoin, hidden: false, }, ViewInBitcoin: { id: keys.ViewInBitcoin, - text: loc.total_balance_view.view_in_bitcoin, + text: loc.total_balance_view.display_in_bitcoin, icon: icons.ViewInBitcoin, hidden: false, },