Merge pull request #7268 from BlueWallet/totlview

REF: Optimize totalwalletsbalance view
This commit is contained in:
GLaDOS 2024-11-09 12:13:15 +00:00 committed by GitHub
commit d943a21d2f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 134 additions and 115 deletions

View File

@ -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.resolvedOptions().locale !== preferredFiatCurrency.locale) {
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<void> {
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<void> {
@ -79,7 +116,10 @@ async function updateExchangeRate(): Promise<void> {
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<CurrencyRate> {
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,
};

View File

@ -209,7 +209,8 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = React.m
};
loadSettings();
}, [languageStorage]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
if (walletsInitialized) {

View File

@ -23,54 +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 totalBalance = useMemo(() => {
return wallets.reduce((prev, curr) => {
if (!curr.hideBalance) {
const balance = curr.getBalance();
return prev + (typeof balance === 'number' ? balance : 0);
}
return prev;
const totalBalanceFormatted = useMemo(() => {
const totalBalance = wallets.reduce((prev, curr) => {
return curr.hideBalance ? prev : prev + (curr.getBalance() || 0);
}, 0);
}, [wallets]);
const formattedBalance = useMemo(() => {
return formatBalanceWithoutSuffix(totalBalance, totalBalancePreferredUnit, true);
}, [totalBalance, totalBalancePreferredUnit]);
}, [wallets, 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,
};
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) => {
@ -85,36 +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;
}
},
[setIsTotalBalanceEnabledStorage, formattedBalance, setTotalBalancePreferredUnitStorage],
[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 (
@ -122,10 +96,10 @@ const TotalWalletsBalance: React.FC = React.memo(() => {
<View style={styles.container}>
<Text style={styles.label}>{loc.wallets.total_balance}</Text>
<TouchableOpacity onPress={handleBalanceOnPress}>
<Text style={[styles.balance, styleHooks.balance]}>
{formattedBalance}{' '}
<Text style={[styles.balance, { color: colors.foregroundColor }]}>
{totalBalanceFormatted}{' '}
{totalBalancePreferredUnit !== BitcoinUnit.LOCAL_CURRENCY && (
<Text style={[styles.currency, styleHooks.currency]}>{totalBalancePreferredUnit}</Text>
<Text style={[styles.currency, { color: colors.foregroundColor }]}>{totalBalancePreferredUnit}</Text>
)}
</Text>
</TouchableOpacity>
@ -148,12 +122,10 @@ const styles = StyleSheet.create({
balance: {
fontSize: 32,
fontWeight: 'bold',
color: '#1D2B53',
},
currency: {
fontSize: 18,
fontWeight: 'bold',
color: '#1D2B53',
},
});

View File

@ -301,7 +301,7 @@
}
}
},
"VIEW_IN_BROWSER_TITLE" : {
"display_in_BROWSER_TITLE" : {
"localizations" : {
"en_US" : {
"stringUnit" : {

View File

@ -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."
},

View File

@ -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."
},

View File

@ -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",
@ -487,9 +486,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."
},

View File

@ -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."
},

View File

@ -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": "הצגת המאזן הכולל של כל הארנקים שלך במסך הכללי."
},

View File

@ -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": "すべてのウォレットの合計残高を概要画面に表示"
},

View File

@ -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."
},

View File

@ -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."
},

View File

@ -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": "Просмотр общего баланса всех ваших кошельков на обзорном экране."
},

View File

@ -44,6 +44,7 @@ const keys = {
SignVerify: 'signVerify',
ExportPrivateKey: 'exportPrivateKey',
PasteFromClipboard: 'pasteFromClipboard',
Hide: 'hide',
};
const icons: { [key: string]: { iconValue: string } } = {
@ -84,6 +85,7 @@ const icons: { [key: string]: { iconValue: string } } = {
Signature: { iconValue: 'signature' },
PasteFromClipboard: { iconValue: 'document.on.clipboard' },
ImportFile: { iconValue: 'document.viewfinder' },
Hide: { iconValue: 'eye.slash' },
ClearClipboard: { iconValue: 'clipboard' },
};
@ -110,7 +112,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: {
@ -143,21 +145,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,
},