From 319832ebc811479a1ed57c24218c746825a713a1 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Mon, 23 Mar 2026 14:27:42 +0100 Subject: [PATCH] feat: clear voiceWs on all voice leave paths --- packages/server/src/ws/events.ts | 15 ++++++++++++++- packages/server/src/ws/handler.ts | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/server/src/ws/events.ts b/packages/server/src/ws/events.ts index f3049ea1..b62b3597 100644 --- a/packages/server/src/ws/events.ts +++ b/packages/server/src/ws/events.ts @@ -762,6 +762,7 @@ function handleVoiceJoin(event: Record, userId: string, ws: Web } function handleVoiceLeave(userId: string): void { + connectionManager.clearVoiceWs(userId); const left = connectionManager.leaveCurrentRoom(userId); if (left) { broadcastRoomLeave(left.roomId, left.room, userId); @@ -1432,6 +1433,12 @@ function handleDmCallReject(event: Record, userId: string): voi const room = connectionManager.getRoom(dmChannelId); if (!room) return; // No active call, silently ignore + // Extract caller ID before destroying the room + const meta = room.metadata as DmRoomMeta; + + // Clear caller's voice ws binding (set during handleDmCallStart) + connectionManager.clearVoiceWs(meta.callerId); + // Destroy room connectionManager.destroyRoom(dmChannelId); @@ -1457,9 +1464,14 @@ function handleDmCallEnd(event: Record, userId: string): void { const room = connectionManager.getRoom(dmChannelId); if (!room) return; // No active call, silently ignore - // Clear voice user states for all participants + // Clear voice ws binding for the caller (may not be in participants if still ringing) + const meta = room.metadata as DmRoomMeta; + connectionManager.clearVoiceWs(meta.callerId); + + // Clear voice user states and voice ws for all participants for (const participantId of room.participants) { connectionManager.clearVoiceUserStatus(participantId); + connectionManager.clearVoiceWs(participantId); } // Destroy room (removes all participants from userToRoom) @@ -1711,6 +1723,7 @@ function handleVoiceDisconnect(event: Record, userId: string): // Remove from voice room connectionManager.leaveRoom(channelId, targetUserId); + connectionManager.clearVoiceWs(targetUserId); // Clear ephemeral voice status (mute/camera/etc) connectionManager.clearVoiceUserStatus(targetUserId); diff --git a/packages/server/src/ws/handler.ts b/packages/server/src/ws/handler.ts index 2b8b30bb..07d2a139 100644 --- a/packages/server/src/ws/handler.ts +++ b/packages/server/src/ws/handler.ts @@ -165,6 +165,7 @@ class ConnectionManager { // Leave voice room if in one (handles both space and DM rooms) const left = this.leaveCurrentRoom(userId); this.clearVoiceUserStatus(userId); + this.voiceWs.delete(userId); if (left) { if (left.room.roomType === 'space') { const meta = left.room.metadata as SpaceRoomMeta; @@ -648,6 +649,7 @@ class ConnectionManager { // Leave voice room if in one const left = this.leaveCurrentRoom(userId); this.clearVoiceUserStatus(userId); + this.voiceWs.delete(userId); if (left) { if (left.room.roomType === 'space') { const meta = left.room.metadata as SpaceRoomMeta;