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 Empty from '@/components/base/empty'; 9import ListLoading from '@/components/base/listLoading'; 10import ListReachEnd from '@/components/base/listReachEnd'; 11import {useParams} from '@/entry/router'; 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 {pluginHash, artistItem} = useParams<'artist-detail'>(); 25 const [queryState, setQueryState] = useState<RequestStateCode>( 26 data?.state ?? RequestStateCode.IDLE, 27 ); 28 29 const queryArtist = useQueryArtist(pluginHash); 30 31 useEffect(() => { 32 queryState === RequestStateCode.IDLE && queryArtist(artistItem, 1, tab); 33 }, []); 34 35 useEffect(() => { 36 setQueryState(data?.state ?? RequestStateCode.IDLE); 37 }, [data]); 38 39 return ( 40 <FlatList 41 onScroll={e => { 42 const currentY = e.nativeEvent.contentOffset.y; 43 if ( 44 !scrollToTopState && 45 currentY < ITEM_HEIGHT * 8 - rpx(350) 46 ) { 47 currentY < lastScrollY.current && setScrollToTopState(true); 48 } else { 49 if (scrollToTopState && currentY > ITEM_HEIGHT * 8) { 50 currentY > lastScrollY.current && 51 setScrollToTopState(false); 52 } 53 } 54 lastScrollY.current = currentY; 55 }} 56 ListEmptyComponent={<Empty />} 57 ListFooterComponent={ 58 queryState === RequestStateCode.PENDING_REST_PAGE ? ( 59 <ListLoading /> 60 ) : queryState === RequestStateCode.FINISHED && 61 data.data?.length !== 0 ? ( 62 <ListReachEnd /> 63 ) : null 64 } 65 onEndReached={() => { 66 (queryState === RequestStateCode.IDLE || 67 queryState === RequestStateCode.PARTLY_DONE) && 68 queryArtist(artistItem, undefined, tab); 69 }} 70 getItemLayout={(_, index) => ({ 71 length: ITEM_HEIGHT, 72 offset: ITEM_HEIGHT * index, 73 index, 74 })} 75 overScrollMode="always" 76 data={data.data ?? []} 77 renderItem={renderItem} 78 /> 79 ); 80} 81