From 40c229786e93ee57e01473e3ad831c6498863ea7 Mon Sep 17 00:00:00 2001 From: cfdaily Date: Wed, 20 May 2026 21:06:34 +0800 Subject: [PATCH] auto-sync: 2026-05-20 21:06:34 --- src/frontend/src/store.ts | 45 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/store.ts b/src/frontend/src/store.ts index 3167eb6..3099e30 100644 --- a/src/frontend/src/store.ts +++ b/src/frontend/src/store.ts @@ -582,20 +582,59 @@ export const useStore = create((set, get) => ({ // ── Countdown & Polling ── let _cdTimer: ReturnType | null = null; +let _blurFlushTimer: ReturnType | null = null; +let _lastActivity = Date.now(); + +// P0: 输入焦点保护 +function hasActiveInput(): boolean { + const el = document.activeElement; + if (!el) return false; + const tag = (el as HTMLElement).tagName; + return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' + || (el as HTMLElement).isContentEditable; +} + +// P0-2: blur 后补刷,执行前再次检查焦点 +function scheduleBlurFlush() { + if (_blurFlushTimer) clearTimeout(_blurFlushTimer); + _blurFlushTimer = setTimeout(() => { + _blurFlushTimer = null; + if (!hasActiveInput()) { + useStore.getState().loadAll(); + } + }, 2000); +} + +// P1: 活跃度追踪 +export function markActivity() { + _lastActivity = Date.now(); +} + +function getPollInterval(): number { + const idle = Date.now() - _lastActivity; + return idle > 60000 ? 30 : 10; // 空闲>60s → 30s,否则 10s +} export function startPolling() { if (_cdTimer) return; useStore.getState().loadAll(); _cdTimer = setInterval(() => { + // P0-1: 有输入焦点时跳过整个 loadAll + if (hasActiveInput()) return; const s = useStore.getState(); const cd = s.countdown - 1; if (cd <= 0) { - s.setCountdown(5); + s.setCountdown(getPollInterval()); s.loadAll(); } else { s.setCountdown(cd); } }, 1000); + + // P0-2: blur 后补刷 + document.addEventListener('focusout', () => { + scheduleBlurFlush(); + }); } export function stopPolling() { @@ -603,6 +642,10 @@ export function stopPolling() { clearInterval(_cdTimer); _cdTimer = null; } + if (_blurFlushTimer) { + clearTimeout(_blurFlushTimer); + _blurFlushTimer = null; + } } // ── Utility ──