import React, { useEffect, useState, useRef } from 'react'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { Platform, Modal, View, StyleSheet, Text, TouchableOpacity, Animated, Keyboard } from 'react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; import Ionicons from '@expo/vector-icons/Ionicons'; import { useNavigation, useRoute, useIsFocused } from '@react-navigation/native'; import type { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { RootStackParamList } from '../types/navigation'; import { useAuth } from '../contexts/AuthContext'; import { useTranslation } from 'react-i18next'; import useUserStore from '../store/user'; import { HomeScreen } from '../screens/HomeScreen'; import { CategoryScreen } from '../screens/CategoryScreen'; import { ChatScreen } from '../screens/ChatScreen'; import { CartScreen } from '../screens/CartScreen'; import { ProfileScreen } from '../screens/ProfileScreen'; type IconProps = { name: string; size: number; color: string; }; const IconComponent = ({ name, size, color }: IconProps) => { const Icon = Ionicons as any; return ; }; type TabBarIconProps = { color: string; size: number; }; const Tab = createBottomTabNavigator(); export const TabNavigator = () => { const { t } = useTranslation(); const navigation = useNavigation>(); const route = useRoute(); const { isLoggedIn } = useAuth(); const { user } = useUserStore(); const [showLoginPrompt, setShowLoginPrompt] = useState(false); const [keyboardVisible, setKeyboardVisible] = useState(false); const [promptShownBefore, setPromptShownBefore] = useState(false); const [currentTab, setCurrentTab] = useState(''); const isFocused = useIsFocused(); // 动画值 const fadeAnim = useRef(new Animated.Value(0)).current; const slideAnim = useRef(new Animated.Value(300)).current; // 监听键盘事件 useEffect(() => { const keyboardDidShowListener = Keyboard.addListener( 'keyboardDidShow', () => { setKeyboardVisible(true); } ); const keyboardDidHideListener = Keyboard.addListener( 'keyboardDidHide', () => { setKeyboardVisible(false); } ); return () => { keyboardDidHideListener.remove(); keyboardDidShowListener.remove(); }; }, []); // 检查是否已经显示过弹窗 useEffect(() => { const checkPromptShown = async () => { try { const value = await AsyncStorage.getItem('loginPromptShown'); setPromptShownBefore(value === 'true'); } catch (error) { console.error('Error checking prompt status:', error); } }; checkPromptShown(); }, []); // 监听当前tab页面变化及用户登录状态,决定是否显示登录提示 useEffect(() => { if (isFocused && (currentTab === 'Home' || currentTab === 'Cart')) { if (!user?.user_id && !promptShownBefore) { showLoginModal(); } } }, [currentTab, user?.user_id, isFocused, promptShownBefore]); const showLoginModal = () => { setShowLoginPrompt(true); Animated.parallel([ Animated.timing(fadeAnim, { toValue: 1, duration: 200, useNativeDriver: true, }), Animated.timing(slideAnim, { toValue: 0, duration: 200, useNativeDriver: true, }) ]).start(); }; const handleCloseModal = async () => { Animated.parallel([ Animated.timing(fadeAnim, { toValue: 0, duration: 200, useNativeDriver: true, }), Animated.timing(slideAnim, { toValue: 300, duration: 200, useNativeDriver: true, }) ]).start(() => { setShowLoginPrompt(false); }); // 记录已经显示过登录提示 try { await AsyncStorage.setItem('loginPromptShown', 'true'); setPromptShownBefore(true); } catch (error) { console.error('Error saving prompt status:', error); } }; const handleGoToLogin = () => { handleCloseModal(); navigation.navigate('Login'); }; return ( <> ({ focus: () => { setCurrentTab(route.name); }, })} > ( ), }} /> ( ), }} /> ( ), }} /> ( ), }} /> ( ), }} /> {showLoginPrompt && ( × {t('login.loginRequired')} {t('login.loginPrompt')} {t('login.loginNow')} )} ); }; const styles = StyleSheet.create({ modalContainer: { flex: 1, justifyContent: 'flex-end', }, modalOverlay: { ...StyleSheet.absoluteFillObject, backgroundColor: 'rgba(0, 0, 0, 0.5)', }, modalOverlayTouch: { flex: 1, }, modalContent: { backgroundColor: '#fff', borderTopLeftRadius: 24, borderTopRightRadius: 24, paddingHorizontal: 20, paddingBottom: Platform.OS === 'ios' ? 40 : 20, position: 'relative', }, closeButton: { position: 'absolute', top: 20, right: 20, width: 24, height: 24, justifyContent: 'center', alignItems: 'center', zIndex: 1, }, closeButtonText: { fontSize: 20, color: '#999', }, modalHeader: { alignItems: 'center', paddingTop: 12, paddingBottom: 20, }, modalIndicator: { width: 40, height: 4, backgroundColor: '#E0E0E0', borderRadius: 2, }, modalTitle: { fontSize: 20, fontWeight: '600', color: '#000', textAlign: 'center', marginBottom: 12, }, modalText: { fontSize: 16, color: '#666', textAlign: 'center', marginBottom: 24, lineHeight: 22, }, modalButton: { backgroundColor: '#0066FF', height: 50, borderRadius: 25, justifyContent: 'center', alignItems: 'center', }, modalButtonText: { color: '#fff', fontSize: 16, fontWeight: '600', }, });