From f10f00afa21304456645161d7b7018987ae1c5b3 Mon Sep 17 00:00:00 2001 From: Timo Date: Thu, 11 Apr 2024 14:24:24 +0200 Subject: [PATCH] add logic to show error view when getting removed --- public/locales/en-GB/app.json | 16 +++++++---- src/room/GroupCallLoader.tsx | 21 ++++---------- src/room/useLoadGroupCall.ts | 52 ++++++++++++++++++++++------------- 3 files changed, 48 insertions(+), 41 deletions(-) diff --git a/public/locales/en-GB/app.json b/public/locales/en-GB/app.json index a020308f..38b2e70e 100644 --- a/public/locales/en-GB/app.json +++ b/public/locales/en-GB/app.json @@ -60,12 +60,16 @@ "disconnected_banner": "Connectivity to the server has been lost.", "full_screen_view_description": "<0>Submitting debug logs will help us track down the problem.", "full_screen_view_h1": "<0>Oops, something's gone wrong.", - "group_call_loader_banned_heading": "Not allowed to join", - "group_call_loader_banned_message": "You are banned from this room and therefore cannot send a request to join.", - "group_call_loader_failed_heading": "Call not found", - "group_call_loader_failed_text": "Calls are now end-to-end encrypted and need to be created from the home page. This helps make sure everyone's using the same encryption key.", - "group_call_loader_reject_message": "The room members declined your request to join.", - "group_call_loader_rejected_heading": "Not allowed to join", + "group_call_loader": { + "banned_body": "You got banned from the room.", + "banned_heading": "Banned", + "call_ended_body": "You got removed from the call.", + "call_ended_heading": "Call Ended", + "failed_heading": "Call not found", + "failed_text": "Calls are now end-to-end encrypted and need to be created from the home page. This helps make sure everyone's using the same encryption key.", + "knock_reject_body": "The room members declined your request to join.", + "knock_reject_heading": "Not allowed to join" + }, "hangup_button_label": "End call", "header_label": "Element Call Home", "header_participants_label": "Participants", diff --git a/src/room/GroupCallLoader.tsx b/src/room/GroupCallLoader.tsx index 9ceb77ff..9a603aac 100644 --- a/src/room/GroupCallLoader.tsx +++ b/src/room/GroupCallLoader.tsx @@ -24,8 +24,7 @@ import { Heading, Link, Text } from "@vector-im/compound-web"; import { useLoadGroupCall, GroupCallStatus, - KnockRejectError, - BannedError, + CustomMessage, } from "./useLoadGroupCall"; import { ErrorView, FullScreenView } from "../FullScreenView"; @@ -69,8 +68,8 @@ export function GroupCallLoader({ if ((groupCallState.error as MatrixError).errcode === "M_NOT_FOUND") { return ( - {t("group_call_loader_failed_heading")} - {t("group_call_loader_failed_text")} + {t("group_call_loader.failed_heading")} + {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. */} @@ -78,26 +77,16 @@ export function GroupCallLoader({ ); - } else if (groupCallState.error instanceof KnockRejectError) { + } else if (groupCallState.error instanceof CustomMessage) { return ( - {t("group_call_loader_rejected_heading")} + {groupCallState.error.messageTitle} {groupCallState.error.message} {t("common.home")} ); - } else if (groupCallState.error instanceof BannedError) { - return ( - - {t("group_call_loader_banned_heading")} - {t("group_call_loader_banned_message")} - - {t("common.home")} - - - ); } else { return ; } diff --git a/src/room/useLoadGroupCall.ts b/src/room/useLoadGroupCall.ts index b65ceb66..53fcf4b9 100644 --- a/src/room/useLoadGroupCall.ts +++ b/src/room/useLoadGroupCall.ts @@ -24,7 +24,6 @@ import { KnownMembership, Membership, RoomType } from "matrix-js-sdk/src/types"; import { JoinRule } from "matrix-js-sdk"; import { useTranslation } from "react-i18next"; -import type { GroupCall } from "matrix-js-sdk/src/webrtc/groupCall"; import { widget } from "../widget"; export type GroupCallLoaded = { @@ -58,13 +57,14 @@ export type GroupCallStatus = | GroupCallLoading | GroupCallWaitForInvite | GroupCallCanKnock; -export interface GroupCallLoadState { - error?: Error | KnockRejectError; - groupCall?: GroupCall; -} -export class KnockRejectError extends Error {} -export class BannedError extends Error {} +export class CustomMessage extends Error { + messageTitle: string; + constructor(messageTitle: string, message: string) { + super(message); + this.messageTitle = messageTitle; + } +} // RoomSummary from the js-sdk (this is not public so we copy it here) export interface RoomSummary { @@ -91,6 +91,19 @@ export const useLoadGroupCall = ( const [state, setState] = useState({ kind: "loading" }); const { t } = useTranslation(); + const BannedError = new CustomMessage( + t("group_call_loader.banned_heading"), + t("group_call_loader.banned_body"), //"You got benned from the room.", + ); + const KnockRejectError = new CustomMessage( + t("group_call_loader.knock_reject_heading"), + t("group_call_loader.knock_reject_body"), //"The room members declined your request to join.", + ); + const RemoveNoticeError = new CustomMessage( + t("group_call_loader.call_ended_heading"), + t("group_call_loader.call_ended_body"), //You got removed from the call + ); + useEffect(() => { const getRoomByAlias = async (alias: string): Promise => { // We lowercase the localpart when we create the room, so we must lowercase @@ -132,16 +145,8 @@ export const useLoadGroupCall = ( logger.log("Auto-joined %s", room.roomId); resolve(); } - if ( - membership === KnownMembership.Ban || - membership === KnownMembership.Leave - ) { - // also resolve in case of rejection - // we will check if joining worked in the next step - reject( - new KnockRejectError(t("group_call_loader_reject_message")), - ); - } + if (membership === KnownMembership.Ban) reject(BannedError); + if (membership === KnownMembership.Leave) reject(KnockRejectError); }, ); }); @@ -183,7 +188,7 @@ export const useLoadGroupCall = ( viaServers, )) as unknown as RoomSummary; if (room?.getMyMembership() === KnownMembership.Ban) { - throw new BannedError(); + throw BannedError; } else { if (roomSummary.join_rule === JoinRule.Public) { room = await client.joinRoom(roomSummary.room_id, { @@ -250,15 +255,24 @@ export const useLoadGroupCall = ( } }; + const observeMyMembership = async () => { + await new Promise((_, reject) => { + client.on(RoomEvent.MyMembership, async (_, membership) => { + if (membership === KnownMembership.Leave) reject(RemoveNoticeError); + if (membership === KnownMembership.Ban) reject(BannedError); + }); + }); + }; + if (state.kind === "loading") { logger.log("Start loading group call"); waitForClientSyncing() .then(fetchOrCreateGroupCall) .then((rtcSession) => setState({ kind: "loaded", rtcSession })) + .then(observeMyMembership) .catch((error) => setState({ kind: "failed", error })); } }, [client, roomIdOrAlias, state, t, viaServers]); - // state === undefined is used to make sure we only run the effect once. But outside the hook it is equivalent to "loading". return state; };