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(e) { 113 console.log('SEARCH ERROR', e); 114 setSearchResults( 115 produce(draft => { 116 const prev = draft[_hash] ?? {}; 117 prev.pending = false; 118 draft[_hash] = prev; 119 }), 120 ); 121 } 122 }); 123 }, 124 []); 125 126 return search; 127} 128 129// export default function useSearch() { 130// const setSearchResult = useSetAtom(searchResultAtom); 131// const setPageStatus = useSetAtom(pageStatusAtom); 132 133// async function search(query: string, page: number) { 134// const plugins = pluginManager.getPlugins(); 135// console.log('1', Date.now()); 136// const _rawResults = await allSettled( 137// // @ts-ignore 138// plugins.map(plugin => 139// plugin.instance?.search?.(query, page)?.then(res => { 140// console.log('1.1', Date.now()); 141// return res; 142// }), 143// ), 144// ); 145// console.log('2', Date.now()); 146// for (let i = 0; i < plugins.length; ++i) { 147// const _rr = _rawResults[i]; 148// setSearchResult(prevResult => 149// produce(page === 1 ? {} : prevResult, draft => { 150// // merge data 151// // @ts-ignore 152// const _result = _rr.status === 'fulfilled' ? _rr.value ?? {} : {}; 153// // 合并搜索结果 154// mergeData(draft, _result, 'music', plugins[i].instance.platform); 155// mergeData(draft, _result, 'album', plugins[i].instance.platform); 156// }), 157// ); 158// } 159// setPageStatus(PageStatus.RESULT); 160// } 161// return search; 162// } 163