1bf6e62f2S猫头猫import {pluginManager, usePlugins} from '@/common/pluginManager'; 2bf6e62f2S猫头猫import produce from 'immer'; 3bf6e62f2S猫头猫import {useAtom, useSetAtom} from 'jotai'; 419c8eb6fS猫头猫import {useCallback, useRef} from 'react'; 5bf6e62f2S猫头猫import {PageStatus, pageStatusAtom, searchResultsAtom} from '../store/atoms'; 6bf6e62f2S猫头猫 7bf6e62f2S猫头猫export default function useSearch() { 8bf6e62f2S猫头猫 const setPageStatus = useSetAtom(pageStatusAtom); 9bf6e62f2S猫头猫 const [searchResults, setSearchResults] = useAtom(searchResultsAtom); 10bf6e62f2S猫头猫 1119c8eb6fS猫头猫 // 当前正在搜索 1219c8eb6fS猫头猫 const currentQueryRef = useRef<string>(''); 1319c8eb6fS猫头猫 14ad2ad8ffS猫头猫 const search = useCallback( 15ad2ad8ffS猫头猫 async function ( 16bf6e62f2S猫头猫 query?: string, 17bf6e62f2S猫头猫 platformHash = 'all', 18bf6e62f2S猫头猫 queryPage = undefined, 19bf6e62f2S猫头猫 ) { 20bf6e62f2S猫头猫 const installedPlugins = pluginManager.getValidPlugins(); 21bf6e62f2S猫头猫 const plugins = 22bf6e62f2S猫头猫 platformHash === 'all' 23bf6e62f2S猫头猫 ? installedPlugins 24bf6e62f2S猫头猫 : [installedPlugins.find(_ => _.hash === platformHash)]; 2519c8eb6fS猫头猫 // 使用选中插件搜素 26bf6e62f2S猫头猫 plugins.forEach(async plugin => { 27bf6e62f2S猫头猫 const _platform = plugin?.instance.platform; 28bf6e62f2S猫头猫 const _hash = plugin?.hash; 29bf6e62f2S猫头猫 if (!plugin || !_platform || !_hash) { 30bf6e62f2S猫头猫 // 没有插件,此时直接进入结果页 31bf6e62f2S猫头猫 setPageStatus(PageStatus.RESULT); 32bf6e62f2S猫头猫 return; 33bf6e62f2S猫头猫 } 3408a8e62cS猫头猫 const _prevResult = searchResults[_hash] ?? {}; 3519c8eb6fS猫头猫 if ( 3619c8eb6fS猫头猫 (_prevResult.state === 'pending' || _prevResult.state === 'done') && 3719c8eb6fS猫头猫 undefined === query 3819c8eb6fS猫头猫 ) { 39bf6e62f2S猫头猫 return; 40bf6e62f2S猫头猫 } 41d139abf1S猫头猫 4219c8eb6fS猫头猫 // 是否是一次新的搜索 43bf6e62f2S猫头猫 const newSearch = 44bf6e62f2S猫头猫 query || _prevResult?.currentPage === undefined || queryPage === 1; 4519c8eb6fS猫头猫 4619c8eb6fS猫头猫 // 搜索关键词 4719c8eb6fS猫头猫 currentQueryRef.current = query = query ?? _prevResult?.query ?? ''; 4819c8eb6fS猫头猫 4919c8eb6fS猫头猫 /** 搜索的页码 */ 50bf6e62f2S猫头猫 const page = 51bf6e62f2S猫头猫 queryPage ?? newSearch ? 1 : (_prevResult.currentPage ?? 0) + 1; 52d139abf1S猫头猫 53bf6e62f2S猫头猫 try { 54*92a7e801S猫头猫 setSearchResults( 55*92a7e801S猫头猫 produce(draft => { 56bf6e62f2S猫头猫 const prev = draft[_hash] ?? {}; 57*92a7e801S猫头猫 draft[_hash] = { 58*92a7e801S猫头猫 state: 'pending', 59*92a7e801S猫头猫 result: newSearch ? {} : prev.result, 60*92a7e801S猫头猫 query: query, 61*92a7e801S猫头猫 currentPage: page, 62*92a7e801S猫头猫 }; 63*92a7e801S猫头猫 return draft; 64bf6e62f2S猫头猫 }), 65bf6e62f2S猫头猫 ); 66ad2ad8ffS猫头猫 // !! jscore的promise有问题,改成hermes就好了,可能和JIT有关,不知道。 67bf6e62f2S猫头猫 const result = await plugin?.instance?.search?.(query, page); 6819c8eb6fS猫头猫 if (currentQueryRef.current !== query) { 6919c8eb6fS猫头猫 return; 7019c8eb6fS猫头猫 } 71bf6e62f2S猫头猫 setPageStatus(PageStatus.RESULT); 72bf6e62f2S猫头猫 if (!result) { 73bf6e62f2S猫头猫 throw new Error(); 74bf6e62f2S猫头猫 } 75bf6e62f2S猫头猫 setSearchResults( 76bf6e62f2S猫头猫 produce(draft => { 77bf6e62f2S猫头猫 const prev = draft[_hash] ?? {}; 7808a8e62cS猫头猫 if (result._isEnd === false) { 7908a8e62cS猫头猫 prev.state = 'resolved'; 8008a8e62cS猫头猫 } else { 8108a8e62cS猫头猫 prev.state = 'done'; 8208a8e62cS猫头猫 } 83bf6e62f2S猫头猫 prev.result = newSearch 84d139abf1S猫头猫 ? mergeResult(result, {}, _platform) 85d139abf1S猫头猫 : mergeResult(prev.result ?? {}, result ?? {}, _platform); 86d139abf1S猫头猫 draft[_hash] = { 87d139abf1S猫头猫 state: prev.state, 88d139abf1S猫头猫 result: prev.result, 89d139abf1S猫头猫 query: query, 90d139abf1S猫头猫 currentPage: page, 91d139abf1S猫头猫 }; 92d139abf1S猫头猫 return draft; 93bf6e62f2S猫头猫 }), 94bf6e62f2S猫头猫 ); 952f655a9eS猫头猫 } catch (e) { 962f655a9eS猫头猫 console.log('SEARCH ERROR', e); 97bf6e62f2S猫头猫 setSearchResults( 98bf6e62f2S猫头猫 produce(draft => { 99bf6e62f2S猫头猫 const prev = draft[_hash] ?? {}; 10008a8e62cS猫头猫 prev.state = 'resolved'; 101bf6e62f2S猫头猫 draft[_hash] = prev; 102bf6e62f2S猫头猫 }), 103bf6e62f2S猫头猫 ); 104bf6e62f2S猫头猫 } 105bf6e62f2S猫头猫 }); 106bf6e62f2S猫头猫 }, 107ad2ad8ffS猫头猫 [searchResults], 108ad2ad8ffS猫头猫 ); 109bf6e62f2S猫头猫 110bf6e62f2S猫头猫 return search; 111bf6e62f2S猫头猫} 112bf6e62f2S猫头猫 113ad2ad8ffS猫头猫// todo: 去重 114d139abf1S猫头猫const resultKeys: (keyof IPlugin.ISearchResult)[] = ['album', 'music']; 115d139abf1S猫头猫function mergeResult( 116d139abf1S猫头猫 obj1: Record<string, any>, 117d139abf1S猫头猫 obj2: Record<string, any>, 118d139abf1S猫头猫 platform: string, 119d139abf1S猫头猫): IPlugin.ISearchResult { 120d139abf1S猫头猫 const result: Record<string, any> = {}; 121d139abf1S猫头猫 for (let k of resultKeys) { 122d139abf1S猫头猫 result[k] = (obj1[k] ?? []) 123d139abf1S猫头猫 .map((_: any) => 124d139abf1S猫头猫 produce(_, (_: any) => { 125d139abf1S猫头猫 _.platform = platform; 126d139abf1S猫头猫 }), 127d139abf1S猫头猫 ) 128d139abf1S猫头猫 .concat( 129d139abf1S猫头猫 (obj2[k] ?? []).map((_: any) => 130d139abf1S猫头猫 produce(_, (_: any) => { 131d139abf1S猫头猫 _.platform = platform; 132d139abf1S猫头猫 }), 133d139abf1S猫头猫 ), 134d139abf1S猫头猫 ); 135d139abf1S猫头猫 } 136d139abf1S猫头猫 return result; 137d139abf1S猫头猫} 138