import { useIsFocused } from '@react-navigation/native' import { NativeStackScreenProps } from '@react-navigation/native-stack' import _ from 'lodash' import React, { useEffect } from 'react' import { useTranslation } from 'react-i18next' import { FlatList, RefreshControl, RefreshControlProps, StyleSheet } from 'react-native' import Animated from 'react-native-reanimated' import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context' import { showMessage } from 'src/alert/actions' import { AppState } from 'src/app/actions' import { appStateSelector, phoneNumberVerifiedSelector, showNotificationSpotlightSelector, } from 'src/app/selectors' import { ALERT_BANNER_DURATION, DEFAULT_TESTNET, SHOW_TESTNET_BANNER } from 'src/config' import ActionsCarousel from 'src/home/ActionsCarousel' import NotificationBox from 'src/home/NotificationBox' import { refreshAllBalances, visitHome } from 'src/home/actions' import NftCelebration from 'src/home/celebration/NftCelebration' import NftReward from 'src/home/celebration/NftReward' import { balancesLoadingSelector, showNftCelebrationSelector, showNftRewardSelector, } from 'src/home/selectors' import { importContacts } from 'src/identity/actions' import { Screens } from 'src/navigator/Screens' import { StackParamList } from 'src/navigator/types' import { phoneRecipientCacheSelector } from 'src/recipients/reducer' import { useDispatch, useSelector } from 'src/redux/hooks' import { initializeSentryUserContext } from 'src/sentry/actions' import { getFeatureGate } from 'src/statsig' import { StatsigFeatureGates } from 'src/statsig/types' import colors from 'src/styles/colors' import TransactionFeed from 'src/transactions/feed/TransactionFeed' import TransactionFeedV2 from 'src/transactions/feed/TransactionFeedV2' import { hasGrantedContactsPermission } from 'src/utils/contacts' const AnimatedFlatList = Animated.createAnimatedComponent(FlatList) type Props = NativeStackScreenProps function TabHome(_props: Props) { const { t } = useTranslation() const appState = useSelector(appStateSelector) const isLoading = useSelector(balancesLoadingSelector) const recipientCache = useSelector(phoneRecipientCacheSelector) const isNumberVerified = useSelector(phoneNumberVerifiedSelector) const showNotificationSpotlight = useSelector(showNotificationSpotlightSelector) const insets = useSafeAreaInsets() const dispatch = useDispatch() const isFocused = useIsFocused() const canShowNftCelebration = useSelector(showNftCelebrationSelector) const showNftCelebration = canShowNftCelebration && isFocused && !showNotificationSpotlight const canShowNftReward = useSelector(showNftRewardSelector) const showNftReward = canShowNftReward && isFocused && !showNotificationSpotlight const showZerionTransactionFeed = getFeatureGate(StatsigFeatureGates.SHOW_ZERION_TRANSACTION_FEED) useEffect(() => { dispatch(visitHome()) }, []) const showTestnetBanner = () => { dispatch( showMessage( t('testnetAlert.1', { testnet: _.startCase(DEFAULT_TESTNET) }), ALERT_BANNER_DURATION, null, null, t('testnetAlert.0', { testnet: _.startCase(DEFAULT_TESTNET) }) ) ) } const tryImportContacts = async () => { // Skip if contacts have already been imported or the user hasn't verified their phone number. if (Object.keys(recipientCache).length || !isNumberVerified) { return } const contactPermissionStatusGranted = await hasGrantedContactsPermission() if (contactPermissionStatusGranted) { dispatch(importContacts()) } } useEffect(() => { // TODO find a better home for this, its unrelated to wallet home dispatch(initializeSentryUserContext()) if (SHOW_TESTNET_BANNER) { showTestnetBanner() } // Waiting 1/2 sec before triggering to allow // rest of feed to load unencumbered setTimeout(tryImportContacts, 500) }, []) useEffect(() => { if (appState === AppState.Active) { dispatch(refreshAllBalances()) } }, [appState]) const onRefresh = async () => { dispatch(refreshAllBalances()) } const keyExtractor = (_item: any, index: number) => { return index.toString() } const refresh: React.ReactElement = ( ) as React.ReactElement const flatListSections = [ { key: 'ActionsCarousel', component: , }, { key: 'NotificationBox', component: , }, { key: 'TransactionFeed', component: , }, ] const renderItem = ({ item }: { item: any }) => item.component return ( {showZerionTransactionFeed ? ( ) : ( )} {showNftCelebration && } {showNftReward && } ) } const styles = StyleSheet.create({ container: { flex: 1, position: 'relative', }, }) export default TabHome