From 35c0146a964e363304b3ad864943f9da30d7a3e4 Mon Sep 17 00:00:00 2001 From: ittoview Date: Sat, 16 May 2026 12:19:01 +0100 Subject: [PATCH] feat: add performance challenge mode --- src/pages/PerformanceDomainPracticePage.tsx | 61 ++++++++++++++++++--- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/src/pages/PerformanceDomainPracticePage.tsx b/src/pages/PerformanceDomainPracticePage.tsx index 4613c4d..1ce3a2c 100644 --- a/src/pages/PerformanceDomainPracticePage.tsx +++ b/src/pages/PerformanceDomainPracticePage.tsx @@ -49,6 +49,7 @@ interface AnswerState { const STORAGE_KEY = 'performance-domain-practice-progress-v3' const CORRECT_AUTO_NEXT_DELAY = 1000 +const CHALLENGE_RESTART_DELAY = 3000 const scopeOptions: Array<{ value: PracticeScope; label: string }> = [ { value: 'all', label: '全部' }, @@ -190,7 +191,9 @@ export default function PerformanceDomainPracticePage() { ) const [answerState, setAnswerState] = useState(null) const [showCelebration, setShowCelebration] = useState(false) + const [challengeMode, setChallengeMode] = useState(false) const autoNextTimerRef = useRef(null) + const challengeRestartTimerRef = useRef(null) const currentQuestionId = progress.queue[0] ?? null const currentQuestion = currentQuestionId @@ -246,6 +249,10 @@ export default function PerformanceDomainPracticePage() { window.clearTimeout(autoNextTimerRef.current) autoNextTimerRef.current = null } + if (challengeRestartTimerRef.current) { + window.clearTimeout(challengeRestartTimerRef.current) + challengeRestartTimerRef.current = null + } setProgress(createProgress(scope, questionBank)) setAnswerState(null) setShowCelebration(false) @@ -256,6 +263,25 @@ export default function PerformanceDomainPracticePage() { restartPractice(scope) } + useEffect(() => { + if (!challengeMode || !answerState || answerState.isCorrect) return + + if (challengeRestartTimerRef.current) { + window.clearTimeout(challengeRestartTimerRef.current) + } + + challengeRestartTimerRef.current = window.setTimeout(() => { + restartPractice(progress.scope) + }, CHALLENGE_RESTART_DELAY) + + return () => { + if (challengeRestartTimerRef.current) { + window.clearTimeout(challengeRestartTimerRef.current) + challengeRestartTimerRef.current = null + } + } + }, [answerState, challengeMode, progress.scope]) + const advanceToNext = (isCorrect: boolean) => { if (!currentQuestionId) return @@ -263,6 +289,10 @@ export default function PerformanceDomainPracticePage() { window.clearTimeout(autoNextTimerRef.current) autoNextTimerRef.current = null } + if (challengeRestartTimerRef.current) { + window.clearTimeout(challengeRestartTimerRef.current) + challengeRestartTimerRef.current = null + } setAnswerState(null) setProgress((prev) => { if (prev.queue[0] !== currentQuestionId) return prev @@ -478,14 +508,29 @@ export default function PerformanceDomainPracticePage() { - +
+ + +