import React, { useCallback, useEffect, useMemo, useState } from 'react'; import Clipboard from '@react-native-clipboard/clipboard'; import { I18nManager, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import LinearGradient from 'react-native-linear-gradient'; import { LightningCustodianWallet, MultisigHDWallet } from '../class'; import WalletGradient from '../class/wallet-gradient'; import { TWallet } from '../class/wallets/types'; import loc, { formatBalance, formatBalanceWithoutSuffix } from '../loc'; import { BitcoinUnit } from '../models/bitcoinUnits'; import { FiatUnit } from '../models/fiatUnit'; import { BlurredBalanceView } from './BlurredBalanceView'; import { useSettings } from '../hooks/context/useSettings'; import ToolTipMenu from './TooltipMenu'; import useAnimateOnChange from '../hooks/useAnimateOnChange'; interface TransactionsNavigationHeaderProps { wallet: TWallet; unit: BitcoinUnit; onWalletUnitChange: (unit: BitcoinUnit) => void; onManageFundsPressed?: (id?: string) => void; onWalletBalanceVisibilityChange?: (isShouldBeVisible: boolean) => void; } const TransactionsNavigationHeader: React.FC = ({ wallet: initialWallet, onWalletUnitChange, onManageFundsPressed, onWalletBalanceVisibilityChange, unit = BitcoinUnit.BTC, }) => { const [wallet, setWallet] = useState(initialWallet); const [allowOnchainAddress, setAllowOnchainAddress] = useState(false); const { preferredFiatCurrency } = useSettings(); const verifyIfWalletAllowsOnchainAddress = useCallback(() => { if (wallet.type === LightningCustodianWallet.type) { wallet .allowOnchainAddress() .then((value: boolean) => setAllowOnchainAddress(value)) .catch(() => { console.error('This LNDhub wallet does not have an onchain address API.'); setAllowOnchainAddress(false); }); } }, [wallet]); useEffect(() => { setWallet(initialWallet); }, [initialWallet]); useEffect(() => { verifyIfWalletAllowsOnchainAddress(); }, [wallet, verifyIfWalletAllowsOnchainAddress]); const handleCopyPress = useCallback(() => { const value = formatBalance(wallet.getBalance(), unit); if (value) { Clipboard.setString(value); } }, [unit, wallet]); const handleBalanceVisibility = useCallback(() => { onWalletBalanceVisibilityChange?.(!wallet.hideBalance); }, [onWalletBalanceVisibilityChange, wallet.hideBalance]); const changeWalletBalanceUnit = () => { let newWalletPreferredUnit = wallet.getPreferredBalanceUnit(); if (newWalletPreferredUnit === BitcoinUnit.BTC) { newWalletPreferredUnit = BitcoinUnit.SATS; } else if (newWalletPreferredUnit === BitcoinUnit.SATS) { newWalletPreferredUnit = BitcoinUnit.LOCAL_CURRENCY; } else { newWalletPreferredUnit = BitcoinUnit.BTC; } onWalletUnitChange(newWalletPreferredUnit); }; const handleManageFundsPressed = useCallback( (actionKeyID?: string) => { if (onManageFundsPressed) { onManageFundsPressed(actionKeyID); } }, [onManageFundsPressed], ); const onPressMenuItem = useCallback( (id: string) => { if (id === 'walletBalanceVisibility') { handleBalanceVisibility(); } else if (id === 'copyToClipboard') { handleCopyPress(); } }, [handleBalanceVisibility, handleCopyPress], ); const toolTipActions = useMemo(() => { return [ { id: actionKeys.Refill, text: loc.lnd.refill, icon: actionIcons.Refill, }, { id: actionKeys.RefillWithExternalWallet, text: loc.lnd.refill_external, icon: actionIcons.RefillWithExternalWallet, }, ]; }, []); const balance = useMemo(() => { const hideBalance = wallet.hideBalance; const balanceFormatted = unit === BitcoinUnit.LOCAL_CURRENCY ? formatBalance(wallet.getBalance(), unit, true) : formatBalanceWithoutSuffix(wallet.getBalance(), unit, true); return !hideBalance && balanceFormatted; }, [unit, wallet]); const toolTipWalletBalanceActions = useMemo(() => { return wallet.hideBalance ? [ { id: 'walletBalanceVisibility', text: loc.transactions.details_balance_show, icon: { iconValue: 'eye', }, }, ] : [ { id: 'walletBalanceVisibility', text: loc.transactions.details_balance_hide, icon: { iconValue: 'eye.slash', }, }, { id: 'copyToClipboard', text: loc.transactions.details_copy, icon: { iconValue: 'doc.on.doc', }, }, ]; }, [wallet.hideBalance]); const imageSource = useMemo(() => { switch (wallet.type) { case LightningCustodianWallet.type: return I18nManager.isRTL ? require('../img/lnd-shape-rtl.png') : require('../img/lnd-shape.png'); case MultisigHDWallet.type: return I18nManager.isRTL ? require('../img/vault-shape-rtl.png') : require('../img/vault-shape.png'); default: return I18nManager.isRTL ? require('../img/btc-shape-rtl.png') : require('../img/btc-shape.png'); } }, [wallet.type]); useAnimateOnChange(balance); useAnimateOnChange(wallet.hideBalance); useAnimateOnChange(unit); useAnimateOnChange(wallet.getID?.()); return ( {wallet.getLabel()} {wallet.hideBalance ? ( ) : ( {balance} )} {unit === BitcoinUnit.LOCAL_CURRENCY ? (preferredFiatCurrency?.endPointKey ?? FiatUnit.USD) : unit} {wallet.type === LightningCustodianWallet.type && allowOnchainAddress && ( {loc.lnd.title} )} {wallet.type === MultisigHDWallet.type && ( handleManageFundsPressed()}> {loc.multisig.manage_keys} )} ); }; const styles = StyleSheet.create({ lineaderGradient: { padding: 15, minHeight: 140, justifyContent: 'center', }, chainIcon: { width: 99, height: 94, position: 'absolute', bottom: 0, right: 0, }, walletLabel: { backgroundColor: 'transparent', fontSize: 19, color: '#fff', writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr', marginBottom: 10, }, walletBalance: { flexShrink: 1, marginRight: 6, }, manageFundsButton: { marginTop: 14, marginBottom: 10, backgroundColor: 'rgba(255,255,255,0.2)', borderRadius: 9, minHeight: 39, alignSelf: 'flex-start', justifyContent: 'center', alignItems: 'center', }, manageFundsButtonText: { fontWeight: '500', fontSize: 14, 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, minHeight: 35, minWidth: 65, }, walletPreferredUnitText: { color: '#fff', fontWeight: '600', }, }); export const actionKeys = { CopyToClipboard: 'copyToClipboard', WalletBalanceVisibility: 'walletBalanceVisibility', Refill: 'refill', RefillWithExternalWallet: 'refillWithExternalWallet', }; export const actionIcons = { Eye: { iconValue: 'eye', }, EyeSlash: { iconValue: 'eye.slash', }, Clipboard: { iconValue: 'doc.on.doc', }, Refill: { iconValue: 'goforward.plus', }, RefillWithExternalWallet: { iconValue: 'qrcode', }, }; export default TransactionsNavigationHeader;