Fix not disconnecting from livekit session.

This happens if there is an error while
(due to opening the app in another tab)
the call is running. The lk session ends if we reroute
to `/` (or quit the widget IFrame)
but we never explicitly disconnect from livekit.

Signed-off-by: Timo K <toger5@hotmail.de>
This commit is contained in:
Timo K
2023-11-24 13:32:30 +01:00
parent 115dfea521
commit 256da431fd
3 changed files with 38 additions and 31 deletions

View File

@@ -44,9 +44,10 @@ import { useRoomAvatar } from "./useRoomAvatar";
import { useRoomName } from "./useRoomName"; import { useRoomName } from "./useRoomName";
import { useJoinRule } from "./useJoinRule"; import { useJoinRule } from "./useJoinRule";
import { InviteModal } from "./InviteModal"; import { InviteModal } from "./InviteModal";
import { E2EEConfig } from "../livekit/useLiveKit"; import { E2EEConfig, useLiveKit } from "../livekit/useLiveKit";
import { useUrlParams } from "../UrlParams"; import { useUrlParams } from "../UrlParams";
import { E2eeType } from "../e2ee/e2eeType"; import { E2eeType } from "../e2ee/e2eeType";
import { useOpenIDSFU } from "../livekit/openIDSFU";
declare global { declare global {
interface Window { interface Window {
@@ -126,6 +127,23 @@ export const GroupCallView: FC<Props> = ({
const latestMuteStates = useRef<MuteStates>(); const latestMuteStates = useRef<MuteStates>();
latestMuteStates.current = muteStates; latestMuteStates.current = muteStates;
const e2eeConfig = useMemo((): E2EEConfig => {
if (perParticipantE2EE) {
return { mode: E2eeType.PER_PARTICIPANT };
} else if (e2eeSharedKey) {
return { mode: E2eeType.SHARED_KEY, sharedKey: e2eeSharedKey };
} else {
return { mode: E2eeType.NONE };
}
}, [perParticipantE2EE, e2eeSharedKey]);
const sfuConfig = useOpenIDSFU(client, rtcSession);
const { livekitRoom, connState } = useLiveKit(
rtcSession,
muteStates,
sfuConfig,
e2eeConfig,
);
useEffect(() => { useEffect(() => {
// this effect is only if we don't want to show the lobby (skipLobby = true) // this effect is only if we don't want to show the lobby (skipLobby = true)
if (!skipLobby) return; if (!skipLobby) return;
@@ -220,7 +238,7 @@ export const GroupCallView: FC<Props> = ({
sendInstantly, sendInstantly,
); );
await leaveRTCSession(rtcSession); await leaveRTCSession(rtcSession, livekitRoom);
if ( if (
!isPasswordlessUser && !isPasswordlessUser &&
@@ -230,7 +248,7 @@ export const GroupCallView: FC<Props> = ({
history.push("/"); history.push("/");
} }
}, },
[rtcSession, isPasswordlessUser, confineToRoom, history], [rtcSession, livekitRoom, isPasswordlessUser, confineToRoom, history],
); );
useEffect(() => { useEffect(() => {
@@ -239,24 +257,14 @@ export const GroupCallView: FC<Props> = ({
ev: CustomEvent<IWidgetApiRequest>, ev: CustomEvent<IWidgetApiRequest>,
): Promise<void> => { ): Promise<void> => {
widget!.api.transport.reply(ev.detail, {}); widget!.api.transport.reply(ev.detail, {});
await leaveRTCSession(rtcSession); await leaveRTCSession(rtcSession, livekitRoom);
}; };
widget.lazyActions.once(ElementWidgetActions.HangupCall, onHangup); widget.lazyActions.once(ElementWidgetActions.HangupCall, onHangup);
return () => { return () => {
widget!.lazyActions.off(ElementWidgetActions.HangupCall, onHangup); widget!.lazyActions.off(ElementWidgetActions.HangupCall, onHangup);
}; };
} }
}, [isJoined, rtcSession]); }, [isJoined, livekitRoom, rtcSession]);
const e2eeConfig = useMemo((): E2EEConfig => {
if (perParticipantE2EE) {
return { mode: E2eeType.PER_PARTICIPANT };
} else if (e2eeSharedKey) {
return { mode: E2eeType.SHARED_KEY, sharedKey: e2eeSharedKey };
} else {
return { mode: E2eeType.NONE };
}
}, [perParticipantE2EE, e2eeSharedKey]);
const onReconnect = useCallback(() => { const onReconnect = useCallback(() => {
setLeft(false); setLeft(false);
@@ -318,11 +326,13 @@ export const GroupCallView: FC<Props> = ({
/> />
); );
if (isJoined) { if (isJoined && livekitRoom) {
return ( return (
<> <>
{shareModal} {shareModal}
<ActiveCall <ActiveCall
livekitRoom={livekitRoom}
connState={connState}
client={client} client={client}
matrixInfo={matrixInfo} matrixInfo={matrixInfo}
rtcSession={rtcSession} rtcSession={rtcSession}

View File

@@ -72,7 +72,7 @@ import { OTelGroupCallMembership } from "../otel/OTelGroupCallMembership";
import { SettingsModal } from "../settings/SettingsModal"; import { SettingsModal } from "../settings/SettingsModal";
import { useRageshakeRequestModal } from "../settings/submit-rageshake"; import { useRageshakeRequestModal } from "../settings/submit-rageshake";
import { RageshakeRequestModal } from "./RageshakeRequestModal"; import { RageshakeRequestModal } from "./RageshakeRequestModal";
import { E2EEConfig, useLiveKit } from "../livekit/useLiveKit"; import { E2EEConfig } from "../livekit/useLiveKit";
import { useFullscreen } from "./useFullscreen"; import { useFullscreen } from "./useFullscreen";
import { useLayoutStates } from "../video-grid/Layout"; import { useLayoutStates } from "../video-grid/Layout";
import { useWakeLock } from "../useWakeLock"; import { useWakeLock } from "../useWakeLock";
@@ -85,7 +85,6 @@ import {
ECAddonConnectionState, ECAddonConnectionState,
ECConnectionState, ECConnectionState,
} from "../livekit/useECConnectionState"; } from "../livekit/useECConnectionState";
import { useOpenIDSFU } from "../livekit/openIDSFU";
const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {}); const canScreenshare = "getDisplayMedia" in (navigator.mediaDevices ?? {});
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
@@ -93,27 +92,22 @@ const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
// How long we wait after a focus switch before showing the real participant list again // How long we wait after a focus switch before showing the real participant list again
const POST_FOCUS_PARTICIPANT_UPDATE_DELAY_MS = 3000; const POST_FOCUS_PARTICIPANT_UPDATE_DELAY_MS = 3000;
export interface ActiveCallProps export interface ActiveCallProps extends InCallViewProps {
extends Omit<InCallViewProps, "livekitRoom" | "connState"> {
e2eeConfig: E2EEConfig; e2eeConfig: E2EEConfig;
} }
export const ActiveCall: FC<ActiveCallProps> = (props) => { export const ActiveCall: FC<ActiveCallProps> = (props) => {
const sfuConfig = useOpenIDSFU(props.client, props.rtcSession); if (!props.livekitRoom) {
const { livekitRoom, connState } = useLiveKit(
props.rtcSession,
props.muteStates,
sfuConfig,
props.e2eeConfig,
);
if (!livekitRoom) {
return null; return null;
} }
return ( return (
<RoomContext.Provider value={livekitRoom}> <RoomContext.Provider value={props.livekitRoom}>
<InCallView {...props} livekitRoom={livekitRoom} connState={connState} /> <InCallView
{...props}
livekitRoom={props.livekitRoom}
connState={props.connState}
/>
</RoomContext.Provider> </RoomContext.Provider>
); );
}; };

View File

@@ -15,6 +15,7 @@ limitations under the License.
*/ */
import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession"; import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
import { Room } from "livekit-client";
import { PosthogAnalytics } from "./analytics/PosthogAnalytics"; import { PosthogAnalytics } from "./analytics/PosthogAnalytics";
import { LivekitFocus } from "./livekit/LivekitFocus"; import { LivekitFocus } from "./livekit/LivekitFocus";
@@ -68,7 +69,9 @@ const widgetPostHangupProcedure = async (
export async function leaveRTCSession( export async function leaveRTCSession(
rtcSession: MatrixRTCSession, rtcSession: MatrixRTCSession,
livekitRoom: Room | undefined,
): Promise<void> { ): Promise<void> {
await livekitRoom?.disconnect();
await rtcSession.leaveRoomSession(); await rtcSession.leaveRoomSession();
if (widget) { if (widget) {
await widgetPostHangupProcedure(widget); await widgetPostHangupProcedure(widget);