feat: voice status visibility + sidebar persistence fixes

- Add WebSocket voice_status/voice_status_update events so mute/deafen
  icons are visible in the sidebar without joining the voice channel
- Server tracks voiceUserStates and includes them in the ready payload
- Re-register voice channel on WebSocket reconnect to prevent sidebar
  users from disappearing after idle timeout
- Re-broadcast deafen state to late joiners via LiveKit data channel
- Fix black grid tile when video stops (enabled-flag guards)
- Remove duplicate mute/deafen from VoiceControls (replaced with
  Video Quality + Noise Suppression)
- Fix missing users in sidebar voice list (identity matching + fallback)
This commit is contained in:
Jannis Braun
2026-02-19 07:58:50 +01:00
parent 503e483b82
commit 0da4a530d6
10 changed files with 307 additions and 102 deletions
+24
View File
@@ -156,6 +156,9 @@ export function handleClientEvent(
case 'dm_call_end':
handleDmCallEnd(event, userId);
break;
case 'voice_status':
handleVoiceStatus(event, userId);
break;
default:
connectionManager.sendToUser(userId, {
type: 'error',
@@ -738,6 +741,27 @@ function handleChannelAck(event: Record<string, unknown>, userId: string): void
});
}
function handleVoiceStatus(event: Record<string, unknown>, userId: string): void {
const isMuted = event.isMuted === true;
const isDeafened = event.isDeafened === true;
const channelId = connectionManager.getUserVoiceChannel(userId);
if (!channelId) return;
const serverId = getChannelServerId(channelId);
if (!serverId) return;
connectionManager.setVoiceUserStatus(userId, isMuted, isDeafened);
connectionManager.sendToServer(serverId, {
type: 'voice_status_update',
userId,
channelId,
isMuted,
isDeafened,
});
}
// ─── DM Call Handlers ──────────────────────────────────────────────────────────
function handleDmCallStart(event: Record<string, unknown>, userId: string, username: string): void {