[feat](trx-frontend-http): add connection-lost overlay for trx-client and trx-server failures
Show a full-screen blurred overlay (reusing decode-history-overlay styles) when the SSE connection to trx-client drops or when trx-server is reported unreachable via server_connected=false. The overlay distinguishes the two failure modes with separate titles and sub-text. It is dismissed on es.onopen (trx-client back) or when a message with server_connected!=false arrives (trx-server back), and cleared on explicit disconnect/logout. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Stanislaw Grams <stanislawgrams@gmail.com>
This commit is contained in:
@@ -334,6 +334,9 @@ const loadingSub = document.getElementById("loading-sub");
|
|||||||
const decodeHistoryOverlayEl = document.getElementById("decode-history-overlay");
|
const decodeHistoryOverlayEl = document.getElementById("decode-history-overlay");
|
||||||
const decodeHistoryOverlayTitleEl = document.getElementById("decode-history-overlay-title");
|
const decodeHistoryOverlayTitleEl = document.getElementById("decode-history-overlay-title");
|
||||||
const decodeHistoryOverlaySubEl = document.getElementById("decode-history-overlay-sub");
|
const decodeHistoryOverlaySubEl = document.getElementById("decode-history-overlay-sub");
|
||||||
|
const connLostOverlayEl = document.getElementById("conn-lost-overlay");
|
||||||
|
const connLostOverlayTitleEl = document.getElementById("conn-lost-overlay-title");
|
||||||
|
const connLostOverlaySubEl = document.getElementById("conn-lost-overlay-sub");
|
||||||
const overviewCanvas = document.getElementById("overview-canvas");
|
const overviewCanvas = document.getElementById("overview-canvas");
|
||||||
const signalOverlayCanvas = document.getElementById("signal-overlay-canvas");
|
const signalOverlayCanvas = document.getElementById("signal-overlay-canvas");
|
||||||
const overviewGl = typeof createTrxWebGlRenderer === "function"
|
const overviewGl = typeof createTrxWebGlRenderer === "function"
|
||||||
@@ -401,6 +404,13 @@ function setDecodeHistoryOverlayVisible(visible, title = "", sub = "") {
|
|||||||
if (decodeHistoryOverlaySubEl) decodeHistoryOverlaySubEl.textContent = sub || "";
|
if (decodeHistoryOverlaySubEl) decodeHistoryOverlaySubEl.textContent = sub || "";
|
||||||
decodeHistoryOverlayEl.classList.toggle("is-hidden", !visible);
|
decodeHistoryOverlayEl.classList.toggle("is-hidden", !visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setConnLostOverlay(visible, title = "Connection lost", sub = "Retrying\u2026") {
|
||||||
|
if (!connLostOverlayEl) return;
|
||||||
|
if (connLostOverlayTitleEl) connLostOverlayTitleEl.textContent = title;
|
||||||
|
if (connLostOverlaySubEl) connLostOverlaySubEl.textContent = sub;
|
||||||
|
connLostOverlayEl.classList.toggle("is-hidden", !visible);
|
||||||
|
}
|
||||||
const decodeHistoryTextDecoder = typeof TextDecoder === "function" ? new TextDecoder() : null;
|
const decodeHistoryTextDecoder = typeof TextDecoder === "function" ? new TextDecoder() : null;
|
||||||
let decodeHistoryReplayActive = false;
|
let decodeHistoryReplayActive = false;
|
||||||
let decodeMapSyncPending = false;
|
let decodeMapSyncPending = false;
|
||||||
@@ -3093,6 +3103,7 @@ function connect() {
|
|||||||
es = new EventSource("/events");
|
es = new EventSource("/events");
|
||||||
lastEventAt = Date.now();
|
lastEventAt = Date.now();
|
||||||
es.onopen = () => {
|
es.onopen = () => {
|
||||||
|
setConnLostOverlay(false);
|
||||||
pollFreshSnapshot();
|
pollFreshSnapshot();
|
||||||
refreshRigList();
|
refreshRigList();
|
||||||
};
|
};
|
||||||
@@ -3105,8 +3116,10 @@ function connect() {
|
|||||||
lastEventAt = Date.now();
|
lastEventAt = Date.now();
|
||||||
if (data.server_connected === false) {
|
if (data.server_connected === false) {
|
||||||
powerHint.textContent = "trx-server connection lost";
|
powerHint.textContent = "trx-server connection lost";
|
||||||
} else if (data.initialized) {
|
setConnLostOverlay(true, "trx-server connection lost", "trx-client is running but cannot reach the radio server");
|
||||||
powerHint.textContent = readyText();
|
} else {
|
||||||
|
setConnLostOverlay(false);
|
||||||
|
if (data.initialized) powerHint.textContent = readyText();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Bad event data", e);
|
console.error("Bad event data", e);
|
||||||
@@ -3125,6 +3138,7 @@ function connect() {
|
|||||||
// Check if this is an auth error by looking at readyState
|
// Check if this is an auth error by looking at readyState
|
||||||
if (es.readyState === EventSource.CLOSED) {
|
if (es.readyState === EventSource.CLOSED) {
|
||||||
powerHint.textContent = "trx-client connection lost, retrying\u2026";
|
powerHint.textContent = "trx-client connection lost, retrying\u2026";
|
||||||
|
setConnLostOverlay(true, "trx-client connection lost", "Retrying\u2026");
|
||||||
es.close();
|
es.close();
|
||||||
pollFreshSnapshot();
|
pollFreshSnapshot();
|
||||||
scheduleReconnect(1000);
|
scheduleReconnect(1000);
|
||||||
@@ -3135,6 +3149,7 @@ function connect() {
|
|||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
if (now - lastEventAt > 15000) {
|
if (now - lastEventAt > 15000) {
|
||||||
powerHint.textContent = "trx-client connection lost, retrying\u2026";
|
powerHint.textContent = "trx-client connection lost, retrying\u2026";
|
||||||
|
setConnLostOverlay(true, "trx-client connection lost", "Retrying\u2026");
|
||||||
es.close();
|
es.close();
|
||||||
pollFreshSnapshot();
|
pollFreshSnapshot();
|
||||||
scheduleReconnect(250);
|
scheduleReconnect(250);
|
||||||
@@ -3163,6 +3178,7 @@ function disconnect() {
|
|||||||
reconnectTimer = null;
|
reconnectTimer = null;
|
||||||
}
|
}
|
||||||
setDecodeHistoryOverlayVisible(false);
|
setDecodeHistoryOverlayVisible(false);
|
||||||
|
setConnLostOverlay(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Yield the main thread so the browser can paint before heavy async work.
|
// Yield the main thread so the browser can paint before heavy async work.
|
||||||
|
|||||||
@@ -980,6 +980,12 @@
|
|||||||
<div id="decode-history-overlay-sub" class="decode-history-overlay-sub">Preparing recent decodes for the UI</div>
|
<div id="decode-history-overlay-sub" class="decode-history-overlay-sub">Preparing recent decodes for the UI</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="conn-lost-overlay" class="decode-history-overlay is-hidden" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="decode-history-overlay-card">
|
||||||
|
<div id="conn-lost-overlay-title" class="decode-history-overlay-title">Connection lost</div>
|
||||||
|
<div id="conn-lost-overlay-sub" class="decode-history-overlay-sub">Retrying…</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<script src="/webgl-renderer.js"></script>
|
<script src="/webgl-renderer.js"></script>
|
||||||
<script src="/app.js"></script>
|
<script src="/app.js"></script>
|
||||||
<script src="/ais.js"></script>
|
<script src="/ais.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user