diff --git a/src/app/play/page.tsx b/src/app/play/page.tsx index dfd7213..b1ef832 100644 --- a/src/app/play/page.tsx +++ b/src/app/play/page.tsx @@ -165,6 +165,7 @@ const PLAY_SHORTCUT_GROUPS = [ items: [ { keys: ['空格'], description: '播放 / 暂停' }, { keys: ['←', '→'], description: '快退 / 快进 10 秒' }, + { keys: ['P'], description: '快捷快进' }, { keys: ['↑', '↓'], description: '音量增加 / 减少' }, { keys: ['F'], description: '切换全屏' }, ], @@ -377,6 +378,18 @@ function PlayPageClient() { skipConfig.outro_time, ]); + // 快捷快进设置(默认 1 分 30 秒) + const DEFAULT_QUICK_FORWARD_SECONDS = 90; + const [quickForwardSeconds, setQuickForwardSeconds] = useState(() => { + if (typeof window === 'undefined') return DEFAULT_QUICK_FORWARD_SECONDS; + const saved = Number(localStorage.getItem('quickForwardSeconds')); + return Number.isFinite(saved) && saved > 0 ? saved : DEFAULT_QUICK_FORWARD_SECONDS; + }); + const quickForwardSecondsRef = useRef(quickForwardSeconds); + useEffect(() => { + quickForwardSecondsRef.current = quickForwardSeconds; + }, [quickForwardSeconds]); + // 跳过检查的时间间隔控制 const lastSkipCheckRef = useRef(0); @@ -1768,6 +1781,26 @@ function PlayPageClient() { return true; }; + const formatQuickForwardDuration = (seconds: number) => { + if (seconds >= 60) { + const minutes = Math.floor(seconds / 60); + const remainingSeconds = seconds % 60; + return remainingSeconds ? `${minutes}分${remainingSeconds}秒` : `${minutes}分钟`; + } + return `${seconds}秒`; + }; + + const seekQuickForward = () => { + const player = artPlayerRef.current; + if (!player) return false; + + const duration = Number.isFinite(player.duration) ? player.duration : Infinity; + const nextTime = Math.min(duration, (player.currentTime || 0) + quickForwardSecondsRef.current); + player.currentTime = nextTime; + player.notice.show = `快进 ${formatQuickForwardDuration(quickForwardSecondsRef.current)}`; + return true; + }; + const isDanmakuAutoLoadDisabled = () => { if (typeof window === 'undefined') { return false; @@ -6315,6 +6348,13 @@ function PlayPageClient() { } } + // P = 使用当前配置快捷快进 + if (!e.altKey && e.key.toLowerCase() === 'p') { + if (seekQuickForward()) { + e.preventDefault(); + } + } + // 左箭头 = 快退 if (!e.altKey && e.key === 'ArrowLeft') { if (artPlayerRef.current && artPlayerRef.current.currentTime > 5) { @@ -7394,6 +7434,86 @@ function PlayPageClient() { return !item.switch; }, }, + { + name: '快捷快进', + html: '快捷快进', + icon: '', + tooltip: `当前:${formatQuickForwardDuration(quickForwardSecondsRef.current)},点击修改`, + onClick: async function () { + const player = artPlayerRef.current; + if (player?.fullscreen) { + player.fullscreen = false; + await new Promise(resolve => setTimeout(resolve, 300)); + } + + const existingDialog = document.querySelector('.quick-forward-settings-dialog'); + existingDialog?.remove(); + + const container = document.createElement('div'); + container.className = 'quick-forward-settings-dialog'; + container.style.cssText = ` + position: fixed; + inset: 0; + z-index: 10000; + display: flex; + align-items: center; + justify-content: center; + padding: 16px; + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(3px); + `; + container.innerHTML = ` +