xref: /MusicFree/src/pages/searchPage/hooks/useSearch.ts (revision efb9da24633a003d2b1a4a47f4bf16d38033266e)
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 {
36*efb9da24S猫头猫                plugins = PluginManager.getSearchablePlugins();
370b940038S猫头猫            }
38c30d30e1S猫头猫            if (plugins.length === 0) {
39c30d30e1S猫头猫                setPageStatus(PageStatus.NO_PLUGIN);
40c30d30e1S猫头猫                return;
41c30d30e1S猫头猫            }
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猫头猫
524060c00aS猫头猫                const searchType =
534060c00aS猫头猫                    type ?? plugin.instance.defaultSearchType ?? 'music';
540b940038S猫头猫                // 上一份搜索结果
550b940038S猫头猫                const prevPluginResult = searchResults[searchType][plugin.hash];
560b940038S猫头猫                /** 上一份搜索还没返回/已经结束 */
5719c8eb6fS猫头猫                if (
5820e2869eS猫头猫                    (prevPluginResult?.state === RequestStateCode.PENDING ||
594060c00aS猫头猫                        prevPluginResult?.state ===
604060c00aS猫头猫                            RequestStateCode.FINISHED) &&
6119c8eb6fS猫头猫                    undefined === query
6219c8eb6fS猫头猫                ) {
63bf6e62f2S猫头猫                    return;
64bf6e62f2S猫头猫                }
65d139abf1S猫头猫
6619c8eb6fS猫头猫                // 是否是一次新的搜索
67bf6e62f2S猫头猫                const newSearch =
684060c00aS猫头猫                    query ||
694060c00aS猫头猫                    prevPluginResult?.page === undefined ||
704060c00aS猫头猫                    queryPage === 1;
7119c8eb6fS猫头猫
720b940038S猫头猫                // 本次搜索关键词
730b940038S猫头猫                currentQueryRef.current = query =
740b940038S猫头猫                    query ?? prevPluginResult?.query ?? '';
7519c8eb6fS猫头猫
7619c8eb6fS猫头猫                /** 搜索的页码 */
77bf6e62f2S猫头猫                const page =
784060c00aS猫头猫                    queryPage ?? newSearch
794060c00aS猫头猫                        ? 1
804060c00aS猫头猫                        : (prevPluginResult?.page ?? 0) + 1;
81d139abf1S猫头猫
8220e2869eS猫头猫                trace('开始搜索', {
8320e2869eS猫头猫                    _platform,
8420e2869eS猫头猫                    query,
8520e2869eS猫头猫                    page,
8620e2869eS猫头猫                    searchType,
8720e2869eS猫头猫                });
8820e2869eS猫头猫
89bf6e62f2S猫头猫                try {
9092a7e801S猫头猫                    setSearchResults(
9192a7e801S猫头猫                        produce(draft => {
920b940038S猫头猫                            const prevMediaResult: any = draft[searchType];
930b940038S猫头猫                            prevMediaResult[_hash] = {
940b940038S猫头猫                                state: newSearch
9520e2869eS猫头猫                                    ? RequestStateCode.PENDING_FP
9620e2869eS猫头猫                                    : RequestStateCode.PENDING,
970b940038S猫头猫                                // @ts-ignore
984060c00aS猫头猫                                data: newSearch
994060c00aS猫头猫                                    ? []
1004060c00aS猫头猫                                    : prevMediaResult[_hash]?.data ?? [],
10192a7e801S猫头猫                                query: query,
1020b940038S猫头猫                                page,
10392a7e801S猫头猫                            };
104bf6e62f2S猫头猫                        }),
105bf6e62f2S猫头猫                    );
106ad2ad8ffS猫头猫                    // !! jscore的promise有问题,改成hermes就好了,可能和JIT有关,不知道。
1075276aef9S猫头猫                    const result = await plugin?.methods?.search?.(
1080b940038S猫头猫                        query,
1090b940038S猫头猫                        page,
1100b940038S猫头猫                        searchType,
1110b940038S猫头猫                    );
1120b940038S猫头猫                    /** 如果搜索结果不是本次结果 */
11319c8eb6fS猫头猫                    if (currentQueryRef.current !== query) {
11419c8eb6fS猫头猫                        return;
11519c8eb6fS猫头猫                    }
1160b940038S猫头猫                    /** 切换到结果页 */
117bf6e62f2S猫头猫                    setPageStatus(PageStatus.RESULT);
118bf6e62f2S猫头猫                    if (!result) {
11920e2869eS猫头猫                        throw new Error('搜索结果为空');
120bf6e62f2S猫头猫                    }
121bf6e62f2S猫头猫                    setSearchResults(
122bf6e62f2S猫头猫                        produce(draft => {
1230b940038S猫头猫                            const prevMediaResult = draft[searchType];
1244060c00aS猫头猫                            const prevPluginResult: any = prevMediaResult[
1254060c00aS猫头猫                                _hash
1264060c00aS猫头猫                            ] ?? {
1270b940038S猫头猫                                data: [],
1280b940038S猫头猫                            };
1298b88e961S猫头猫                            const currResult = result.data ?? [];
1300b940038S猫头猫
1310b940038S猫头猫                            prevMediaResult[_hash] = {
1320b940038S猫头猫                                state:
1334060c00aS猫头猫                                    result?.isEnd === false &&
1344060c00aS猫头猫                                    result?.data?.length
13520e2869eS猫头猫                                        ? RequestStateCode.PARTLY_DONE
13620e2869eS猫头猫                                        : RequestStateCode.FINISHED,
1370b940038S猫头猫                                query,
1380b940038S猫头猫                                page,
1390b940038S猫头猫                                data: newSearch
1408b88e961S猫头猫                                    ? currResult
1414060c00aS猫头猫                                    : (prevPluginResult.data ?? []).concat(
1424060c00aS猫头猫                                          currResult,
1434060c00aS猫头猫                                      ),
144d139abf1S猫头猫                            };
145d139abf1S猫头猫                            return draft;
146bf6e62f2S猫头猫                        }),
147bf6e62f2S猫头猫                    );
1482f655a9eS猫头猫                } catch (e) {
149ef60be1cS猫头猫                    errorLog('搜索失败', e);
1500b940038S猫头猫                    setPageStatus(PageStatus.RESULT);
151bf6e62f2S猫头猫                    setSearchResults(
152bf6e62f2S猫头猫                        produce(draft => {
1530b940038S猫头猫                            const prevMediaResult = draft[searchType];
1544060c00aS猫头猫                            const prevPluginResult = prevMediaResult[_hash] ?? {
1554060c00aS猫头猫                                data: [],
1564060c00aS猫头猫                            };
1570b940038S猫头猫
1584060c00aS猫头猫                            prevPluginResult.state =
1594060c00aS猫头猫                                RequestStateCode.PARTLY_DONE;
1600b940038S猫头猫                            return draft;
161bf6e62f2S猫头猫                        }),
162bf6e62f2S猫头猫                    );
163bf6e62f2S猫头猫                }
164bf6e62f2S猫头猫            });
165bf6e62f2S猫头猫        },
166ad2ad8ffS猫头猫        [searchResults],
167ad2ad8ffS猫头猫    );
168bf6e62f2S猫头猫
169bf6e62f2S猫头猫    return search;
170bf6e62f2S猫头猫}
171