/* Copyright 2022-2024 New Vector Ltd. SPDX-License-Identifier: AGPL-3.0-only Please see LICENSE in the repository root for full details. */ import { useState, useCallback, type FormEvent, type FormEventHandler, type FC, } from "react"; import { type MatrixClient } from "matrix-js-sdk/src/client"; import { useTranslation } from "react-i18next"; import { Heading, Text } from "@vector-im/compound-web"; import { logger } from "matrix-js-sdk/src/logger"; import { Button } from "@vector-im/compound-web"; import { useNavigate } from "react-router-dom"; import { createRoom, getRelativeRoomUrl, roomAliasLocalpartFromRoomName, sanitiseRoomNameInput, } from "../utils/matrix"; import { useGroupCallRooms } from "./useGroupCallRooms"; import { Header, HeaderLogo, LeftNav, RightNav } from "../Header"; import commonStyles from "./common.module.css"; import styles from "./RegisteredView.module.css"; import { FieldRow, InputField, ErrorMessage } from "../input/Input"; import { CallList } from "./CallList"; import { UserMenuContainer } from "../UserMenuContainer"; import { JoinExistingCallModal } from "./JoinExistingCallModal"; import { Form } from "../form/Form"; import { AnalyticsNotice } from "../analytics/AnalyticsNotice"; import { E2eeType } from "../e2ee/e2eeType"; import { useOptInAnalytics } from "../settings/settings"; interface Props { client: MatrixClient; } export const RegisteredView: FC = ({ client }) => { const [loading, setLoading] = useState(false); const [error, setError] = useState(); const [optInAnalytics] = useOptInAnalytics(); const navigate = useNavigate(); const { t } = useTranslation(); const [joinExistingCallModalOpen, setJoinExistingCallModalOpen] = useState(false); const onDismissJoinExistingCallModal = useCallback( () => setJoinExistingCallModalOpen(false), [setJoinExistingCallModalOpen], ); const onSubmit: FormEventHandler = useCallback( (e: FormEvent) => { e.preventDefault(); const data = new FormData(e.target as HTMLFormElement); const roomNameData = data.get("callName"); const roomName = typeof roomNameData === "string" ? sanitiseRoomNameInput(roomNameData) : ""; async function submit(): Promise { setError(undefined); setLoading(true); const createRoomResult = await createRoom( client, roomName, E2eeType.SHARED_KEY, ); if (!createRoomResult.password) throw new Error("Failed to create room with shared secret"); await navigate( getRelativeRoomUrl( createRoomResult.roomId, { kind: E2eeType.SHARED_KEY, secret: createRoomResult.password }, roomName, ), ); } submit().catch((error) => { if (error.errcode === "M_ROOM_IN_USE") { setExistingAlias(roomAliasLocalpartFromRoomName(roomName)); setLoading(false); setError(undefined); setJoinExistingCallModalOpen(true); } else { logger.error(error); setLoading(false); setError(error); } }); }, [client, navigate, setJoinExistingCallModalOpen], ); const recentRooms = useGroupCallRooms(client); const [existingAlias, setExistingAlias] = useState(); const onJoinExistingRoom = useCallback(() => { navigate(`/${existingAlias}`)?.catch((error) => { logger.error("Failed to navigate to existing alias", error); }); }, [navigate, existingAlias]); return ( <>
{t("start_new_call")}
{optInAnalytics === null && ( )} {error && ( )}
{recentRooms.length > 0 && ( )}
); };