1import React, {useEffect, useRef, useState} from 'react'; 2import {StyleSheet, Text, View} from 'react-native'; 3import rpx from '@/utils/rpx'; 4import MusicItem from '@/components/mediaItem/musicItem'; 5import {FlatList} from 'react-native-gesture-handler'; 6import {useAtom, useSetAtom} from 'jotai'; 7import {IQueryResult, scrollToTopAtom} from '../store/atoms'; 8import {RequestStateCode} from '@/constants/commonConst'; 9import useQueryArtist from '../hooks/useQuery'; 10import {useRoute} from '@react-navigation/native'; 11import Empty from '@/components/base/empty'; 12import ListLoading from '@/components/base/listLoading'; 13import ListReachEnd from '@/components/base/listReachEnd'; 14 15const fakeMusicList = Array(50) 16 .fill(1) 17 .map(_ => ({ 18 id: '1125499111' + Math.random(), 19 artist: '周杰伦', 20 title: '我是如此相信 (电影《天火》主题曲)', 21 album: '我是如此相信', 22 artwork: 23 'https://mcontent.migu.cn/newlv2/new/album/20201103/1125499110/s_Xlihp7auugzpWgbW.jpg', 24 url: 'https://freetyst.nf.migu.cn/public%2Fproduct6th%2Fproduct36%2F2019%2F12%2F1319%2F2019%E5%B9%B412%E6%9C%8813%E6%97%A519%E7%82%B933%E5%88%86%E7%B4%A7%E6%80%A5%E5%86%85%E5%AE%B9%E5%87%86%E5%85%A5%E7%BA%B5%E6%A8%AA%E4%B8%96%E4%BB%A31%E9%A6%96%2F%E5%85%A8%E6%9B%B2%E8%AF%95%E5%90%AC%2FMp3_64_22_16%2F60054704118.mp3?Key=418a2b05ec5576d6&Tim=1662191674042&channelid=01&msisdn=dbea15217ccb4a1882585e57f2a23b3e', 25 lrc: 'https://tyqk.migu.cn/files/lyric/2019-12-14/dcf94ea8351c4cdc9a60316cdd8f14aa.lrc', 26 platform: '咪咕', 27 })); 28 29const ITEM_HEIGHT = rpx(120); 30 31interface IResultListProps<T = IArtist.ArtistMediaType> { 32 tab: T; 33 data: IQueryResult<T>; 34 renderItem: (...args: any) => any; 35} 36export default function ResultList(props: IResultListProps) { 37 const {data, renderItem, tab} = props; 38 const [scrollToTopState, setScrollToTopState] = useAtom(scrollToTopAtom); 39 const lastScrollY = useRef<number>(0); 40 const route = useRoute<any>(); 41 const pluginHash: string = route.params.pluginHash; 42 const artistItem: IArtist.IArtistItem = route.params.artistItem; 43 const [queryState, setQueryState] = useState<RequestStateCode>( 44 data?.state ?? RequestStateCode.IDLE, 45 ); 46 47 const queryArtist = useQueryArtist(pluginHash); 48 49 useEffect(() => { 50 queryState === RequestStateCode.IDLE && queryArtist(artistItem, 1, tab); 51 }, []); 52 53 useEffect(() => { 54 setQueryState(data?.state ?? RequestStateCode.IDLE); 55 }, [data]); 56 57 return ( 58 <FlatList 59 onScroll={e => { 60 const currentY = e.nativeEvent.contentOffset.y; 61 if (!scrollToTopState && currentY < ITEM_HEIGHT * 8 - rpx(350)) { 62 currentY < lastScrollY.current && setScrollToTopState(true); 63 } else { 64 if (scrollToTopState && currentY > ITEM_HEIGHT * 8) { 65 currentY > lastScrollY.current && setScrollToTopState(false); 66 } 67 } 68 lastScrollY.current = currentY; 69 }} 70 ListEmptyComponent={<Empty></Empty>} 71 ListFooterComponent={ 72 queryState === RequestStateCode.PENDING ? ( 73 <ListLoading></ListLoading> 74 ) : (queryState === RequestStateCode.FINISHED && data.data?.length !== 0) ? ( 75 <ListReachEnd></ListReachEnd> 76 ) : ( 77 <></> 78 ) 79 } 80 onEndReached={() => { 81 (queryState === RequestStateCode.IDLE || 82 queryState === RequestStateCode.PARTLY_DONE) && 83 queryArtist(artistItem, undefined, tab); 84 }} 85 getItemLayout={(_, index) => ({ 86 length: ITEM_HEIGHT, 87 offset: ITEM_HEIGHT * index, 88 index, 89 })} 90 overScrollMode="always" 91 data={data.data ?? []} 92 renderItem={renderItem}></FlatList> 93 ); 94} 95