From 2f211e05887422b15b4a30baa814999db204799a Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Tue, 31 Mar 2026 23:41:50 +0200 Subject: [PATCH] feat(federation): useLiveKit connects to remote LiveKit for federated calls (FED-009) --- packages/web/src/hooks/useLiveKit.ts | 33 +++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/web/src/hooks/useLiveKit.ts b/packages/web/src/hooks/useLiveKit.ts index 4b24b19f..1dedede4 100644 --- a/packages/web/src/hooks/useLiveKit.ts +++ b/packages/web/src/hooks/useLiveKit.ts @@ -184,7 +184,21 @@ export function useLiveKit() { const allParticipants: ParticipantInfo[] = []; const processParticipant = (p: Participant, isLocal: boolean) => { if (!p.identity) return; - const { userId, username } = parseIdentity(p.identity); + const { userId: rawId, username } = parseIdentity(p.identity); + + // Resolve identity: for federated calls rawId may be homeUserId from another instance. + // Check DM members for a user whose homeUserId matches. + let userId = rawId; + const activeDmCall = useVoiceStore.getState().activeDmCall; + if (activeDmCall) { + const dmChannels = useSpaceStore.getState().dmChannels; + const dmChannel = dmChannels.find(d => d.id === activeDmCall.dmChannelId); + if (dmChannel) { + const match = dmChannel.members.find(m => m.homeUserId === rawId || m.id === rawId); + if (match) userId = match.id; + } + } + const memberMatch = useSpaceStore.getState().members.find(m => m.userId === userId); let cachedUser: User | null; let homeUserId: string | null; @@ -418,8 +432,21 @@ export function useLiveKit() { } try { - const client = getApiForOrigin(getChannelOrigin(channelId)); - const { token, url } = isDm ? await client.livekit.dmToken(channelId) : await client.livekit.token(channelId); + let token: string; + let url: string; + + // For federated calls, use the stored token from S2S relay + const { federatedCallToken, federatedCallUrl, clearFederatedCallData } = useVoiceStore.getState(); + if (isDm && federatedCallToken && federatedCallUrl) { + token = federatedCallToken; + url = federatedCallUrl; + clearFederatedCallData(); + } else { + const client = getApiForOrigin(getChannelOrigin(channelId)); + const resp = isDm ? await client.livekit.dmToken(channelId) : await client.livekit.token(channelId); + token = resp.token; + url = resp.url; + } if (gen !== _connectGeneration) return; const newRoom = new Room({ adaptiveStream: true, dynacast: true, publishDefaults: { videoCodec: 'h264', simulcast: true } }); roomRef.current = newRoom;