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
+4 -2
View File
@@ -185,11 +185,12 @@ export type ClientEvent =
| { type: 'dm_call_start'; dmChannelId: string }
| { type: 'dm_call_accept'; dmChannelId: string }
| { type: 'dm_call_reject'; dmChannelId: string }
| { type: 'dm_call_end'; dmChannelId: string };
| { type: 'dm_call_end'; dmChannelId: string }
| { type: 'voice_status'; isMuted: boolean; isDeafened: boolean };
// Server → Client Events
export type ServerEvent =
| { type: 'ready'; user: User; servers: ServerWithChannelsAndMembers[]; dmChannels: DmChannel[]; folders?: ServerFolder[]; voiceStates?: Record<string, string[]>; readStates?: ReadState[] }
| { type: 'ready'; user: User; servers: ServerWithChannelsAndMembers[]; dmChannels: DmChannel[]; folders?: ServerFolder[]; voiceStates?: Record<string, string[]>; voiceUserStates?: Record<string, { isMuted: boolean; isDeafened: boolean }>; readStates?: ReadState[] }
| { type: 'message_created'; message: MessageWithUser }
| { type: 'message_updated'; message: MessageWithUser }
| { type: 'message_deleted'; messageId: string; channelId: string }
@@ -211,6 +212,7 @@ export type ServerEvent =
| { type: 'dm_call_accepted'; dmChannelId: string }
| { type: 'dm_call_rejected'; dmChannelId: string }
| { type: 'dm_call_ended'; dmChannelId: string }
| { type: 'voice_status_update'; userId: string; channelId: string; isMuted: boolean; isDeafened: boolean }
| { type: 'error'; message: string };
// ─── API Request/Response Types ─────────────────────────────────────────────