xref: /MusicFree/src/pages/searchPage/hooks/useSearch.ts (revision ef60be1c70f066ecf4ce40dd183880baa09898a2)
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猫头猫
494060c00aS猫头猫                const searchType =
504060c00aS猫头猫                    type ?? plugin.instance.defaultSearchType ?? 'music';
510b940038S猫头猫                // 上一份搜索结果
520b940038S猫头猫                const prevPluginResult = searchResults[searchType][plugin.hash];
530b940038S猫头猫                /** 上一份搜索还没返回/已经结束 */
5419c8eb6fS猫头猫                if (
5520e2869eS猫头猫                    (prevPluginResult?.state === RequestStateCode.PENDING ||
564060c00aS猫头猫                        prevPluginResult?.state ===
574060c00aS猫头猫                            RequestStateCode.FINISHED) &&
5819c8eb6fS猫头猫                    undefined === query
5919c8eb6fS猫头猫                ) {
60bf6e62f2S猫头猫                    return;
61bf6e62f2S猫头猫                }
62d139abf1S猫头猫
6319c8eb6fS猫头猫                // 是否是一次新的搜索
64bf6e62f2S猫头猫                const newSearch =
654060c00aS猫头猫                    query ||
664060c00aS猫头猫                    prevPluginResult?.page === undefined ||
674060c00aS猫头猫                    queryPage === 1;
6819c8eb6fS猫头猫
690b940038S猫头猫                // 本次搜索关键词
700b940038S猫头猫                currentQueryRef.current = query =
710b940038S猫头猫                    query ?? prevPluginResult?.query ?? '';
7219c8eb6fS猫头猫
7319c8eb6fS猫头猫                /** 搜索的页码 */
74bf6e62f2S猫头猫                const page =
754060c00aS猫头猫                    queryPage ?? newSearch
764060c00aS猫头猫                        ? 1
774060c00aS猫头猫                        : (prevPluginResult?.page ?? 0) + 1;
78d139abf1S猫头猫
7920e2869eS猫头猫                trace('开始搜索', {
8020e2869eS猫头猫                    _platform,
8120e2869eS猫头猫                    query,
8220e2869eS猫头猫                    page,
8320e2869eS猫头猫                    searchType,
8420e2869eS猫头猫                });
8520e2869eS猫头猫
86bf6e62f2S猫头猫                try {
8792a7e801S猫头猫                    setSearchResults(
8892a7e801S猫头猫                        produce(draft => {
890b940038S猫头猫                            const prevMediaResult: any = draft[searchType];
900b940038S猫头猫                            prevMediaResult[_hash] = {
910b940038S猫头猫                                state: newSearch
9220e2869eS猫头猫                                    ? RequestStateCode.PENDING_FP
9320e2869eS猫头猫                                    : RequestStateCode.PENDING,
940b940038S猫头猫                                // @ts-ignore
954060c00aS猫头猫                                data: newSearch
964060c00aS猫头猫                                    ? []
974060c00aS猫头猫                                    : prevMediaResult[_hash]?.data ?? [],
9892a7e801S猫头猫                                query: query,
990b940038S猫头猫                                page,
10092a7e801S猫头猫                            };
101bf6e62f2S猫头猫                        }),
102bf6e62f2S猫头猫                    );
103ad2ad8ffS猫头猫                    // !! jscore的promise有问题,改成hermes就好了,可能和JIT有关,不知道。
1045276aef9S猫头猫                    const result = await plugin?.methods?.search?.(
1050b940038S猫头猫                        query,
1060b940038S猫头猫                        page,
1070b940038S猫头猫                        searchType,
1080b940038S猫头猫                    );
1090b940038S猫头猫                    /** 如果搜索结果不是本次结果 */
11019c8eb6fS猫头猫                    if (currentQueryRef.current !== query) {
11119c8eb6fS猫头猫                        return;
11219c8eb6fS猫头猫                    }
1130b940038S猫头猫                    /** 切换到结果页 */
114bf6e62f2S猫头猫                    setPageStatus(PageStatus.RESULT);
115bf6e62f2S猫头猫                    if (!result) {
11620e2869eS猫头猫                        throw new Error('搜索结果为空');
117bf6e62f2S猫头猫                    }
118bf6e62f2S猫头猫                    setSearchResults(
119bf6e62f2S猫头猫                        produce(draft => {
1200b940038S猫头猫                            const prevMediaResult = draft[searchType];
1214060c00aS猫头猫                            const prevPluginResult: any = prevMediaResult[
1224060c00aS猫头猫                                _hash
1234060c00aS猫头猫                            ] ?? {
1240b940038S猫头猫                                data: [],
1250b940038S猫头猫                            };
1268b88e961S猫头猫                            const currResult = result.data ?? [];
1270b940038S猫头猫
1280b940038S猫头猫                            prevMediaResult[_hash] = {
1290b940038S猫头猫                                state:
1304060c00aS猫头猫                                    result?.isEnd === false &&
1314060c00aS猫头猫                                    result?.data?.length
13220e2869eS猫头猫                                        ? RequestStateCode.PARTLY_DONE
13320e2869eS猫头猫                                        : RequestStateCode.FINISHED,
1340b940038S猫头猫                                query,
1350b940038S猫头猫                                page,
1360b940038S猫头猫                                data: newSearch
1378b88e961S猫头猫                                    ? currResult
1384060c00aS猫头猫                                    : (prevPluginResult.data ?? []).concat(
1394060c00aS猫头猫                                          currResult,
1404060c00aS猫头猫                                      ),
141d139abf1S猫头猫                            };
142d139abf1S猫头猫                            return draft;
143bf6e62f2S猫头猫                        }),
144bf6e62f2S猫头猫                    );
1452f655a9eS猫头猫                } catch (e) {
146*ef60be1cS猫头猫                    errorLog('搜索失败', e);
1470b940038S猫头猫                    setPageStatus(PageStatus.RESULT);
148bf6e62f2S猫头猫                    setSearchResults(
149bf6e62f2S猫头猫                        produce(draft => {
1500b940038S猫头猫                            const prevMediaResult = draft[searchType];
1514060c00aS猫头猫                            const prevPluginResult = prevMediaResult[_hash] ?? {
1524060c00aS猫头猫                                data: [],
1534060c00aS猫头猫                            };
1540b940038S猫头猫
1554060c00aS猫头猫                            prevPluginResult.state =
1564060c00aS猫头猫                                RequestStateCode.PARTLY_DONE;
1570b940038S猫头猫                            return draft;
158bf6e62f2S猫头猫                        }),
159bf6e62f2S猫头猫                    );
160bf6e62f2S猫头猫                }
161bf6e62f2S猫头猫            });
162bf6e62f2S猫头猫        },
163ad2ad8ffS猫头猫        [searchResults],
164ad2ad8ffS猫头猫    );
165bf6e62f2S猫头猫
166bf6e62f2S猫头猫    return search;
167bf6e62f2S猫头猫}
168