frontAnswerer/lib/utils/hooks/FlowControlLogic/useQuestionTimer.ts

79 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useEffect, useRef } from "react";
import { enqueueSnackbar } from "notistack";
import { useQuizViewStore } from "@/stores/quizView";
import { sendQuestionAnswer } from "@/utils/sendQuestionAnswer";
type Params = {
enabled: boolean;
seconds: number;
quizId: string;
preview: boolean;
currentQuestion: any; // Using any to avoid tight coupling with question union types
onNext: () => void;
};
export function useQuestionTimer({ enabled, seconds, quizId, preview, currentQuestion, onNext }: Params) {
const ownVariants = useQuizViewStore((state) => state.ownVariants);
const currentQuizStep = useQuizViewStore((state) => state.currentQuizStep);
const timeoutRef = useRef<number | null>(null);
const isFirstQuestionRef = useRef<boolean>(true);
useEffect(() => {
if (!enabled) {
return;
}
if (!seconds || seconds <= 0) {
return;
}
if (!currentQuestion) {
return;
}
if (currentQuizStep !== "question") {
return;
}
if (currentQuestion.type === "result") {
return;
}
// Сбрасываем предыдущий таймер
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
// Для первого вопроса добавляем дополнительную задержку, чтобы избежать конфликтов с навигацией
const isFirstQuestion = isFirstQuestionRef.current;
const startDelay = isFirstQuestion ? 2000 : 100; // 2 секунды для первого вопроса, 100ms для остальных
if (isFirstQuestion) {
isFirstQuestionRef.current = false;
}
timeoutRef.current = window.setTimeout(
async () => {
try {
if (!preview) {
// Отправляем пустую строку в ответе (questionAnswer === undefined)
await sendQuestionAnswer(quizId, currentQuestion, undefined, ownVariants);
} else {
}
} catch (e) {
console.error("❌ Error sending empty timed answer", e);
enqueueSnackbar("Ошибка при отправке ответа по таймеру");
} finally {
onNext();
}
},
seconds * 1000 + startDelay
);
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
};
}, [enabled, seconds, quizId, preview, currentQuestion?.id, currentQuizStep, onNext]);
}