diff --git a/server/go/web/ws.go b/server/go/web/ws.go index 1328f1a..bd2c6ad 100644 --- a/server/go/web/ws.go +++ b/server/go/web/ws.go @@ -229,8 +229,30 @@ func (h *wsHub) OnDeviceOnline(_ hub.DeviceInfo) { h.broadcastAuthenticated(`{"cmd":"devices_changed"}`) } -func (h *wsHub) OnDeviceOffline(_ string) { +func (h *wsHub) OnDeviceOffline(id string) { + // Tell everyone authenticated to refresh their device list (covers + // users sitting on the devices-page). h.broadcastAuthenticated(`{"cmd":"devices_changed"}`) + + // Also tell any browser actively viewing this device's screen — the + // devices_changed handler only refreshes the list page; viewers on the + // screen page would otherwise see a frozen frame with "Connected" status + // indefinitely. The browser handles this by showing "Device offline" and + // bouncing back to the device list after 2 s. + if id == "" { + return + } + msg := mustJSON(map[string]any{ + "cmd": "device_offline", + "id": id, + }) + h.mu.RLock() + defer h.mu.RUnlock() + for c := range h.clients { + if c.watching == id && c.token != "" { + c.queue(msg) + } + } } // OnCursorChange relays the remote cursor index to every viewer of this