xref: /MusicFree/src/pages/searchPage/hooks/useSearch.ts (revision 2f655a9e3b66a152e554db5b6801c554a8ee8c95)
1bf6e62f2S猫头猫import {pluginManager, usePlugins} from '@/common/pluginManager';
2bf6e62f2S猫头猫import produce from 'immer';
3bf6e62f2S猫头猫import {useAtom, useSetAtom} from 'jotai';
4bf6e62f2S猫头猫import {useCallback} from 'react';
5bf6e62f2S猫头猫import {PageStatus, pageStatusAtom, searchResultsAtom} from '../store/atoms';
6bf6e62f2S猫头猫
7bf6e62f2S猫头猫const mergeData = (
8bf6e62f2S猫头猫  target: IPlugin.ISearchResult,
9bf6e62f2S猫头猫  original: IPlugin.ISearchResult,
10bf6e62f2S猫头猫  key: IPlugin.ISearchResultType,
11bf6e62f2S猫头猫  platform: string,
12bf6e62f2S猫头猫) => {
13bf6e62f2S猫头猫  // @ts-ignore
14bf6e62f2S猫头猫  target[key] = (target[key] ?? [])?.concat(
15bf6e62f2S猫头猫    (original[key] ?? [])?.map(_ => {
16bf6e62f2S猫头猫      _.platform = platform;
17bf6e62f2S猫头猫      return _;
18bf6e62f2S猫头猫    }),
19bf6e62f2S猫头猫  );
20bf6e62f2S猫头猫  return target;
21bf6e62f2S猫头猫};
22bf6e62f2S猫头猫
23bf6e62f2S猫头猫export default function useSearch() {
24bf6e62f2S猫头猫  const setPageStatus = useSetAtom(pageStatusAtom);
25bf6e62f2S猫头猫  const [searchResults, setSearchResults] = useAtom(searchResultsAtom);
26bf6e62f2S猫头猫
27bf6e62f2S猫头猫  const search = useCallback(async function (
28bf6e62f2S猫头猫    query?: string,
29bf6e62f2S猫头猫    platformHash = 'all',
30bf6e62f2S猫头猫    queryPage = undefined,
31bf6e62f2S猫头猫  ) {
32bf6e62f2S猫头猫    // 如果没有搜索结果缓存,那就是没有搜过
33bf6e62f2S猫头猫    const installedPlugins = pluginManager.getValidPlugins();
34bf6e62f2S猫头猫    const plugins =
35bf6e62f2S猫头猫      platformHash === 'all'
36bf6e62f2S猫头猫        ? installedPlugins
37bf6e62f2S猫头猫        : [installedPlugins.find(_ => _.hash === platformHash)];
38bf6e62f2S猫头猫    plugins.forEach(async plugin => {
39bf6e62f2S猫头猫      const _platform = plugin?.instance.platform;
40bf6e62f2S猫头猫      const _hash = plugin?.hash;
41bf6e62f2S猫头猫      if (!plugin || !_platform || !_hash) {
42bf6e62f2S猫头猫        // 没有插件,此时直接进入结果页
43bf6e62f2S猫头猫        setPageStatus(PageStatus.RESULT);
44bf6e62f2S猫头猫        return;
45bf6e62f2S猫头猫      }
46bf6e62f2S猫头猫      const _prevResult = searchResults[_hash];
47bf6e62f2S猫头猫      if (_prevResult?.pending) {
48bf6e62f2S猫头猫        return;
49bf6e62f2S猫头猫      }
50bf6e62f2S猫头猫      const newSearch =
51bf6e62f2S猫头猫        query || _prevResult?.currentPage === undefined || queryPage === 1;
52bf6e62f2S猫头猫      query = query ?? _prevResult?.query ?? '';
53bf6e62f2S猫头猫      const page =
54bf6e62f2S猫头猫        queryPage ?? newSearch ? 1 : (_prevResult.currentPage ?? 0) + 1;
55bf6e62f2S猫头猫      try {
56bf6e62f2S猫头猫        setSearchResults(
57bf6e62f2S猫头猫          produce(draft => {
58bf6e62f2S猫头猫            const prev = draft[_hash] ?? {};
59bf6e62f2S猫头猫            prev.query = query;
60bf6e62f2S猫头猫            prev.pending = true;
61bf6e62f2S猫头猫            draft[_hash] = prev;
62bf6e62f2S猫头猫          }),
63bf6e62f2S猫头猫        );
64bf6e62f2S猫头猫        // !! jscore的promise有问题,改成hermes就好了,可能和JIT有关,不知道。
65bf6e62f2S猫头猫        const result = await plugin?.instance?.search?.(query, page);
66bf6e62f2S猫头猫        setPageStatus(PageStatus.RESULT);
67bf6e62f2S猫头猫        if (!result) {
68bf6e62f2S猫头猫          throw new Error();
69bf6e62f2S猫头猫        }
70bf6e62f2S猫头猫        setSearchResults(
71bf6e62f2S猫头猫          produce(draft => {
72bf6e62f2S猫头猫            const prev = draft[_hash] ?? {};
73bf6e62f2S猫头猫            prev.query = query!;
74bf6e62f2S猫头猫            prev.currentPage = page;
75bf6e62f2S猫头猫            prev.pending = false;
76bf6e62f2S猫头猫            prev.result = newSearch
77bf6e62f2S猫头猫              ? [result]
78bf6e62f2S猫头猫              : [...(prev?.result ?? []), result];
79bf6e62f2S猫头猫            draft[_hash] = prev;
80bf6e62f2S猫头猫          }),
81bf6e62f2S猫头猫        );
82bf6e62f2S猫头猫        // plugin?.instance
83bf6e62f2S猫头猫        //   ?.search?.(query, page)
84bf6e62f2S猫头猫        //   ?.then(result => {
85bf6e62f2S猫头猫        //     // 任何一个加载出来就可以出现结果页了
86bf6e62f2S猫头猫        //     setPageStatus(PageStatus.RESULT);
87bf6e62f2S猫头猫        //     if (!result) {
88bf6e62f2S猫头猫        //       throw new Error();
89bf6e62f2S猫头猫        //     }
90bf6e62f2S猫头猫        //     setSearchResults(
91bf6e62f2S猫头猫        //       produce(draft => {
92bf6e62f2S猫头猫        //         const prev = draft[_platform] ?? {};
93bf6e62f2S猫头猫        //         prev.query = query!;
94bf6e62f2S猫头猫        //         prev.currentPage = page;
95bf6e62f2S猫头猫        //         prev.pending = false;
96bf6e62f2S猫头猫        //         prev.result = newSearch
97bf6e62f2S猫头猫        //           ? [result]
98bf6e62f2S猫头猫        //           : [...(prev?.result ?? []), result];
99bf6e62f2S猫头猫        //         draft[_platform] = prev;
100bf6e62f2S猫头猫        //       }),
101bf6e62f2S猫头猫        //     );
102bf6e62f2S猫头猫        //   })
103bf6e62f2S猫头猫        //   ?.catch(() => {
104bf6e62f2S猫头猫        //     setSearchResults(
105bf6e62f2S猫头猫        //       produce(draft => {
106bf6e62f2S猫头猫        //         const prev = draft[_platform] ?? {};
107bf6e62f2S猫头猫        //         prev.pending = false;
108bf6e62f2S猫头猫        //         draft[_platform] = prev;
109bf6e62f2S猫头猫        //       }),
110bf6e62f2S猫头猫        //     );
111bf6e62f2S猫头猫        //   });
112*2f655a9eS猫头猫      } catch(e) {
113*2f655a9eS猫头猫        console.log('SEARCH ERROR', e);
114bf6e62f2S猫头猫        setSearchResults(
115bf6e62f2S猫头猫          produce(draft => {
116bf6e62f2S猫头猫            const prev = draft[_hash] ?? {};
117bf6e62f2S猫头猫            prev.pending = false;
118bf6e62f2S猫头猫            draft[_hash] = prev;
119bf6e62f2S猫头猫          }),
120bf6e62f2S猫头猫        );
121bf6e62f2S猫头猫      }
122bf6e62f2S猫头猫    });
123bf6e62f2S猫头猫  },
124bf6e62f2S猫头猫  []);
125bf6e62f2S猫头猫
126bf6e62f2S猫头猫  return search;
127bf6e62f2S猫头猫}
128bf6e62f2S猫头猫
129bf6e62f2S猫头猫// export default function useSearch() {
130bf6e62f2S猫头猫//   const setSearchResult = useSetAtom(searchResultAtom);
131bf6e62f2S猫头猫//   const setPageStatus = useSetAtom(pageStatusAtom);
132bf6e62f2S猫头猫
133bf6e62f2S猫头猫//   async function search(query: string, page: number) {
134bf6e62f2S猫头猫//     const plugins = pluginManager.getPlugins();
135bf6e62f2S猫头猫//     console.log('1', Date.now());
136bf6e62f2S猫头猫//     const _rawResults = await allSettled(
137bf6e62f2S猫头猫//       // @ts-ignore
138bf6e62f2S猫头猫//       plugins.map(plugin =>
139bf6e62f2S猫头猫//         plugin.instance?.search?.(query, page)?.then(res => {
140bf6e62f2S猫头猫//           console.log('1.1', Date.now());
141bf6e62f2S猫头猫//           return res;
142bf6e62f2S猫头猫//         }),
143bf6e62f2S猫头猫//       ),
144bf6e62f2S猫头猫//     );
145bf6e62f2S猫头猫//     console.log('2', Date.now());
146bf6e62f2S猫头猫//     for (let i = 0; i < plugins.length; ++i) {
147bf6e62f2S猫头猫//       const _rr = _rawResults[i];
148bf6e62f2S猫头猫//       setSearchResult(prevResult =>
149bf6e62f2S猫头猫//         produce(page === 1 ? {} : prevResult, draft => {
150bf6e62f2S猫头猫//           // merge data
151bf6e62f2S猫头猫//           // @ts-ignore
152bf6e62f2S猫头猫//           const _result = _rr.status === 'fulfilled' ? _rr.value ?? {} : {};
153bf6e62f2S猫头猫//           // 合并搜索结果
154bf6e62f2S猫头猫//           mergeData(draft, _result, 'music', plugins[i].instance.platform);
155bf6e62f2S猫头猫//           mergeData(draft, _result, 'album', plugins[i].instance.platform);
156bf6e62f2S猫头猫//         }),
157bf6e62f2S猫头猫//       );
158bf6e62f2S猫头猫//     }
159bf6e62f2S猫头猫//     setPageStatus(PageStatus.RESULT);
160bf6e62f2S猫头猫//   }
161bf6e62f2S猫头猫//   return search;
162bf6e62f2S猫头猫// }
163