xref: /MusicFree/src/pages/searchPage/hooks/useSearch.ts (revision 5589cdf32b2bb0f641e5ac7bf1f6152cd6b9b70e)
1ea6d708fS猫头猫import {devLog, errorLog, trace} from '@/utils/log';
220e2869eS猫头猫import {RequestStateCode} from '@/constants/commonConst';
3*5589cdf3S猫头猫import {produce} from 'immer';
4c0cf1425S猫头猫import {getDefaultStore, 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 {
36efb9da24S猫头猫                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 (
58956ee1b7S猫头猫                    (prevPluginResult?.state ===
59956ee1b7S猫头猫                        RequestStateCode.PENDING_REST_PAGE ||
604060c00aS猫头猫                        prevPluginResult?.state ===
614060c00aS猫头猫                            RequestStateCode.FINISHED) &&
6219c8eb6fS猫头猫                    undefined === query
6319c8eb6fS猫头猫                ) {
64bf6e62f2S猫头猫                    return;
65bf6e62f2S猫头猫                }
66d139abf1S猫头猫
6719c8eb6fS猫头猫                // 是否是一次新的搜索
68bf6e62f2S猫头猫                const newSearch =
694060c00aS猫头猫                    query ||
704060c00aS猫头猫                    prevPluginResult?.page === undefined ||
714060c00aS猫头猫                    queryPage === 1;
7219c8eb6fS猫头猫
730b940038S猫头猫                // 本次搜索关键词
740b940038S猫头猫                currentQueryRef.current = query =
750b940038S猫头猫                    query ?? prevPluginResult?.query ?? '';
7619c8eb6fS猫头猫
7719c8eb6fS猫头猫                /** 搜索的页码 */
78bf6e62f2S猫头猫                const page =
794060c00aS猫头猫                    queryPage ?? newSearch
804060c00aS猫头猫                        ? 1
814060c00aS猫头猫                        : (prevPluginResult?.page ?? 0) + 1;
82d139abf1S猫头猫
8320e2869eS猫头猫                trace('开始搜索', {
8420e2869eS猫头猫                    _platform,
8520e2869eS猫头猫                    query,
8620e2869eS猫头猫                    page,
8720e2869eS猫头猫                    searchType,
8820e2869eS猫头猫                });
8920e2869eS猫头猫
90bf6e62f2S猫头猫                try {
9192a7e801S猫头猫                    setSearchResults(
9292a7e801S猫头猫                        produce(draft => {
930b940038S猫头猫                            const prevMediaResult: any = draft[searchType];
940b940038S猫头猫                            prevMediaResult[_hash] = {
950b940038S猫头猫                                state: newSearch
96956ee1b7S猫头猫                                    ? RequestStateCode.PENDING_FIRST_PAGE
97956ee1b7S猫头猫                                    : RequestStateCode.PENDING_REST_PAGE,
980b940038S猫头猫                                // @ts-ignore
994060c00aS猫头猫                                data: newSearch
1004060c00aS猫头猫                                    ? []
1014060c00aS猫头猫                                    : prevMediaResult[_hash]?.data ?? [],
10292a7e801S猫头猫                                query: query,
1030b940038S猫头猫                                page,
10492a7e801S猫头猫                            };
105bf6e62f2S猫头猫                        }),
106bf6e62f2S猫头猫                    );
107ad2ad8ffS猫头猫                    // !! jscore的promise有问题,改成hermes就好了,可能和JIT有关,不知道。
1085276aef9S猫头猫                    const result = await plugin?.methods?.search?.(
1090b940038S猫头猫                        query,
1100b940038S猫头猫                        page,
1110b940038S猫头猫                        searchType,
1120b940038S猫头猫                    );
1130b940038S猫头猫                    /** 如果搜索结果不是本次结果 */
11419c8eb6fS猫头猫                    if (currentQueryRef.current !== query) {
11519c8eb6fS猫头猫                        return;
11619c8eb6fS猫头猫                    }
1170b940038S猫头猫                    /** 切换到结果页 */
118bf6e62f2S猫头猫                    setPageStatus(PageStatus.RESULT);
119bf6e62f2S猫头猫                    if (!result) {
12020e2869eS猫头猫                        throw new Error('搜索结果为空');
121bf6e62f2S猫头猫                    }
122bf6e62f2S猫头猫                    setSearchResults(
123bf6e62f2S猫头猫                        produce(draft => {
1240b940038S猫头猫                            const prevMediaResult = draft[searchType];
1254060c00aS猫头猫                            const prevPluginResult: any = prevMediaResult[
1264060c00aS猫头猫                                _hash
1274060c00aS猫头猫                            ] ?? {
1280b940038S猫头猫                                data: [],
1290b940038S猫头猫                            };
1308b88e961S猫头猫                            const currResult = result.data ?? [];
1310b940038S猫头猫
1320b940038S猫头猫                            prevMediaResult[_hash] = {
1330b940038S猫头猫                                state:
1344060c00aS猫头猫                                    result?.isEnd === false &&
1354060c00aS猫头猫                                    result?.data?.length
13620e2869eS猫头猫                                        ? RequestStateCode.PARTLY_DONE
13720e2869eS猫头猫                                        : RequestStateCode.FINISHED,
1380b940038S猫头猫                                query,
1390b940038S猫头猫                                page,
1400b940038S猫头猫                                data: newSearch
1418b88e961S猫头猫                                    ? currResult
1424060c00aS猫头猫                                    : (prevPluginResult.data ?? []).concat(
1434060c00aS猫头猫                                          currResult,
1444060c00aS猫头猫                                      ),
145d139abf1S猫头猫                            };
146d139abf1S猫头猫                            return draft;
147bf6e62f2S猫头猫                        }),
148bf6e62f2S猫头猫                    );
149e88bcca2S猫头猫                } catch (e: any) {
150e88bcca2S猫头猫                    errorLog('搜索失败', e?.message);
151ea6d708fS猫头猫                    devLog(
152ea6d708fS猫头猫                        'error',
153ea6d708fS猫头猫                        '搜索失败',
154ea6d708fS猫头猫                        `Plugin: ${plugin.name} Query: ${query} Page: ${page}`,
155ea6d708fS猫头猫                        e,
156ea6d708fS猫头猫                        e?.message,
157ea6d708fS猫头猫                    );
158c0cf1425S猫头猫                    const currentPageStatus =
159c0cf1425S猫头猫                        getDefaultStore().get(pageStatusAtom);
160c0cf1425S猫头猫                    if (currentPageStatus !== PageStatus.EDITING) {
1610b940038S猫头猫                        setPageStatus(PageStatus.RESULT);
162c0cf1425S猫头猫                    }
163bf6e62f2S猫头猫                    setSearchResults(
164bf6e62f2S猫头猫                        produce(draft => {
1650b940038S猫头猫                            const prevMediaResult = draft[searchType];
1664060c00aS猫头猫                            const prevPluginResult = prevMediaResult[_hash] ?? {
1674060c00aS猫头猫                                data: [],
1684060c00aS猫头猫                            };
1690b940038S猫头猫
1704060c00aS猫头猫                            prevPluginResult.state =
1714060c00aS猫头猫                                RequestStateCode.PARTLY_DONE;
1720b940038S猫头猫                            return draft;
173bf6e62f2S猫头猫                        }),
174bf6e62f2S猫头猫                    );
175bf6e62f2S猫头猫                }
176bf6e62f2S猫头猫            });
177bf6e62f2S猫头猫        },
178ad2ad8ffS猫头猫        [searchResults],
179ad2ad8ffS猫头猫    );
180bf6e62f2S猫头猫
181bf6e62f2S猫头猫    return search;
182bf6e62f2S猫头猫}
183