From 2220a6eb3cca7226e72a3d8607b64e424e5d88c8 Mon Sep 17 00:00:00 2001 From: Steve Biedermann Date: Sun, 11 Oct 2026 18:28:47 +0200 Subject: [PATCH] fix(ui): fall back to polling when websocket is unavailable Poll the state endpoint while the WebSocket is not open so browsers that fail to establish the socket still receive initial state and continue updating the UI. Retain WebSocket streaming as the primary transport. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ui/src/api.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/ui/src/api.rs b/ui/src/api.rs index 077b982..0e962f2 100644 --- a/ui/src/api.rs +++ b/ui/src/api.rs @@ -17,13 +17,32 @@ pub fn connect(on_state: impl Fn(String) + 'static) { let Some(loc) = web_sys::window().map(|w| w.location()) else { return; }; + let on_state = Rc::new(on_state); let proto = if loc.protocol().is_ok_and(|p| p == "https:") { "wss" } else { "ws" }; let Ok(host) = loc.host() else { return }; - open(format!("{proto}://{host}/ws"), Rc::new(on_state)); + open(format!("{proto}://{host}/ws"), on_state.clone()); + + spawn_local(async move { + loop { + TimeoutFuture::new(1000).await; + let connected = SOCKET.with(|socket| { + socket + .borrow() + .as_ref() + .is_some_and(|socket| socket.ready_state() == WebSocket::OPEN) + }); + if connected { + continue; + } + if let Some(state) = get_text("/api/state").await { + on_state(state); + } + } + }); } fn open(url: String, on_state: Rc) {