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