xref: /MusicFree/src/pages/searchPage/hooks/useSearch.ts (revision 20e2869e216f04ba2dbb37ce330d5579608bc45e)
1*20e2869eS猫头猫import {errorLog, trace} from '@/common/logManager';
20b940038S猫头猫import {Plugin, pluginManager} from '@/common/pluginManager';
3*20e2869eS猫头猫import {RequestStateCode} from '@/constants/commonConst';
4*20e2869eS猫头猫import { makeTag } from '@/utils/makeTag';
5bf6e62f2S猫头猫import produce from 'immer';
6bf6e62f2S猫头猫import {useAtom, useSetAtom} from 'jotai';
719c8eb6fS猫头猫import {useCallback, useRef} from 'react';
8*20e2869eS猫头猫import {PageStatus, pageStatusAtom, searchResultsAtom} from '../store/atoms';
9bf6e62f2S猫头猫
10bf6e62f2S猫头猫export default function useSearch() {
11bf6e62f2S猫头猫  const setPageStatus = useSetAtom(pageStatusAtom);
12bf6e62f2S猫头猫  const [searchResults, setSearchResults] = useAtom(searchResultsAtom);
13bf6e62f2S猫头猫
1419c8eb6fS猫头猫  // 当前正在搜索
1519c8eb6fS猫头猫  const currentQueryRef = useRef<string>('');
1619c8eb6fS猫头猫
170b940038S猫头猫  /**
180b940038S猫头猫   * query: 搜索词
190b940038S猫头猫   * queryPage: 搜索页码
200b940038S猫头猫   * type: 搜索类型
210b940038S猫头猫   * pluginHash: 搜索条件
220b940038S猫头猫   */
23ad2ad8ffS猫头猫  const search = useCallback(
24ad2ad8ffS猫头猫    async function (
25bf6e62f2S猫头猫      query?: string,
260b940038S猫头猫      queryPage?: number,
270b940038S猫头猫      type?: ICommon.SupportMediaType,
280b940038S猫头猫      pluginHash?: string,
29bf6e62f2S猫头猫    ) {
300b940038S猫头猫      /** 如果没有指定插件,就用所有插件搜索 */
310b940038S猫头猫
320b940038S猫头猫      let plugins: Plugin[] = [];
330b940038S猫头猫      if (pluginHash) {
340b940038S猫头猫        const tgtPlugin = pluginManager.getPluginByHash(pluginHash);
350b940038S猫头猫        tgtPlugin && (plugins = [tgtPlugin]);
360b940038S猫头猫      } else {
370b940038S猫头猫        plugins = pluginManager.getValidPlugins();
380b940038S猫头猫      }
390b940038S猫头猫
4019c8eb6fS猫头猫      // 使用选中插件搜素
41bf6e62f2S猫头猫      plugins.forEach(async plugin => {
420b940038S猫头猫        const _platform = plugin.instance.platform;
430b940038S猫头猫        const _hash = plugin.hash;
440b940038S猫头猫        if (!_platform || !_hash) {
450b940038S猫头猫          // 插件无效,此时直接进入结果页
46bf6e62f2S猫头猫          setPageStatus(PageStatus.RESULT);
47bf6e62f2S猫头猫          return;
48bf6e62f2S猫头猫        }
490b940038S猫头猫
500b940038S猫头猫        const searchType = type ?? plugin.instance.defaultSearchType ?? 'music';
510b940038S猫头猫        // 上一份搜索结果
520b940038S猫头猫        const prevPluginResult = searchResults[searchType][plugin.hash];
530b940038S猫头猫        /** 上一份搜索还没返回/已经结束 */
5419c8eb6fS猫头猫        if (
55*20e2869eS猫头猫          (prevPluginResult?.state === RequestStateCode.PENDING ||
56*20e2869eS猫头猫            prevPluginResult?.state === RequestStateCode.FINISHED) &&
5719c8eb6fS猫头猫          undefined === query
5819c8eb6fS猫头猫        ) {
59bf6e62f2S猫头猫          return;
60bf6e62f2S猫头猫        }
61d139abf1S猫头猫
6219c8eb6fS猫头猫        // 是否是一次新的搜索
63bf6e62f2S猫头猫        const newSearch =
640b940038S猫头猫          query || prevPluginResult?.page === undefined || queryPage === 1;
6519c8eb6fS猫头猫
660b940038S猫头猫        // 本次搜索关键词
670b940038S猫头猫        currentQueryRef.current = query =
680b940038S猫头猫          query ?? prevPluginResult?.query ?? '';
6919c8eb6fS猫头猫
7019c8eb6fS猫头猫        /** 搜索的页码 */
71bf6e62f2S猫头猫        const page =
720b940038S猫头猫          queryPage ?? newSearch ? 1 : (prevPluginResult?.page ?? 0) + 1;
73d139abf1S猫头猫
74*20e2869eS猫头猫        trace('开始搜索', {
75*20e2869eS猫头猫          _platform,
76*20e2869eS猫头猫          query,
77*20e2869eS猫头猫          page,
78*20e2869eS猫头猫          searchType,
79*20e2869eS猫头猫        });
80*20e2869eS猫头猫
81bf6e62f2S猫头猫        try {
8292a7e801S猫头猫          setSearchResults(
8392a7e801S猫头猫            produce(draft => {
840b940038S猫头猫              const prevMediaResult: any = draft[searchType];
850b940038S猫头猫              prevMediaResult[_hash] = {
860b940038S猫头猫                state: newSearch
87*20e2869eS猫头猫                  ? RequestStateCode.PENDING_FP
88*20e2869eS猫头猫                  : RequestStateCode.PENDING,
890b940038S猫头猫                // @ts-ignore
900b940038S猫头猫                data: newSearch ? [] : prevMediaResult[_hash]?.data ?? [],
9192a7e801S猫头猫                query: query,
920b940038S猫头猫                page,
9392a7e801S猫头猫              };
94bf6e62f2S猫头猫            }),
95bf6e62f2S猫头猫          );
96ad2ad8ffS猫头猫          // !! jscore的promise有问题,改成hermes就好了,可能和JIT有关,不知道。
970b940038S猫头猫          const result = await plugin?.instance?.search?.(
980b940038S猫头猫            query,
990b940038S猫头猫            page,
1000b940038S猫头猫            searchType,
1010b940038S猫头猫          );
1020b940038S猫头猫          /** 如果搜索结果不是本次结果 */
10319c8eb6fS猫头猫          if (currentQueryRef.current !== query) {
10419c8eb6fS猫头猫            return;
10519c8eb6fS猫头猫          }
1060b940038S猫头猫          /** 切换到结果页 */
107bf6e62f2S猫头猫          setPageStatus(PageStatus.RESULT);
108bf6e62f2S猫头猫          if (!result) {
109*20e2869eS猫头猫            throw new Error('搜索结果为空');
110bf6e62f2S猫头猫          }
111bf6e62f2S猫头猫          setSearchResults(
112bf6e62f2S猫头猫            produce(draft => {
1130b940038S猫头猫              const prevMediaResult = draft[searchType];
1140b940038S猫头猫              const prevPluginResult: any = prevMediaResult[_hash] ?? {
1150b940038S猫头猫                data: [],
1160b940038S猫头猫              };
1170b940038S猫头猫              const tagedResult = makeTag(result.data ?? [], _platform);
1180b940038S猫头猫
1190b940038S猫头猫              prevMediaResult[_hash] = {
1200b940038S猫头猫                state:
121a4ae8da5S猫头猫                  result?.isEnd === false && result?.data?.length
122*20e2869eS猫头猫                    ? RequestStateCode.PARTLY_DONE
123*20e2869eS猫头猫                    : RequestStateCode.FINISHED,
1240b940038S猫头猫                query,
1250b940038S猫头猫                page,
1260b940038S猫头猫                data: newSearch
1270b940038S猫头猫                  ? tagedResult
1280b940038S猫头猫                  : (prevPluginResult.data ?? []).concat(tagedResult),
129d139abf1S猫头猫              };
130d139abf1S猫头猫              return draft;
131bf6e62f2S猫头猫            }),
132bf6e62f2S猫头猫          );
1332f655a9eS猫头猫        } catch (e) {
134*20e2869eS猫头猫          errorLog('', e);
1350b940038S猫头猫          setPageStatus(PageStatus.RESULT);
136bf6e62f2S猫头猫          setSearchResults(
137bf6e62f2S猫头猫            produce(draft => {
1380b940038S猫头猫              const prevMediaResult = draft[searchType];
1390b940038S猫头猫              const prevPluginResult = prevMediaResult[_hash] ?? {data: []};
1400b940038S猫头猫
141*20e2869eS猫头猫              prevPluginResult.state = RequestStateCode.PARTLY_DONE;
1420b940038S猫头猫              return draft;
143bf6e62f2S猫头猫            }),
144bf6e62f2S猫头猫          );
145bf6e62f2S猫头猫        }
146bf6e62f2S猫头猫      });
147bf6e62f2S猫头猫    },
148ad2ad8ffS猫头猫    [searchResults],
149ad2ad8ffS猫头猫  );
150bf6e62f2S猫头猫
151bf6e62f2S猫头猫  return search;
152bf6e62f2S猫头猫}
153bf6e62f2S猫头猫
154