Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow join unmuted in widget mode #2848

Open
wants to merge 13 commits into
base: livekit
Choose a base branch
from
2 changes: 1 addition & 1 deletion docs/url-params.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ There are two formats for Element Call urls.
| `returnToLobby` | `true` or `false` | No, defaults to `false` | Not applicable | Displays the lobby in widget mode after leaving a call; shows a blank page if set to `false`. Useful for video rooms. |
| `roomId` | [Matrix Room ID](https://spec.matrix.org/v1.12/appendices/#room-ids) | Yes | No | Anything about what room we're pointed to should be from useRoomIdentifier which parses the path and resolves alias with respect to the default server name, however roomId is an exception as we need the room ID in embedded widget mode, and not the room alias (or even the via params because we are not trying to join it). This is also not validated, where it is in `useRoomIdentifier()`. |
| `showControls` | `true` or `false` | No, defaults to `true` | No, defaults to `true` | Displays controls like mute, screen-share, invite, and hangup buttons during a call. |
| `skipLobby` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Skips the lobby to join a call directly, can be combined with preload in widget. When `true` the audio and video inputs will be muted by default. (This means there currently is no way to start without muted video if one wants to skip the lobby. Also not in widget mode.) |
| `skipLobby` | `true` or `false` | No, defaults to `false` | No, defaults to `false` | Skips the lobby to join a call directly, can be combined with `preload` in widget. When `true` the audio and video inputs will be muted by default unless running as a widget. |
| `theme` | One of: `light`, `dark`, `light-high-contrast`, `dark-high-contrast` | No, defaults to `dark` | No, defaults to `dark` | UI theme to use. |
| `userId` | [Matrix User Identifier](https://spec.matrix.org/v1.12/appendices/#user-identifiers) | Yes | Not applicable | The Matrix user ID. |
| `viaServers` | Comma separated list of [Matrix Server Names](https://spec.matrix.org/v1.12/appendices/#server-name) | Not applicable | No | Homeserver for joining a room, non-empty value required for rooms not on the user’s default homeserver. |
Expand Down
29 changes: 28 additions & 1 deletion src/room/MuteStates.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@
expect(screen.getByTestId("video-enabled").textContent).toBe("false");
});

it("skipLobby mutes inputs", () => {
it("skipLobby mutes inputs on SPA", () => {
mockConfig();

render(
Expand All @@ -169,4 +169,31 @@
expect(screen.getByTestId("audio-enabled").textContent).toBe("false");
expect(screen.getByTestId("video-enabled").textContent).toBe("false");
});

it("skipLobby does not mute inputs in widget mode", () => {
mockConfig();
vi.mock("../widget", () => {
return {
widget: {
api: {
transport: {
send: async (): Promise<void> => new Promise((r) => r()),
},
},
lazyActions: { on: vi.fn(), off: vi.fn() },
},
ElementWidgetActions: {},
};
});

render(
<MemoryRouter initialEntries={["/room/?skipLobby=true"]}>
<MediaDevicesContext.Provider value={mockMediaDevices()}>
<TestComponent />
</MediaDevicesContext.Provider>
</MemoryRouter>,
);
expect(screen.getByTestId("audio-enabled").textContent).toBe("true");

Check failure on line 196 in src/room/MuteStates.test.tsx

View workflow job for this annotation

GitHub Actions / Run vitest tests

src/room/MuteStates.test.tsx > useMuteStates > skipLobby does not mute inputs in widget mode

AssertionError: expected 'false' to be 'true' // Object.is equality Expected: "true" Received: "false" ❯ src/room/MuteStates.test.tsx:196:61
expect(screen.getByTestId("video-enabled").textContent).toBe("true");
});
});
9 changes: 5 additions & 4 deletions src/room/MuteStates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,14 @@ export function useMuteStates(): MuteStates {
const devices = useMediaDevices();

const { skipLobby } = useUrlParams();

// In SPA without lobby we need to protect from unmuted joins (Privacy).
const allowStartUnmuted = !skipLobby || !widget;
toger5 marked this conversation as resolved.
Show resolved Hide resolved
const audio = useMuteState(devices.audioInput, () => {
return Config.get().media_devices.enable_audio && !skipLobby;
return Config.get().media_devices.enable_audio && allowStartUnmuted;
});
const video = useMuteState(
devices.videoInput,
() => Config.get().media_devices.enable_video && !skipLobby,
() => Config.get().media_devices.enable_video && allowStartUnmuted,
);

useEffect(() => {
Expand All @@ -90,7 +91,7 @@ export function useMuteStates(): MuteStates {
video_enabled: video.enabled,
})
.catch((e) =>
logger.warn("Could not send DeviceMute action to widget", e),
logger.warn("Could not send DeviceMute action to widget host", e),
);
}, [audio, video]);

Expand Down
Loading