mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-04-13 13:09:43 +08:00
Merge pull request #445 from EstrellaXD/fix/webui-search-bangumi-api
fix: 修复搜索番剧输入框报错后中断、不能再输入查询的问题
This commit is contained in:
@@ -7,50 +7,7 @@ import type { BangumiRule } from '#/bangumi';
|
||||
export const apiSearch = {
|
||||
/**
|
||||
* 番剧搜索接口是 Server Send 流式数据,每条是一个 Bangumi JSON 字符串,
|
||||
* 使用接口方式需要订阅使用
|
||||
*
|
||||
* Usage Example:
|
||||
*
|
||||
* ```ts
|
||||
* import {
|
||||
* Subject,
|
||||
* tap,
|
||||
* map,
|
||||
* switchMap,
|
||||
* debounceTime,
|
||||
* } from 'rxjs';
|
||||
*
|
||||
*
|
||||
* const input$ = new Subject<string>();
|
||||
* const onInput = (e: Event) => input$.next(e.target);
|
||||
*
|
||||
* // vue: <input @input="onInput">
|
||||
*
|
||||
* const bangumiInfo$ = apiSearch.get('魔女之旅');
|
||||
*
|
||||
* // vue: start loading animation
|
||||
*
|
||||
* input$.pipe(
|
||||
* debounceTime(1000),
|
||||
* tap((input: string) => {
|
||||
* console.log('input', input)
|
||||
* // clear Search Result List
|
||||
* }),
|
||||
*
|
||||
* // switchMap 把输入 keyword 查询为 bangumiInfo$ 流,多次输入停用前一次查询
|
||||
* switchMap((input: string) => apiSearch(input, site)),
|
||||
*
|
||||
* tap((bangumi: BangumiRule) => console.log(bangumi)),
|
||||
* tap((bangumi: BangumiRule) => {
|
||||
* console.log('bangumi', bangumi)
|
||||
* // set bangumi info to Search Result List
|
||||
* }),
|
||||
* ).subscribe({
|
||||
* complete() {
|
||||
* // end of stream, stop loading animation
|
||||
* },
|
||||
* })
|
||||
* ```
|
||||
* 使用接口方式是监听连接消息后,转为 Observable 配合外层调用时 switchMap 订阅使用
|
||||
*/
|
||||
get(keyword: string, site = 'mikan'): Observable<BangumiRule> {
|
||||
const bangumiInfo$ = new Observable<BangumiRule>(observer => {
|
||||
@@ -64,11 +21,13 @@ export const apiSearch = {
|
||||
const data: BangumiRule = JSON.parse(ev.data);
|
||||
observer.next(data);
|
||||
} catch (error) {
|
||||
observer.error(error);
|
||||
console.error('[/search/bangumi] Parse Error |', { keyword }, 'response:', ev.data)
|
||||
}
|
||||
};
|
||||
|
||||
eventSource.onerror = ev => observer.error(ev);
|
||||
eventSource.onerror = ev => {
|
||||
console.error('[/search/bangumi] Server Error |', { keyword }, 'error:', ev)
|
||||
};
|
||||
|
||||
return () => {
|
||||
eventSource.close();
|
||||
|
||||
@@ -3,7 +3,6 @@ import {Down, Search} from '@icon-park/vue-next';
|
||||
|
||||
const {
|
||||
onSelect,
|
||||
onInput,
|
||||
onSearch,
|
||||
inputValue,
|
||||
selectingProvider,
|
||||
@@ -43,12 +42,11 @@ onMounted(() => {
|
||||
/>
|
||||
|
||||
<input
|
||||
v-model="inputValue"
|
||||
type="text"
|
||||
:placeholder="$t('topbar.search.placeholder')"
|
||||
input-reset
|
||||
:value="inputValue"
|
||||
@keyup.enter="onSearch"
|
||||
@input="onInput"
|
||||
/>
|
||||
<div
|
||||
h-full
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
debounceTime,
|
||||
filter,
|
||||
switchMap,
|
||||
takeUntil, tap,
|
||||
tap,
|
||||
} from "rxjs";
|
||||
import type {BangumiRule} from "#/bangumi";
|
||||
|
||||
@@ -19,6 +19,10 @@ export function useSearchStore() {
|
||||
|
||||
const input$ = new Subject<string>();
|
||||
|
||||
watch(inputValue, input => {
|
||||
input$.next(input);
|
||||
})
|
||||
|
||||
const {execute: getProviders, onResult: onGetProvidersResult} = useApi(
|
||||
apiSearch.getProvider
|
||||
);
|
||||
@@ -33,27 +37,21 @@ export function useSearchStore() {
|
||||
* - 切换 provider 源站时触发搜索
|
||||
*/
|
||||
|
||||
|
||||
|
||||
const bangumiInfo$ = input$.pipe(
|
||||
debounceTime(600),
|
||||
tap(() => {
|
||||
// 有输入更新后清理之前的搜索结果
|
||||
bangumiList.value = [];
|
||||
}),
|
||||
filter(Boolean),
|
||||
switchMap((input: string) => apiSearch.get(input, provider.value).pipe(takeUntil(input$))),
|
||||
// switchMap 把输入 keyword 查询为 bangumiInfo$ 流,多次输入自动取消并停止前一次查询
|
||||
switchMap((input: string) => apiSearch.get(input, provider.value)),
|
||||
tap((bangumi: BangumiRule) => {
|
||||
bangumiList.value.push(bangumi);
|
||||
}),
|
||||
)
|
||||
.subscribe()
|
||||
|
||||
function onInput(e: Event) {
|
||||
const value = (e.target as HTMLInputElement).value;
|
||||
input$.next(value);
|
||||
inputValue.value = value;
|
||||
}
|
||||
|
||||
function onSearch() {
|
||||
input$.next(inputValue.value);
|
||||
}
|
||||
@@ -70,7 +68,6 @@ export function useSearchStore() {
|
||||
inputValue,
|
||||
selectingProvider,
|
||||
onSelect,
|
||||
onInput,
|
||||
onSearch,
|
||||
provider,
|
||||
getProviders,
|
||||
|
||||
Reference in New Issue
Block a user