xref: /MusicFree/src/pages/searchPage/hooks/useSearch.ts (revision a4ae8da553c6798d1634b4da485abd00e53dbd67)
10b940038S猫头猫import {Plugin, pluginManager} from '@/common/pluginManager';
2bf6e62f2S猫头猫import produce from 'immer';
3bf6e62f2S猫头猫import {useAtom, useSetAtom} from 'jotai';
419c8eb6fS猫头猫import {useCallback, useRef} from 'react';
50b940038S猫头猫import {
60b940038S猫头猫  PageStatus,
70b940038S猫头猫  pageStatusAtom,
80b940038S猫头猫  searchResultsAtom,
90b940038S猫头猫  SearchStateCode,
100b940038S猫头猫} 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猫头猫
190b940038S猫头猫  /**
200b940038S猫头猫   * query: 搜索词
210b940038S猫头猫   * queryPage: 搜索页码
220b940038S猫头猫   * type: 搜索类型
230b940038S猫头猫   * pluginHash: 搜索条件
240b940038S猫头猫   */
25ad2ad8ffS猫头猫  const search = useCallback(
26ad2ad8ffS猫头猫    async function (
27bf6e62f2S猫头猫      query?: string,
280b940038S猫头猫      queryPage?: number,
290b940038S猫头猫      type?: ICommon.SupportMediaType,
300b940038S猫头猫      pluginHash?: string,
31bf6e62f2S猫头猫    ) {
320b940038S猫头猫      /** 如果没有指定插件,就用所有插件搜索 */
330b940038S猫头猫
340b940038S猫头猫      let plugins: Plugin[] = [];
350b940038S猫头猫      if (pluginHash) {
360b940038S猫头猫        const tgtPlugin = pluginManager.getPluginByHash(pluginHash);
370b940038S猫头猫        tgtPlugin && (plugins = [tgtPlugin]);
380b940038S猫头猫      } else {
390b940038S猫头猫        plugins = pluginManager.getValidPlugins();
400b940038S猫头猫      }
410b940038S猫头猫
4219c8eb6fS猫头猫      // 使用选中插件搜素
43bf6e62f2S猫头猫      plugins.forEach(async plugin => {
440b940038S猫头猫        const _platform = plugin.instance.platform;
450b940038S猫头猫        const _hash = plugin.hash;
460b940038S猫头猫        if (!_platform || !_hash) {
470b940038S猫头猫          // 插件无效,此时直接进入结果页
48bf6e62f2S猫头猫          setPageStatus(PageStatus.RESULT);
49bf6e62f2S猫头猫          return;
50bf6e62f2S猫头猫        }
510b940038S猫头猫
520b940038S猫头猫        const searchType = type ?? plugin.instance.defaultSearchType ?? 'music';
530b940038S猫头猫        // 上一份搜索结果
540b940038S猫头猫        const prevPluginResult = searchResults[searchType][plugin.hash];
550b940038S猫头猫        /** 上一份搜索还没返回/已经结束 */
5619c8eb6fS猫头猫        if (
570b940038S猫头猫          (prevPluginResult?.state === SearchStateCode.PENDING ||
580b940038S猫头猫            prevPluginResult?.state === SearchStateCode.FINISHED) &&
5919c8eb6fS猫头猫          undefined === query
6019c8eb6fS猫头猫        ) {
61bf6e62f2S猫头猫          return;
62bf6e62f2S猫头猫        }
63d139abf1S猫头猫
64*a4ae8da5S猫头猫        console.log('SEARCHWITH', _platform, searchType);
65*a4ae8da5S猫头猫
6619c8eb6fS猫头猫        // 是否是一次新的搜索
67bf6e62f2S猫头猫        const newSearch =
680b940038S猫头猫          query || prevPluginResult?.page === undefined || queryPage === 1;
6919c8eb6fS猫头猫
700b940038S猫头猫        // 本次搜索关键词
710b940038S猫头猫        currentQueryRef.current = query =
720b940038S猫头猫          query ?? prevPluginResult?.query ?? '';
7319c8eb6fS猫头猫
7419c8eb6fS猫头猫        /** 搜索的页码 */
75bf6e62f2S猫头猫        const page =
760b940038S猫头猫          queryPage ?? newSearch ? 1 : (prevPluginResult?.page ?? 0) + 1;
77d139abf1S猫头猫
78bf6e62f2S猫头猫        try {
7992a7e801S猫头猫          setSearchResults(
8092a7e801S猫头猫            produce(draft => {
810b940038S猫头猫              const prevMediaResult: any = draft[searchType];
820b940038S猫头猫              prevMediaResult[_hash] = {
830b940038S猫头猫                state: newSearch
840b940038S猫头猫                  ? SearchStateCode.PENDING_FP
850b940038S猫头猫                  : SearchStateCode.PENDING,
860b940038S猫头猫                // @ts-ignore
870b940038S猫头猫                data: newSearch ? [] : prevMediaResult[_hash]?.data ?? [],
8892a7e801S猫头猫                query: query,
890b940038S猫头猫                page,
9092a7e801S猫头猫              };
91bf6e62f2S猫头猫            }),
92bf6e62f2S猫头猫          );
93ad2ad8ffS猫头猫          // !! jscore的promise有问题,改成hermes就好了,可能和JIT有关,不知道。
940b940038S猫头猫          const result = await plugin?.instance?.search?.(
950b940038S猫头猫            query,
960b940038S猫头猫            page,
970b940038S猫头猫            searchType,
980b940038S猫头猫          );
990b940038S猫头猫          /** 如果搜索结果不是本次结果 */
10019c8eb6fS猫头猫          if (currentQueryRef.current !== query) {
10119c8eb6fS猫头猫            return;
10219c8eb6fS猫头猫          }
1030b940038S猫头猫          /** 切换到结果页 */
104bf6e62f2S猫头猫          setPageStatus(PageStatus.RESULT);
105bf6e62f2S猫头猫          if (!result) {
106bf6e62f2S猫头猫            throw new Error();
107bf6e62f2S猫头猫          }
108bf6e62f2S猫头猫          setSearchResults(
109bf6e62f2S猫头猫            produce(draft => {
1100b940038S猫头猫              const prevMediaResult = draft[searchType];
1110b940038S猫头猫              const prevPluginResult: any = prevMediaResult[_hash] ?? {
1120b940038S猫头猫                data: [],
1130b940038S猫头猫              };
1140b940038S猫头猫              const tagedResult = makeTag(result.data ?? [], _platform);
1150b940038S猫头猫
1160b940038S猫头猫              prevMediaResult[_hash] = {
1170b940038S猫头猫                state:
118*a4ae8da5S猫头猫                  result?.isEnd === false && result?.data?.length
1190b940038S猫头猫                    ? SearchStateCode.PARTLY_DONE
1200b940038S猫头猫                    : SearchStateCode.FINISHED,
1210b940038S猫头猫                query,
1220b940038S猫头猫                page,
1230b940038S猫头猫                data: newSearch
1240b940038S猫头猫                  ? tagedResult
1250b940038S猫头猫                  : (prevPluginResult.data ?? []).concat(tagedResult),
126d139abf1S猫头猫              };
127d139abf1S猫头猫              return draft;
128bf6e62f2S猫头猫            }),
129bf6e62f2S猫头猫          );
1302f655a9eS猫头猫        } catch (e) {
1312f655a9eS猫头猫          console.log('SEARCH ERROR', e);
1320b940038S猫头猫          setPageStatus(PageStatus.RESULT);
133bf6e62f2S猫头猫          setSearchResults(
134bf6e62f2S猫头猫            produce(draft => {
1350b940038S猫头猫              const prevMediaResult = draft[searchType];
1360b940038S猫头猫              const prevPluginResult = prevMediaResult[_hash] ?? {data: []};
1370b940038S猫头猫
1380b940038S猫头猫              prevPluginResult.state = SearchStateCode.PARTLY_DONE;
1390b940038S猫头猫              return draft;
140bf6e62f2S猫头猫            }),
141bf6e62f2S猫头猫          );
142bf6e62f2S猫头猫        }
143bf6e62f2S猫头猫      });
144bf6e62f2S猫头猫    },
145ad2ad8ffS猫头猫    [searchResults],
146ad2ad8ffS猫头猫  );
147bf6e62f2S猫头猫
148bf6e62f2S猫头猫  return search;
149bf6e62f2S猫头猫}
150bf6e62f2S猫头猫
1510b940038S猫头猫function makeTag<X extends Record<string, any>[] = any[]>(
1520b940038S猫头猫  objArray: X,
1530b940038S猫头猫  tag: string,
1540b940038S猫头猫): X {
1550b940038S猫头猫  objArray.forEach(_ => {
1560b940038S猫头猫    _.platform = tag;
1570b940038S猫头猫  });
1580b940038S猫头猫  return objArray;
159d139abf1S猫头猫}
160