1import React, {useEffect, useRef, useState} from 'react'; 2import rpx from '@/utils/rpx'; 3import {FlatList} from 'react-native-gesture-handler'; 4import {useAtom} from 'jotai'; 5import {IQueryResult, scrollToTopAtom} from '../store/atoms'; 6import {RequestStateCode} from '@/constants/commonConst'; 7import useQueryArtist from '../hooks/useQuery'; 8import {useRoute} from '@react-navigation/native'; 9import Empty from '@/components/base/empty'; 10import ListLoading from '@/components/base/listLoading'; 11import ListReachEnd from '@/components/base/listReachEnd'; 12 13const ITEM_HEIGHT = rpx(120); 14 15interface IResultListProps<T = IArtist.ArtistMediaType> { 16 tab: T; 17 data: IQueryResult<T>; 18 renderItem: (...args: any) => any; 19} 20export default function ResultList(props: IResultListProps) { 21 const {data, renderItem, tab} = props; 22 const [scrollToTopState, setScrollToTopState] = useAtom(scrollToTopAtom); 23 const lastScrollY = useRef<number>(0); 24 const route = useRoute<any>(); 25 const pluginHash: string = route.params.pluginHash; 26 const artistItem: IArtist.IArtistItem = route.params.artistItem; 27 const [queryState, setQueryState] = useState<RequestStateCode>( 28 data?.state ?? RequestStateCode.IDLE, 29 ); 30 31 const queryArtist = useQueryArtist(pluginHash); 32 33 useEffect(() => { 34 queryState === RequestStateCode.IDLE && queryArtist(artistItem, 1, tab); 35 }, []); 36 37 useEffect(() => { 38 setQueryState(data?.state ?? RequestStateCode.IDLE); 39 }, [data]); 40 41 return ( 42 <FlatList 43 onScroll={e => { 44 const currentY = e.nativeEvent.contentOffset.y; 45 if ( 46 !scrollToTopState && 47 currentY < ITEM_HEIGHT * 8 - rpx(350) 48 ) { 49 currentY < lastScrollY.current && setScrollToTopState(true); 50 } else { 51 if (scrollToTopState && currentY > ITEM_HEIGHT * 8) { 52 currentY > lastScrollY.current && 53 setScrollToTopState(false); 54 } 55 } 56 lastScrollY.current = currentY; 57 }} 58 ListEmptyComponent={<Empty />} 59 ListFooterComponent={ 60 queryState === RequestStateCode.PENDING ? ( 61 <ListLoading /> 62 ) : queryState === RequestStateCode.FINISHED && 63 data.data?.length !== 0 ? ( 64 <ListReachEnd /> 65 ) : ( 66 <></> 67 ) 68 } 69 onEndReached={() => { 70 (queryState === RequestStateCode.IDLE || 71 queryState === RequestStateCode.PARTLY_DONE) && 72 queryArtist(artistItem, undefined, tab); 73 }} 74 getItemLayout={(_, index) => ({ 75 length: ITEM_HEIGHT, 76 offset: ITEM_HEIGHT * index, 77 index, 78 })} 79 overScrollMode="always" 80 data={data.data ?? []} 81 renderItem={renderItem} 82 /> 83 ); 84} 85