mirror of
https://github.com/vector-im/element-call.git
synced 2026-07-18 18:59:23 +00:00
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:
@@ -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}
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user