1import React, {memo, useEffect, useMemo, useRef, useState} from 'react'; 2import {Text} from 'react-native'; 3import rpx, {vw} 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(props.tab).map( 66 _ => ({ 67 key: _.hash, 68 title: _.name, 69 }), 70 ); 71 const renderScene = useMemo( 72 () => getSubRouterScene(props.tab, routes), 73 [props.tab], 74 ); 75 76 return ( 77 <TabView 78 lazy 79 navigationState={{ 80 index, 81 routes, 82 }} 83 renderTabBar={_ => ( 84 <TabBar 85 {..._} 86 scrollEnabled 87 style={{ 88 backgroundColor: 'transparent', 89 shadowColor: 'transparent', 90 borderColor: 'transparent', 91 }} 92 tabStyle={{ 93 width: rpx(200), 94 }} 95 renderIndicator={() => null} 96 pressColor="transparent" 97 renderLabel={({route, focused, color}) => ( 98 <Text 99 numberOfLines={1} 100 style={{ 101 fontWeight: focused 102 ? fontWeightConst.bolder 103 : fontWeightConst.bold, 104 color, 105 }}> 106 {route.title ?? '(未命名)'} 107 </Text> 108 )} 109 /> 110 )} 111 renderScene={renderScene} 112 onIndexChange={setIndex} 113 initialLayout={{width: vw(100)}} 114 /> 115 ); 116} 117 118// 不然会一直重新渲染 119export default memo(ResultSubPanel); 120