diff --git a/src/trx-client/src/remote_client.rs b/src/trx-client/src/remote_client.rs index ee5789b..8bc30d9 100644 --- a/src/trx-client/src/remote_client.rs +++ b/src/trx-client/src/remote_client.rs @@ -109,6 +109,8 @@ pub async fn run_remote_client( warn!("Remote connection dropped: {}", e); } config.server_connected.store(false, Ordering::Relaxed); + // Nudge the state watch so SSE clients see server_connected=false. + state_tx.send_modify(|_| {}); } Ok(Err(e)) => { warn!("Remote connect failed: {}", e); 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 d528d04..10590f9 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 @@ -3381,6 +3381,8 @@ function connect() { lastEventAt = Date.now(); es.onopen = () => { setConnLostOverlay(false); + const tm = document.getElementById("tab-main"); + if (tm) tm.classList.remove("server-disconnected"); if (!aboutUptimeStart) aboutUptimeStart = Date.now(); pollFreshSnapshot(); refreshRigList(); @@ -3392,11 +3394,12 @@ function connect() { lastRendered = evt.data; render(data); lastEventAt = Date.now(); + const tabMain = document.getElementById("tab-main"); if (data.server_connected === false) { powerHint.textContent = "trx-server connection lost"; - setConnLostOverlay(true, "trx-server connection lost", "trx-client is running but cannot reach the radio server"); + if (tabMain) tabMain.classList.add("server-disconnected"); } else { - setConnLostOverlay(false); + if (tabMain) tabMain.classList.remove("server-disconnected"); if (data.initialized) powerHint.textContent = readyText(); } } catch (e) { diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html index cb93c8d..99689e2 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html @@ -96,6 +96,7 @@
+
trx-server connection lost — waiting for reconnect
Initializing (rig)…
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css index ec64b29..01a2123 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css @@ -1431,6 +1431,39 @@ small { color: var(--text-muted); } position: fixed; border-radius: 0; } +#server-lost-banner { + display: none; + align-items: center; + justify-content: center; + gap: 0.5rem; + padding: 0.45rem 0.75rem; + background: color-mix(in srgb, var(--accent-red) 18%, var(--card-bg)); + border: 1px solid color-mix(in srgb, var(--accent-red) 40%, var(--border)); + border-radius: 0.4rem; + color: var(--accent-red); + font-size: 0.82rem; + font-weight: 600; + margin-bottom: 0.5rem; +} +#server-lost-banner .banner-dot { + width: 7px; height: 7px; border-radius: 50%; + background: var(--accent-red); + animation: banner-pulse 1.5s ease-in-out infinite; +} +@keyframes banner-pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.3; } +} +#tab-main.server-disconnected #content { + pointer-events: none; + filter: saturate(0.3) brightness(0.7); + opacity: 0.55; + transition: filter 0.4s ease, opacity 0.4s ease; +} +#tab-main.server-disconnected #server-lost-banner { display: flex; } +#tab-main:not(.server-disconnected) #content { + transition: filter 0.3s ease, opacity 0.3s ease; +} .decode-history-overlay-card { min-width: min(26rem, calc(100vw - 2.4rem)); max-width: min(30rem, calc(100vw - 2.4rem));