1import {pluginManager, usePlugins} from '@/common/pluginManager'; 2import produce from 'immer'; 3import {useAtom, useSetAtom} from 'jotai'; 4import {useCallback} from 'react'; 5import {PageStatus, pageStatusAtom, searchResultsAtom} from '../store/atoms'; 6 7export default function useSearch() { 8 const setPageStatus = useSetAtom(pageStatusAtom); 9 const [searchResults, setSearchResults] = useAtom(searchResultsAtom); 10 11 const search = useCallback(async function ( 12 query?: string, 13 platformHash = 'all', 14 queryPage = undefined, 15 ) { 16 // 如果没有搜索结果缓存,那就是没有搜过 17 const installedPlugins = pluginManager.getValidPlugins(); 18 console.log('HASH', platformHash); 19 const plugins = 20 platformHash === 'all' 21 ? installedPlugins 22 : [installedPlugins.find(_ => _.hash === platformHash)]; 23 plugins.forEach(async plugin => { 24 const _platform = plugin?.instance.platform; 25 const _hash = plugin?.hash; 26 if (!plugin || !_platform || !_hash) { 27 // 没有插件,此时直接进入结果页 28 setPageStatus(PageStatus.RESULT); 29 return; 30 } 31 const _prevResult = searchResults[_hash] ?? {}; 32 if (_prevResult.state === 'pending' || _prevResult.state === 'done') { 33 return; 34 } 35 36 const newSearch = 37 query || _prevResult?.currentPage === undefined || queryPage === 1; 38 query = query ?? _prevResult?.query ?? ''; 39 const page = 40 queryPage ?? newSearch ? 1 : (_prevResult.currentPage ?? 0) + 1; 41 42 const rand = Math.random(); 43 console.log('RANDOM', rand); 44 45 try { 46 setSearchResults(prevState => 47 produce(prevState, draft => { 48 const prev = draft[_hash] ?? {}; 49 prev.query = query; 50 prev.state = 'pending'; 51 draft[_hash] = prev; 52 }), 53 ); 54 // !! jscore的promise有问题,改成hermes就好了,可能和JIT 55 const result = await plugin?.instance?.search?.(query, page); 56 setPageStatus(PageStatus.RESULT); 57 if (!result) { 58 throw new Error(); 59 } 60 setSearchResults( 61 produce(draft => { 62 const prev = draft[_hash] ?? {}; 63 console.log('SAVED PAGE', page, prev, rand); 64 if (result._isEnd === false) { 65 prev.state = 'resolved'; 66 } else { 67 prev.state = 'done'; 68 } 69 prev.result = newSearch 70 ? mergeResult(result, {}, _platform) 71 : mergeResult(prev.result ?? {}, result ?? {}, _platform); 72 draft[_hash] = { 73 state: prev.state, 74 result: prev.result, 75 query: query, 76 currentPage: page, 77 }; 78 return draft; 79 }), 80 ); 81 } catch (e) { 82 console.log('SEARCH ERROR', e); 83 setSearchResults( 84 produce(draft => { 85 const prev = draft[_hash] ?? {}; 86 prev.state = 'resolved'; 87 draft[_hash] = prev; 88 }), 89 ); 90 } 91 }); 92 }, 93 []); 94 95 return search; 96} 97 98const resultKeys: (keyof IPlugin.ISearchResult)[] = ['album', 'music']; 99function mergeResult( 100 obj1: Record<string, any>, 101 obj2: Record<string, any>, 102 platform: string, 103): IPlugin.ISearchResult { 104 const result: Record<string, any> = {}; 105 for (let k of resultKeys) { 106 result[k] = (obj1[k] ?? []) 107 .map((_: any) => 108 produce(_, (_: any) => { 109 _.platform = platform; 110 }), 111 ) 112 .concat( 113 (obj2[k] ?? []).map((_: any) => 114 produce(_, (_: any) => { 115 _.platform = platform; 116 }), 117 ), 118 ); 119 } 120 return result; 121} 122 123// export default function useSearch() { 124// const setSearchResult = useSetAtom(searchResultAtom); 125// const setPageStatus = useSetAtom(pageStatusAtom); 126 127// async function search(query: string, page: number) { 128// const plugins = pluginManager.getPlugins(); 129// console.log('1', Date.now()); 130// const _rawResults = await allSettled( 131// // @ts-ignore 132// plugins.map(plugin => 133// plugin.instance?.search?.(query, page)?.then(res => { 134// console.log('1.1', Date.now()); 135// return res; 136// }), 137// ), 138// ); 139// console.log('2', Date.now()); 140// for (let i = 0; i < plugins.length; ++i) { 141// const _rr = _rawResults[i]; 142// setSearchResult(prevResult => 143// produce(page === 1 ? {} : prevResult, draft => { 144// // merge data 145// // @ts-ignore 146// const _result = _rr.status === 'fulfilled' ? _rr.value ?? {} : {}; 147// // 合并搜索结果 148// mergeData(draft, _result, 'music', plugins[i].instance.platform); 149// mergeData(draft, _result, 'album', plugins[i].instance.platform); 150// }), 151// ); 152// } 153// setPageStatus(PageStatus.RESULT); 154// } 155// return search; 156// } 157