import React, { useEffect, useCallback, useRef, useState } 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 { Search, Settings } from "lucide-react-native"; import { StyledButton } from "@/components/StyledButton"; import useHomeStore, { RowItem, Category } from "@/stores/homeStore"; 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 = "dark"; const flatListRef = useRef(null); const [selectedTag, setSelectedTag] = useState(null); const { categories, selectedCategory, contentData, loading, loadingMore, error, fetchInitialData, loadMoreData, selectCategory, refreshPlayRecords, } = useHomeStore(); useFocusEffect( useCallback(() => { refreshPlayRecords(); }, [refreshPlayRecords]) ); useEffect(() => { if (selectedCategory && !selectedCategory.tags) { fetchInitialData(); flatListRef.current?.scrollToOffset({ animated: false, offset: 0 }); } else if (selectedCategory?.tags && !selectedCategory.tag) { // Category with tags selected, but no specific tag yet. Select the first one. const defaultTag = selectedCategory.tags[0]; setSelectedTag(defaultTag); selectCategory({ ...selectedCategory, tag: defaultTag }); } }, [selectedCategory, fetchInitialData, selectCategory]); useEffect(() => { if (selectedCategory && selectedCategory.tag) { fetchInitialData(); flatListRef.current?.scrollToOffset({ animated: false, offset: 0 }); } }, [fetchInitialData, selectedCategory, selectedCategory.tag]); const handleCategorySelect = (category: Category) => { setSelectedTag(null); selectCategory(category); }; const handleTagSelect = (tag: string) => { setSelectedTag(tag); if (selectedCategory) { // Create a new category object with the selected tag const categoryWithTag = { ...selectedCategory, tag: tag }; selectCategory(categoryWithTag); } }; const renderCategory = ({ item }: { item: Category }) => { const isSelected = selectedCategory?.title === item.title; return ( handleCategorySelect(item)} isSelected={isSelected} style={styles.categoryButton} textStyle={styles.categoryText} /> ); }; const renderContentItem = ({ item }: { item: RowItem }) => ( ); const renderFooter = () => { if (!loadingMore) return null; return ; }; return ( {/* 顶部导航 */} 首页 router.push("/live")}> {({ focused }) => ( 直播 )} router.push({ pathname: "/search" })} variant="ghost" > router.push("/settings")} variant="ghost"> {/* 分类选择器 */} item.title} horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.categoryListContent} /> {/* Sub-category Tags */} {selectedCategory && selectedCategory.tags && ( { const isSelected = selectedTag === item; return ( handleTagSelect(item)} isSelected={isSelected} style={styles.categoryButton} textStyle={styles.categoryText} variant="ghost" /> ); }} keyExtractor={(item) => item} 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={ {selectedCategory?.tags ? "请选择一个子分类" : "该分类下暂无内容"} } /> )} ); } 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, }, // Category Selector categoryContainer: { paddingBottom: 6, }, categoryListContent: { paddingHorizontal: 16, }, categoryButton: { paddingHorizontal: 2, paddingVertical: 6, borderRadius: 8, marginHorizontal: 6, }, categoryText: { fontSize: 16, fontWeight: "500", }, // Content Grid listContent: { paddingHorizontal: 16, paddingBottom: 20, }, itemContainer: { margin: 8, width: ITEM_WIDTH, alignItems: "center", }, });