mirror of
https://github.com/vector-im/element-call.git
synced 2026-08-29 21:15:19 +00:00
add logic to show error view when getting removed
This commit is contained in:
@@ -60,12 +60,16 @@
|
|||||||
"disconnected_banner": "Connectivity to the server has been lost.",
|
"disconnected_banner": "Connectivity to the server has been lost.",
|
||||||
"full_screen_view_description": "<0>Submitting debug logs will help us track down the problem.</0>",
|
"full_screen_view_description": "<0>Submitting debug logs will help us track down the problem.</0>",
|
||||||
"full_screen_view_h1": "<0>Oops, something's gone wrong.</0>",
|
"full_screen_view_h1": "<0>Oops, something's gone wrong.</0>",
|
||||||
"group_call_loader_banned_heading": "Not allowed to join",
|
"group_call_loader": {
|
||||||
"group_call_loader_banned_message": "You are banned from this room and therefore cannot send a request to join.",
|
"banned_body": "You got banned from the room.",
|
||||||
"group_call_loader_failed_heading": "Call not found",
|
"banned_heading": "Banned",
|
||||||
"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.",
|
"call_ended_body": "You got removed from the call.",
|
||||||
"group_call_loader_reject_message": "The room members declined your request to join.",
|
"call_ended_heading": "Call Ended",
|
||||||
"group_call_loader_rejected_heading": "Not allowed to join",
|
"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",
|
"hangup_button_label": "End call",
|
||||||
"header_label": "Element Call Home",
|
"header_label": "Element Call Home",
|
||||||
"header_participants_label": "Participants",
|
"header_participants_label": "Participants",
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ import { Heading, Link, Text } from "@vector-im/compound-web";
|
|||||||
import {
|
import {
|
||||||
useLoadGroupCall,
|
useLoadGroupCall,
|
||||||
GroupCallStatus,
|
GroupCallStatus,
|
||||||
KnockRejectError,
|
CustomMessage,
|
||||||
BannedError,
|
|
||||||
} from "./useLoadGroupCall";
|
} from "./useLoadGroupCall";
|
||||||
import { ErrorView, FullScreenView } from "../FullScreenView";
|
import { ErrorView, FullScreenView } from "../FullScreenView";
|
||||||
|
|
||||||
@@ -69,8 +68,8 @@ export function GroupCallLoader({
|
|||||||
if ((groupCallState.error as MatrixError).errcode === "M_NOT_FOUND") {
|
if ((groupCallState.error as MatrixError).errcode === "M_NOT_FOUND") {
|
||||||
return (
|
return (
|
||||||
<FullScreenView>
|
<FullScreenView>
|
||||||
<Heading>{t("group_call_loader_failed_heading")}</Heading>
|
<Heading>{t("group_call_loader.failed_heading")}</Heading>
|
||||||
<Text>{t("group_call_loader_failed_text")}</Text>
|
<Text>{t("group_call_loader.failed_text")}</Text>
|
||||||
{/* XXX: A 'create it for me' button would be the obvious UX here. Two screens already have
|
{/* 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. */}
|
dupes of this flow, let's make a common component and put it here. */}
|
||||||
<Link href="/" onClick={onHomeClick}>
|
<Link href="/" onClick={onHomeClick}>
|
||||||
@@ -78,26 +77,16 @@ export function GroupCallLoader({
|
|||||||
</Link>
|
</Link>
|
||||||
</FullScreenView>
|
</FullScreenView>
|
||||||
);
|
);
|
||||||
} else if (groupCallState.error instanceof KnockRejectError) {
|
} else if (groupCallState.error instanceof CustomMessage) {
|
||||||
return (
|
return (
|
||||||
<FullScreenView>
|
<FullScreenView>
|
||||||
<Heading>{t("group_call_loader_rejected_heading")}</Heading>
|
<Heading>{groupCallState.error.messageTitle}</Heading>
|
||||||
<Text>{groupCallState.error.message}</Text>
|
<Text>{groupCallState.error.message}</Text>
|
||||||
<Link href="/" onClick={onHomeClick}>
|
<Link href="/" onClick={onHomeClick}>
|
||||||
{t("common.home")}
|
{t("common.home")}
|
||||||
</Link>
|
</Link>
|
||||||
</FullScreenView>
|
</FullScreenView>
|
||||||
);
|
);
|
||||||
} else if (groupCallState.error instanceof BannedError) {
|
|
||||||
return (
|
|
||||||
<FullScreenView>
|
|
||||||
<Heading>{t("group_call_loader_banned_heading")}</Heading>
|
|
||||||
<Text>{t("group_call_loader_banned_message")}</Text>
|
|
||||||
<Link href="/" onClick={onHomeClick}>
|
|
||||||
{t("common.home")}
|
|
||||||
</Link>
|
|
||||||
</FullScreenView>
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return <ErrorView error={groupCallState.error} />;
|
return <ErrorView error={groupCallState.error} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import { KnownMembership, Membership, RoomType } from "matrix-js-sdk/src/types";
|
|||||||
import { JoinRule } from "matrix-js-sdk";
|
import { JoinRule } from "matrix-js-sdk";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import type { GroupCall } from "matrix-js-sdk/src/webrtc/groupCall";
|
|
||||||
import { widget } from "../widget";
|
import { widget } from "../widget";
|
||||||
|
|
||||||
export type GroupCallLoaded = {
|
export type GroupCallLoaded = {
|
||||||
@@ -58,13 +57,14 @@ export type GroupCallStatus =
|
|||||||
| GroupCallLoading
|
| GroupCallLoading
|
||||||
| GroupCallWaitForInvite
|
| GroupCallWaitForInvite
|
||||||
| GroupCallCanKnock;
|
| GroupCallCanKnock;
|
||||||
export interface GroupCallLoadState {
|
|
||||||
error?: Error | KnockRejectError;
|
|
||||||
groupCall?: GroupCall;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class KnockRejectError extends Error {}
|
export class CustomMessage extends Error {
|
||||||
export class BannedError 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)
|
// RoomSummary from the js-sdk (this is not public so we copy it here)
|
||||||
export interface RoomSummary {
|
export interface RoomSummary {
|
||||||
@@ -91,6 +91,19 @@ export const useLoadGroupCall = (
|
|||||||
const [state, setState] = useState<GroupCallStatus>({ kind: "loading" });
|
const [state, setState] = useState<GroupCallStatus>({ kind: "loading" });
|
||||||
const { t } = useTranslation();
|
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(() => {
|
useEffect(() => {
|
||||||
const getRoomByAlias = async (alias: string): Promise<Room> => {
|
const getRoomByAlias = async (alias: string): Promise<Room> => {
|
||||||
// We lowercase the localpart when we create the room, so we must lowercase
|
// 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);
|
logger.log("Auto-joined %s", room.roomId);
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
if (
|
if (membership === KnownMembership.Ban) reject(BannedError);
|
||||||
membership === KnownMembership.Ban ||
|
if (membership === KnownMembership.Leave) reject(KnockRejectError);
|
||||||
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")),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -183,7 +188,7 @@ export const useLoadGroupCall = (
|
|||||||
viaServers,
|
viaServers,
|
||||||
)) as unknown as RoomSummary;
|
)) as unknown as RoomSummary;
|
||||||
if (room?.getMyMembership() === KnownMembership.Ban) {
|
if (room?.getMyMembership() === KnownMembership.Ban) {
|
||||||
throw new BannedError();
|
throw BannedError;
|
||||||
} else {
|
} else {
|
||||||
if (roomSummary.join_rule === JoinRule.Public) {
|
if (roomSummary.join_rule === JoinRule.Public) {
|
||||||
room = await client.joinRoom(roomSummary.room_id, {
|
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") {
|
if (state.kind === "loading") {
|
||||||
logger.log("Start loading group call");
|
logger.log("Start loading group call");
|
||||||
waitForClientSyncing()
|
waitForClientSyncing()
|
||||||
.then(fetchOrCreateGroupCall)
|
.then(fetchOrCreateGroupCall)
|
||||||
.then((rtcSession) => setState({ kind: "loaded", rtcSession }))
|
.then((rtcSession) => setState({ kind: "loaded", rtcSession }))
|
||||||
|
.then(observeMyMembership)
|
||||||
.catch((error) => setState({ kind: "failed", error }));
|
.catch((error) => setState({ kind: "failed", error }));
|
||||||
}
|
}
|
||||||
}, [client, roomIdOrAlias, state, t, viaServers]);
|
}, [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;
|
return state;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user