REF: Update balance view to new UX

This commit is contained in:
Marcos Rodriguez Velez 2024-03-31 12:33:25 -04:00
parent 04d1a239f3
commit 7f0c489968
No known key found for this signature in database
GPG key ID: 6030B2F48CCE86D7
7 changed files with 142 additions and 91 deletions

View file

@ -15,7 +15,6 @@ import {
TouchableOpacity,
View,
I18nManager,
ImageBackground,
} from 'react-native';
import Clipboard from '@react-native-clipboard/clipboard';
import NetworkTransactionFees, { NetworkTransactionFee, NetworkTransactionFeeType } from './models/networkTransactionFees';
@ -191,18 +190,6 @@ export const BlueButtonLink = forwardRef((props, ref) => {
);
});
export const BluePrivateBalance = () => {
return (
<View style={{ flexDirection: 'row', alignItems: 'center', marginTop: 13, borderRadius: 9 }}>
<ImageBackground
blurRadius={6}
style={{ backgroundColor: '#FFFFFF', opacity: 0.5, height: 30, width: 110, marginRight: 8, borderRadius: 9 }}
/>
<Icon name="eye-slash" type="font-awesome" color="#FFFFFF" />
</View>
);
};
export const BlueCard = props => {
return <View {...props} style={{ padding: 20 }} />;
};

View file

@ -0,0 +1,18 @@
import React from 'react';
import { ImageBackground, StyleSheet, View } from 'react-native';
import { Icon } from 'react-native-elements';
export const BlurredBalanceView = () => {
return (
<View style={styles.container}>
{/* @ts-ignore: We just want the blur effect. No source prop needed */}
<ImageBackground blurRadius={6} style={styles.background} />
<Icon name="eye-slash" type="font-awesome" color="#FFFFFF" />
</View>
);
};
const styles = StyleSheet.create({
container: { flexDirection: 'row', alignItems: 'center', borderRadius: 9 },
background: { backgroundColor: '#FFFFFF', opacity: 0.5, height: 30, width: 110, marginRight: 8, borderRadius: 9 },
});

View file

@ -41,6 +41,7 @@ const ToolTipMenu = (props, ref) => {
const isMenuPrimaryAction = props.isMenuPrimaryAction ? props.isMenuPrimaryAction : false;
const renderPreview = props.renderPreview ?? undefined;
const disabled = props.disabled ?? false;
const onPress = props.onPress ?? undefined;
const buttonStyle = props.buttonStyle;
return isButton ? (
@ -55,14 +56,11 @@ const ToolTipMenu = (props, ref) => {
menuTitle,
menuItems,
}}
style={buttonStyle}
onPress={onPress}
accessibilityRole="button"
>
{props.onPress ? (
<TouchableOpacity accessibilityRole="button" style={buttonStyle} onPress={props.onPress}>
{props.children}
</TouchableOpacity>
) : (
props.children
)}
{props.children}
</ContextMenuButton>
) : props.onPress ? (
<TouchableOpacity accessibilityRole="button" onPress={props.onPress}>

View file

@ -1,17 +1,17 @@
import React, { useState, useEffect, useRef, useContext, useCallback, useMemo } from 'react';
import { Image, Text, TouchableOpacity, View, I18nManager, StyleSheet } from 'react-native';
import { Image, Text, TouchableOpacity, View, I18nManager, StyleSheet, LayoutAnimation } from 'react-native';
import Clipboard from '@react-native-clipboard/clipboard';
import LinearGradient from 'react-native-linear-gradient';
import { HDSegwitBech32Wallet, LightningCustodianWallet, LightningLdkWallet, MultisigHDWallet } from '../class';
import { BitcoinUnit } from '../models/bitcoinUnits';
import WalletGradient from '../class/wallet-gradient';
import Biometric from '../class/biometrics';
import loc, { formatBalance } from '../loc';
import loc, { formatBalance, formatBalanceWithoutSuffix } from '../loc';
import { BlueStorageContext } from '../blue_modules/storage-context';
import ToolTipMenu from './TooltipMenu';
import { BluePrivateBalance } from '../BlueComponents';
import { FiatUnit } from '../models/fiatUnit';
import { TWallet } from '../class/wallets/types';
import { BlurredBalanceView } from './BlurredBalanceView';
interface TransactionsNavigationHeaderProps {
wallet: TWallet;
@ -87,6 +87,7 @@ const TransactionsNavigationHeader: React.FC<TransactionsNavigationHeaderProps>
}
const updatedWallet = updateWalletVisibility(wallet, !wallet.hideBalance);
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setWallet(updatedWallet);
saveToDisk();
};
@ -109,6 +110,8 @@ const TransactionsNavigationHeader: React.FC<TransactionsNavigationHeaderProps>
newWalletPreferredUnit = BitcoinUnit.BTC;
}
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
const updatedWallet = updateWalletWithNewUnit(wallet, newWalletPreferredUnit);
setWallet(updatedWallet);
onWalletUnitChange?.(updatedWallet);
@ -136,8 +139,11 @@ const TransactionsNavigationHeader: React.FC<TransactionsNavigationHeaderProps>
const balance = useMemo(() => {
const hideBalance = wallet.hideBalance;
const balanceUnit = wallet.getPreferredBalanceUnit();
const balanceFormatted = formatBalance(wallet.getBalance(), balanceUnit, true);
return !hideBalance && balanceFormatted?.toString();
const balanceFormatted =
balanceUnit === BitcoinUnit.LOCAL_CURRENCY
? formatBalance(wallet.getBalance(), balanceUnit, true)
: formatBalanceWithoutSuffix(wallet.getBalance(), balanceUnit, true);
return !hideBalance && balanceFormatted;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.hideBalance, wallet.getPreferredBalanceUnit()]);
@ -166,65 +172,79 @@ const TransactionsNavigationHeader: React.FC<TransactionsNavigationHeaderProps>
<Text testID="WalletLabel" numberOfLines={1} style={styles.walletLabel}>
{wallet.getLabel()}
</Text>
<ToolTipMenu
enableAndroidRipple={false}
onPress={changeWalletBalanceUnit}
ref={menuRef}
title={`${loc.wallets.balance} (${
wallet.getPreferredBalanceUnit() === BitcoinUnit.LOCAL_CURRENCY
? preferredFiatCurrency?.endPointKey ?? FiatUnit.USD
: wallet.getPreferredBalanceUnit()
})`}
onPressMenuItem={onPressMenuItem}
actions={
wallet.hideBalance
? [
{
id: 'walletBalanceVisibility',
text: loc.transactions.details_balance_show,
icon: {
iconType: 'SYSTEM',
iconValue: 'eye',
<View style={styles.walletBalanceAndUnitContainer}>
<ToolTipMenu
isMenuPrimaryAction
isButton
enableAndroidRipple={false}
ref={menuRef}
buttonStyle={styles.walletBalance}
title={`${loc.wallets.balance} (${
wallet.getPreferredBalanceUnit() === BitcoinUnit.LOCAL_CURRENCY
? preferredFiatCurrency?.endPointKey ?? FiatUnit.USD
: wallet.getPreferredBalanceUnit()
})`}
onPressMenuItem={onPressMenuItem}
actions={
wallet.hideBalance
? [
{
id: 'walletBalanceVisibility',
text: loc.transactions.details_balance_show,
icon: {
iconType: 'SYSTEM',
iconValue: 'eye',
},
},
},
]
: [
{
id: 'walletBalanceVisibility',
text: loc.transactions.details_balance_hide,
icon: {
iconType: 'SYSTEM',
iconValue: 'eye.slash',
]
: [
{
id: 'walletBalanceVisibility',
text: loc.transactions.details_balance_hide,
icon: {
iconType: 'SYSTEM',
iconValue: 'eye.slash',
},
},
},
{
id: 'copyToClipboard',
text: loc.transactions.details_copy,
icon: {
iconType: 'SYSTEM',
iconValue: 'doc.on.doc',
{
id: 'copyToClipboard',
text: loc.transactions.details_copy,
icon: {
iconType: 'SYSTEM',
iconValue: 'doc.on.doc',
},
},
},
]
}
>
<View style={styles.walletBalance}>
{wallet.hideBalance ? (
<BluePrivateBalance />
) : (
<Text
testID="WalletBalance"
// @ts-ignore: Ugh
key={balance} // force component recreation on balance change. To fix right-to-left languages, like Farsi
numberOfLines={1}
adjustsFontSizeToFit
style={styles.walletBalance}
>
{balance}
</Text>
)}
</View>
</ToolTipMenu>
]
}
>
<View style={styles.walletBalance}>
{wallet.hideBalance ? (
<BlurredBalanceView />
) : (
<TouchableOpacity>
<Text
testID="WalletBalance"
// @ts-ignore: Ugh
key={balance} // force component recreation on balance change. To fix right-to-left languages, like Farsi
numberOfLines={1}
adjustsFontSizeToFit
style={styles.walletBalanceText}
ellipsizeMode="middle"
>
{balance}
</Text>
</TouchableOpacity>
)}
</View>
</ToolTipMenu>
<TouchableOpacity style={styles.walletPreferredUnitView} onPress={changeWalletBalanceUnit}>
<Text style={styles.walletPreferredUnitText}>
{wallet.getPreferredBalanceUnit() === BitcoinUnit.LOCAL_CURRENCY
? preferredFiatCurrency?.endPointKey ?? FiatUnit.USD
: wallet.getPreferredBalanceUnit()}
</Text>
</TouchableOpacity>
</View>
{wallet.type === LightningCustodianWallet.type && allowOnchainAddress && (
<ToolTipMenu
isMenuPrimaryAction
@ -291,13 +311,11 @@ const styles = StyleSheet.create({
fontSize: 19,
color: '#fff',
writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr',
marginBottom: 10,
},
walletBalance: {
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 36,
color: '#fff',
writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr',
flexShrink: 1,
marginRight: 6,
},
manageFundsButton: {
marginTop: 14,
@ -315,6 +333,31 @@ const styles = StyleSheet.create({
color: '#FFFFFF',
padding: 12,
},
walletBalanceAndUnitContainer: {
flexDirection: 'row',
alignItems: 'center',
paddingRight: 10, // Ensure there's some padding to the right
},
walletBalanceText: {
color: '#fff',
fontWeight: 'bold',
fontSize: 36,
flexShrink: 1, // Allow the text to shrink if there's not enough space
},
walletPreferredUnitView: {
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(255, 255, 255, 0.25)',
borderRadius: 8,
paddingVertical: 5,
minHeight: 35,
minWidth: 65,
padding: 10, // Adjust padding as needed to fit the content
},
walletPreferredUnitText: {
color: '#fff',
fontWeight: '600',
},
});
export const actionKeys = {

View file

@ -19,10 +19,11 @@ import LinearGradient from 'react-native-linear-gradient';
import loc, { formatBalance, transactionTimeToReadable } from '../loc';
import { LightningCustodianWallet, LightningLdkWallet, MultisigHDWallet } from '../class';
import WalletGradient from '../class/wallet-gradient';
import { BluePrivateBalance } from '../BlueComponents';
import { BlueSpacing10 } from '../BlueComponents';
import { BlueStorageContext, WalletTransactionsStatus } from '../blue_modules/storage-context';
import { isTablet, isDesktop } from '../blue_modules/environment';
import { useTheme } from './themes';
import { BlurredBalanceView } from './BlurredBalanceView';
const nStyles = StyleSheet.create({
container: {
@ -218,7 +219,10 @@ export const WalletCarouselItem = ({ item, _, onPress, handleLongPress, isSelect
{item.getLabel()}
</Text>
{item.hideBalance ? (
<BluePrivateBalance />
<>
<BlueSpacing10 />
<BlurredBalanceView />
</>
) : (
<Text
numberOfLines={1}

View file

@ -1,6 +1,6 @@
export const BitcoinUnit = {
BTC: 'BTC',
SATS: 'sats',
SATS: 'Sats',
LOCAL_CURRENCY: 'local_currency',
MAX: 'MAX',
} as const;

View file

@ -3,7 +3,7 @@ import { View, ActivityIndicator, Image, Text, TouchableOpacity, I18nManager, Fl
import LinearGradient from 'react-native-linear-gradient';
import { useRoute, useNavigation, useNavigationState } from '@react-navigation/native';
import { BlueText, BlueSpacing20, BluePrivateBalance } from '../../BlueComponents';
import { BlueText, BlueSpacing20 } from '../../BlueComponents';
import navigationStyle from '../../components/navigationStyle';
import WalletGradient from '../../class/wallet-gradient';
import loc, { formatBalance, transactionTimeToReadable } from '../../loc';
@ -13,6 +13,7 @@ import { useTheme } from '../../components/themes';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
import SafeArea from '../../components/SafeArea';
import { Chain } from '../../models/bitcoinUnits';
import { BlurredBalanceView } from '../../components/BlurredBalanceView';
const SelectWallet = () => {
const { chainType, onWalletSelect, availableWallets, noWalletExplanationText, onChainRequireSend = false } = useRoute().params;
@ -167,7 +168,7 @@ const SelectWallet = () => {
{item.getLabel()}
</Text>
{item.hideBalance ? (
<BluePrivateBalance />
<BlurredBalanceView />
) : (
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.balance}>
{formatBalance(Number(item.getBalance()), item.getPreferredBalanceUnit(), true)}