diff --git a/modules/turnero/api/sse_turno.php b/modules/turnero/api/sse_turno.php index ab636db..a9c57a8 100644 --- a/modules/turnero/api/sse_turno.php +++ b/modules/turnero/api/sse_turno.php @@ -116,7 +116,6 @@ function buildSnapshot(PDO $pdo, int $sesionId, string $area, ?int $lugarId): ar // ── Loop principal ──────────────────────────────────────────── $sesionId = obtenerOCrearSesionHoy(); -$lastPing = null; // sse_ping_at de la última iteración $lastKeepalive = time(); $lastEmit = 0; @@ -124,6 +123,12 @@ $lastEmit = 0; $snapshot = buildSnapshot($pdo, $sesionId, $area, $lugarId); 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()) { sleep(2); diff --git a/modules/turnero/views/display.php b/modules/turnero/views/display.php index 6ecc390..dba6518 100644 --- a/modules/turnero/views/display.php +++ b/modules/turnero/views/display.php @@ -427,8 +427,8 @@ function anunciarTurno(codigo, nombre) { } } -// ── Estado previo ───────────────────────────────────────────── -let lastCodigoActivo = null; +// ── Estado previo — usamos llamado_at para evitar doble sonido ─ +let lastLlamadoAt = null; // ── Render ──────────────────────────────────────────────────── function renderSnapshot(snap) { @@ -443,13 +443,15 @@ function renderSnapshot(snap) { const elRing = document.getElementById('ring'); if (activo) { - // ¿Cambió el turno? → animar + sonido - if (activo.codigo !== lastCodigoActivo) { + // ¿Nueva llamada? comparar llamado_at para evitar doble sonido + // 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 || ''); elRing.classList.remove('animar'); void elRing.offsetWidth; elRing.classList.add('animar'); - lastCodigoActivo = activo.codigo; + lastLlamadoAt = llamadoAt; } const prioColor = activo.prioridad_color || '#1565c0'; @@ -473,7 +475,7 @@ function renderSnapshot(snap) { elPrio.style.background = '#f1f5f9'; elPrio.style.color = '#94a3b8'; elPrio.innerHTML = ' Esperando turno'; - lastCodigoActivo = null; + lastLlamadoAt = null; } // Lista de cola (excluir el activo si está ahí)