fix: директивы неактивны на паузе, отложенные правки не уходят в закрытое занятие

This commit is contained in:
GGlamer 2026-09-27 22:30:18 +03:00
commit d403965f49
2 changed files with 8 additions and 1 deletions

View file

@ -60,6 +60,7 @@ export function useCall(sessionId: string | null) {
const patchTimer = useRef<ReturnType<typeof setTimeout> | null>(null); const patchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
const textMode = useRef(false); const textMode = useRef(false);
const pausedRef = useRef(false); const pausedRef = useRef(false);
const endedRef = useRef(false);
const append = useCallback((line: Line) => { const append = useCallback((line: Line) => {
setLines((prev) => { setLines((prev) => {
@ -70,6 +71,7 @@ export function useCall(sessionId: string | null) {
useEffect(() => { useEffect(() => {
if (!sessionId) return; if (!sessionId) return;
endedRef.current = false;
const ch = callChannel(sessionId, { const ch = callChannel(sessionId, {
onStatus: (next) => { onStatus: (next) => {
setStatus(next); setStatus(next);
@ -133,6 +135,7 @@ export function useCall(sessionId: string | null) {
setTimers(event.timers); setTimers(event.timers);
break; break;
case "call.ended": case "call.ended":
endedRef.current = true;
setPhase("ended"); setPhase("ended");
audio.current?.ambience.stop(); audio.current?.ambience.stop();
if (textMode.current) { setCardSubmitted(true); break; } if (textMode.current) { setCardSubmitted(true); break; }
@ -154,6 +157,10 @@ export function useCall(sessionId: string | null) {
setCallerSpeaking(false); setCallerSpeaking(false);
if (patchTimer.current) clearTimeout(patchTimer.current); if (patchTimer.current) clearTimeout(patchTimer.current);
patchTimer.current = null; patchTimer.current = null;
} else if (endedRef.current) {
// Занятие завершили прямо на паузе: сервер снимает её после
// `call.ended`, и отложенные правки уже не войдут в оценку.
outbox.current = {};
} else { } else {
// При переподключении сервер первым присылает состояние паузы. // При переподключении сервер первым присылает состояние паузы.
// Только после этого повторяем правки, ожидающие подтверждения. // Только после этого повторяем правки, ожидающие подтверждения.

View file

@ -708,7 +708,7 @@ export function Instructor() {
</p> </p>
)} )}
{sessionId && session.title && !session.ended && ( {sessionId && session.title && !session.ended && (
exercise === "call" && <Director onInject={control.inject} disabled={control.status !== "open"} error={session.error} /> exercise === "call" && <Director onInject={control.inject} disabled={control.status !== "open" || session.paused} error={session.error} />
)} )}
{links && startPendingId && ( {links && startPendingId && (
<p className="ref" role="status">Создаём занятие. Ссылки появятся автоматически после подключения.</p> <p className="ref" role="status">Создаём занятие. Ссылки появятся автоматически после подключения.</p>