fix: sync collab overlay connection state with runtime WS status

The overlay was blindly setting 'connected' on runtime ready without
checking actual WebSocket state, and never subscribed to connect/disconnect
events — causing stale "Reconnecting…" badges.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-30 19:48:45 -07:00
parent f9457a0e11
commit 6a0ad06c11
1 changed files with 16 additions and 4 deletions

View File

@ -47,6 +47,8 @@ export class RStackCollabOverlay extends HTMLElement {
#unsubAwareness: (() => void) | null = null;
#unsubPresence: (() => void) | null = null;
#unsubLeave: (() => void) | null = null;
#unsubConnect: (() => void) | null = null;
#unsubDisconnect: (() => void) | null = null;
#mouseMoveTimer: ReturnType<typeof setInterval> | null = null;
#lastCursor = { x: 0, y: 0 };
#gcInterval: ReturnType<typeof setInterval> | null = null;
@ -112,6 +114,8 @@ export class RStackCollabOverlay extends HTMLElement {
this.#unsubAwareness?.();
this.#unsubPresence?.();
this.#unsubLeave?.();
this.#unsubConnect?.();
this.#unsubDisconnect?.();
this.#stopMouseTracking();
this.#stopFocusTracking();
}
@ -189,7 +193,14 @@ export class RStackCollabOverlay extends HTMLElement {
this.#localPeerId = runtime.peerId;
// Assign a deterministic color from peer ID
this.#localColor = this.#colorForPeer(this.#localPeerId!);
this.#connState = 'connected';
// Set initial state from actual runtime connection status
this.#connState = runtime.isOnline ? 'connected' : 'offline';
// Track ongoing connection state changes
this.#unsubConnect = runtime.onConnect(() => this.setConnState('connected'));
this.#unsubDisconnect = runtime.onDisconnect(() => {
this.setConnState(navigator.onLine ? 'reconnecting' : 'offline');
});
// Load space members for offline display
this.#loadSpaceMembers();
@ -517,7 +528,7 @@ export class RStackCollabOverlay extends HTMLElement {
if (this.#connState === 'offline' || this.#connState === 'reconnecting' || this.#connState === 'connecting') {
const msg = this.#connState === 'offline'
? '\u26a0 You\u2019re offline. Changes are saved locally and will resync when you reconnect.'
: 'Reconnecting to server\u2026';
: this.#connState === 'connecting' ? 'Connecting to server\u2026' : 'Reconnecting to server\u2026';
fragments.push(`<div class="conn-notice">${this.#escHtml(msg)}</div>`);
}
@ -669,12 +680,13 @@ export class RStackCollabOverlay extends HTMLElement {
}
if (this.#connState === 'reconnecting' || this.#connState === 'connecting') {
const label = this.#connState === 'connecting' ? 'Connecting\u2026' : 'Reconnecting\u2026';
badge.innerHTML = `
<span class="dot" style="background:#3b82f6"></span>
<span class="count">Reconnecting\u2026</span>
<span class="count">${label}</span>
`;
badge.classList.add('visible');
badge.title = 'Reconnecting to server\u2026';
badge.title = label;
return;
}