import { useRouter } from "expo-router"; import React, { useCallback, useEffect, useMemo, useRef, useState, } from "react"; import { ActivityIndicator, FlatList, RefreshControl, StatusBar, StyleSheet, Text, View, } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { KefuPopup, KefuPopupRef } from "@/components/mine/KefuPopup"; import { Banner } from "@/components/home/Banner"; import { GoodsCard } from "@/components/home/GoodsCard"; import { IPFilter } from "@/components/home/IPFilter"; import { QuickEntry } from "@/components/home/QuickEntry"; import { SearchBar } from "@/components/home/SearchBar"; import { Colors } from "@/constants/Colors"; // Import Colors // API 服务 import { getIPList, IPItem } from "@/services/award"; import { BannerItem, getPageConfig, TabItem } from "@/services/base"; import { getGoodsList, GoodsItem, GoodsListParams } from "@/services/mall"; export default function HomeScreen() { const insets = useSafeAreaInsets(); const router = useRouter(); const kefuRef = useRef(null); const [refreshing, setRefreshing] = useState(false); const [loading, setLoading] = useState(true); const [listLoading, setListLoading] = useState(false); // 数据状态 const [goods, setGoods] = useState([]); const [banners, setBanners] = useState([]); const [tabs, setTabs] = useState([]); const [ipList, setIpList] = useState([]); const [ipIndex, setIpIndex] = useState(0); // 搜索参数 const [searchParams, setSearchParams] = useState({ current: 1, size: 15, keyword: "", worksId: "", }); // 加载商品列表 const loadGoods = useCallback( async (params: GoodsListParams, append = false) => { try { if (!append) setListLoading(true); const data = await getGoodsList(params); if (append) { setGoods((prev) => [...prev, ...data]); } else { setGoods(data); } } catch (error) { console.error("加载商品失败:", error); } finally { if (!append) setListLoading(false); } }, [], ); // 加载 IP 列表 const loadIPList = useCallback(async () => { try { const data = await getIPList(); const allIP: IPItem = { id: "", name: "全域" }; // '所有IP' -> '全域' setIpList([allIP, ...data.filter((item) => item !== null)]); } catch (error) { console.error("加载IP列表失败:", error); } }, []); // 加载页面配置 const loadPageConfig = useCallback(async () => { try { const bannerConfig = await getPageConfig("index_banner"); if (bannerConfig?.components?.[0]?.elements) { setBanners(bannerConfig.components[0].elements); } const iconConfig = await getPageConfig("index_icon"); if (iconConfig?.components?.[0]?.elements) { setTabs(iconConfig.components[0].elements); } } catch (error) { console.error("加载页面配置失败:", error); } }, []); // 初始化数据 const initData = useCallback(async () => { setLoading(true); await Promise.all([ loadGoods(searchParams), loadIPList(), loadPageConfig(), ]); setLoading(false); }, []); useEffect(() => { initData(); }, []); // 下拉刷新 const onRefresh = async () => { setRefreshing(true); const newParams = { ...searchParams, current: 1 }; setSearchParams(newParams); await Promise.all([loadGoods(newParams), loadIPList(), loadPageConfig()]); setRefreshing(false); }; // 搜索 const handleSearch = async (keyword: string) => { const newParams = { ...searchParams, keyword, current: 1 }; setSearchParams(newParams); await loadGoods(newParams); }; // Banner 点击 const handleBannerPress = (item: BannerItem) => { console.log("Banner pressed:", item); }; // 功能入口点击 const handleQuickEntryPress = (item: TabItem) => { const title = item.title?.trim(); if (title === "领福利") { kefuRef.current?.open(); } else if (title === "福利屋") { router.push("/dimension/room" as any); } else if (title === "攻略") { router.push({ pathname: "/agreement" as any, params: { type: "game_walkthrough" }, }); } else if (item.path?.url) { // 通用跳转:后端配置了 URL 的按钮 router.push(item.path.url as any); } }; // IP 筛选 const handleIPSelect = (item: IPItem, index: number) => { // 立即更新 UI,不等待网络请求 setIpIndex(index); setGoods([]); // 异步加载数据 requestAnimationFrame(async () => { const newParams = { ...searchParams, worksId: item.id, current: 1 }; setSearchParams(newParams); await loadGoods(newParams); }); }; // 商品点击 const handleGoodsPress = (item: GoodsItem) => { // 虚拟 ID 检查,防止爬虫(Obfuscation) if (item.id === "99999999") return; router.push(`/product/${item.id}` as any); }; // 列表头部组件 const ListHeader = useMemo(() => { return ( <> {/* 搜索栏 */} {/* Banner 轮播 */} {banners.length > 0 && ( )} {/* 功能入口 */} {tabs.length > 0 && ( )} {/* IP 分类筛选 */} {ipList.length > 0 && ( )} ); }, [banners, tabs, ipList, ipIndex]); // 依赖项 const renderItem = useCallback(({ item }: { item: GoodsItem }) => { return ; }, []); const ListEmptyComponent = useMemo(() => { if (listLoading) { return ( 数据加载中... ); } if (!loading && goods.length === 0) { return ( 暂无装备 ); } return null; }, [listLoading, loading, goods.length]); if (loading) { return ( 系统接入中... ); } return ( {/* Remove ImageBackground or use a dark one */} item.id} ListHeaderComponent={ListHeader} numColumns={2} columnWrapperStyle={styles.columnWrapper} contentContainerStyle={{ paddingTop: insets.top + 10, paddingBottom: 20, }} showsVerticalScrollIndicator={false} refreshControl={ } ListEmptyComponent={ListEmptyComponent} onEndReachedThreshold={0.5} /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: Colors.darkBg, }, background: { flex: 1, backgroundColor: Colors.darkBg, // Use solid dark background }, section: { paddingHorizontal: 10, }, loadingContainer: { flex: 1, backgroundColor: Colors.darkBg, justifyContent: "center", alignItems: "center", }, loadingListContainer: { padding: 20, alignItems: "center", }, loadingText: { color: Colors.textSecondary, marginTop: 10, fontSize: 14, fontFamily: "System", // Keep default for now }, columnWrapper: { justifyContent: "space-between", paddingHorizontal: 10, }, emptyContainer: { padding: 50, alignItems: "center", }, emptyText: { color: Colors.textTertiary, fontSize: 14, }, });