import React, { useRef, useCallback, useImperativeHandle, forwardRef, useContext } from 'react'; import PropTypes from 'prop-types'; import { Animated, Image, I18nManager, Platform, StyleSheet, Text, TouchableOpacity, useWindowDimensions, View, Dimensions, FlatList, Pressable, } from 'react-native'; 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 { BlueStorageContext } from '../blue_modules/storage-context'; import { isTablet, isDesktop } from '../blue_modules/environment'; import { useTheme } from './themes'; const nStyles = StyleSheet.create({ container: { 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(); const { width } = useWindowDimensions(); const itemWidth = width * 0.82 > 375 ? 375 : width * 0.82; const isLargeScreen = Platform.OS === 'android' ? isTablet() : (width >= Dimensions.get('screen').width / 2 && isTablet()) || isDesktop; const nStylesHooks = StyleSheet.create({ container: isLargeScreen ? { paddingHorizontal: 24, marginVertical: 16, } : { paddingVertical: 16, paddingHorizontal: 24 }, }); 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: 20 }, rootLargeDevice: { marginVertical: 20 }, 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', }, 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, _, onPress, handleLongPress, isSelectedWallet }) => { const scaleValue = new Animated.Value(1.0); const { colors } = useTheme(); const { walletTransactionUpdateStatus } = useContext(BlueStorageContext); const { width } = useWindowDimensions(); const itemWidth = width * 0.82 > 375 ? 375 : width * 0.82; const isLargeScreen = Platform.OS === 'android' ? isTablet() : (width >= Dimensions.get('screen').width / 2 && isTablet()) || isDesktop; const onPressedIn = () => { Animated.spring(scaleValue, { duration: 50, useNativeDriver: true, toValue: 0.9 }).start(); }; const onPressedOut = () => { Animated.spring(scaleValue, { duration: 50, useNativeDriver: true, toValue: 1.0 }).start(); }; const opacity = isSelectedWallet === false ? 0.5 : 1.0; let image; switch (item.type) { case LightningLdkWallet.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(); setTimeout(() => { onPress(item); // Replace 'onPress' with your navigation function }, 50); }} > {item.getLabel()} {item.hideBalance ? ( ) : ( {balance} )} {loc.wallets.list_latest_transaction} {latestTransactionText} ); }; WalletCarouselItem.propTypes = { item: PropTypes.any, onPress: PropTypes.func.isRequired, handleLongPress: PropTypes.func.isRequired, isSelectedWallet: PropTypes.bool, }; const cStyles = StyleSheet.create({ content: { paddingTop: 16, }, contentLargeScreen: { paddingHorizontal: 16, }, separatorStyle: { width: 16, height: 20, }, }); const ListHeaderComponent = () => ; const WalletsCarousel = forwardRef((props, ref) => { const { preferredFiatCurrency, language } = useContext(BlueStorageContext); const { horizontal, data, handleLongPress, onPress, selectedWallet } = props; const renderItem = useCallback( ({ item, index }) => item ? ( ) : ( ), // eslint-disable-next-line react-hooks/exhaustive-deps [horizontal, selectedWallet, handleLongPress, onPress, preferredFiatCurrency, language], ); const flatListRef = useRef(); useImperativeHandle(ref, () => ({ scrollToItem: ({ item }) => { setTimeout(() => { flatListRef?.current?.scrollToItem({ item, viewOffset: 16 }); }, 300); }, scrollToIndex: ({ index }) => { setTimeout(() => { flatListRef?.current?.scrollToIndex({ index, viewOffset: 16 }); }, 300); }, })); const onScrollToIndexFailed = error => { console.log('onScrollToIndexFailed'); console.log(error); flatListRef.current.scrollToOffset({ offset: error.averageItemLength * error.index, animated: true }); setTimeout(() => { if (data.length !== 0 && flatListRef.current !== null) { flatListRef.current.scrollToIndex({ index: error.index, animated: true }); } }, 100); }; const { width } = useWindowDimensions(); const sliderHeight = 195; const itemWidth = width * 0.82 > 375 ? 375 : width * 0.82; return horizontal ? ( index.toString()} showsVerticalScrollIndicator={false} pagingEnabled disableIntervalMomentum={horizontal} snapToInterval={itemWidth} // Adjust to your content width decelerationRate="fast" contentContainerStyle={cStyles.content} directionalLockEnabled showsHorizontalScrollIndicator={false} initialNumToRender={10} ListHeaderComponent={ListHeaderComponent} style={{ minHeight: sliderHeight + 9 }} onScrollToIndexFailed={onScrollToIndexFailed} {...props} /> ) : ( {data.map((item, index) => item ? ( ) : ( ), )} ); }); WalletsCarousel.propTypes = { horizontal: PropTypes.bool, selectedWallet: PropTypes.string, onPress: PropTypes.func.isRequired, handleLongPress: PropTypes.func.isRequired, data: PropTypes.array, }; export default WalletsCarousel;