merge: upstream Element Call v0.28.0 (cinny #201) #61

Merged
jared merged 197 commits from lotus-upstream-v0.28.0 into lotus 2026-10-24 01:14:32 -04:00
2 changed files with 75 additions and 5 deletions
Showing only changes of commit 1bfb018d90 - Show all commits
+73
View File
@@ -0,0 +1,73 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { type FC, type ReactNode, useState } from "react";
import { type MatrixClient } from "matrix-js-sdk";
import { type MatrixRTCSession } from "matrix-js-sdk/lib/matrixrtc";
import { GroupCallView } from "./room/GroupCallView";
import { type MuteStates } from "./state/MuteStates";
import { type UrlParams } from "./UrlParams";
interface Props {
/** The client to place the call with. */
client: MatrixClient;
/** The call to join. */
rtcSession: MatrixRTCSession;
/** The audio and video mute state to start from, and keep in step with. */
muteStates: MuteStates;
/**
* Whether the user is signed in as a guest, and so should be offered the
* chance to create an account when the call ends.
*/
isPasswordlessUser: boolean;
/** Whether to keep the user in this call rather than letting them navigate. */
confineToRoom: boolean;
/** Whether to wait for the host to ask us to join. */
preload: UrlParams["preload"];
/** Whether to enter the call directly, without showing the lobby first. */
skipLobby: UrlParams["skipLobby"];
}
/**
* A call, as a component.
*
* This owns being in a call, and nothing about how Element Call came to be
* showing one: no routing, no authentication, no resolving of room aliases.
* Those belong to whatever is hosting it — the standalone app's own shell, or
* an application embedding Element Call directly.
*
* TODO: `muteStates` is still passed in, because the standalone shell shares
* one with the lobby it shows while waiting to be let into a room. Ownership
* moves here once that lobby has its own.
*/
export const ElementCallView: FC<Props> = ({
client,
rtcSession,
muteStates,
isPasswordlessUser,
confineToRoom,
preload,
skipLobby,
}): ReactNode => {
// Whether the user is in the call is the call's own business, not its host's.
const [joined, setJoined] = useState(false);
return (
<GroupCallView
client={client}
rtcSession={rtcSession}
joined={joined}
setJoined={setJoined}
isPasswordlessUser={isPasswordlessUser}
confineToRoom={confineToRoom}
preload={preload}
skipLobby={skipLobby}
muteStates={muteStates}
/>
);
};
+2 -5
View File
@@ -25,7 +25,7 @@ import {
import { useClientLegacy } from "../ClientContext";
import { ErrorPage, FullScreenView, LoadingPage } from "../FullScreenView";
import { RoomAuthView } from "./RoomAuthView";
import { GroupCallView } from "./GroupCallView";
import { ElementCallView } from "../ElementCallView";
import { useRoomIdentifier, useUrlParams } from "../UrlParams";
import { useRegisterPasswordlessUser } from "../auth/useRegisterPasswordlessUser";
import { HomePage } from "../home/HomePage";
@@ -62,7 +62,6 @@ export const RoomPage: FC = (): ReactNode => {
const { avatarUrl, displayName: userDisplayName } = useProfile(client);
const groupCallState = useLoadGroupCall(client, roomIdOrAlias, viaServers);
const [joined, setJoined] = useState(false);
const devices = useMediaDevices();
const [muteStates, setMuteStates] = useState<MuteStates | null>(null);
@@ -125,11 +124,9 @@ export const RoomPage: FC = (): ReactNode => {
case "loaded":
return (
muteStates && (
<GroupCallView
<ElementCallView
client={client!}
rtcSession={groupCallState.rtcSession}
joined={joined}
setJoined={setJoined}
isPasswordlessUser={passwordlessUser}
confineToRoom={confineToRoom}
preload={preload}