pause ptz turns when no ones on

This commit is contained in:
legop3
2026-09-24 18:06:24 -04:00
parent ffd34de56c
commit 8ca714cf1a
4 changed files with 21 additions and 10 deletions
@@ -121,7 +121,7 @@ function describeParticipation(socket) {
color: cameraConfig.color || DEFAULT_PTZ_COLOR,
fallback: null,
},
enabled: entered && (isOperator || position > 0),
enabled: entered && (isOperator || position > 0) && participation.state.queue.length > 0,
isActive: isOperator,
turnsAhead: isOperator ? 0 : position || null,
queueLength: participation.state.queue.length + (participation.state.operatorSocketId ? 1 : 0),
@@ -22,19 +22,27 @@ function createParticipation({ io, events, emitChange, getTurnDurationMs, canPar
}
function scheduleTurn() {
clearTimeout(timer);
// Uncontested control has no deadline. Starting a new wait gets a full turn,
// while later queue changes must not reset an already running countdown.
if (!state.operatorSocketId || !state.queue.length) {
clearTimeout(timer);
timer = null;
state.deadline = null;
return;
}
if (timer) return;
const duration = getTurnDurationMs();
state.deadline = Date.now() + duration;
timer = setTimeout(() => {
// An expired operator stays when alone, but is not automatically requeued
// when another participant takes over. Preserve the existing PTZ rule.
state.queue = state.queue.filter((id) => eligible(id));
timer = null;
state.queue = state.queue.filter(eligible);
if (state.queue.length) {
// Preserve PTZ's explicit request-to-rejoin rule after a handoff.
stopOperator('turn-expired');
advance('turn-expired');
} else {
scheduleTurn();
emitChange('turn-extended-empty-queue');
emitChange('turn-uncontested');
}
}, duration);
}
@@ -45,14 +53,15 @@ function createParticipation({ io, events, emitChange, getTurnDurationMs, canPar
}
function advance(reason) {
state.queue = state.queue.filter(eligible);
while (!state.operatorSocketId && state.queue.length) {
const next = state.queue.shift();
if (!eligible(next)) continue;
state.operatorSocketId = next;
state.generation += 1;
scheduleTurn();
events.emit('operator', { socketId: next, action: 'active' });
}
scheduleTurn();
emitChange(reason);
}