xref: /MusicFree/src/pages/searchPage/components/resultPanel/resultWrapper.tsx (revision 1fa77b042dffea2ad8db31c1b15672ed8f3755cf)
1import React, {memo, useEffect, useState} from 'react';
2import {useAtomValue} from 'jotai';
3import {ISearchResult, queryAtom} from '../../store/atoms';
4import {renderMap} from './results';
5import useSearch from '../../hooks/useSearch';
6import Loading from '@/components/base/loading';
7import {RequestStateCode} from '@/constants/commonConst';
8import ListLoading from '@/components/base/listLoading';
9import Empty from '@/components/base/empty';
10import ListReachEnd from '@/components/base/listReachEnd';
11import useOrientation from '@/hooks/useOrientation';
12import {FlashList} from '@shopify/flash-list';
13import rpx from '@/utils/rpx';
14
15interface IResultWrapperProps<
16    T extends ICommon.SupportMediaType = ICommon.SupportMediaType,
17> {
18    tab: T;
19    pluginHash: string;
20    pluginName: string;
21    searchResult: ISearchResult<T>;
22    pluginSearchResultRef: React.MutableRefObject<ISearchResult<T>>;
23}
24function ResultWrapper(props: IResultWrapperProps) {
25    const {tab, pluginHash, searchResult, pluginSearchResultRef} = props;
26    const search = useSearch();
27    const [searchState, setSearchState] = useState<RequestStateCode>(
28        searchResult?.state ?? RequestStateCode.IDLE,
29    );
30    const orientation = useOrientation();
31    const query = useAtomValue(queryAtom);
32
33    const ResultComponent = renderMap[tab]!;
34    const data: any = searchResult?.data ?? [];
35
36    useEffect(() => {
37        if (searchState === RequestStateCode.IDLE) {
38            search(query, 1, tab, pluginHash);
39        }
40    }, []);
41
42    useEffect(() => {
43        setSearchState(searchResult?.state ?? RequestStateCode.IDLE);
44    }, [searchResult]);
45
46    const renderItem = ({item, index}: any) => (
47        <ResultComponent
48            item={item}
49            index={index}
50            pluginHash={pluginHash}
51            pluginSearchResultRef={pluginSearchResultRef}
52        />
53    );
54
55    return searchState === RequestStateCode.PENDING_FP ? (
56        <Loading />
57    ) : (
58        <FlashList
59            extraData={searchState}
60            ListEmptyComponent={() => <Empty />}
61            ListFooterComponent={() =>
62                searchState === RequestStateCode.PENDING ? (
63                    <ListLoading />
64                ) : searchState === RequestStateCode.FINISHED ? (
65                    <ListReachEnd />
66                ) : (
67                    <></>
68                )
69            }
70            data={data}
71            refreshing={false}
72            onRefresh={() => {
73                search(query, 1, tab, pluginHash);
74            }}
75            onEndReached={() => {
76                (searchState === RequestStateCode.PARTLY_DONE ||
77                    searchState === RequestStateCode.IDLE) &&
78                    search(undefined, undefined, tab, pluginHash);
79            }}
80            estimatedItemSize={tab === 'sheet' ? rpx(306) : rpx(120)}
81            numColumns={
82                tab === 'sheet' ? (orientation === 'vertical' ? 3 : 4) : 1
83            }
84            renderItem={renderItem}
85        />
86    );
87}
88
89export default memo(ResultWrapper);
90