From 10c4b735cfe78f52c9c5551d684dacf2875e08a3 Mon Sep 17 00:00:00 2001 From: Stanislaw Grams Date: Sun, 8 Feb 2026 22:44:21 +0100 Subject: [PATCH] [fix](trx-frontend-http): show decode SSE connection status The decode EventSource silently retried on 404 leaving the status stuck on "Waiting for server decode". Probe /decode first to distinguish 404 (audio disabled) from real SSE errors and update the APRS/CW status text accordingly. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Stanislaw Grams --- .../trx-frontend-http/assets/web/app.js | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js index 6234ef3..8904bd4 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js @@ -1125,24 +1125,45 @@ document.getElementById("copyright-year").textContent = new Date().getFullYear() // --- Server-side decode SSE --- let decodeSource = null; let decodeConnected = false; +function updateDecodeStatus(text) { + const aprs = document.getElementById("aprs-status"); + const cw = document.getElementById("cw-status"); + if (aprs && aprs.textContent !== "Receiving") aprs.textContent = text; + if (cw && cw.textContent !== "Receiving") cw.textContent = text; +} function connectDecode() { if (decodeSource) { decodeSource.close(); } - decodeSource = new EventSource("/decode"); - decodeSource.onopen = () => { decodeConnected = true; }; - decodeSource.onmessage = (evt) => { - try { - const msg = JSON.parse(evt.data); - if (msg.type === "aprs" && window.onServerAprs) window.onServerAprs(msg); - if (msg.type === "cw" && window.onServerCw) window.onServerCw(msg); - } catch (e) { - // ignore parse errors + // Probe first to distinguish 404 from real SSE errors + fetch("/decode", { method: "HEAD" }).then((r) => { + if (r.status === 404) { + updateDecodeStatus("Decode not available (audio disabled?)"); + setTimeout(connectDecode, 10000); + return; } - }; - decodeSource.onerror = () => { - decodeSource.close(); - decodeConnected = false; + decodeSource = new EventSource("/decode"); + decodeSource.onopen = () => { + decodeConnected = true; + updateDecodeStatus("Connected, listening for packets"); + }; + decodeSource.onmessage = (evt) => { + try { + const msg = JSON.parse(evt.data); + if (msg.type === "aprs" && window.onServerAprs) window.onServerAprs(msg); + if (msg.type === "cw" && window.onServerCw) window.onServerCw(msg); + } catch (e) { + // ignore parse errors + } + }; + decodeSource.onerror = () => { + decodeSource.close(); + decodeConnected = false; + updateDecodeStatus("Decode disconnected, retrying…"); + setTimeout(connectDecode, 5000); + }; + }).catch(() => { + updateDecodeStatus("Decode endpoint unreachable"); setTimeout(connectDecode, 5000); - }; + }); } connectDecode();