diff --git a/src/app/play/page.tsx b/src/app/play/page.tsx index 133ef53..e43991e 100644 --- a/src/app/play/page.tsx +++ b/src/app/play/page.tsx @@ -1809,6 +1809,9 @@ function PlayPageClient() { } } catch (error) { console.error('获取弹幕剧集列表失败:', error); + if (artPlayerRef.current) { + artPlayerRef.current.notice.show = '弹幕加载失败:无法获取剧集列表'; + } } } @@ -1825,6 +1828,9 @@ function PlayPageClient() { setDanmakuMatches(searchResult.animes); setShowDanmakuSourceSelector(true); setDanmakuLoading(false); + if (artPlayerRef.current) { + artPlayerRef.current.notice.show = `找到 ${searchResult.animes.length} 个弹幕源,请选择`; + } return; } @@ -1874,12 +1880,21 @@ function PlayPageClient() { } } else { console.warn('未找到剧集信息'); + if (artPlayerRef.current) { + artPlayerRef.current.notice.show = '弹幕加载失败:未找到剧集信息'; + } } } else { console.warn('未找到匹配的弹幕'); + if (artPlayerRef.current) { + artPlayerRef.current.notice.show = '未找到匹配的弹幕,可在弹幕选项卡手动搜索'; + } } } catch (error) { console.error('自动搜索弹幕失败:', error); + if (artPlayerRef.current) { + artPlayerRef.current.notice.show = '弹幕加载失败,请检查网络或稍后重试'; + } } finally { setDanmakuLoading(false); } diff --git a/src/components/DanmakuFilterSettings.tsx b/src/components/DanmakuFilterSettings.tsx index c18d158..95ec81f 100644 --- a/src/components/DanmakuFilterSettings.tsx +++ b/src/components/DanmakuFilterSettings.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ 'use client'; -import { useState, useEffect } from 'react'; +import { useState, useEffect, useRef } from 'react'; import { X, Plus, Trash2, ToggleLeft, ToggleRight } from 'lucide-react'; import { DanmakuFilterConfig, DanmakuFilterRule } from '@/lib/types'; import { getDanmakuFilterConfig, saveDanmakuFilterConfig } from '@/lib/db.client'; @@ -26,6 +26,8 @@ export default function DanmakuFilterSettings({ const [saving, setSaving] = useState(false); const [isVisible, setIsVisible] = useState(false); const [isAnimating, setIsAnimating] = useState(false); + const [inputKey, setInputKey] = useState(0); // 用于强制重新渲染输入框 + const inputRef = useRef(null); // 用于直接操作输入框 DOM // 控制动画状态 useEffect(() => { @@ -176,7 +178,17 @@ export default function DanmakuFilterSettings({ rules: [...prev.rules, newRule], })); + // 清空输入框并强制重新渲染 setNewKeyword(''); + + // 使用 setTimeout 确保在状态更新后操作 DOM + setTimeout(() => { + if (inputRef.current) { + inputRef.current.value = ''; // 直接清空 DOM 值 + inputRef.current.blur(); // 失去焦点,阻止自动填充 + } + setInputKey(prev => prev + 1); // 强制重新渲染输入框 + }, 0); }; // 删除规则 @@ -279,11 +291,19 @@ export default function DanmakuFilterSettings({
setNewKeyword(e.target.value)} onKeyPress={(e) => e.key === 'Enter' && handleAddRule()} placeholder="输入要屏蔽的关键字" + autoComplete="off" + autoCorrect="off" + autoCapitalize="off" + spellCheck="false" + data-form-type="other" + data-lpignore="true" className="w-full px-4 py-3 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-lg border border-gray-200 dark:border-gray-600 focus:border-teal-500 focus:outline-none focus:ring-2 focus:ring-teal-500/20 transition-all duration-200" />
diff --git a/src/components/DanmakuPanel.tsx b/src/components/DanmakuPanel.tsx index 0006fb0..5971875 100644 --- a/src/components/DanmakuPanel.tsx +++ b/src/components/DanmakuPanel.tsx @@ -1,7 +1,7 @@ 'use client'; import { MagnifyingGlassIcon } from '@heroicons/react/24/outline'; -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { getEpisodes, searchAnime } from '@/lib/danmaku/api'; import type { @@ -30,6 +30,7 @@ export default function DanmakuPanel({ const [isSearching, setIsSearching] = useState(false); const [isLoadingEpisodes, setIsLoadingEpisodes] = useState(false); const [searchError, setSearchError] = useState(null); + const initializedRef = useRef(false); // 标记是否已初始化过 // 搜索弹幕 const handleSearch = useCallback(async (keyword: string) => { @@ -116,12 +117,13 @@ export default function DanmakuPanel({ [currentSelection] ); - // 当视频标题变化时,更新搜索关键词 + // 当视频标题首次加载时,初始化搜索关键词(仅执行一次) useEffect(() => { - if (videoTitle && !searchKeyword) { + if (videoTitle && !initializedRef.current) { setSearchKeyword(videoTitle); + initializedRef.current = true; // 标记已初始化,防止后续自动填充 } - }, [videoTitle, searchKeyword]); + }, [videoTitle]); return (
@@ -138,6 +140,12 @@ export default function DanmakuPanel({ } }} placeholder='输入动漫名称搜索弹幕...' + autoComplete='off' + autoCorrect='off' + autoCapitalize='off' + spellCheck='false' + data-form-type='other' + data-lpignore='true' className='flex-1 rounded-lg border border-gray-300 px-3 py-2 text-sm transition-colors focus:border-green-500 focus:outline-none focus:ring-2 focus:ring-green-500/20 diff --git a/src/lib/danmaku/api.ts b/src/lib/danmaku/api.ts index dfbbc8e..feab539 100644 --- a/src/lib/danmaku/api.ts +++ b/src/lib/danmaku/api.ts @@ -19,7 +19,7 @@ export async function searchAnime( const response = await fetch(url); if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error('弹幕服务器连接异常,请检查你的设置'); } const data = (await response.json()) as DanmakuSearchResponse; @@ -52,7 +52,7 @@ export async function matchAnime( }); if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error('弹幕服务器连接异常,请检查你的设置'); } const data = (await response.json()) as DanmakuMatchResponse; @@ -78,7 +78,7 @@ export async function getEpisodes( const response = await fetch(url); if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error('弹幕服务器连接异常,请检查你的设置'); } const data = (await response.json()) as DanmakuEpisodesResponse; @@ -107,7 +107,7 @@ export async function getDanmakuById( const response = await fetch(url); if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error('弹幕服务器连接异常,请检查你的设置'); } const data = (await response.json()) as DanmakuCommentsResponse; @@ -125,7 +125,7 @@ export async function getDanmakuByUrl(url: string): Promise { const response = await fetch(apiUrl); if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error('弹幕服务器连接异常,请检查你的设置'); } const data = (await response.json()) as DanmakuCommentsResponse;