79 lines
2.5 KiB
TypeScript
79 lines
2.5 KiB
TypeScript
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]);
|
||
}
|