Files
element-call/src/room/RoomPage.tsx
T

189 lines
5.8 KiB
TypeScript
Raw Normal View History

2022-01-05 15:06:51 -08:00
/*
Copyright 2021-2024 New Vector Ltd.
2022-01-05 15:06:51 -08:00
SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
2022-01-05 15:06:51 -08:00
*/
2023-09-17 17:48:03 -04:00
import { FC, useEffect, useState, useCallback, ReactNode } from "react";
2023-09-25 18:04:34 +01:00
import { logger } from "matrix-js-sdk/src/logger";
2024-04-23 15:15:13 +02:00
import { useTranslation } from "react-i18next";
import { CheckIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
2022-08-02 00:46:16 +02:00
2023-06-30 16:43:28 +01:00
import { useClientLegacy } from "../ClientContext";
2022-01-05 15:35:12 -08:00
import { ErrorView, LoadingView } from "../FullScreenView";
import { RoomAuthView } from "./RoomAuthView";
import { GroupCallLoader } from "./GroupCallLoader";
import { GroupCallView } from "./GroupCallView";
2023-09-18 17:49:10 +01:00
import { useRoomIdentifier, useUrlParams } from "../UrlParams";
import { useRegisterPasswordlessUser } from "../auth/useRegisterPasswordlessUser";
2023-07-29 20:42:16 +02:00
import { HomePage } from "../home/HomePage";
2023-09-17 17:48:03 -04:00
import { platform } from "../Platform";
import { AppSelectionModal } from "./AppSelectionModal";
import { widget } from "../widget";
2024-04-23 15:15:13 +02:00
import { GroupCallStatus } from "./useLoadGroupCall";
import { LobbyView } from "./LobbyView";
import { E2eeType } from "../e2ee/e2eeType";
import { useProfile } from "../profile/useProfile";
import { useMuteStates } from "./MuteStates";
import { useOptInAnalytics } from "../settings/settings";
2022-01-05 15:06:51 -08:00
2022-08-05 16:16:59 -04:00
export const RoomPage: FC = () => {
2023-10-25 13:49:18 +02:00
const {
confineToRoom,
appPrompt,
preload,
hideHeader,
displayName,
skipLobby,
} = useUrlParams();
2024-04-23 15:15:13 +02:00
const { t } = useTranslation();
2023-09-18 17:49:10 +01:00
const { roomAlias, roomId, viaServers } = useRoomIdentifier();
2022-07-27 16:14:05 -04:00
const roomIdOrAlias = roomId ?? roomAlias;
2023-07-29 20:31:18 +02:00
if (!roomIdOrAlias) {
2023-09-25 18:04:34 +01:00
logger.error("No room specified");
2023-07-29 20:31:18 +02:00
}
2022-07-27 16:14:05 -04:00
const { registerPasswordlessUser } = useRegisterPasswordlessUser();
const [isRegistering, setIsRegistering] = useState(false);
2022-01-05 15:06:51 -08:00
2023-06-30 16:43:28 +01:00
const { loading, authenticated, client, error, passwordlessUser } =
useClientLegacy();
2024-04-23 15:15:13 +02:00
const { avatarUrl, displayName: userDisplayName } = useProfile(client);
const muteStates = useMuteStates();
2023-06-30 16:43:28 +01:00
useEffect(() => {
// If we've finished loading, are not already authed and we've been given a display name as
// a URL param, automatically register a passwordless user
if (!loading && !authenticated && displayName && !widget) {
setIsRegistering(true);
registerPasswordlessUser(displayName).finally(() => {
setIsRegistering(false);
});
}
}, [
2023-06-30 16:43:28 +01:00
loading,
authenticated,
displayName,
setIsRegistering,
registerPasswordlessUser,
]);
const [optInAnalytics, setOptInAnalytics] = useOptInAnalytics();
2024-04-23 15:15:13 +02:00
useEffect(() => {
// During the beta, opt into analytics by default
if (optInAnalytics === null && setOptInAnalytics) setOptInAnalytics(true);
}, [optInAnalytics, setOptInAnalytics]);
const groupCallView = useCallback(
2024-04-23 15:15:13 +02:00
(groupCallState: GroupCallStatus): JSX.Element => {
switch (groupCallState.kind) {
case "loaded":
return (
<GroupCallView
client={client!}
rtcSession={groupCallState.rtcSession}
isPasswordlessUser={passwordlessUser}
confineToRoom={confineToRoom}
preload={preload}
skipLobby={skipLobby}
hideHeader={hideHeader}
muteStates={muteStates}
/>
);
case "waitForInvite":
case "canKnock": {
const knock =
groupCallState.kind === "canKnock" ? groupCallState.knock : null;
const label: string | JSX.Element =
groupCallState.kind === "canKnock" ? (
t("lobby.ask_to_join")
) : (
<>
{t("lobby.waiting_for_invite")}
<CheckIcon />
</>
);
return (
<LobbyView
client={client!}
matrixInfo={{
userId: client!.getUserId() ?? "",
displayName: userDisplayName ?? "",
avatarUrl: avatarUrl ?? "",
roomAlias: null,
roomId: groupCallState.roomSummary.room_id,
roomName: groupCallState.roomSummary.name ?? "",
roomAvatar: groupCallState.roomSummary.avatar_url ?? null,
e2eeSystem: {
kind: groupCallState.roomSummary[
"im.nheko.summary.encryption"
]
? E2eeType.PER_PARTICIPANT
: E2eeType.NONE,
},
}}
onEnter={(): void => knock?.()}
enterLabel={label}
waitingForInvite={groupCallState.kind === "waitForInvite"}
confineToRoom={confineToRoom}
hideHeader={hideHeader}
participantCount={null}
muteStates={muteStates}
onShareClick={null}
/>
);
}
default:
return <> </>;
}
},
[
client,
passwordlessUser,
confineToRoom,
preload,
skipLobby,
hideHeader,
muteStates,
t,
userDisplayName,
avatarUrl,
],
);
2023-09-17 17:48:03 -04:00
let content: ReactNode;
if (loading || isRegistering) {
2023-09-17 17:48:03 -04:00
content = <LoadingView />;
} else if (error) {
content = <ErrorView error={error} />;
} else if (!client) {
content = <RoomAuthView />;
} else if (!roomIdOrAlias) {
// TODO: This doesn't belong here, the app routes need to be reworked
content = <HomePage />;
} else {
content = (
<GroupCallLoader
client={client}
roomIdOrAlias={roomIdOrAlias}
viaServers={viaServers}
>
{groupCallView}
</GroupCallLoader>
);
2023-07-29 20:42:16 +02:00
}
2022-01-05 15:06:51 -08:00
return (
2023-09-17 17:48:03 -04:00
<>
{content}
2023-09-18 20:47:47 -04:00
{/* On Android and iOS, show a prompt to launch the mobile app. */}
2024-04-23 15:15:13 +02:00
{appPrompt &&
(platform === "android" || platform === "ios") &&
roomId && <AppSelectionModal roomId={roomId} />}
2023-09-17 17:48:03 -04:00
</>
2022-01-05 15:06:51 -08:00
);
2022-08-05 16:16:59 -04:00
};