93 lines
3.0 KiB
TypeScript
93 lines
3.0 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);
|
|
|
|
useEffect(() => {
|
|
console.log("🕐 useQuestionTimer useEffect triggered", {
|
|
enabled,
|
|
seconds,
|
|
quizId,
|
|
preview,
|
|
currentQuestionId: currentQuestion?.id,
|
|
currentQuestionType: currentQuestion?.type,
|
|
currentQuizStep,
|
|
hasCurrentQuestion: !!currentQuestion,
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
|
|
if (!enabled) {
|
|
console.log("❌ Timer disabled");
|
|
return;
|
|
}
|
|
if (!seconds || seconds <= 0) {
|
|
console.log("❌ Invalid seconds:", seconds);
|
|
return;
|
|
}
|
|
if (!currentQuestion) {
|
|
console.log("❌ No current question");
|
|
return;
|
|
}
|
|
if (currentQuizStep !== "question") {
|
|
console.log("❌ Not on question step:", currentQuizStep);
|
|
return;
|
|
}
|
|
if (currentQuestion.type === "result") {
|
|
console.log("❌ Question is result type");
|
|
return;
|
|
}
|
|
|
|
console.log("✅ Starting timer for", seconds, "seconds");
|
|
|
|
// Сбрасываем предыдущий таймер
|
|
if (timeoutRef.current) {
|
|
console.log("🔄 Clearing previous timer");
|
|
clearTimeout(timeoutRef.current);
|
|
timeoutRef.current = null;
|
|
}
|
|
|
|
timeoutRef.current = window.setTimeout(async () => {
|
|
console.log("⏰ Timer expired! Auto-advancing to next question");
|
|
try {
|
|
if (!preview) {
|
|
console.log("📤 Sending empty answer for question:", currentQuestion.id);
|
|
// Отправляем пустую строку в ответе (questionAnswer === undefined)
|
|
await sendQuestionAnswer(quizId, currentQuestion, undefined, ownVariants);
|
|
console.log("✅ Empty answer sent successfully");
|
|
} else {
|
|
console.log("👀 Preview mode - skipping answer send");
|
|
}
|
|
} catch (e) {
|
|
console.error("❌ Error sending empty timed answer", e);
|
|
enqueueSnackbar("Ошибка при отправке ответа по таймеру");
|
|
} finally {
|
|
console.log("➡️ Calling onNext()");
|
|
onNext();
|
|
}
|
|
}, seconds * 1000);
|
|
|
|
return () => {
|
|
console.log("🧹 Cleaning up timer");
|
|
if (timeoutRef.current) {
|
|
clearTimeout(timeoutRef.current);
|
|
timeoutRef.current = null;
|
|
}
|
|
};
|
|
}, [enabled, seconds, quizId, preview, currentQuestion?.id, currentQuizStep, onNext]);
|
|
}
|