xref: /MusicFree/src/pages/searchPage/hooks/useSearch.ts (revision 5276aef9a9da3850fb02bcdfa8c468cc9b4bb88b)
1242960d3S猫头猫import {errorLog, trace} from '@/utils/log';
220e2869eS猫头猫import {RequestStateCode} from '@/constants/commonConst';
3bf6e62f2S猫头猫import produce from 'immer';
4bf6e62f2S猫头猫import {useAtom, useSetAtom} from 'jotai';
519c8eb6fS猫头猫import {useCallback, useRef} from 'react';
620e2869eS猫头猫import {PageStatus, pageStatusAtom, searchResultsAtom} from '../store/atoms';
7927dbe93S猫头猫import PluginManager, { Plugin } from '@/core/pluginManager';
8bf6e62f2S猫头猫
9bf6e62f2S猫头猫export default function useSearch() {
10bf6e62f2S猫头猫  const setPageStatus = useSetAtom(pageStatusAtom);
11bf6e62f2S猫头猫  const [searchResults, setSearchResults] = useAtom(searchResultsAtom);
12bf6e62f2S猫头猫
1319c8eb6fS猫头猫  // 当前正在搜索
1419c8eb6fS猫头猫  const currentQueryRef = useRef<string>('');
1519c8eb6fS猫头猫
160b940038S猫头猫  /**
170b940038S猫头猫   * query: 搜索词
180b940038S猫头猫   * queryPage: 搜索页码
190b940038S猫头猫   * type: 搜索类型
200b940038S猫头猫   * pluginHash: 搜索条件
210b940038S猫头猫   */
22ad2ad8ffS猫头猫  const search = useCallback(
23ad2ad8ffS猫头猫    async function (
24bf6e62f2S猫头猫      query?: string,
250b940038S猫头猫      queryPage?: number,
260b940038S猫头猫      type?: ICommon.SupportMediaType,
270b940038S猫头猫      pluginHash?: string,
28bf6e62f2S猫头猫    ) {
290b940038S猫头猫      /** 如果没有指定插件,就用所有插件搜索 */
300b940038S猫头猫
310b940038S猫头猫      let plugins: Plugin[] = [];
320b940038S猫头猫      if (pluginHash) {
338b88e961S猫头猫        const tgtPlugin = PluginManager.getByHash(pluginHash);
340b940038S猫头猫        tgtPlugin && (plugins = [tgtPlugin]);
350b940038S猫头猫      } else {
368b88e961S猫头猫        plugins = PluginManager.getValidPlugins();
370b940038S猫头猫      }
380b940038S猫头猫
3919c8eb6fS猫头猫      // 使用选中插件搜素
40bf6e62f2S猫头猫      plugins.forEach(async plugin => {
410b940038S猫头猫        const _platform = plugin.instance.platform;
420b940038S猫头猫        const _hash = plugin.hash;
430b940038S猫头猫        if (!_platform || !_hash) {
440b940038S猫头猫          // 插件无效,此时直接进入结果页
45bf6e62f2S猫头猫          setPageStatus(PageStatus.RESULT);
46bf6e62f2S猫头猫          return;
47bf6e62f2S猫头猫        }
480b940038S猫头猫
490b940038S猫头猫        const searchType = type ?? plugin.instance.defaultSearchType ?? 'music';
500b940038S猫头猫        // 上一份搜索结果
510b940038S猫头猫        const prevPluginResult = searchResults[searchType][plugin.hash];
520b940038S猫头猫        /** 上一份搜索还没返回/已经结束 */
5319c8eb6fS猫头猫        if (
5420e2869eS猫头猫          (prevPluginResult?.state === RequestStateCode.PENDING ||
5520e2869eS猫头猫            prevPluginResult?.state === RequestStateCode.FINISHED) &&
5619c8eb6fS猫头猫          undefined === query
5719c8eb6fS猫头猫        ) {
58bf6e62f2S猫头猫          return;
59bf6e62f2S猫头猫        }
60d139abf1S猫头猫
6119c8eb6fS猫头猫        // 是否是一次新的搜索
62bf6e62f2S猫头猫        const newSearch =
630b940038S猫头猫          query || prevPluginResult?.page === undefined || queryPage === 1;
6419c8eb6fS猫头猫
650b940038S猫头猫        // 本次搜索关键词
660b940038S猫头猫        currentQueryRef.current = query =
670b940038S猫头猫          query ?? prevPluginResult?.query ?? '';
6819c8eb6fS猫头猫
6919c8eb6fS猫头猫        /** 搜索的页码 */
70bf6e62f2S猫头猫        const page =
710b940038S猫头猫          queryPage ?? newSearch ? 1 : (prevPluginResult?.page ?? 0) + 1;
72d139abf1S猫头猫
7320e2869eS猫头猫        trace('开始搜索', {
7420e2869eS猫头猫          _platform,
7520e2869eS猫头猫          query,
7620e2869eS猫头猫          page,
7720e2869eS猫头猫          searchType,
7820e2869eS猫头猫        });
7920e2869eS猫头猫
80bf6e62f2S猫头猫        try {
8192a7e801S猫头猫          setSearchResults(
8292a7e801S猫头猫            produce(draft => {
830b940038S猫头猫              const prevMediaResult: any = draft[searchType];
840b940038S猫头猫              prevMediaResult[_hash] = {
850b940038S猫头猫                state: newSearch
8620e2869eS猫头猫                  ? RequestStateCode.PENDING_FP
8720e2869eS猫头猫                  : RequestStateCode.PENDING,
880b940038S猫头猫                // @ts-ignore
890b940038S猫头猫                data: newSearch ? [] : prevMediaResult[_hash]?.data ?? [],
9092a7e801S猫头猫                query: query,
910b940038S猫头猫                page,
9292a7e801S猫头猫              };
93bf6e62f2S猫头猫            }),
94bf6e62f2S猫头猫          );
95ad2ad8ffS猫头猫          // !! jscore的promise有问题,改成hermes就好了,可能和JIT有关,不知道。
96*5276aef9S猫头猫          const result = await plugin?.methods?.search?.(
970b940038S猫头猫            query,
980b940038S猫头猫            page,
990b940038S猫头猫            searchType,
1000b940038S猫头猫          );
1010b940038S猫头猫          /** 如果搜索结果不是本次结果 */
10219c8eb6fS猫头猫          if (currentQueryRef.current !== query) {
10319c8eb6fS猫头猫            return;
10419c8eb6fS猫头猫          }
1050b940038S猫头猫          /** 切换到结果页 */
106bf6e62f2S猫头猫          setPageStatus(PageStatus.RESULT);
107bf6e62f2S猫头猫          if (!result) {
10820e2869eS猫头猫            throw new Error('搜索结果为空');
109bf6e62f2S猫头猫          }
110bf6e62f2S猫头猫          setSearchResults(
111bf6e62f2S猫头猫            produce(draft => {
1120b940038S猫头猫              const prevMediaResult = draft[searchType];
1130b940038S猫头猫              const prevPluginResult: any = prevMediaResult[_hash] ?? {
1140b940038S猫头猫                data: [],
1150b940038S猫头猫              };
1168b88e961S猫头猫              const currResult = result.data ?? [];
1170b940038S猫头猫
1180b940038S猫头猫              prevMediaResult[_hash] = {
1190b940038S猫头猫                state:
120a4ae8da5S猫头猫                  result?.isEnd === false && result?.data?.length
12120e2869eS猫头猫                    ? RequestStateCode.PARTLY_DONE
12220e2869eS猫头猫                    : RequestStateCode.FINISHED,
1230b940038S猫头猫                query,
1240b940038S猫头猫                page,
1250b940038S猫头猫                data: newSearch
1268b88e961S猫头猫                  ? currResult
1278b88e961S猫头猫                  : (prevPluginResult.data ?? []).concat(currResult),
128d139abf1S猫头猫              };
129d139abf1S猫头猫              return draft;
130bf6e62f2S猫头猫            }),
131bf6e62f2S猫头猫          );
1322f655a9eS猫头猫        } catch (e) {
13320e2869eS猫头猫          errorLog('', e);
1340b940038S猫头猫          setPageStatus(PageStatus.RESULT);
135bf6e62f2S猫头猫          setSearchResults(
136bf6e62f2S猫头猫            produce(draft => {
1370b940038S猫头猫              const prevMediaResult = draft[searchType];
1380b940038S猫头猫              const prevPluginResult = prevMediaResult[_hash] ?? {data: []};
1390b940038S猫头猫
14020e2869eS猫头猫              prevPluginResult.state = RequestStateCode.PARTLY_DONE;
1410b940038S猫头猫              return draft;
142bf6e62f2S猫头猫            }),
143bf6e62f2S猫头猫          );
144bf6e62f2S猫头猫        }
145bf6e62f2S猫头猫      });
146bf6e62f2S猫头猫    },
147ad2ad8ffS猫头猫    [searchResults],
148ad2ad8ffS猫头猫  );
149bf6e62f2S猫头猫
150bf6e62f2S猫头猫  return search;
151bf6e62f2S猫头猫}
152bf6e62f2S猫头猫
153