import React, { useRef, useCallback, useState, useImperativeHandle, forwardRef, useContext } from 'react'; import PropTypes from 'prop-types'; import { ActivityIndicator, Animated, Image, I18nManager, Platform, StyleSheet, Text, TouchableOpacity, TouchableWithoutFeedback, useWindowDimensions, View, } from 'react-native'; import { useTheme } from '@react-navigation/native'; import LinearGradient from 'react-native-linear-gradient'; import Carousel from 'react-native-snap-carousel'; import loc, { formatBalance, transactionTimeToReadable } from '../loc'; import { LightningCustodianWallet, MultisigHDWallet, PlaceholderWallet } from '../class'; import WalletGradient from '../class/wallet-gradient'; import { BluePrivateBalance } from '../BlueComponents'; import { BlueStorageContext } from '../blue_modules/storage-context'; const nStyles = StyleSheet.create({ root: { marginVertical: 17, paddingRight: 10, }, container: { paddingHorizontal: 24, paddingVertical: 16, borderRadius: 10, minHeight: Platform.OS === 'ios' ? 164 : 181, justifyContent: 'center', alignItems: 'flex-start', }, addAWAllet: { fontWeight: '600', fontSize: 24, marginBottom: 4, }, addLine: { fontSize: 13, }, button: { marginTop: 12, backgroundColor: '#007AFF', paddingHorizontal: 32, paddingVertical: 12, borderRadius: 8, }, buttonText: { fontWeight: '500', }, }); const NewWalletPanel = ({ onPress }) => { const { colors } = useTheme(); return ( {loc.wallets.list_create_a_wallet} {loc.wallets.list_create_a_wallet_text} {loc.wallets.list_create_a_button} ); }; NewWalletPanel.propTypes = { onPress: PropTypes.func.isRequired, }; const iStyles = StyleSheet.create({ root: { paddingRight: 10, marginVertical: 17, }, grad: { padding: 15, borderRadius: 12, minHeight: 164, elevation: 5, }, image: { width: 99, height: 94, position: 'absolute', bottom: 0, right: 0, }, br: { backgroundColor: 'transparent', }, label: { backgroundColor: 'transparent', fontSize: 19, writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr', }, importError: { backgroundColor: 'transparent', fontSize: 19, marginTop: 40, }, activity: { marginTop: 40, }, balance: { backgroundColor: 'transparent', fontWeight: 'bold', fontSize: 36, writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr', }, latestTx: { backgroundColor: 'transparent', fontSize: 13, writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr', }, latestTxTime: { backgroundColor: 'transparent', fontWeight: 'bold', writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr', fontSize: 16, }, }); 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 }; props.useNativeDriver = true; props.toValue = 0.9; Animated.spring(scaleValue, props).start(); }; const onPressedOut = () => { const props = { duration: 50 }; props.useNativeDriver = true; props.toValue = 1.0; Animated.spring(scaleValue, props).start(); }; if (!item) return ( { onPressedOut(); onPress(index); }} /> ); if (item.type === PlaceholderWallet.type) { return ( { if (item.getIsFailure()) { onPressedOut(); onPress(index); onPressedOut(); } }} > {item.getIsFailure() ? loc.wallets.import_placeholder_fail : loc.wallets.import_placeholder_inprogress} {item.getIsFailure() ? ( {loc.wallets.list_import_error} ) : ( )} ); } const opacity = isSelectedWallet === false ? 0.5 : 1.0; let image; switch (item.type) { case LightningCustodianWallet.type: image = I18nManager.isRTL ? require('../img/lnd-shape-rtl.png') : require('../img/lnd-shape.png'); break; case MultisigHDWallet.type: image = I18nManager.isRTL ? require('../img/vault-shape-rtl.png') : require('../img/vault-shape.png'); break; default: image = I18nManager.isRTL ? require('../img/btc-shape-rtl.png') : 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()); const balance = !item.hideBalance && formatBalance(Number(item.getBalance()), item.getPreferredBalanceUnit(), true); return ( { onPressedOut(); onPress(index); onPressedOut(); }} > {item.getLabel()} {item.hideBalance ? ( ) : ( {balance} )} {loc.wallets.list_latest_transaction} {latestTransactionText} ); }; WalletCarouselItem.propTypes = { item: PropTypes.any, index: PropTypes.number.isRequired, onPress: PropTypes.func.isRequired, handleLongPress: PropTypes.func.isRequired, isSelectedWallet: PropTypes.bool, }; const cStyles = StyleSheet.create({ loading: { position: 'absolute', alignItems: 'center', }, content: { left: 16, flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row', }, }); const WalletsCarousel = forwardRef((props, ref) => { const carouselRef = useRef(); const [loading, setLoading] = useState(true); const { preferredFiatCurrency, language } = useContext(BlueStorageContext); const renderItem = useCallback( ({ item, index }) => ( ), // eslint-disable-next-line react-hooks/exhaustive-deps [props.vertical, props.selectedWallet, props.handleLongPress, props.onPress, preferredFiatCurrency, language], ); useImperativeHandle(ref, () => ({ snapToItem: item => carouselRef?.current?.snapToItem(item), })); const { width } = useWindowDimensions(); const sliderWidth = width * 1; const itemWidth = width * 0.82 > 375 ? 375 : width * 0.82; const sliderHeight = 190; const onLayout = () => setLoading(false); return ( <> {loading && ( )} ); }); WalletsCarousel.propTypes = { vertical: PropTypes.bool, selectedWallet: PropTypes.string, onPress: PropTypes.func.isRequired, handleLongPress: PropTypes.func.isRequired, }; export default WalletsCarousel;