xref: /MusicFree/src/pages/searchPage/components/resultPanel/resultSubPanel.tsx (revision 5d19d26c98d1c233995663070b95e5f28b5b9e1c)
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                    scrollEnabled
73                    style={{
74                        backgroundColor: 'transparent',
75                        shadowColor: 'transparent',
76                        borderColor: 'transparent',
77                    }}
78                    tabStyle={{
79                        width: rpx(200),
80                    }}
81                    renderIndicator={() => null}
82                    pressColor="transparent"
83                    renderLabel={({route, focused, color}) => (
84                        <Text
85                            numberOfLines={1}
86                            style={{
87                                fontWeight: focused
88                                    ? fontWeightConst.bolder
89                                    : fontWeightConst.bold,
90                                color,
91                            }}>
92                            {route.title ?? '(未命名)'}
93                        </Text>
94                    )}
95                />
96            )}
97            renderScene={useCallback(getSubRouterScene(props.tab, routes), [
98                props.tab,
99            ])}
100            onIndexChange={setIndex}
101            initialLayout={{width: rpx(750)}}
102        />
103    );
104}
105
106// 不然会一直重新渲染
107export default memo(ResultSubPanel);
108