From 9766cb2ca2fb338a207aa1968663161923d26c20 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Tue, 10 Sep 2024 13:33:12 +0200 Subject: [PATCH 01/21] Add button to remove call from recents Fixes: #2243 Signed-off-by: Johannes Marbach --- src/home/CallList.tsx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/home/CallList.tsx b/src/home/CallList.tsx index aa6db6f3..cda6f3a7 100644 --- a/src/home/CallList.tsx +++ b/src/home/CallList.tsx @@ -9,7 +9,10 @@ import { Link } from "react-router-dom"; import { MatrixClient } from "matrix-js-sdk/src/client"; import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { Room } from "matrix-js-sdk/src/models/room"; -import { FC } from "react"; +import { FC, useCallback, MouseEvent } from "react"; +import { t } from "i18next"; +import { IconButton } from "@vector-im/compound-web"; +import { DeleteIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; import { Avatar, Size } from "../Avatar"; import styles from "./CallList.module.css"; @@ -55,8 +58,16 @@ interface CallTileProps { client: MatrixClient; } -const CallTile: FC = ({ name, avatarUrl, room }) => { +const CallTile: FC = ({ name, avatarUrl, room, client }) => { const roomEncryptionSystem = useRoomEncryptionSystem(room.roomId); + const onRemove = useCallback( + (e: MouseEvent) => { + e.stopPropagation(); + e.preventDefault(); + void client.leave(room.roomId); + }, + [room, client], + ); return (
= ({ name, avatarUrl, room }) => { {name}
-
+ + +
); From 09af614fb8cff95e801284666d8ab40fc66d0d7a Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Tue, 10 Sep 2024 16:21:56 +0200 Subject: [PATCH 02/21] Switch to close icon --- src/home/CallList.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/home/CallList.tsx b/src/home/CallList.tsx index cda6f3a7..a136c086 100644 --- a/src/home/CallList.tsx +++ b/src/home/CallList.tsx @@ -12,7 +12,7 @@ import { Room } from "matrix-js-sdk/src/models/room"; import { FC, useCallback, MouseEvent } from "react"; import { t } from "i18next"; import { IconButton } from "@vector-im/compound-web"; -import { DeleteIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; +import { CloseIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; import { Avatar, Size } from "../Avatar"; import styles from "./CallList.module.css"; @@ -81,7 +81,7 @@ const CallTile: FC = ({ name, avatarUrl, room, client }) => { - + From e15296427c9f22262a872e19b42e942dc210a299 Mon Sep 17 00:00:00 2001 From: Robin Date: Tue, 10 Sep 2024 18:18:55 -0400 Subject: [PATCH 03/21] Update the copyright header template This updates the text suggested by our copyright header lint rule. --- .eslintrc.cjs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 3ef03c68..5e979883 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,17 +1,8 @@ const COPYRIGHT_HEADER = `/* -Copyright %%CURRENT_YEAR%% New Vector Ltd +Copyright %%CURRENT_YEAR%% New Vector Ltd. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +SPDX-License-Identifier: AGPL-3.0-only +Please see LICENSE in the repository root for full details. */ `; From 1b5b9342fe80005bb64dc01af6defd769da0892f Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 11 Sep 2024 01:27:02 -0400 Subject: [PATCH 04/21] Warn about duplicate rooms --- src/room/GroupCallView.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/room/GroupCallView.tsx b/src/room/GroupCallView.tsx index f1986d4b..af97ce07 100644 --- a/src/room/GroupCallView.tsx +++ b/src/room/GroupCallView.tsx @@ -85,6 +85,14 @@ export const GroupCallView: FC = ({ }; }, [rtcSession]); + useEffect(() => { + // Sanity check the room object + if (client.getRoom(rtcSession.room.roomId) !== rtcSession.room) + logger.warn( + `We've ended up with multiple rooms for the same ID (${rtcSession.room.roomId}). This indicates a bug in the group call loading code, and may lead to incomplete room state.`, + ); + }, [client, rtcSession.room]); + const { displayName, avatarUrl } = useProfile(client); const roomName = useRoomName(rtcSession.room); const roomAvatar = useRoomAvatar(rtcSession.room); From ca135d471e97d5af96b0dd9d46aec2c178d1975c Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 11 Sep 2024 01:27:24 -0400 Subject: [PATCH 05/21] React more actively to changes in room membership --- src/state/CallViewModel.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/state/CallViewModel.ts b/src/state/CallViewModel.ts index 219df600..6cd8495b 100644 --- a/src/state/CallViewModel.ts +++ b/src/state/CallViewModel.ts @@ -16,7 +16,11 @@ import { ParticipantEvent, RemoteParticipant, } from "livekit-client"; -import { Room as MatrixRoom, RoomMember } from "matrix-js-sdk/src/matrix"; +import { + Room as MatrixRoom, + RoomMember, + RoomStateEvent, +} from "matrix-js-sdk/src/matrix"; import { EMPTY, Observable, @@ -321,6 +325,8 @@ export class CallViewModel extends ViewModel { this.remoteParticipants, observeParticipantMedia(this.livekitRoom.localParticipant), duplicateTiles.value, + // Also react to changes in the list of members + fromEvent(this.matrixRoom, RoomStateEvent.Update).pipe(startWith(null)), ]).pipe( scan( ( From 7e5b70d439a84725936cd2219e93621f39dd2b1d Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 11 Sep 2024 14:02:59 +0100 Subject: [PATCH 06/21] Rageshake logging improvements (#2622) --- src/main.tsx | 10 ++++++---- src/settings/rageshake.ts | 28 ++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/main.tsx b/src/main.tsx index b3e10985..f847e21a 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -18,7 +18,7 @@ import "./index.css"; import { logger } from "matrix-js-sdk/src/logger"; import { setLogExtension as setLKLogExtension, - setLogLevel, + setLogLevel as setLKLogLevel, } from "livekit-client"; import { App } from "./App"; @@ -28,9 +28,11 @@ import { Initializer } from "./initializer"; initRageshake().catch((e) => { logger.error("Failed to initialize rageshake", e); }); - -setLogLevel("debug"); -setLKLogExtension(global.mx_rage_logger.log); +setLKLogLevel("debug"); +setLKLogExtension((level, msg, context) => { + // we pass a synthetic logger name of "livekit" to the rageshake to make it easier to read + global.mx_rage_logger.log(level, "livekit", msg, context); +}); logger.info(`Element Call ${import.meta.env.VITE_APP_VERSION || "dev"}`); diff --git a/src/settings/rageshake.ts b/src/settings/rageshake.ts index e0868b9e..ea9805df 100644 --- a/src/settings/rageshake.ts +++ b/src/settings/rageshake.ts @@ -29,9 +29,9 @@ Please see LICENSE in the repository root for full details. import EventEmitter from "events"; import { throttle } from "lodash"; -import { logger } from "matrix-js-sdk/src/logger"; +import { Logger, logger } from "matrix-js-sdk/src/logger"; import { randomString } from "matrix-js-sdk/src/randomstring"; -import { LoggingMethod } from "loglevel"; +import loglevel, { LoggingMethod } from "loglevel"; // the length of log data we keep in indexeddb (and include in the reports) const MAX_LOG_SIZE = 1024 * 1024 * 5; // 5 MB @@ -467,7 +467,12 @@ declare global { */ export async function init(): Promise { global.mx_rage_logger = new ConsoleLogger(); - setLogExtension(global.mx_rage_logger.log); + setLogExtension(logger, global.mx_rage_logger.log); + // these are the child/prefixed loggers we want to capture from js-sdk + // there doesn't seem to be an easy way to capture all children + ["MatrixRTCSession", "MatrixRTCSessionManager"].forEach((loggerName) => { + setLogExtension(logger.getChild(loggerName), global.mx_rage_logger.log); + }); return tryInitStorage(); } @@ -580,10 +585,14 @@ type LogLevelString = keyof typeof LogLevel; * took loglevel's example honouring log levels). Adds a loglevel logging extension * in the recommended way. */ -export function setLogExtension(extension: LogExtensionFunc): void { - const originalFactory = logger.methodFactory; +function setLogExtension( + _loggerToExtend: Logger, + extension: LogExtensionFunc, +): void { + const loggerToExtend = _loggerToExtend as unknown as loglevel.Logger; + const originalFactory = loggerToExtend.methodFactory; - logger.methodFactory = function ( + loggerToExtend.methodFactory = function ( methodName, configLevel, loggerName, @@ -594,11 +603,14 @@ export function setLogExtension(extension: LogExtensionFunc): void { const needLog = logLevel >= configLevel && logLevel < LogLevel.silent; return (...args) => { + // we don't send the logger name to the raw method as some of them are already outputting the prefix rawMethod.apply(this, args); if (needLog) { - extension(logLevel, ...args); + // we prefix the logger name to the extension + // this makes sure that the rageshake contains the logger name + extension(logLevel, loggerName?.toString(), ...args); } }; }; - logger.setLevel(logger.getLevel()); // Be sure to call setLevel method in order to apply plugin + loggerToExtend.setLevel(loggerToExtend.getLevel()); // Be sure to call setLevel method in order to apply plugin } From a5aeb6f32474d954ef37e0854cfc8a3bb5ae80e2 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 11 Sep 2024 14:53:50 +0100 Subject: [PATCH 07/21] Give user feedback if the rageshake submission failed (#2621) --- src/settings/FeedbackSettingsTab.tsx | 13 +++++-------- src/settings/submit-rageshake.ts | 8 +++++++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/settings/FeedbackSettingsTab.tsx b/src/settings/FeedbackSettingsTab.tsx index f47d10ac..afefe07e 100644 --- a/src/settings/FeedbackSettingsTab.tsx +++ b/src/settings/FeedbackSettingsTab.tsx @@ -69,9 +69,7 @@ export const FeedbackSettingsTab: FC = ({ roomId }) => { disabled={sending || sent} /> - {sent ? ( - {t("settings.feedback_tab_thank_you")} - ) : ( + {!sent && ( = ({ roomId }) => { type="checkbox" defaultChecked /> - {error && ( - - - - )} )} + + {error && } + {sent && {t("settings.feedback_tab_thank_you")}} + ); diff --git a/src/settings/submit-rageshake.ts b/src/settings/submit-rageshake.ts index 16b81d0b..1ab90667 100644 --- a/src/settings/submit-rageshake.ts +++ b/src/settings/submit-rageshake.ts @@ -270,11 +270,17 @@ export function useSubmitRageshake(): { ); } - await fetch(Config.get().rageshake!.submit_url, { + const res = await fetch(Config.get().rageshake!.submit_url, { method: "POST", body, }); + if (res.status !== 200) { + throw new Error( + `Failed to submit feedback: receive HTTP ${res.status} ${res.statusText}`, + ); + } + setState({ sending: false, sent: true, error: undefined }); } catch (error) { setState({ sending: false, sent: false, error: error as Error }); From e5e6233efb4c0b31e4e0d0e6930ae8327c2446c5 Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 11 Sep 2024 13:44:43 -0400 Subject: [PATCH 08/21] Replace typography components with Compound components --- src/analytics/AnalyticsNotice.tsx | 12 +- src/auth/RegisterPage.tsx | 20 +- src/button/Link.module.css | 10 + src/button/Link.tsx | 33 +++- src/home/CallList.module.css | 6 + src/home/CallList.tsx | 6 +- src/home/RegisteredView.tsx | 7 +- src/home/UnauthenticatedView.tsx | 28 +-- src/index.css | 10 - src/room/CallEndedView.tsx | 19 +- src/room/GroupCallLoader.tsx | 22 +-- src/room/GroupCallView.tsx | 15 +- src/room/RageshakeRequestModal.tsx | 5 +- src/room/RoomAuthView.tsx | 25 ++- src/settings/FeedbackSettingsTab.tsx | 7 +- src/settings/SettingsModal.tsx | 7 +- src/typography/Typography.module.css | 47 ----- src/typography/Typography.tsx | 262 --------------------------- 18 files changed, 118 insertions(+), 423 deletions(-) create mode 100644 src/button/Link.module.css delete mode 100644 src/typography/Typography.module.css delete mode 100644 src/typography/Typography.tsx diff --git a/src/analytics/AnalyticsNotice.tsx b/src/analytics/AnalyticsNotice.tsx index 8df2d742..9ba78f0d 100644 --- a/src/analytics/AnalyticsNotice.tsx +++ b/src/analytics/AnalyticsNotice.tsx @@ -8,14 +8,20 @@ Please see LICENSE in the repository root for full details. import { FC } from "react"; import { Trans } from "react-i18next"; -import { Link } from "../typography/Typography"; +import { ExternalLink } from "../button/Link"; export const AnalyticsNotice: FC = () => ( By participating in this beta, you consent to the collection of anonymous data, which we use to improve the product. You can find more information about which data we track in our{" "} - Privacy Policy and our{" "} - Cookie Policy. + + Privacy Policy + {" "} + and our{" "} + + Cookie Policy + + . ); diff --git a/src/auth/RegisterPage.tsx b/src/auth/RegisterPage.tsx index 5ee1c9eb..392f8a7a 100644 --- a/src/auth/RegisterPage.tsx +++ b/src/auth/RegisterPage.tsx @@ -19,7 +19,7 @@ import { captureException } from "@sentry/react"; import { sleep } from "matrix-js-sdk/src/utils"; import { Trans, useTranslation } from "react-i18next"; import { logger } from "matrix-js-sdk/src/logger"; -import { Button } from "@vector-im/compound-web"; +import { Button, Text } from "@vector-im/compound-web"; import { FieldRow, InputField, ErrorMessage } from "../input/Input"; import { useClientLegacy } from "../ClientContext"; @@ -28,10 +28,10 @@ import styles from "./LoginPage.module.css"; import Logo from "../icons/LogoLarge.svg?react"; import { LoadingView } from "../FullScreenView"; import { useRecaptcha } from "./useRecaptcha"; -import { Caption, Link } from "../typography/Typography"; import { usePageTitle } from "../usePageTitle"; import { PosthogAnalytics } from "../analytics/PosthogAnalytics"; import { Config } from "../config/Config"; +import { ExternalLink, Link } from "../button/Link"; export const RegisterPage: FC = () => { const { t } = useTranslation(); @@ -201,24 +201,24 @@ export const RegisterPage: FC = () => { data-testid="register_confirm_password" /> - + This site is protected by ReCAPTCHA and the Google{" "} - + Privacy Policy - {" "} + {" "} and{" "} - + Terms of Service - {" "} + {" "} apply.
By clicking "Register", you agree to our{" "} - + End User Licensing Agreement (EULA) - +
- +
{error && ( diff --git a/src/button/Link.module.css b/src/button/Link.module.css new file mode 100644 index 00000000..710d5a1a --- /dev/null +++ b/src/button/Link.module.css @@ -0,0 +1,10 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only +Please see LICENSE in the repository root for full details. +*/ + +.external { + color: inherit; +} diff --git a/src/button/Link.tsx b/src/button/Link.tsx index 35c9af98..4114bd20 100644 --- a/src/button/Link.tsx +++ b/src/button/Link.tsx @@ -15,10 +15,16 @@ import { import { Link as CpdLink } from "@vector-im/compound-web"; import { useHistory } from "react-router-dom"; import { createPath, LocationDescriptor, Path } from "history"; +import classNames from "classnames"; + +import { useLatest } from "../useLatest"; +import styles from "./Link.module.css"; export function useLink( to: LocationDescriptor, + state?: unknown, ): [Path, (e: MouseEvent) => void] { + const latestState = useLatest(state); const history = useHistory(); const path = useMemo( () => (typeof to === "string" ? to : createPath(to)), @@ -27,9 +33,9 @@ export function useLink( const onClick = useCallback( (e: MouseEvent) => { e.preventDefault(); - history.push(to); + history.push(to, latestState.current); }, - [history, to], + [history, to, latestState], ); return [path, onClick]; @@ -38,15 +44,32 @@ export function useLink( type Props = Omit< ComponentPropsWithoutRef, "href" | "onClick" -> & { to: LocationDescriptor }; +> & { to: LocationDescriptor; state?: unknown }; /** * A version of Compound's link component that integrates with our router setup. */ export const Link = forwardRef(function Link( - { to, ...props }, + { to, state, ...props }, ref, ) { - const [path, onClick] = useLink(to); + const [path, onClick] = useLink(to, state); return ; }); + +export const ExternalLink = forwardRef< + HTMLAnchorElement, + ComponentPropsWithoutRef<"a"> +>(function ExternalLink({ className, children, ...props }, ref) { + return ( + + {children} + + ); +}); diff --git a/src/home/CallList.module.css b/src/home/CallList.module.css index 8e988d03..21f6866f 100644 --- a/src/home/CallList.module.css +++ b/src/home/CallList.module.css @@ -50,6 +50,12 @@ Please see LICENSE in the repository root for full details. margin-bottom: 0; } +.callName { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + .facePile { margin-top: 8px; } diff --git a/src/home/CallList.tsx b/src/home/CallList.tsx index aa6db6f3..0446bb02 100644 --- a/src/home/CallList.tsx +++ b/src/home/CallList.tsx @@ -10,11 +10,11 @@ import { MatrixClient } from "matrix-js-sdk/src/client"; import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { Room } from "matrix-js-sdk/src/models/room"; import { FC } from "react"; +import { Text } from "@vector-im/compound-web"; import { Avatar, Size } from "../Avatar"; import styles from "./CallList.module.css"; import { getRelativeRoomUrl } from "../utils/matrix"; -import { Body } from "../typography/Typography"; import { GroupCallRoom } from "./useGroupCallRooms"; import { useRoomEncryptionSystem } from "../e2ee/sharedKeyManagement"; @@ -65,9 +65,9 @@ const CallTile: FC = ({ name, avatarUrl, room }) => { >
- + {name} - +
diff --git a/src/home/RegisteredView.tsx b/src/home/RegisteredView.tsx index 34abe113..db242414 100644 --- a/src/home/RegisteredView.tsx +++ b/src/home/RegisteredView.tsx @@ -9,7 +9,7 @@ import { useState, useCallback, FormEvent, FormEventHandler, FC } from "react"; import { useHistory } from "react-router-dom"; import { MatrixClient } from "matrix-js-sdk/src/client"; import { useTranslation } from "react-i18next"; -import { Heading } from "@vector-im/compound-web"; +import { Heading, Text } from "@vector-im/compound-web"; import { logger } from "matrix-js-sdk/src/logger"; import { Button } from "@vector-im/compound-web"; @@ -27,7 +27,6 @@ import { FieldRow, InputField, ErrorMessage } from "../input/Input"; import { CallList } from "./CallList"; import { UserMenuContainer } from "../UserMenuContainer"; import { JoinExistingCallModal } from "./JoinExistingCallModal"; -import { Caption } from "../typography/Typography"; import { Form } from "../form/Form"; import { AnalyticsNotice } from "../analytics/AnalyticsNotice"; import { E2eeType } from "../e2ee/e2eeType"; @@ -144,9 +143,9 @@ export const RegisteredView: FC = ({ client }) => { {optInAnalytics === null && ( - + - + )} {error && ( diff --git a/src/home/UnauthenticatedView.tsx b/src/home/UnauthenticatedView.tsx index a1ea8514..daafa9f8 100644 --- a/src/home/UnauthenticatedView.tsx +++ b/src/home/UnauthenticatedView.tsx @@ -9,7 +9,7 @@ import { FC, useCallback, useState, FormEventHandler } from "react"; import { useHistory } from "react-router-dom"; import { randomString } from "matrix-js-sdk/src/randomstring"; import { Trans, useTranslation } from "react-i18next"; -import { Button, Heading } from "@vector-im/compound-web"; +import { Button, Heading, Text } from "@vector-im/compound-web"; import { logger } from "matrix-js-sdk/src/logger"; import { useClient } from "../ClientContext"; @@ -25,7 +25,6 @@ import { import { useInteractiveRegistration } from "../auth/useInteractiveRegistration"; import { JoinExistingCallModal } from "./JoinExistingCallModal"; import { useRecaptcha } from "../auth/useRecaptcha"; -import { Body, Caption, Link } from "../typography/Typography"; import { Form } from "../form/Form"; import styles from "./UnauthenticatedView.module.css"; import commonStyles from "./common.module.css"; @@ -34,6 +33,7 @@ import { AnalyticsNotice } from "../analytics/AnalyticsNotice"; import { Config } from "../config/Config"; import { E2eeType } from "../e2ee/e2eeType"; import { useOptInAnalytics } from "../settings/settings"; +import { ExternalLink, Link } from "../button/Link"; export const UnauthenticatedView: FC = () => { const { setClient } = useClient(); @@ -178,18 +178,18 @@ export const UnauthenticatedView: FC = () => { /> {optInAnalytics === null && ( - + - + )} - + By clicking "Go", you agree to our{" "} - + End User Licensing Agreement (EULA) - + - + {error && ( @@ -207,19 +207,19 @@ export const UnauthenticatedView: FC = () => {
- - + + {t("unauthenticated_view_login_button")} - - + + Not registered yet?{" "} - + Create an account - +
{onFinished && ( diff --git a/src/index.css b/src/index.css index b416dcca..02f335f9 100644 --- a/src/index.css +++ b/src/index.css @@ -237,16 +237,6 @@ body[data-platform="desktop"] { line-height: var(--font-size-title); } - a { - color: var(--cpd-color-text-action-accent); - text-decoration: none; - } - - a:hover, - a:active { - opacity: 0.8; - } - hr { width: calc(100% - 24px); border: none; diff --git a/src/room/CallEndedView.tsx b/src/room/CallEndedView.tsx index 296bf2fb..556dc6e5 100644 --- a/src/room/CallEndedView.tsx +++ b/src/room/CallEndedView.tsx @@ -9,12 +9,11 @@ import { FC, FormEventHandler, ReactNode, useCallback, useState } from "react"; import { MatrixClient } from "matrix-js-sdk/src/client"; import { Trans, useTranslation } from "react-i18next"; import { useHistory } from "react-router-dom"; -import { Button } from "@vector-im/compound-web"; +import { Button, Heading, Text } from "@vector-im/compound-web"; import styles from "./CallEndedView.module.css"; import feedbackStyle from "../input/FeedbackInput.module.css"; import { useProfile } from "../profile/useProfile"; -import { Body, Headline } from "../typography/Typography"; import { Header, HeaderLogo, LeftNav, RightNav } from "../Header"; import { PosthogAnalytics } from "../analytics/PosthogAnalytics"; import { FieldRow, InputField } from "../input/Input"; @@ -139,11 +138,11 @@ export const CallEndedView: FC = ({ return ( <>
- + You were disconnected from the call - +
{!confineToRoom && ( - + {t("return_home_button")} - + )} ); @@ -164,7 +163,7 @@ export const CallEndedView: FC = ({ return ( <>
- + {surveySubmitted ? t("call_ended_view.headline", { displayName, @@ -174,16 +173,16 @@ export const CallEndedView: FC = ({ }) + "\n" + t("call_ended_view.survey_prompt")} - + {(!surveySubmitted || confineToRoom) && PosthogAnalytics.instance.isEnabled() ? qualitySurveyDialog : createAccountDialog}
{!confineToRoom && ( - + {t("call_ended_view.not_now_button")} - + )} ); diff --git a/src/room/GroupCallLoader.tsx b/src/room/GroupCallLoader.tsx index 36bdcc4c..f843f3f4 100644 --- a/src/room/GroupCallLoader.tsx +++ b/src/room/GroupCallLoader.tsx @@ -5,13 +5,12 @@ SPDX-License-Identifier: AGPL-3.0-only Please see LICENSE in the repository root for full details. */ -import { useCallback } from "react"; import { MatrixClient } from "matrix-js-sdk/src/client"; import { useTranslation } from "react-i18next"; import { MatrixError } from "matrix-js-sdk/src/matrix"; -import { useHistory } from "react-router-dom"; -import { Heading, Link, Text } from "@vector-im/compound-web"; +import { Heading, Text } from "@vector-im/compound-web"; +import { Link } from "../button/Link"; import { useLoadGroupCall, GroupCallStatus, @@ -35,15 +34,6 @@ export function GroupCallLoader({ const { t } = useTranslation(); const groupCallState = useLoadGroupCall(client, roomIdOrAlias, viaServers); - const history = useHistory(); - const onHomeClick = useCallback( - (ev: React.MouseEvent) => { - ev.preventDefault(); - history.push("/"); - }, - [history], - ); - switch (groupCallState.kind) { case "loaded": case "waitForInvite": @@ -63,9 +53,7 @@ export function GroupCallLoader({ {t("group_call_loader.failed_text")} {/* XXX: A 'create it for me' button would be the obvious UX here. Two screens already have dupes of this flow, let's make a common component and put it here. */} - - {t("common.home")} - + {t("common.home")} ); } else if (groupCallState.error instanceof CallTerminatedMessage) { @@ -79,9 +67,7 @@ export function GroupCallLoader({ "{groupCallState.error.reason}" )} - - {t("common.home")} - + {t("common.home")} ); } else { diff --git a/src/room/GroupCallView.tsx b/src/room/GroupCallView.tsx index af97ce07..6892262b 100644 --- a/src/room/GroupCallView.tsx +++ b/src/room/GroupCallView.tsx @@ -15,7 +15,7 @@ import { import { logger } from "matrix-js-sdk/src/logger"; import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession"; import { JoinRule } from "matrix-js-sdk/src/matrix"; -import { Heading, Link, Text } from "@vector-im/compound-web"; +import { Heading, Text } from "@vector-im/compound-web"; import { useTranslation } from "react-i18next"; import type { IWidgetApiRequest } from "matrix-widget-api"; @@ -40,6 +40,7 @@ import { useJoinRule } from "./useJoinRule"; import { InviteModal } from "./InviteModal"; import { useUrlParams } from "../UrlParams"; import { E2eeType } from "../e2ee/e2eeType"; +import { Link } from "../button/Link"; declare global { interface Window { @@ -281,14 +282,6 @@ export const GroupCallView: FC = ({ ); const onShareClick = joinRule === JoinRule.Public ? onShareClickFn : null; - const onHomeClick = useCallback( - (ev: React.MouseEvent) => { - ev.preventDefault(); - history.push("/"); - }, - [history], - ); - const { t } = useTranslation(); if (!isE2EESupportedBrowser() && e2eeSystem.kind !== E2eeType.NONE) { @@ -297,9 +290,7 @@ export const GroupCallView: FC = ({ {t("browser_media_e2ee_unsupported_heading")} {t("browser_media_e2ee_unsupported")} - - {t("common.home")} - + {t("common.home")} ); } diff --git a/src/room/RageshakeRequestModal.tsx b/src/room/RageshakeRequestModal.tsx index 03b0c1c0..d22b0bea 100644 --- a/src/room/RageshakeRequestModal.tsx +++ b/src/room/RageshakeRequestModal.tsx @@ -7,12 +7,11 @@ Please see LICENSE in the repository root for full details. import { FC, useEffect } from "react"; import { useTranslation } from "react-i18next"; -import { Button } from "@vector-im/compound-web"; +import { Button, Text } from "@vector-im/compound-web"; import { Modal, Props as ModalProps } from "../Modal"; import { FieldRow, ErrorMessage } from "../input/Input"; import { useSubmitRageshake } from "../settings/submit-rageshake"; -import { Body } from "../typography/Typography"; interface Props extends Omit { rageshakeRequestId: string; @@ -40,7 +39,7 @@ export const RageshakeRequestModal: FC = ({ open={open} onDismiss={onDismiss} > - {t("rageshake_request_modal.body")} + {t("rageshake_request_modal.body")}