xref: /MusicFree/src/pages/searchPage/hooks/useSearch.ts (revision 4060c00a75883036bbd315fb25c90065209312b3)
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猫头猫
49*4060c00aS猫头猫                const searchType =
50*4060c00aS猫头猫                    type ?? plugin.instance.defaultSearchType ?? 'music';
510b940038S猫头猫                // 上一份搜索结果
520b940038S猫头猫                const prevPluginResult = searchResults[searchType][plugin.hash];
530b940038S猫头猫                /** 上一份搜索还没返回/已经结束 */
5419c8eb6fS猫头猫                if (
5520e2869eS猫头猫                    (prevPluginResult?.state === RequestStateCode.PENDING ||
56*4060c00aS猫头猫                        prevPluginResult?.state ===
57*4060c00aS猫头猫                            RequestStateCode.FINISHED) &&
5819c8eb6fS猫头猫                    undefined === query
5919c8eb6fS猫头猫                ) {
60bf6e62f2S猫头猫                    return;
61bf6e62f2S猫头猫                }
62d139abf1S猫头猫
6319c8eb6fS猫头猫                // 是否是一次新的搜索
64bf6e62f2S猫头猫                const newSearch =
65*4060c00aS猫头猫                    query ||
66*4060c00aS猫头猫                    prevPluginResult?.page === undefined ||
67*4060c00aS猫头猫                    queryPage === 1;
6819c8eb6fS猫头猫
690b940038S猫头猫                // 本次搜索关键词
700b940038S猫头猫                currentQueryRef.current = query =
710b940038S猫头猫                    query ?? prevPluginResult?.query ?? '';
7219c8eb6fS猫头猫
7319c8eb6fS猫头猫                /** 搜索的页码 */
74bf6e62f2S猫头猫                const page =
75*4060c00aS猫头猫                    queryPage ?? newSearch
76*4060c00aS猫头猫                        ? 1
77*4060c00aS猫头猫                        : (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
95*4060c00aS猫头猫                                data: newSearch
96*4060c00aS猫头猫                                    ? []
97*4060c00aS猫头猫                                    : 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];
121*4060c00aS猫头猫                            const prevPluginResult: any = prevMediaResult[
122*4060c00aS猫头猫                                _hash
123*4060c00aS猫头猫                            ] ?? {
1240b940038S猫头猫                                data: [],
1250b940038S猫头猫                            };
1268b88e961S猫头猫                            const currResult = result.data ?? [];
1270b940038S猫头猫
1280b940038S猫头猫                            prevMediaResult[_hash] = {
1290b940038S猫头猫                                state:
130*4060c00aS猫头猫                                    result?.isEnd === false &&
131*4060c00aS猫头猫                                    result?.data?.length
13220e2869eS猫头猫                                        ? RequestStateCode.PARTLY_DONE
13320e2869eS猫头猫                                        : RequestStateCode.FINISHED,
1340b940038S猫头猫                                query,
1350b940038S猫头猫                                page,
1360b940038S猫头猫                                data: newSearch
1378b88e961S猫头猫                                    ? currResult
138*4060c00aS猫头猫                                    : (prevPluginResult.data ?? []).concat(
139*4060c00aS猫头猫                                          currResult,
140*4060c00aS猫头猫                                      ),
141d139abf1S猫头猫                            };
142d139abf1S猫头猫                            return draft;
143bf6e62f2S猫头猫                        }),
144bf6e62f2S猫头猫                    );
1452f655a9eS猫头猫                } catch (e) {
14620e2869eS猫头猫                    errorLog('', e);
1470b940038S猫头猫                    setPageStatus(PageStatus.RESULT);
148bf6e62f2S猫头猫                    setSearchResults(
149bf6e62f2S猫头猫                        produce(draft => {
1500b940038S猫头猫                            const prevMediaResult = draft[searchType];
151*4060c00aS猫头猫                            const prevPluginResult = prevMediaResult[_hash] ?? {
152*4060c00aS猫头猫                                data: [],
153*4060c00aS猫头猫                            };
1540b940038S猫头猫
155*4060c00aS猫头猫                            prevPluginResult.state =
156*4060c00aS猫头猫                                RequestStateCode.PARTLY_DONE;
1570b940038S猫头猫                            return draft;
158bf6e62f2S猫头猫                        }),
159bf6e62f2S猫头猫                    );
160bf6e62f2S猫头猫                }
161bf6e62f2S猫头猫            });
162bf6e62f2S猫头猫        },
163ad2ad8ffS猫头猫        [searchResults],
164ad2ad8ffS猫头猫    );
165bf6e62f2S猫头猫
166bf6e62f2S猫头猫    return search;
167bf6e62f2S猫头猫}
168