Merge pull request #3051 from element-hq/robin/return-to-lobby

Respect the returnToLobby flag
This commit is contained in:
Robin
2025-03-05 12:17:53 -05:00
committed by GitHub
5 changed files with 45 additions and 27 deletions

View File

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

View File

@@ -264,7 +264,9 @@ export const getUrlParams = (
"skipLobby", "skipLobby",
isWidget && intent === UserIntent.StartNewCall, isWidget && intent === UserIntent.StartNewCall,
), ),
returnToLobby: isWidget ? parser.getFlagParam("returnToLobby") : true, // In SPA mode the user should always exit to the home screen when hanging
// up, rather than being sent back to the lobby
returnToLobby: isWidget ? parser.getFlagParam("returnToLobby") : false,
theme: parser.getParam("theme"), theme: parser.getParam("theme"),
viaServers: !isWidget ? parser.getParam("viaServers") : null, viaServers: !isWidget ? parser.getParam("viaServers") : null,
homeserver: !isWidget ? parser.getParam("homeserver") : null, homeserver: !isWidget ? parser.getParam("homeserver") : null,

View File

@@ -495,9 +495,7 @@ export const GroupCallView: FC<Props> = ({
} }
} else if (left && widget !== null) { } else if (left && widget !== null) {
// Left in widget mode: // Left in widget mode:
if (!returnToLobby) { body = returnToLobby ? lobbyView : null;
body = null;
}
} else if (preload || skipLobby) { } else if (preload || skipLobby) {
body = null; body = null;
} else { } else {

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 { 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 { AutoDiscovery } from "matrix-js-sdk/src/autodiscovery";
import EventEmitter from "events"; import EventEmitter from "events";
@@ -15,11 +15,17 @@ import { mockConfig } from "./utils/test";
import { ElementWidgetActions, widget } from "./widget"; import { ElementWidgetActions, widget } from "./widget";
import { ErrorCode } from "./utils/errors.ts"; 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")); const actualWidget = await vi.hoisted(async () => vi.importActual("./widget"));
vi.mock("./widget", () => ({ vi.mock("./widget", () => ({
...actualWidget, ...actualWidget,
widget: { 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(), 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(); vi.clearAllMocks();
const session = { leaveRoomSession: vi.fn() } as unknown as MatrixRTCSession; const session = { leaveRoomSession: vi.fn() } as unknown as MatrixRTCSession;
await leaveRTCSession(session, "user"); await leaveRTCSession(session, cause);
expect(session.leaveRoomSession).toHaveBeenCalled(); expect(session.leaveRoomSession).toHaveBeenCalled();
expect(widget!.api.transport.send).toHaveBeenCalledWith( expect(widget!.api.transport.send).toHaveBeenCalledWith(
ElementWidgetActions.HangupCall, ElementWidgetActions.HangupCall,
expect.anything(), expect.anything(),
); );
expect(widget!.api.transport.send).toHaveBeenCalledWith( if (expectClose) {
ElementWidgetActions.Close, expect(widget!.api.transport.send).toHaveBeenCalledWith(
expect.anything(), 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 () => { test("leaveRTCSession doesn't close the widget on a fatal error", async () => {
vi.clearAllMocks(); await testLeaveRTCSession("error", false);
const session = { leaveRoomSession: vi.fn() } as unknown as MatrixRTCSession; });
await leaveRTCSession(session, "error");
expect(session.leaveRoomSession).toHaveBeenCalled(); test("leaveRTCSession doesn't close the widget when returning to lobby", async () => {
expect(widget!.api.transport.send).toHaveBeenCalledWith( getUrlParams.mockReturnValue({ returnToLobby: true });
ElementWidgetActions.HangupCall, onTestFinished(() => void getUrlParams.mockReset());
expect.anything(), await testLeaveRTCSession("user", false);
);
expect(widget!.api.transport.send).not.toHaveBeenCalledWith(
ElementWidgetActions.Close,
expect.anything(),
);
}); });
test("It fails with configuration error if no live kit url config is set in fallback", async () => { 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 { Config } from "./config/Config";
import { ElementWidgetActions, widget, type WidgetHelpers } from "./widget"; import { ElementWidgetActions, widget, type WidgetHelpers } from "./widget";
import { MatrixRTCFocusMissingError } from "./utils/errors.ts"; import { MatrixRTCFocusMissingError } from "./utils/errors.ts";
import { getUrlParams } from "./UrlParams.ts";
const FOCI_WK_KEY = "org.matrix.msc4143.rtc_foci"; const FOCI_WK_KEY = "org.matrix.msc4143.rtc_foci";
@@ -156,7 +157,7 @@ const widgetPostHangupProcedure = async (
} }
// On a normal user hangup we can shut down and close the widget. But if an // 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. // error occurs we should keep the widget open until the user reads it.
if (cause === "user") { if (cause === "user" && !getUrlParams().returnToLobby) {
try { try {
await widget.api.transport.send(ElementWidgetActions.Close, {}); await widget.api.transport.send(ElementWidgetActions.Close, {});
} catch (e) { } catch (e) {