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