From b14223137eab23f495e559bc7d8e93f4fee4613a Mon Sep 17 00:00:00 2001 From: Ayush Nigade Date: Wed, 2 Sep 2026 10:10:57 -0700 Subject: [PATCH] fix(love): allow rejoining a room the client is still recorded in ParticipantInfo is written by the person's own client on join and leave. When that client goes away mid-call (reload, crash, network loss) the record keeps pointing at the room while no LiveKit session exists. The room popup then hides Enter room because the person counts as joined, and the meeting controls need a live session, so the person can neither hear anything nor re-establish the call. Show Enter room whenever no LiveKit session is connected, and route it through a new reconnectMeeting() that connects directly instead of knocking again when the record already places the person in the room. Leave keeps working as before. Signed-off-by: Ayush Nigade --- .../src/components/RoomPopup.svelte | 13 ++++++++++--- plugins/love-resources/src/meetings.ts | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/plugins/love-resources/src/components/RoomPopup.svelte b/plugins/love-resources/src/components/RoomPopup.svelte index df32a6e3d7b..ff1d3c7ae8d 100644 --- a/plugins/love-resources/src/components/RoomPopup.svelte +++ b/plugins/love-resources/src/components/RoomPopup.svelte @@ -32,7 +32,7 @@ import ShareScreenButton from './meeting/controls/ShareScreenButton.svelte' import LeaveRoomButton from './meeting/controls/LeaveRoomButton.svelte' import MeetingHeader from './meeting/MeetingHeader.svelte' - import { joinMeeting } from '../meetings' + import { joinMeeting, reconnectMeeting } from '../meetings' export let room: Room @@ -53,8 +53,14 @@ const dispatch = createEventDispatcher() + // A stale record (still "in" the room, but no LiveKit session - e.g. after + // a reload mid-call) must re-establish the media, not knock again. async function connect (): Promise { - await joinMeeting(room) + if (joined) { + await reconnectMeeting(room) + } else { + await joinMeeting(room) + } dispatch('close') } @@ -121,7 +127,8 @@ {/if} {#if joined} dispatch('close')} /> - {:else} + {/if} + {#if !joined || !$lkSessionConnected} { await connectToMeeting(room) } +/** + * Re-establish the call for a room this client is already recorded in. + * + * After a reload mid-call the ParticipantInfo still points at the room while + * no LiveKit session exists, so `joinMeeting` (which would knock again) is + * the wrong entry point: the person is already in, only the media is gone. + */ +export async function reconnectMeeting (room: Room): Promise { + if (get(myInfo)?.room !== room._id) { + await joinMeeting(room) + return + } + await connectToMeeting(room) +} + export async function joinOrCreateMeetingByInvite (roomId: Ref): Promise { if (currentMeetingRoom === roomId) return