Avoid closing the widget in returnToLobby mode

If returnToLobby is enabled then we obviously want to keep the widget open once the user leaves the call.
This commit is contained in:
Robin
2025-03-04 15:09:59 -05:00
parent b5f5edba09
commit 28c45c6107
4 changed files with 42 additions and 24 deletions

View File

@@ -110,8 +110,8 @@ describe("UrlParams", () => {
});
describe("returnToLobby", () => {
it("is true in SPA mode", () => {
expect(getUrlParams("?returnToLobby=false").returnToLobby).toBe(true);
it("is false in SPA mode", () => {
expect(getUrlParams("?returnToLobby=true").returnToLobby).toBe(false);
});
it("defaults to false in widget mode", () => {

View File

@@ -264,7 +264,7 @@ export const getUrlParams = (
"skipLobby",
isWidget && intent === UserIntent.StartNewCall,
),
returnToLobby: isWidget ? parser.getFlagParam("returnToLobby") : true,
returnToLobby: isWidget ? parser.getFlagParam("returnToLobby") : false,
theme: parser.getParam("theme"),
viaServers: !isWidget ? parser.getParam("viaServers") : null,
homeserver: !isWidget ? parser.getParam("homeserver") : null,

View File

@@ -6,7 +6,7 @@ Please see LICENSE in the repository root for full details.
*/
import { type MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
import { expect, test, vi } from "vitest";
import { expect, onTestFinished, test, vi } from "vitest";
import { AutoDiscovery } from "matrix-js-sdk/src/autodiscovery";
import EventEmitter from "events";
@@ -15,11 +15,17 @@ import { mockConfig } from "./utils/test";
import { ElementWidgetActions, widget } from "./widget";
import { ErrorCode } from "./utils/errors.ts";
const getUrlParams = vi.hoisted(() => vi.fn(() => ({})));
vi.mock("./UrlParams", () => ({ getUrlParams }));
const actualWidget = await vi.hoisted(async () => vi.importActual("./widget"));
vi.mock("./widget", () => ({
...actualWidget,
widget: {
api: { transport: { send: vi.fn(), reply: vi.fn(), stop: vi.fn() } },
api: {
setAlwaysOnScreen: (): void => {},
transport: { send: vi.fn(), reply: vi.fn(), stop: vi.fn() },
},
lazyActions: new EventEmitter(),
},
}));
@@ -109,34 +115,45 @@ test("It joins the correct Session", async () => {
);
});
test("leaveRTCSession closes the widget on a normal hangup", async () => {
async function testLeaveRTCSession(
cause: "user" | "error",
expectClose: boolean,
): Promise<void> {
vi.clearAllMocks();
const session = { leaveRoomSession: vi.fn() } as unknown as MatrixRTCSession;
await leaveRTCSession(session, "user");
await leaveRTCSession(session, cause);
expect(session.leaveRoomSession).toHaveBeenCalled();
expect(widget!.api.transport.send).toHaveBeenCalledWith(
ElementWidgetActions.HangupCall,
expect.anything(),
);
expect(widget!.api.transport.send).toHaveBeenCalledWith(
ElementWidgetActions.Close,
expect.anything(),
);
if (expectClose) {
expect(widget!.api.transport.send).toHaveBeenCalledWith(
ElementWidgetActions.Close,
expect.anything(),
);
expect(widget!.api.transport.stop).toHaveBeenCalled();
} else {
expect(widget!.api.transport.send).not.toHaveBeenCalledWith(
ElementWidgetActions.Close,
expect.anything(),
);
expect(widget!.api.transport.stop).not.toHaveBeenCalled();
}
}
test("leaveRTCSession closes the widget on a normal hangup", async () => {
await testLeaveRTCSession("user", true);
});
test("leaveRTCSession doesn't close the widget on a fatal error", async () => {
vi.clearAllMocks();
const session = { leaveRoomSession: vi.fn() } as unknown as MatrixRTCSession;
await leaveRTCSession(session, "error");
expect(session.leaveRoomSession).toHaveBeenCalled();
expect(widget!.api.transport.send).toHaveBeenCalledWith(
ElementWidgetActions.HangupCall,
expect.anything(),
);
expect(widget!.api.transport.send).not.toHaveBeenCalledWith(
ElementWidgetActions.Close,
expect.anything(),
);
await testLeaveRTCSession("error", false);
});
test("leaveRTCSession doesn't close the widget when returning to lobby", async () => {
getUrlParams.mockReturnValue({ returnToLobby: true });
onTestFinished(() => void getUrlParams.mockReset());
await testLeaveRTCSession("user", false);
});
test("It fails with configuration error if no live kit url config is set in fallback", async () => {

View File

@@ -19,6 +19,7 @@ import { PosthogAnalytics } from "./analytics/PosthogAnalytics";
import { Config } from "./config/Config";
import { ElementWidgetActions, widget, type WidgetHelpers } from "./widget";
import { MatrixRTCFocusMissingError } from "./utils/errors.ts";
import { getUrlParams } from "./UrlParams.ts";
const FOCI_WK_KEY = "org.matrix.msc4143.rtc_foci";
@@ -149,7 +150,7 @@ const widgetPostHangupProcedure = async (
}
// On a normal user hangup we can shut down and close the widget. But if an
// error occurs we should keep the widget open until the user reads it.
if (cause === "user") {
if (cause === "user" && !getUrlParams().returnToLobby) {
try {
await widget.api.transport.send(ElementWidgetActions.Close, {});
} catch (e) {