refactor: unify backend voice signaling with VoiceRoom abstraction

Replace dual voiceStates + activeCalls maps with a single VoiceRoom
system that tracks both server channels and DM calls uniformly.

Fixes four bugs:
- voice_status silently dropped for DM call participants
- DM calls not cleaned up on WebSocket disconnect
- DM call state missing from ready payload on reconnect
- No spatial tracking of DM call participants
This commit is contained in:
Jannis Braun
2026-02-23 22:15:41 +01:00
parent 628d417723
commit 653e59bfb2
4 changed files with 504 additions and 200 deletions
+34 -1
View File
@@ -4,7 +4,7 @@ import { useServerStore } from '../stores/serverStore';
import { useChatStore } from '../stores/chatStore';
import { useVoiceStore } from '../stores/voiceStore';
import { useSocialStore } from '../stores/socialStore';
import type { ServerEvent, ClientEvent } from '@opencord/shared';
import type { ServerEvent, ClientEvent, ActiveCallInfo } from '@opencord/shared';
let globalWs: WebSocket | null = null;
let reconnectAttempts = 0;
@@ -61,6 +61,39 @@ function handleEvent(event: ServerEvent): void {
wsSend({ type: 'voice_status', isMuted: curMuted, isDeafened: curDeafened, isCameraOn: curCamera, isScreenSharing: curScreen });
}
}
// Restore DM call state from server (handles reconnect and page refresh)
{
const { activeDmCall, setActiveDmCall, setIncomingCall, incomingCall } = useVoiceStore.getState();
const myId = event.user.id;
if (event.activeCalls && event.activeCalls.length > 0) {
for (const call of event.activeCalls) {
const isParticipant = call.participants.includes(myId);
if (call.state === 'active' && isParticipant) {
// Restore active DM call
setActiveDmCall({ dmChannelId: call.dmChannelId });
break;
} else if (call.state === 'ringing' && call.callerId !== myId) {
// Restore incoming call (we're the callee)
// Look up caller name from DM channel members
const dmCh = event.dmChannels?.find((d: any) => d.id === call.dmChannelId);
const callerUser = dmCh?.members?.find((m: any) => m.id === call.callerId);
setIncomingCall({
dmChannelId: call.dmChannelId,
callerId: call.callerId,
callerName: callerUser?.displayName || callerUser?.username || call.callerId,
});
}
}
} else {
// No active calls on server — clear stale local state
if (activeDmCall) {
setActiveDmCall(null);
}
if (incomingCall) {
setIncomingCall(null);
}
}
}
break;
case 'message_created':