xref: /MusicFree/src/pages/searchPage/hooks/useSearch.ts (revision d139abf142067550444f19228dea857c8dd9b95d)
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猫头猫export default function useSearch() {
8bf6e62f2S猫头猫  const setPageStatus = useSetAtom(pageStatusAtom);
9bf6e62f2S猫头猫  const [searchResults, setSearchResults] = useAtom(searchResultsAtom);
10bf6e62f2S猫头猫
11bf6e62f2S猫头猫  const search = useCallback(async function (
12bf6e62f2S猫头猫    query?: string,
13bf6e62f2S猫头猫    platformHash = 'all',
14bf6e62f2S猫头猫    queryPage = undefined,
15bf6e62f2S猫头猫  ) {
16bf6e62f2S猫头猫    // 如果没有搜索结果缓存,那就是没有搜过
17bf6e62f2S猫头猫    const installedPlugins = pluginManager.getValidPlugins();
18*d139abf1S猫头猫    console.log('HASH', platformHash);
19bf6e62f2S猫头猫    const plugins =
20bf6e62f2S猫头猫      platformHash === 'all'
21bf6e62f2S猫头猫        ? installedPlugins
22bf6e62f2S猫头猫        : [installedPlugins.find(_ => _.hash === platformHash)];
23bf6e62f2S猫头猫    plugins.forEach(async plugin => {
24bf6e62f2S猫头猫      const _platform = plugin?.instance.platform;
25bf6e62f2S猫头猫      const _hash = plugin?.hash;
26bf6e62f2S猫头猫      if (!plugin || !_platform || !_hash) {
27bf6e62f2S猫头猫        // 没有插件,此时直接进入结果页
28bf6e62f2S猫头猫        setPageStatus(PageStatus.RESULT);
29bf6e62f2S猫头猫        return;
30bf6e62f2S猫头猫      }
3108a8e62cS猫头猫      const _prevResult = searchResults[_hash] ?? {};
3208a8e62cS猫头猫      if (_prevResult.state === 'pending' || _prevResult.state === 'done') {
33bf6e62f2S猫头猫        return;
34bf6e62f2S猫头猫      }
35*d139abf1S猫头猫
36bf6e62f2S猫头猫      const newSearch =
37bf6e62f2S猫头猫        query || _prevResult?.currentPage === undefined || queryPage === 1;
38bf6e62f2S猫头猫      query = query ?? _prevResult?.query ?? '';
39bf6e62f2S猫头猫      const page =
40bf6e62f2S猫头猫        queryPage ?? newSearch ? 1 : (_prevResult.currentPage ?? 0) + 1;
41*d139abf1S猫头猫
42*d139abf1S猫头猫      const rand = Math.random();
43*d139abf1S猫头猫      console.log('RANDOM', rand);
44*d139abf1S猫头猫
45bf6e62f2S猫头猫      try {
46*d139abf1S猫头猫        setSearchResults(prevState =>
47*d139abf1S猫头猫          produce(prevState, draft => {
48bf6e62f2S猫头猫            const prev = draft[_hash] ?? {};
49bf6e62f2S猫头猫            prev.query = query;
5008a8e62cS猫头猫            prev.state = 'pending';
51bf6e62f2S猫头猫            draft[_hash] = prev;
52bf6e62f2S猫头猫          }),
53bf6e62f2S猫头猫        );
5408a8e62cS猫头猫        // !! jscore的promise有问题,改成hermes就好了,可能和JIT
55bf6e62f2S猫头猫        const result = await plugin?.instance?.search?.(query, page);
56bf6e62f2S猫头猫        setPageStatus(PageStatus.RESULT);
57bf6e62f2S猫头猫        if (!result) {
58bf6e62f2S猫头猫          throw new Error();
59bf6e62f2S猫头猫        }
60bf6e62f2S猫头猫        setSearchResults(
61bf6e62f2S猫头猫          produce(draft => {
62bf6e62f2S猫头猫            const prev = draft[_hash] ?? {};
63*d139abf1S猫头猫            console.log('SAVED PAGE', page, prev, rand);
6408a8e62cS猫头猫            if (result._isEnd === false) {
6508a8e62cS猫头猫              prev.state = 'resolved';
6608a8e62cS猫头猫            } else {
6708a8e62cS猫头猫              prev.state = 'done';
6808a8e62cS猫头猫            }
69bf6e62f2S猫头猫            prev.result = newSearch
70*d139abf1S猫头猫              ? mergeResult(result, {}, _platform)
71*d139abf1S猫头猫              : mergeResult(prev.result ?? {}, result ?? {}, _platform);
72*d139abf1S猫头猫            draft[_hash] = {
73*d139abf1S猫头猫              state: prev.state,
74*d139abf1S猫头猫              result: prev.result,
75*d139abf1S猫头猫              query: query,
76*d139abf1S猫头猫              currentPage: page,
77*d139abf1S猫头猫            };
78*d139abf1S猫头猫            return draft;
79bf6e62f2S猫头猫          }),
80bf6e62f2S猫头猫        );
812f655a9eS猫头猫      } catch (e) {
822f655a9eS猫头猫        console.log('SEARCH ERROR', e);
83bf6e62f2S猫头猫        setSearchResults(
84bf6e62f2S猫头猫          produce(draft => {
85bf6e62f2S猫头猫            const prev = draft[_hash] ?? {};
8608a8e62cS猫头猫            prev.state = 'resolved';
87bf6e62f2S猫头猫            draft[_hash] = prev;
88bf6e62f2S猫头猫          }),
89bf6e62f2S猫头猫        );
90bf6e62f2S猫头猫      }
91bf6e62f2S猫头猫    });
92bf6e62f2S猫头猫  },
93bf6e62f2S猫头猫  []);
94bf6e62f2S猫头猫
95bf6e62f2S猫头猫  return search;
96bf6e62f2S猫头猫}
97bf6e62f2S猫头猫
98*d139abf1S猫头猫const resultKeys: (keyof IPlugin.ISearchResult)[] = ['album', 'music'];
99*d139abf1S猫头猫function mergeResult(
100*d139abf1S猫头猫  obj1: Record<string, any>,
101*d139abf1S猫头猫  obj2: Record<string, any>,
102*d139abf1S猫头猫  platform: string,
103*d139abf1S猫头猫): IPlugin.ISearchResult {
104*d139abf1S猫头猫  const result: Record<string, any> = {};
105*d139abf1S猫头猫  for (let k of resultKeys) {
106*d139abf1S猫头猫    result[k] = (obj1[k] ?? [])
107*d139abf1S猫头猫      .map((_: any) =>
108*d139abf1S猫头猫        produce(_, (_: any) => {
109*d139abf1S猫头猫          _.platform = platform;
110*d139abf1S猫头猫        }),
111*d139abf1S猫头猫      )
112*d139abf1S猫头猫      .concat(
113*d139abf1S猫头猫        (obj2[k] ?? []).map((_: any) =>
114*d139abf1S猫头猫          produce(_, (_: any) => {
115*d139abf1S猫头猫            _.platform = platform;
116*d139abf1S猫头猫          }),
117*d139abf1S猫头猫        ),
118*d139abf1S猫头猫      );
119*d139abf1S猫头猫  }
120*d139abf1S猫头猫  return result;
121*d139abf1S猫头猫}
122*d139abf1S猫头猫
123bf6e62f2S猫头猫// export default function useSearch() {
124bf6e62f2S猫头猫//   const setSearchResult = useSetAtom(searchResultAtom);
125bf6e62f2S猫头猫//   const setPageStatus = useSetAtom(pageStatusAtom);
126bf6e62f2S猫头猫
127bf6e62f2S猫头猫//   async function search(query: string, page: number) {
128bf6e62f2S猫头猫//     const plugins = pluginManager.getPlugins();
129bf6e62f2S猫头猫//     console.log('1', Date.now());
130bf6e62f2S猫头猫//     const _rawResults = await allSettled(
131bf6e62f2S猫头猫//       // @ts-ignore
132bf6e62f2S猫头猫//       plugins.map(plugin =>
133bf6e62f2S猫头猫//         plugin.instance?.search?.(query, page)?.then(res => {
134bf6e62f2S猫头猫//           console.log('1.1', Date.now());
135bf6e62f2S猫头猫//           return res;
136bf6e62f2S猫头猫//         }),
137bf6e62f2S猫头猫//       ),
138bf6e62f2S猫头猫//     );
139bf6e62f2S猫头猫//     console.log('2', Date.now());
140bf6e62f2S猫头猫//     for (let i = 0; i < plugins.length; ++i) {
141bf6e62f2S猫头猫//       const _rr = _rawResults[i];
142bf6e62f2S猫头猫//       setSearchResult(prevResult =>
143bf6e62f2S猫头猫//         produce(page === 1 ? {} : prevResult, draft => {
144bf6e62f2S猫头猫//           // merge data
145bf6e62f2S猫头猫//           // @ts-ignore
146bf6e62f2S猫头猫//           const _result = _rr.status === 'fulfilled' ? _rr.value ?? {} : {};
147bf6e62f2S猫头猫//           // 合并搜索结果
148bf6e62f2S猫头猫//           mergeData(draft, _result, 'music', plugins[i].instance.platform);
149bf6e62f2S猫头猫//           mergeData(draft, _result, 'album', plugins[i].instance.platform);
150bf6e62f2S猫头猫//         }),
151bf6e62f2S猫头猫//       );
152bf6e62f2S猫头猫//     }
153bf6e62f2S猫头猫//     setPageStatus(PageStatus.RESULT);
154bf6e62f2S猫头猫//   }
155bf6e62f2S猫头猫//   return search;
156bf6e62f2S猫头猫// }
157