1*0b940038S猫头猫import {Plugin, pluginManager} from '@/common/pluginManager'; 2bf6e62f2S猫头猫import produce from 'immer'; 3bf6e62f2S猫头猫import {useAtom, useSetAtom} from 'jotai'; 419c8eb6fS猫头猫import {useCallback, useRef} from 'react'; 5*0b940038S猫头猫import { 6*0b940038S猫头猫 PageStatus, 7*0b940038S猫头猫 pageStatusAtom, 8*0b940038S猫头猫 searchResultsAtom, 9*0b940038S猫头猫 SearchStateCode, 10*0b940038S猫头猫} from '../store/atoms'; 11bf6e62f2S猫头猫 12bf6e62f2S猫头猫export default function useSearch() { 13bf6e62f2S猫头猫 const setPageStatus = useSetAtom(pageStatusAtom); 14bf6e62f2S猫头猫 const [searchResults, setSearchResults] = useAtom(searchResultsAtom); 15bf6e62f2S猫头猫 1619c8eb6fS猫头猫 // 当前正在搜索 1719c8eb6fS猫头猫 const currentQueryRef = useRef<string>(''); 1819c8eb6fS猫头猫 19*0b940038S猫头猫 /** 20*0b940038S猫头猫 * query: 搜索词 21*0b940038S猫头猫 * queryPage: 搜索页码 22*0b940038S猫头猫 * type: 搜索类型 23*0b940038S猫头猫 * pluginHash: 搜索条件 24*0b940038S猫头猫 */ 25ad2ad8ffS猫头猫 const search = useCallback( 26ad2ad8ffS猫头猫 async function ( 27bf6e62f2S猫头猫 query?: string, 28*0b940038S猫头猫 queryPage?: number, 29*0b940038S猫头猫 type?: ICommon.SupportMediaType, 30*0b940038S猫头猫 pluginHash?: string, 31bf6e62f2S猫头猫 ) { 32*0b940038S猫头猫 /** 如果没有指定插件,就用所有插件搜索 */ 33*0b940038S猫头猫 34*0b940038S猫头猫 let plugins: Plugin[] = []; 35*0b940038S猫头猫 if (pluginHash) { 36*0b940038S猫头猫 const tgtPlugin = pluginManager.getPluginByHash(pluginHash); 37*0b940038S猫头猫 tgtPlugin && (plugins = [tgtPlugin]); 38*0b940038S猫头猫 } else { 39*0b940038S猫头猫 plugins = pluginManager.getValidPlugins(); 40*0b940038S猫头猫 } 41*0b940038S猫头猫 4219c8eb6fS猫头猫 // 使用选中插件搜素 43bf6e62f2S猫头猫 plugins.forEach(async plugin => { 44*0b940038S猫头猫 const _platform = plugin.instance.platform; 45*0b940038S猫头猫 const _hash = plugin.hash; 46*0b940038S猫头猫 if (!_platform || !_hash) { 47*0b940038S猫头猫 // 插件无效,此时直接进入结果页 48bf6e62f2S猫头猫 setPageStatus(PageStatus.RESULT); 49bf6e62f2S猫头猫 return; 50bf6e62f2S猫头猫 } 51*0b940038S猫头猫 52*0b940038S猫头猫 const searchType = type ?? plugin.instance.defaultSearchType ?? 'music'; 53*0b940038S猫头猫 // 上一份搜索结果 54*0b940038S猫头猫 const prevPluginResult = searchResults[searchType][plugin.hash]; 55*0b940038S猫头猫 /** 上一份搜索还没返回/已经结束 */ 5619c8eb6fS猫头猫 if ( 57*0b940038S猫头猫 (prevPluginResult?.state === SearchStateCode.PENDING || 58*0b940038S猫头猫 prevPluginResult?.state === SearchStateCode.FINISHED) && 5919c8eb6fS猫头猫 undefined === query 6019c8eb6fS猫头猫 ) { 61bf6e62f2S猫头猫 return; 62bf6e62f2S猫头猫 } 63d139abf1S猫头猫 6419c8eb6fS猫头猫 // 是否是一次新的搜索 65bf6e62f2S猫头猫 const newSearch = 66*0b940038S猫头猫 query || prevPluginResult?.page === undefined || queryPage === 1; 6719c8eb6fS猫头猫 68*0b940038S猫头猫 // 本次搜索关键词 69*0b940038S猫头猫 currentQueryRef.current = query = 70*0b940038S猫头猫 query ?? prevPluginResult?.query ?? ''; 7119c8eb6fS猫头猫 7219c8eb6fS猫头猫 /** 搜索的页码 */ 73bf6e62f2S猫头猫 const page = 74*0b940038S猫头猫 queryPage ?? newSearch ? 1 : (prevPluginResult?.page ?? 0) + 1; 75d139abf1S猫头猫 76bf6e62f2S猫头猫 try { 7792a7e801S猫头猫 setSearchResults( 7892a7e801S猫头猫 produce(draft => { 79*0b940038S猫头猫 const prevMediaResult: any = draft[searchType]; 80*0b940038S猫头猫 prevMediaResult[_hash] = { 81*0b940038S猫头猫 state: newSearch 82*0b940038S猫头猫 ? SearchStateCode.PENDING_FP 83*0b940038S猫头猫 : SearchStateCode.PENDING, 84*0b940038S猫头猫 // @ts-ignore 85*0b940038S猫头猫 data: newSearch ? [] : prevMediaResult[_hash]?.data ?? [], 8692a7e801S猫头猫 query: query, 87*0b940038S猫头猫 page, 8892a7e801S猫头猫 }; 8992a7e801S猫头猫 return draft; 90bf6e62f2S猫头猫 }), 91bf6e62f2S猫头猫 ); 92ad2ad8ffS猫头猫 // !! jscore的promise有问题,改成hermes就好了,可能和JIT有关,不知道。 93*0b940038S猫头猫 const result = await plugin?.instance?.search?.( 94*0b940038S猫头猫 query, 95*0b940038S猫头猫 page, 96*0b940038S猫头猫 searchType, 97*0b940038S猫头猫 ); 98*0b940038S猫头猫 /** 如果搜索结果不是本次结果 */ 9919c8eb6fS猫头猫 if (currentQueryRef.current !== query) { 10019c8eb6fS猫头猫 return; 10119c8eb6fS猫头猫 } 102*0b940038S猫头猫 /** 切换到结果页 */ 103bf6e62f2S猫头猫 setPageStatus(PageStatus.RESULT); 104bf6e62f2S猫头猫 if (!result) { 105bf6e62f2S猫头猫 throw new Error(); 106bf6e62f2S猫头猫 } 107bf6e62f2S猫头猫 setSearchResults( 108bf6e62f2S猫头猫 produce(draft => { 109*0b940038S猫头猫 const prevMediaResult = draft[searchType]; 110*0b940038S猫头猫 const prevPluginResult: any = prevMediaResult[_hash] ?? { 111*0b940038S猫头猫 data: [], 112*0b940038S猫头猫 }; 113*0b940038S猫头猫 const tagedResult = makeTag(result.data ?? [], _platform); 114*0b940038S猫头猫 115*0b940038S猫头猫 prevMediaResult[_hash] = { 116*0b940038S猫头猫 state: 117*0b940038S猫头猫 (result?.isEnd === false && result?.data?.length) 118*0b940038S猫头猫 ? SearchStateCode.PARTLY_DONE 119*0b940038S猫头猫 : SearchStateCode.FINISHED, 120*0b940038S猫头猫 query, 121*0b940038S猫头猫 page, 122*0b940038S猫头猫 data: newSearch 123*0b940038S猫头猫 ? tagedResult 124*0b940038S猫头猫 : (prevPluginResult.data ?? []).concat(tagedResult), 125d139abf1S猫头猫 }; 126d139abf1S猫头猫 return draft; 127bf6e62f2S猫头猫 }), 128bf6e62f2S猫头猫 ); 1292f655a9eS猫头猫 } catch (e) { 1302f655a9eS猫头猫 console.log('SEARCH ERROR', e); 131*0b940038S猫头猫 setPageStatus(PageStatus.RESULT); 132bf6e62f2S猫头猫 setSearchResults( 133bf6e62f2S猫头猫 produce(draft => { 134*0b940038S猫头猫 const prevMediaResult = draft[searchType]; 135*0b940038S猫头猫 const prevPluginResult = prevMediaResult[_hash] ?? {data: []}; 136*0b940038S猫头猫 137*0b940038S猫头猫 prevPluginResult.state = SearchStateCode.PARTLY_DONE; 138*0b940038S猫头猫 return draft; 139bf6e62f2S猫头猫 }), 140bf6e62f2S猫头猫 ); 141bf6e62f2S猫头猫 } 142bf6e62f2S猫头猫 }); 143bf6e62f2S猫头猫 }, 144ad2ad8ffS猫头猫 [searchResults], 145ad2ad8ffS猫头猫 ); 146bf6e62f2S猫头猫 147bf6e62f2S猫头猫 return search; 148bf6e62f2S猫头猫} 149bf6e62f2S猫头猫 150*0b940038S猫头猫function makeTag<X extends Record<string, any>[] = any[]>( 151*0b940038S猫头猫 objArray: X, 152*0b940038S猫头猫 tag: string, 153*0b940038S猫头猫): X { 154*0b940038S猫头猫 objArray.forEach(_ => { 155*0b940038S猫头猫 _.platform = tag; 156*0b940038S猫头猫 }); 157*0b940038S猫头猫 return objArray; 158d139abf1S猫头猫} 159