fix: sonido del turno se disparaba 3 veces en la pantalla TV
Dos causas: 1. sse_turno.php inicializaba \$lastPing = null, haciendo que la primera iteración del loop (2s después del emit inicial) siempre emitiera un snapshot extra aunque no hubiera cambios reales. Fix: inicializar \$lastPing con el sse_ping_at actual de la BD. 2. display.php comparaba activo.codigo para detectar nueva llamada. Si el poll y el SSE llegaban casi simultáneamente antes de que lastCodigoActivo se actualizara, ambos disparaban el sonido. Fix: comparar llamado_at en vez del código — el timestamp es único por llamada, por lo que sonidos duplicados son imposibles. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
ae8d2cb13a
commit
4058cfe929
@@ -116,7 +116,6 @@ function buildSnapshot(PDO $pdo, int $sesionId, string $area, ?int $lugarId): ar
|
|||||||
|
|
||||||
// ── Loop principal ────────────────────────────────────────────
|
// ── Loop principal ────────────────────────────────────────────
|
||||||
$sesionId = obtenerOCrearSesionHoy();
|
$sesionId = obtenerOCrearSesionHoy();
|
||||||
$lastPing = null; // sse_ping_at de la última iteración
|
|
||||||
$lastKeepalive = time();
|
$lastKeepalive = time();
|
||||||
$lastEmit = 0;
|
$lastEmit = 0;
|
||||||
|
|
||||||
@@ -124,6 +123,12 @@ $lastEmit = 0;
|
|||||||
$snapshot = buildSnapshot($pdo, $sesionId, $area, $lugarId);
|
$snapshot = buildSnapshot($pdo, $sesionId, $area, $lugarId);
|
||||||
sseEvent('cola_update', $snapshot);
|
sseEvent('cola_update', $snapshot);
|
||||||
|
|
||||||
|
// Inicializar $lastPing con el valor ACTUAL (no null) para que la
|
||||||
|
// primera iteración del loop no emita un snapshot extra sin cambios
|
||||||
|
$stmt = $pdo->prepare('SELECT sse_ping_at FROM turnero_sesiones WHERE id = ?');
|
||||||
|
$stmt->execute([$sesionId]);
|
||||||
|
$lastPing = $stmt->fetchColumn() ?: null;
|
||||||
|
|
||||||
while (!connection_aborted()) {
|
while (!connection_aborted()) {
|
||||||
sleep(2);
|
sleep(2);
|
||||||
|
|
||||||
|
|||||||
@@ -427,8 +427,8 @@ function anunciarTurno(codigo, nombre) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Estado previo ─────────────────────────────────────────────
|
// ── Estado previo — usamos llamado_at para evitar doble sonido ─
|
||||||
let lastCodigoActivo = null;
|
let lastLlamadoAt = null;
|
||||||
|
|
||||||
// ── Render ────────────────────────────────────────────────────
|
// ── Render ────────────────────────────────────────────────────
|
||||||
function renderSnapshot(snap) {
|
function renderSnapshot(snap) {
|
||||||
@@ -443,13 +443,15 @@ function renderSnapshot(snap) {
|
|||||||
const elRing = document.getElementById('ring');
|
const elRing = document.getElementById('ring');
|
||||||
|
|
||||||
if (activo) {
|
if (activo) {
|
||||||
// ¿Cambió el turno? → animar + sonido
|
// ¿Nueva llamada? comparar llamado_at para evitar doble sonido
|
||||||
if (activo.codigo !== lastCodigoActivo) {
|
// cuando poll y SSE llegan casi al mismo tiempo con el mismo turno
|
||||||
|
const llamadoAt = activo.llamado_at || activo.llamado_recepcion_at || activo.codigo;
|
||||||
|
if (llamadoAt !== lastLlamadoAt) {
|
||||||
anunciarTurno(activo.codigo, activo.paciente_nombre || '');
|
anunciarTurno(activo.codigo, activo.paciente_nombre || '');
|
||||||
elRing.classList.remove('animar');
|
elRing.classList.remove('animar');
|
||||||
void elRing.offsetWidth;
|
void elRing.offsetWidth;
|
||||||
elRing.classList.add('animar');
|
elRing.classList.add('animar');
|
||||||
lastCodigoActivo = activo.codigo;
|
lastLlamadoAt = llamadoAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prioColor = activo.prioridad_color || '#1565c0';
|
const prioColor = activo.prioridad_color || '#1565c0';
|
||||||
@@ -473,7 +475,7 @@ function renderSnapshot(snap) {
|
|||||||
elPrio.style.background = '#f1f5f9';
|
elPrio.style.background = '#f1f5f9';
|
||||||
elPrio.style.color = '#94a3b8';
|
elPrio.style.color = '#94a3b8';
|
||||||
elPrio.innerHTML = '<i class="fas fa-hourglass-half"></i> Esperando turno';
|
elPrio.innerHTML = '<i class="fas fa-hourglass-half"></i> Esperando turno';
|
||||||
lastCodigoActivo = null;
|
lastLlamadoAt = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lista de cola (excluir el activo si está ahí)
|
// Lista de cola (excluir el activo si está ahí)
|
||||||
|
|||||||
Reference in New Issue
Block a user