import { View, RefreshControl, ActivityIndicator, Animated, Easing, TouchableOpacity, } from "react-native"; import React, { useState, useRef, useEffect } from "react"; import StreamerCard from "../../../components/StreamerCard"; import Empty from "../../../components/Empty"; import { useTailwind } from "tailwind-rn"; import baseRequest from "../../../utils/baseRequest"; import Toast from "react-native-toast-message"; import { generateSignature } from "../../../utils/crypto"; import { FlashList } from "@shopify/flash-list"; import { Svg, Path } from "react-native-svg"; export default function FeedStream() { //获取推荐的主播mid const [recommMids, setRecommMids] = useState([]); const getRecommMids = async () => { if (!isEnd) return; const apiUrl = process.env.EXPO_PUBLIC_API_URL; try { const base = await baseRequest(); const signature = await generateSignature({ ...base, }); const response = await fetch( `${apiUrl}/api/streamer/recomm_list?signature=${signature}`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ ...base, }), } ); const recommData = await response.json(); if (recommData.ret === -1) { Toast.show({ type: "error", text1: recommData.msg, topOffset: 60, }); return; } setIsEnd(false); setRecommMids(recommData.data.recomm_list); } catch (error) { console.error(error); } }; //查询的起始索引 const [startIndex, setStartIndex] = useState(0); // 定义每次取多少个用户ID const batchSize = 4; //获取新数据 const [data, setData] = useState([]); const [isEnd, setIsEnd] = useState(true); const [isActivityIndicatorShow, setIsActivityIndicatorShow] = useState(true); const [isFetching, setIsFetching] = useState(false); const getData = async (type) => { if (isFetching) return; if (isEnd) return; if (recommMids.length === 0) return; const apiUrl = process.env.EXPO_PUBLIC_API_URL; const batchStreamerMids = recommMids.slice( startIndex, startIndex + batchSize ); if (batchStreamerMids.length === 0) { if (type !== "top") { setIsActivityIndicatorShow(false); return; } setIsActivityIndicatorShow(true); setIsEnd(true); setStartIndex(0); return; } setIsFetching((prev) => true); try { const base = await baseRequest(); const signature = await generateSignature({ mids: batchStreamerMids, ...base, }); const detailResponse = await fetch( `${apiUrl}/api/streamer/list_ext_by_mids?signature=${signature}`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ mids: batchStreamerMids, ...base, }), } ); const detailData = await detailResponse.json(); if (detailData.ret === -1) { Toast.show({ type: "error", text1: detailData.msg, topOffset: 60, }); return; } const sortedData = detailData.data.list.sort((a, b) => b.fans - a.fans); if (type === "top") { setData((prev) => { if (startIndex === 0) { return sortedData; } else return [...sortedData, ...prev]; }); } else { setData((prev) => [...prev, ...sortedData]); } // 更新下一次查询的起始索引 setStartIndex(startIndex + batchSize); setIsFetching((prev) => false); } catch (error) { console.error(error); } }; //获取推荐mid useEffect(() => { getRecommMids(); }, [isEnd]); //当推荐的mid改变,获取新数据 useEffect(() => { getData("top"); }, [recommMids]); const tailwind = useTailwind(); const renderItem = ({ item }) => ; const [refreshing, setRefreshing] = useState(false); //刷新动画 const flatListRef = useRef(null); const [rotateValue] = useState(new Animated.Value(0)); const startRotation = () => { Animated.timing(rotateValue, { toValue: 1, duration: 500, easing: Easing.linear, useNativeDriver: true, }).start(() => { rotateValue.setValue(0); }); }; const spin = rotateValue.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"], }); //下拉刷新 const handleRefresh = async () => { startRotation(); flatListRef.current.scrollToOffset({ animated: false, offset: 0 }); setRefreshing(true); await getData("top"); setRefreshing(false); }; return ( handleRefresh()} /> } onEndReached={() => getData("bottom")} ListEmptyComponent={} ListFooterComponent={ {isActivityIndicatorShow && data.length !== 0 && ( )} } keyExtractor={(item) => item.mid} /> ); }