diff --git a/openless-all/app/src/components/Onboarding.tsx b/openless-all/app/src/components/Onboarding.tsx index b7f8807b..1f272707 100644 --- a/openless-all/app/src/components/Onboarding.tsx +++ b/openless-all/app/src/components/Onboarding.tsx @@ -3,7 +3,7 @@ // 触发条件:App.tsx 启动检查 accessibility + microphone,任一未授权则渲染本组件而非主 Shell。 // 与 Swift `Sources/OpenLessApp/Onboarding/` 同语义,但简化为单页三步。 -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { checkAccessibilityPermission, @@ -25,6 +25,7 @@ export function Onboarding({ onComplete }: OnboardingProps) { const [accessibility, setAccessibility] = useState('notDetermined'); const [microphone, setMicrophone] = useState('notDetermined'); const [busy, setBusy] = useState(false); + const refreshTimeoutRef = useRef | null>(null); const { capability } = useHotkeySettings(); const refresh = async () => { @@ -48,6 +49,7 @@ export function Onboarding({ onComplete }: OnboardingProps) { return () => { window.clearInterval(id); window.removeEventListener('focus', onFocus); + if (refreshTimeoutRef.current) clearTimeout(refreshTimeoutRef.current); }; }, []); @@ -76,7 +78,8 @@ export function Onboarding({ onComplete }: OnboardingProps) { } finally { setBusy(false); } - setTimeout(refresh, 800); + if (refreshTimeoutRef.current) clearTimeout(refreshTimeoutRef.current); + refreshTimeoutRef.current = window.setTimeout(refresh, 800); }; return ( diff --git a/openless-all/app/src/pages/Settings.tsx b/openless-all/app/src/pages/Settings.tsx index ea171387..0474ba6a 100644 --- a/openless-all/app/src/pages/Settings.tsx +++ b/openless-all/app/src/pages/Settings.tsx @@ -735,11 +735,19 @@ function LanguageSection() { function AboutSection() { const { t } = useTranslation(); const [qqCopied, setQqCopied] = useState(false); + const qqCopiedRef = useRef | null>(null); + + useEffect(() => { + return () => { + if (qqCopiedRef.current) clearTimeout(qqCopiedRef.current); + }; + }, []); const copyQq = () => { navigator.clipboard?.writeText('1078960553'); setQqCopied(true); - setTimeout(() => setQqCopied(false), 1500); + if (qqCopiedRef.current) clearTimeout(qqCopiedRef.current); + qqCopiedRef.current = window.setTimeout(() => setQqCopied(false), 1500); }; return (