From c4032417ae2fdfbf941e4763dcd68490e0e3416d Mon Sep 17 00:00:00 2001 From: Fredrik Johansson Date: Thu, 25 Jun 2026 20:54:47 +0200 Subject: [PATCH] Show peers immediately on discovery, before DataChannel opens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Emit peer_connected + peer_status(connecting) as soon as a PeerConn is created, so peers appear in the sidebar even if ICE is still negotiating or ultimately fails. The alias updates in-place once the DataChannel hello arrives with the real nick. Fixes: mobile/CGNAT peers being completely invisible when STUN hole punching fails — they now show with a connecting/failed dot instead of not appearing at all. Co-Authored-By: Claude Sonnet 4.6 --- web/src/adapter/browser.ts | 14 ++++++++++++++ web/src/store/index.ts | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/web/src/adapter/browser.ts b/web/src/adapter/browser.ts index f442bd8..f29852b 100644 --- a/web/src/adapter/browser.ts +++ b/web/src/adapter/browser.ts @@ -707,6 +707,7 @@ export class BrowserAdapter { const peer = new PeerConn(this.identity, this.sig!, pid, (ev, data) => this._onPeerEvent(ev, data), this.identity.nick, this.sharedFiles) this.peers.set(pid, peer) + this._emitDiscovered(pid) await peer.startOffer() } @@ -716,6 +717,7 @@ export class BrowserAdapter { if (!peer || peer.pc.connectionState === 'failed' || peer.pc.connectionState === 'closed') { peer = new PeerConn(this.identity, this.sig!, from, (ev, data) => this._onPeerEvent(ev, data), this.identity.nick, this.sharedFiles) + this._emitDiscovered(from) this.peers.set(from, peer) } await peer.onBox(box) @@ -810,6 +812,18 @@ export class BrowserAdapter { } } + private _emitDiscovered(pid: string) { + this.emit({ + type: 'peer_connected', + peer: { id: pid, alias: pid.slice(0, 8), public_key: pid, created_at: new Date().toISOString() }, + }) + this.emit({ + type: 'peer_status', + peer_id: pid as unknown as import('../types').PeerID, + conn_state: 'connecting', + }) + } + setSharedFiles(files: Map) { this.sharedFiles = files this.peers.forEach(p => { p.share = files }) diff --git a/web/src/store/index.ts b/web/src/store/index.ts index ddc50a7..25dda6d 100644 --- a/web/src/store/index.ts +++ b/web/src/store/index.ts @@ -235,7 +235,7 @@ export const useWaste = create((set, get) => ({ if (msg.peer) { set(s => ({ connectedPeers: s.connectedPeers.some(p => p.id === msg.peer!.id) - ? s.connectedPeers + ? s.connectedPeers.map(p => p.id === msg.peer!.id ? { ...p, ...msg.peer } : p) : [...s.connectedPeers, msg.peer!], })) }