1bf6e62f2S猫头猫import {pluginManager, usePlugins} from '@/common/pluginManager'; 2bf6e62f2S猫头猫import produce from 'immer'; 3bf6e62f2S猫头猫import {useAtom, useSetAtom} from 'jotai'; 4*19c8eb6fS猫头猫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猫头猫 11*19c8eb6fS猫头猫 // 当前正在搜索 12*19c8eb6fS猫头猫 const currentQueryRef = useRef<string>(''); 13*19c8eb6fS猫头猫 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)]; 25*19c8eb6fS猫头猫 // 使用选中插件搜素 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] ?? {}; 35*19c8eb6fS猫头猫 if ( 36*19c8eb6fS猫头猫 (_prevResult.state === 'pending' || _prevResult.state === 'done') && 37*19c8eb6fS猫头猫 undefined === query 38*19c8eb6fS猫头猫 ) { 39bf6e62f2S猫头猫 return; 40bf6e62f2S猫头猫 } 41d139abf1S猫头猫 42*19c8eb6fS猫头猫 // 是否是一次新的搜索 43bf6e62f2S猫头猫 const newSearch = 44bf6e62f2S猫头猫 query || _prevResult?.currentPage === undefined || queryPage === 1; 45*19c8eb6fS猫头猫 46*19c8eb6fS猫头猫 // 搜索关键词 47*19c8eb6fS猫头猫 currentQueryRef.current = query = query ?? _prevResult?.query ?? ''; 48*19c8eb6fS猫头猫 49*19c8eb6fS猫头猫 /** 搜索的页码 */ 50bf6e62f2S猫头猫 const page = 51bf6e62f2S猫头猫 queryPage ?? newSearch ? 1 : (_prevResult.currentPage ?? 0) + 1; 52d139abf1S猫头猫 53*19c8eb6fS猫头猫 54bf6e62f2S猫头猫 try { 55d139abf1S猫头猫 setSearchResults(prevState => 56d139abf1S猫头猫 produce(prevState, draft => { 57bf6e62f2S猫头猫 const prev = draft[_hash] ?? {}; 58bf6e62f2S猫头猫 prev.query = query; 5908a8e62cS猫头猫 prev.state = 'pending'; 60*19c8eb6fS猫头猫 prev.result = newSearch ? {} : prev.result; 61bf6e62f2S猫头猫 draft[_hash] = prev; 62bf6e62f2S猫头猫 }), 63bf6e62f2S猫头猫 ); 64ad2ad8ffS猫头猫 // !! jscore的promise有问题,改成hermes就好了,可能和JIT有关,不知道。 65bf6e62f2S猫头猫 const result = await plugin?.instance?.search?.(query, page); 66*19c8eb6fS猫头猫 if (currentQueryRef.current !== query) { 67*19c8eb6fS猫头猫 return; 68*19c8eb6fS猫头猫 } 69bf6e62f2S猫头猫 setPageStatus(PageStatus.RESULT); 70bf6e62f2S猫头猫 if (!result) { 71bf6e62f2S猫头猫 throw new Error(); 72bf6e62f2S猫头猫 } 73bf6e62f2S猫头猫 setSearchResults( 74bf6e62f2S猫头猫 produce(draft => { 75bf6e62f2S猫头猫 const prev = draft[_hash] ?? {}; 7608a8e62cS猫头猫 if (result._isEnd === false) { 7708a8e62cS猫头猫 prev.state = 'resolved'; 7808a8e62cS猫头猫 } else { 7908a8e62cS猫头猫 prev.state = 'done'; 8008a8e62cS猫头猫 } 81bf6e62f2S猫头猫 prev.result = newSearch 82d139abf1S猫头猫 ? mergeResult(result, {}, _platform) 83d139abf1S猫头猫 : mergeResult(prev.result ?? {}, result ?? {}, _platform); 84d139abf1S猫头猫 draft[_hash] = { 85d139abf1S猫头猫 state: prev.state, 86d139abf1S猫头猫 result: prev.result, 87d139abf1S猫头猫 query: query, 88d139abf1S猫头猫 currentPage: page, 89d139abf1S猫头猫 }; 90d139abf1S猫头猫 return draft; 91bf6e62f2S猫头猫 }), 92bf6e62f2S猫头猫 ); 932f655a9eS猫头猫 } catch (e) { 942f655a9eS猫头猫 console.log('SEARCH ERROR', e); 95bf6e62f2S猫头猫 setSearchResults( 96bf6e62f2S猫头猫 produce(draft => { 97bf6e62f2S猫头猫 const prev = draft[_hash] ?? {}; 9808a8e62cS猫头猫 prev.state = 'resolved'; 99bf6e62f2S猫头猫 draft[_hash] = prev; 100bf6e62f2S猫头猫 }), 101bf6e62f2S猫头猫 ); 102bf6e62f2S猫头猫 } 103bf6e62f2S猫头猫 }); 104bf6e62f2S猫头猫 }, 105ad2ad8ffS猫头猫 [searchResults], 106ad2ad8ffS猫头猫 ); 107bf6e62f2S猫头猫 108bf6e62f2S猫头猫 return search; 109bf6e62f2S猫头猫} 110bf6e62f2S猫头猫 111ad2ad8ffS猫头猫// todo: 去重 112d139abf1S猫头猫const resultKeys: (keyof IPlugin.ISearchResult)[] = ['album', 'music']; 113d139abf1S猫头猫function mergeResult( 114d139abf1S猫头猫 obj1: Record<string, any>, 115d139abf1S猫头猫 obj2: Record<string, any>, 116d139abf1S猫头猫 platform: string, 117d139abf1S猫头猫): IPlugin.ISearchResult { 118d139abf1S猫头猫 const result: Record<string, any> = {}; 119d139abf1S猫头猫 for (let k of resultKeys) { 120d139abf1S猫头猫 result[k] = (obj1[k] ?? []) 121d139abf1S猫头猫 .map((_: any) => 122d139abf1S猫头猫 produce(_, (_: any) => { 123d139abf1S猫头猫 _.platform = platform; 124d139abf1S猫头猫 }), 125d139abf1S猫头猫 ) 126d139abf1S猫头猫 .concat( 127d139abf1S猫头猫 (obj2[k] ?? []).map((_: any) => 128d139abf1S猫头猫 produce(_, (_: any) => { 129d139abf1S猫头猫 _.platform = platform; 130d139abf1S猫头猫 }), 131d139abf1S猫头猫 ), 132d139abf1S猫头猫 ); 133d139abf1S猫头猫 } 134d139abf1S猫头猫 return result; 135d139abf1S猫头猫} 136