fix: acceptor sets activeDmCall in click handler, not server response

Bug A: handleAccept relied on dm_call_accepted server response to set
activeDmCall. But connectFn's async AudioContext resume yields to the
event loop, dm_call_accepted arrives during the yield, finds
isLiveKitConnected=false (connectFn just reset it), and skips
setActiveDmCall. The acceptor connects to LiveKit but the UI never
shows the call. Fix: set activeDmCall and clear incomingCall
directly in the click handler.

Bug B: ready handler no longer sets activeDmCall for active calls.
On refresh/restart the client has no LiveKit connection — showing
"Connecting..." with no connection is broken. The call exists on
the server but this client session is disconnected.
This commit is contained in:
Jannis Braun
2026-04-08 14:23:41 +02:00
parent aae0b1a74e
commit c037803c5a
2 changed files with 14 additions and 16 deletions
@@ -42,12 +42,19 @@ export function IncomingCallModal() {
const handleAccept = () => {
if (timerRef.current) clearTimeout(timerRef.current);
const dmChannelId = incomingCall.dmChannelId;
const { callOrigin, federatedCallId } = useVoiceStore.getState();
const { callOrigin, federatedCallId, setActiveDmCall, connectFn } = useVoiceStore.getState();
const origin = callOrigin || (dmChannelId ? getChannelOrigin(dmChannelId) : undefined);
const callDmId = dmChannelId || federatedCallId!;
// Immediately transition to active call state — don't wait for server response.
// The dm_call_accepted event races with connectFn's async AudioContext resume,
// causing isLiveKitConnected to be false when it arrives → activeDmCall never set.
setIncomingCall(null);
setActiveDmCall({ dmChannelId: callDmId });
wsSend({ type: 'dm_call_accept', dmChannelId, federatedCallId }, origin);
// Connect directly within gesture context (required for iOS audio permission)
const connectFn = useVoiceStore.getState().connectFn;
if (connectFn) connectFn(dmChannelId || federatedCallId!, true);
if (connectFn) connectFn(callDmId, true);
};
const handleDecline = () => {