import React, { useEffect, useCallback, useRef } from 'react'; import { View, StyleSheet, ActivityIndicator, FlatList, Pressable, Dimensions } from 'react-native'; import { ThemedView } from '@/components/ThemedView'; import { ThemedText } from '@/components/ThemedText'; import { api } from '@/services/api'; import VideoCard from '@/components/VideoCard.tv'; import { useFocusEffect, useRouter } from 'expo-router'; import { useColorScheme } from 'react-native'; import { Search, Settings } from 'lucide-react-native'; import { SettingsModal } from '@/components/SettingsModal'; import useHomeStore, { RowItem, Category } from '@/stores/homeStore'; import { useSettingsStore } from '@/stores/settingsStore'; const NUM_COLUMNS = 5; const { width } = Dimensions.get('window'); const ITEM_WIDTH = width / NUM_COLUMNS - 24; export default function HomeScreen() { const router = useRouter(); const colorScheme = useColorScheme(); const flatListRef = useRef(null); const { categories, selectedCategory, contentData, loading, loadingMore, error, fetchInitialData, loadMoreData, selectCategory, refreshPlayRecords, } = useHomeStore(); const showSettingsModal = useSettingsStore(state => state.showModal); useFocusEffect( useCallback(() => { refreshPlayRecords(); }, [refreshPlayRecords]) ); useEffect(() => { fetchInitialData(); flatListRef.current?.scrollToOffset({ animated: false, offset: 0 }); }, [selectedCategory, fetchInitialData]); const handleCategorySelect = (category: Category) => { selectCategory(category); }; const renderCategory = ({ item }: { item: Category }) => { const isSelected = selectedCategory?.title === item.title; return ( [ styles.categoryButton, isSelected && styles.categoryButtonSelected, focused && styles.categoryButtonFocused, ]} onPress={() => handleCategorySelect(item)} > {item.title} ); }; const renderContentItem = ({ item }: { item: RowItem }) => ( ); const renderFooter = () => { if (!loadingMore) return null; return ; }; return ( {/* 顶部导航 */} 首页 [styles.searchButton, focused && styles.searchButtonFocused]} onPress={() => router.push({ pathname: '/search' })} > [styles.searchButton, focused && styles.searchButtonFocused]} onPress={showSettingsModal} > {/* 分类选择器 */} item.title} horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.categoryListContent} /> {/* 内容网格 */} {loading ? ( ) : error ? ( {error} ) : ( `${item.source}-${item.id}-${index}`} numColumns={NUM_COLUMNS} contentContainerStyle={styles.listContent} onEndReached={loadMoreData} onEndReachedThreshold={0.5} ListFooterComponent={renderFooter} ListEmptyComponent={ 该分类下暂无内容 } /> )} ); } const styles = StyleSheet.create({ container: { flex: 1, paddingTop: 40, }, centerContainer: { flex: 1, paddingTop: 20, justifyContent: 'center', alignItems: 'center', }, // Header headerContainer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingHorizontal: 24, marginBottom: 10, }, headerTitle: { fontSize: 32, fontWeight: 'bold', paddingTop: 16, }, rightHeaderButtons: { flexDirection: 'row', alignItems: 'center', }, searchButton: { padding: 10, borderRadius: 30, marginLeft: 10, }, searchButtonFocused: { backgroundColor: '#007AFF', transform: [{ scale: 1.1 }], }, // Category Selector categoryContainer: { paddingBottom: 10, }, categoryListContent: { paddingHorizontal: 16, }, categoryButton: { paddingHorizontal: 12, paddingVertical: 6, borderRadius: 8, marginHorizontal: 5, }, categoryButtonSelected: { backgroundColor: '#007AFF', // A bright blue for selected state }, categoryButtonFocused: { backgroundColor: '#0056b3', // A darker blue for focused state elevation: 5, }, categoryText: { fontSize: 16, fontWeight: '500', }, categoryTextSelected: { color: '#FFFFFF', }, // Content Grid listContent: { paddingHorizontal: 16, paddingBottom: 20, }, itemContainer: { margin: 8, width: ITEM_WIDTH, alignItems: 'center', }, });