1import React, {memo, useCallback, useEffect, useState} from 'react'; 2import {StyleSheet, Text, View} 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 <ResultWrapper 29 tab={tab} 30 searchResult={pluginSearchResult} 31 pluginHash={pluginHash} 32 pluginName={pluginName}></ResultWrapper> 33 }, 34 () => true, 35 ) 36 : () => <DefaultResults></DefaultResults>; 37} 38 39/** 结果scene */ 40function getSubRouterScene( 41 tab: ICommon.SupportMediaType, 42 routes: Array<{key: string; title: string}>, 43) { 44 const scene: Record<string, React.FC> = {}; 45 routes.forEach(r => { 46 scene[r.key] = getResultComponent(tab, r.key, r.title); 47 }); 48 return SceneMap(scene); 49} 50 51function ResultSubPanel(props: IResultSubPanelProps) { 52 const [index, setIndex] = useState(0); 53 // todo 是否聚合结果,如果是的话 54 const routes = PluginManager.getValidPlugins().map(_ => ({ 55 key: _.hash, 56 title: _.name, 57 })); 58 59 return ( 60 <TabView 61 lazy 62 navigationState={{ 63 index, 64 routes, 65 }} 66 renderTabBar={props => ( 67 <TabBar 68 {...props} 69 style={{ 70 backgroundColor: 'transparent', 71 shadowColor: 'transparent', 72 borderColor: 'transparent', 73 }} 74 tabStyle={{ 75 width: rpx(200), 76 }} 77 renderIndicator={() => null} 78 pressColor="transparent" 79 renderLabel={({route, focused, color}) => ( 80 <Text 81 numberOfLines={1} 82 style={{ 83 fontWeight: focused 84 ? fontWeightConst.bolder 85 : fontWeightConst.bold, 86 color, 87 }}> 88 {route.title ?? '(未命名)'} 89 </Text> 90 )}></TabBar> 91 )} 92 renderScene={useCallback(getSubRouterScene(props.tab, routes), [ 93 props.tab, 94 ])} 95 onIndexChange={setIndex} 96 initialLayout={{width: rpx(750)}}></TabView> 97 ); 98} 99 100// 不然会一直重新渲染 101export default memo(ResultSubPanel); 102