xref: /MusicFree/src/pages/artistDetail/components/resultList.tsx (revision 316c909695af8978fd54ffb10af86d9214d66fef)
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