xref: /MusicFree/src/pages/searchPage/components/resultPanel/resultSubPanel.tsx (revision b882a19d884fffa32f7c8cef31652b909dceaa0f)
1import React, {memo, useCallback, useState} from 'react';
2import {Text} from 'react-native';
3import rpx from '@/utils/rpx';
4import {SceneMap, TabBar, TabView} from 'react-native-tab-view';
5import DefaultResults from './results/defaultResults';
6import {renderMap} from './results';
7import ResultWrapper from './resultWrapper';
8import {fontWeightConst} from '@/constants/uiConst';
9import {useAtomValue} from 'jotai';
10import {searchResultsAtom} from '../../store/atoms';
11import PluginManager from '@/core/pluginManager';
12
13interface IResultSubPanelProps {
14    tab: ICommon.SupportMediaType;
15}
16
17// 展示结果的视图
18function getResultComponent(
19    tab: ICommon.SupportMediaType,
20    pluginHash: string,
21    pluginName: string,
22) {
23    return tab in renderMap
24        ? memo(
25              () => {
26                  const searchResults = useAtomValue(searchResultsAtom);
27                  const pluginSearchResult = searchResults[tab][pluginHash];
28                  return (
29                      <ResultWrapper
30                          tab={tab}
31                          searchResult={pluginSearchResult}
32                          pluginHash={pluginHash}
33                          pluginName={pluginName}
34                      />
35                  );
36              },
37              () => true,
38          )
39        : () => <DefaultResults />;
40}
41
42/** 结果scene */
43function getSubRouterScene(
44    tab: ICommon.SupportMediaType,
45    routes: Array<{key: string; title: string}>,
46) {
47    const scene: Record<string, React.FC> = {};
48    routes.forEach(r => {
49        scene[r.key] = getResultComponent(tab, r.key, r.title);
50    });
51    return SceneMap(scene);
52}
53
54function ResultSubPanel(props: IResultSubPanelProps) {
55    const [index, setIndex] = useState(0);
56    // todo 是否聚合结果,如果是的话
57    const routes = PluginManager.getValidPlugins().map(_ => ({
58        key: _.hash,
59        title: _.name,
60    }));
61
62    return (
63        <TabView
64            lazy
65            navigationState={{
66                index,
67                routes,
68            }}
69            renderTabBar={_ => (
70                <TabBar
71                    {..._}
72                    style={{
73                        backgroundColor: 'transparent',
74                        shadowColor: 'transparent',
75                        borderColor: 'transparent',
76                    }}
77                    tabStyle={{
78                        width: rpx(200),
79                    }}
80                    renderIndicator={() => null}
81                    pressColor="transparent"
82                    renderLabel={({route, focused, color}) => (
83                        <Text
84                            numberOfLines={1}
85                            style={{
86                                fontWeight: focused
87                                    ? fontWeightConst.bolder
88                                    : fontWeightConst.bold,
89                                color,
90                            }}>
91                            {route.title ?? '(未命名)'}
92                        </Text>
93                    )}
94                />
95            )}
96            renderScene={useCallback(getSubRouterScene(props.tab, routes), [
97                props.tab,
98            ])}
99            onIndexChange={setIndex}
100            initialLayout={{width: rpx(750)}}
101        />
102    );
103}
104
105// 不然会一直重新渲染
106export default memo(ResultSubPanel);
107