Add Element Call participant limit (#9358)
This commit is contained in:
parent
5680d13acf
commit
bb71c86c8a
8 changed files with 107 additions and 26 deletions
|
@ -119,6 +119,7 @@ export interface IConfigOptions {
|
||||||
element_call: {
|
element_call: {
|
||||||
url?: string;
|
url?: string;
|
||||||
use_exclusively?: boolean;
|
use_exclusively?: boolean;
|
||||||
|
participant_limit?: number;
|
||||||
brand?: string;
|
brand?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ export const DEFAULTS: IConfigOptions = {
|
||||||
element_call: {
|
element_call: {
|
||||||
url: "https://call.element.io",
|
url: "https://call.element.io",
|
||||||
use_exclusively: false,
|
use_exclusively: false,
|
||||||
|
participant_limit: 8,
|
||||||
brand: "Element Call",
|
brand: "Element Call",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import type { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import type { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
import type { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
import { Call, ConnectionState } from "../../../models/Call";
|
import { Call, ConnectionState } from "../../../models/Call";
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
import { useCall, useConnectionState, useParticipants } from "../../../hooks/useCall";
|
import { useCall, useConnectionState, useJoinCallButtonDisabledTooltip, useParticipants } from "../../../hooks/useCall";
|
||||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||||
import type { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
import type { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
||||||
import { Action } from "../../../dispatcher/actions";
|
import { Action } from "../../../dispatcher/actions";
|
||||||
|
@ -28,9 +28,9 @@ import type { ButtonEvent } from "../elements/AccessibleButton";
|
||||||
import MemberAvatar from "../avatars/MemberAvatar";
|
import MemberAvatar from "../avatars/MemberAvatar";
|
||||||
import { LiveContentSummary, LiveContentType } from "../rooms/LiveContentSummary";
|
import { LiveContentSummary, LiveContentType } from "../rooms/LiveContentSummary";
|
||||||
import FacePile from "../elements/FacePile";
|
import FacePile from "../elements/FacePile";
|
||||||
import AccessibleButton from "../elements/AccessibleButton";
|
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import { CallDuration, CallDurationFromEvent } from "../voip/CallDuration";
|
import { CallDuration, CallDurationFromEvent } from "../voip/CallDuration";
|
||||||
|
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||||
|
|
||||||
const MAX_FACES = 8;
|
const MAX_FACES = 8;
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@ interface ActiveCallEventProps {
|
||||||
participants: Set<RoomMember>;
|
participants: Set<RoomMember>;
|
||||||
buttonText: string;
|
buttonText: string;
|
||||||
buttonKind: string;
|
buttonKind: string;
|
||||||
|
buttonTooltip?: string;
|
||||||
|
buttonDisabled?: boolean;
|
||||||
onButtonClick: ((ev: ButtonEvent) => void) | null;
|
onButtonClick: ((ev: ButtonEvent) => void) | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +51,8 @@ const ActiveCallEvent = forwardRef<any, ActiveCallEventProps>(
|
||||||
participants,
|
participants,
|
||||||
buttonText,
|
buttonText,
|
||||||
buttonKind,
|
buttonKind,
|
||||||
|
buttonDisabled,
|
||||||
|
buttonTooltip,
|
||||||
onButtonClick,
|
onButtonClick,
|
||||||
},
|
},
|
||||||
ref,
|
ref,
|
||||||
|
@ -80,14 +84,15 @@ const ActiveCallEvent = forwardRef<any, ActiveCallEventProps>(
|
||||||
<FacePile members={facePileMembers} faceSize={24} overflow={facePileOverflow} />
|
<FacePile members={facePileMembers} faceSize={24} overflow={facePileOverflow} />
|
||||||
</div>
|
</div>
|
||||||
<CallDurationFromEvent mxEvent={mxEvent} />
|
<CallDurationFromEvent mxEvent={mxEvent} />
|
||||||
<AccessibleButton
|
<AccessibleTooltipButton
|
||||||
className="mx_CallEvent_button"
|
className="mx_CallEvent_button"
|
||||||
kind={buttonKind}
|
kind={buttonKind}
|
||||||
disabled={onButtonClick === null}
|
disabled={onButtonClick === null || buttonDisabled}
|
||||||
onClick={onButtonClick}
|
onClick={onButtonClick}
|
||||||
|
tooltip={buttonTooltip}
|
||||||
>
|
>
|
||||||
{ buttonText }
|
{ buttonText }
|
||||||
</AccessibleButton>
|
</AccessibleTooltipButton>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
},
|
},
|
||||||
|
@ -101,6 +106,7 @@ interface ActiveLoadedCallEventProps {
|
||||||
const ActiveLoadedCallEvent = forwardRef<any, ActiveLoadedCallEventProps>(({ mxEvent, call }, ref) => {
|
const ActiveLoadedCallEvent = forwardRef<any, ActiveLoadedCallEventProps>(({ mxEvent, call }, ref) => {
|
||||||
const connectionState = useConnectionState(call);
|
const connectionState = useConnectionState(call);
|
||||||
const participants = useParticipants(call);
|
const participants = useParticipants(call);
|
||||||
|
const joinCallButtonDisabledTooltip = useJoinCallButtonDisabledTooltip(call);
|
||||||
|
|
||||||
const connect = useCallback((ev: ButtonEvent) => {
|
const connect = useCallback((ev: ButtonEvent) => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
@ -132,6 +138,8 @@ const ActiveLoadedCallEvent = forwardRef<any, ActiveLoadedCallEventProps>(({ mxE
|
||||||
participants={participants}
|
participants={participants}
|
||||||
buttonText={buttonText}
|
buttonText={buttonText}
|
||||||
buttonKind={buttonKind}
|
buttonKind={buttonKind}
|
||||||
|
buttonDisabled={Boolean(joinCallButtonDisabledTooltip)}
|
||||||
|
buttonTooltip={joinCallButtonDisabledTooltip}
|
||||||
onButtonClick={onButtonClick}
|
onButtonClick={onButtonClick}
|
||||||
/>;
|
/>;
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { defer, IDeferred } from "matrix-js-sdk/src/utils";
|
||||||
import type { Room } from "matrix-js-sdk/src/models/room";
|
import type { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import type { ConnectionState } from "../../../models/Call";
|
import type { ConnectionState } from "../../../models/Call";
|
||||||
import { Call, CallEvent, ElementCall, isConnected } from "../../../models/Call";
|
import { Call, CallEvent, ElementCall, isConnected } from "../../../models/Call";
|
||||||
import { useCall, useConnectionState, useParticipants } from "../../../hooks/useCall";
|
import { useCall, useConnectionState, useJoinCallButtonDisabledTooltip, useParticipants } from "../../../hooks/useCall";
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import AppTile from "../elements/AppTile";
|
import AppTile from "../elements/AppTile";
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
|
@ -35,7 +35,7 @@ import IconizedContextMenu, {
|
||||||
} from "../context_menus/IconizedContextMenu";
|
} from "../context_menus/IconizedContextMenu";
|
||||||
import { aboveLeftOf, ContextMenuButton, useContextMenu } from "../../structures/ContextMenu";
|
import { aboveLeftOf, ContextMenuButton, useContextMenu } from "../../structures/ContextMenu";
|
||||||
import { Alignment } from "../elements/Tooltip";
|
import { Alignment } from "../elements/Tooltip";
|
||||||
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
import { ButtonEvent } from "../elements/AccessibleButton";
|
||||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||||
import FacePile from "../elements/FacePile";
|
import FacePile from "../elements/FacePile";
|
||||||
import MemberAvatar from "../avatars/MemberAvatar";
|
import MemberAvatar from "../avatars/MemberAvatar";
|
||||||
|
@ -110,10 +110,11 @@ const MAX_FACES = 8;
|
||||||
interface LobbyProps {
|
interface LobbyProps {
|
||||||
room: Room;
|
room: Room;
|
||||||
connect: () => Promise<void>;
|
connect: () => Promise<void>;
|
||||||
|
joinCallButtonDisabledTooltip?: string;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Lobby: FC<LobbyProps> = ({ room, connect, children }) => {
|
export const Lobby: FC<LobbyProps> = ({ room, joinCallButtonDisabledTooltip, connect, children }) => {
|
||||||
const [connecting, setConnecting] = useState(false);
|
const [connecting, setConnecting] = useState(false);
|
||||||
const me = useMemo(() => room.getMember(room.myUserId)!, [room]);
|
const me = useMemo(() => room.getMember(room.myUserId)!, [room]);
|
||||||
const videoRef = useRef<HTMLVideoElement>(null);
|
const videoRef = useRef<HTMLVideoElement>(null);
|
||||||
|
@ -233,14 +234,15 @@ export const Lobby: FC<LobbyProps> = ({ room, connect, children }) => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<AccessibleButton
|
<AccessibleTooltipButton
|
||||||
className="mx_CallView_connectButton"
|
className="mx_CallView_connectButton"
|
||||||
kind="primary"
|
kind="primary"
|
||||||
disabled={connecting}
|
disabled={connecting || Boolean(joinCallButtonDisabledTooltip)}
|
||||||
onClick={onConnectClick}
|
onClick={onConnectClick}
|
||||||
>
|
title={_t("Join")}
|
||||||
{ _t("Join") }
|
label={_t("Join")}
|
||||||
</AccessibleButton>
|
tooltip={connecting ? _t("Connecting") : joinCallButtonDisabledTooltip}
|
||||||
|
/>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -321,6 +323,7 @@ const JoinCallView: FC<JoinCallViewProps> = ({ room, resizing, call }) => {
|
||||||
const cli = useContext(MatrixClientContext);
|
const cli = useContext(MatrixClientContext);
|
||||||
const connected = isConnected(useConnectionState(call));
|
const connected = isConnected(useConnectionState(call));
|
||||||
const participants = useParticipants(call);
|
const participants = useParticipants(call);
|
||||||
|
const joinCallButtonDisabledTooltip = useJoinCallButtonDisabledTooltip(call);
|
||||||
|
|
||||||
const connect = useCallback(async () => {
|
const connect = useCallback(async () => {
|
||||||
// Disconnect from any other active calls first, since we don't yet support holding
|
// Disconnect from any other active calls first, since we don't yet support holding
|
||||||
|
@ -344,7 +347,13 @@ const JoinCallView: FC<JoinCallViewProps> = ({ room, resizing, call }) => {
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
lobby = <Lobby room={room} connect={connect}>{ facePile }</Lobby>;
|
lobby = <Lobby
|
||||||
|
room={room}
|
||||||
|
connect={connect}
|
||||||
|
joinCallButtonDisabledTooltip={joinCallButtonDisabledTooltip}
|
||||||
|
>
|
||||||
|
{ facePile }
|
||||||
|
</Lobby>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className="mx_CallView">
|
return <div className="mx_CallView">
|
||||||
|
|
|
@ -17,11 +17,13 @@ limitations under the License.
|
||||||
import { useState, useCallback } from "react";
|
import { useState, useCallback } from "react";
|
||||||
|
|
||||||
import type { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
import type { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
import type { Call, ConnectionState, ElementCall, Layout } from "../models/Call";
|
import { Call, ConnectionState, ElementCall, Layout } from "../models/Call";
|
||||||
import { useTypedEventEmitterState } from "./useEventEmitter";
|
import { useTypedEventEmitterState } from "./useEventEmitter";
|
||||||
import { CallEvent } from "../models/Call";
|
import { CallEvent } from "../models/Call";
|
||||||
import { CallStore, CallStoreEvent } from "../stores/CallStore";
|
import { CallStore, CallStoreEvent } from "../stores/CallStore";
|
||||||
import { useEventEmitter } from "./useEventEmitter";
|
import { useEventEmitter } from "./useEventEmitter";
|
||||||
|
import SdkConfig, { DEFAULTS } from "../SdkConfig";
|
||||||
|
import { _t } from "../languageHandler";
|
||||||
|
|
||||||
export const useCall = (roomId: string): Call | null => {
|
export const useCall = (roomId: string): Call | null => {
|
||||||
const [call, setCall] = useState(() => CallStore.instance.getCall(roomId));
|
const [call, setCall] = useState(() => CallStore.instance.getCall(roomId));
|
||||||
|
@ -45,6 +47,24 @@ export const useParticipants = (call: Call): Set<RoomMember> =>
|
||||||
useCallback(state => state ?? call.participants, [call]),
|
useCallback(state => state ?? call.participants, [call]),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const useFull = (call: Call): boolean => {
|
||||||
|
const participants = useParticipants(call);
|
||||||
|
|
||||||
|
return (
|
||||||
|
participants.size
|
||||||
|
>= (SdkConfig.get("element_call").participant_limit ?? DEFAULTS.element_call.participant_limit)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useJoinCallButtonDisabledTooltip = (call: Call): string | null => {
|
||||||
|
const isFull = useFull(call);
|
||||||
|
const state = useConnectionState(call);
|
||||||
|
|
||||||
|
if (state === ConnectionState.Connecting) return _t("Connecting");
|
||||||
|
if (isFull) return _t("Sorry — this call is currently full");
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
export const useLayout = (call: ElementCall): Layout =>
|
export const useLayout = (call: ElementCall): Layout =>
|
||||||
useTypedEventEmitterState(
|
useTypedEventEmitterState(
|
||||||
call,
|
call,
|
||||||
|
|
|
@ -797,10 +797,10 @@
|
||||||
"Don't miss a reply": "Don't miss a reply",
|
"Don't miss a reply": "Don't miss a reply",
|
||||||
"Notifications": "Notifications",
|
"Notifications": "Notifications",
|
||||||
"Enable desktop notifications": "Enable desktop notifications",
|
"Enable desktop notifications": "Enable desktop notifications",
|
||||||
|
"Join": "Join",
|
||||||
"Unknown room": "Unknown room",
|
"Unknown room": "Unknown room",
|
||||||
"Video call started": "Video call started",
|
"Video call started": "Video call started",
|
||||||
"Video": "Video",
|
"Video": "Video",
|
||||||
"Join": "Join",
|
|
||||||
"Close": "Close",
|
"Close": "Close",
|
||||||
"Unknown caller": "Unknown caller",
|
"Unknown caller": "Unknown caller",
|
||||||
"Voice call": "Voice call",
|
"Voice call": "Voice call",
|
||||||
|
@ -1014,6 +1014,8 @@
|
||||||
"When rooms are upgraded": "When rooms are upgraded",
|
"When rooms are upgraded": "When rooms are upgraded",
|
||||||
"My Ban List": "My Ban List",
|
"My Ban List": "My Ban List",
|
||||||
"This is your list of users/servers you have blocked - don't leave the room!": "This is your list of users/servers you have blocked - don't leave the room!",
|
"This is your list of users/servers you have blocked - don't leave the room!": "This is your list of users/servers you have blocked - don't leave the room!",
|
||||||
|
"Connecting": "Connecting",
|
||||||
|
"Sorry — this call is currently full": "Sorry — this call is currently full",
|
||||||
"Create account": "Create account",
|
"Create account": "Create account",
|
||||||
"You made it!": "You made it!",
|
"You made it!": "You made it!",
|
||||||
"Find and invite your friends": "Find and invite your friends",
|
"Find and invite your friends": "Find and invite your friends",
|
||||||
|
@ -1070,7 +1072,6 @@
|
||||||
"You held the call <a>Switch</a>": "You held the call <a>Switch</a>",
|
"You held the call <a>Switch</a>": "You held the call <a>Switch</a>",
|
||||||
"You held the call <a>Resume</a>": "You held the call <a>Resume</a>",
|
"You held the call <a>Resume</a>": "You held the call <a>Resume</a>",
|
||||||
"%(peerName)s held the call": "%(peerName)s held the call",
|
"%(peerName)s held the call": "%(peerName)s held the call",
|
||||||
"Connecting": "Connecting",
|
|
||||||
"Dialpad": "Dialpad",
|
"Dialpad": "Dialpad",
|
||||||
"Mute the microphone": "Mute the microphone",
|
"Mute the microphone": "Mute the microphone",
|
||||||
"Unmute the microphone": "Unmute the microphone",
|
"Unmute the microphone": "Unmute the microphone",
|
||||||
|
|
|
@ -19,7 +19,6 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
|
||||||
import { _t } from '../languageHandler';
|
import { _t } from '../languageHandler';
|
||||||
import RoomAvatar from '../components/views/avatars/RoomAvatar';
|
import RoomAvatar from '../components/views/avatars/RoomAvatar';
|
||||||
import AccessibleButton from '../components/views/elements/AccessibleButton';
|
|
||||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||||
import defaultDispatcher from "../dispatcher/dispatcher";
|
import defaultDispatcher from "../dispatcher/dispatcher";
|
||||||
import { ViewRoomPayload } from "../dispatcher/payloads/ViewRoomPayload";
|
import { ViewRoomPayload } from "../dispatcher/payloads/ViewRoomPayload";
|
||||||
|
@ -31,14 +30,34 @@ import {
|
||||||
LiveContentSummaryWithCall,
|
LiveContentSummaryWithCall,
|
||||||
LiveContentType,
|
LiveContentType,
|
||||||
} from "../components/views/rooms/LiveContentSummary";
|
} from "../components/views/rooms/LiveContentSummary";
|
||||||
import { useCall } from "../hooks/useCall";
|
import { useCall, useJoinCallButtonDisabledTooltip } from "../hooks/useCall";
|
||||||
import { useRoomState } from "../hooks/useRoomState";
|
import { useRoomState } from "../hooks/useRoomState";
|
||||||
import { ButtonEvent } from "../components/views/elements/AccessibleButton";
|
import { ButtonEvent } from "../components/views/elements/AccessibleButton";
|
||||||
import { useDispatcher } from "../hooks/useDispatcher";
|
import { useDispatcher } from "../hooks/useDispatcher";
|
||||||
import { ActionPayload } from "../dispatcher/payloads";
|
import { ActionPayload } from "../dispatcher/payloads";
|
||||||
|
import { Call } from "../models/Call";
|
||||||
|
|
||||||
export const getIncomingCallToastKey = (stateKey: string) => `call_${stateKey}`;
|
export const getIncomingCallToastKey = (stateKey: string) => `call_${stateKey}`;
|
||||||
|
|
||||||
|
interface JoinCallButtonWithCallProps {
|
||||||
|
onClick: (e: ButtonEvent) => void;
|
||||||
|
call: Call;
|
||||||
|
}
|
||||||
|
|
||||||
|
function JoinCallButtonWithCall({ onClick, call }: JoinCallButtonWithCallProps) {
|
||||||
|
const tooltip = useJoinCallButtonDisabledTooltip(call);
|
||||||
|
|
||||||
|
return <AccessibleTooltipButton
|
||||||
|
className="mx_IncomingCallToast_joinButton"
|
||||||
|
onClick={onClick}
|
||||||
|
disabled={Boolean(tooltip)}
|
||||||
|
tooltip={tooltip}
|
||||||
|
kind="primary"
|
||||||
|
>
|
||||||
|
{ _t("Join") }
|
||||||
|
</AccessibleTooltipButton>;
|
||||||
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
callEvent: MatrixEvent;
|
callEvent: MatrixEvent;
|
||||||
}
|
}
|
||||||
|
@ -114,13 +133,16 @@ export function IncomingCallToast({ callEvent }: Props) {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<AccessibleButton
|
{ call
|
||||||
className="mx_IncomingCallToast_joinButton"
|
? <JoinCallButtonWithCall onClick={onJoinClick} call={call} />
|
||||||
onClick={onJoinClick}
|
: <AccessibleTooltipButton
|
||||||
kind="primary"
|
className="mx_IncomingCallToast_joinButton"
|
||||||
>
|
onClick={onJoinClick}
|
||||||
{ _t("Join") }
|
kind="primary"
|
||||||
</AccessibleButton>
|
>
|
||||||
|
{ _t("Join") }
|
||||||
|
</AccessibleTooltipButton>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
className="mx_IncomingCallToast_closeButton"
|
className="mx_IncomingCallToast_closeButton"
|
||||||
|
|
|
@ -22,6 +22,7 @@ import { MatrixClient, PendingEventOrdering } from "matrix-js-sdk/src/client";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
|
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
|
||||||
import { Widget } from "matrix-widget-api";
|
import { Widget } from "matrix-widget-api";
|
||||||
|
import "@testing-library/jest-dom";
|
||||||
|
|
||||||
import type { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
import type { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
import type { ClientWidgetApi } from "matrix-widget-api";
|
import type { ClientWidgetApi } from "matrix-widget-api";
|
||||||
|
@ -38,6 +39,7 @@ import { CallView as _CallView } from "../../../../src/components/views/voip/Cal
|
||||||
import { WidgetMessagingStore } from "../../../../src/stores/widgets/WidgetMessagingStore";
|
import { WidgetMessagingStore } from "../../../../src/stores/widgets/WidgetMessagingStore";
|
||||||
import { CallStore } from "../../../../src/stores/CallStore";
|
import { CallStore } from "../../../../src/stores/CallStore";
|
||||||
import { Call, ConnectionState } from "../../../../src/models/Call";
|
import { Call, ConnectionState } from "../../../../src/models/Call";
|
||||||
|
import SdkConfig from "../../../../src/SdkConfig";
|
||||||
|
|
||||||
const CallView = wrapInMatrixClientContext(_CallView);
|
const CallView = wrapInMatrixClientContext(_CallView);
|
||||||
|
|
||||||
|
@ -163,6 +165,23 @@ describe("CallLobby", () => {
|
||||||
fireEvent.click(screen.getByRole("button", { name: "Join" }));
|
fireEvent.click(screen.getByRole("button", { name: "Join" }));
|
||||||
await waitFor(() => expect(connectSpy).toHaveBeenCalled(), { interval: 1 });
|
await waitFor(() => expect(connectSpy).toHaveBeenCalled(), { interval: 1 });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("disables join button when the participant limit has been exceeded", async () => {
|
||||||
|
const bob = mkRoomMember(room.roomId, "@bob:example.org");
|
||||||
|
const carol = mkRoomMember(room.roomId, "@carol:example.org");
|
||||||
|
|
||||||
|
SdkConfig.put({
|
||||||
|
"element_call": { participant_limit: 2, url: "", use_exclusively: false, brand: "Element Call" },
|
||||||
|
});
|
||||||
|
call.participants = new Set([bob, carol]);
|
||||||
|
|
||||||
|
await renderView();
|
||||||
|
const connectSpy = jest.spyOn(call, "connect");
|
||||||
|
const joinButton = screen.getByRole("button", { name: "Join" });
|
||||||
|
expect(joinButton).toHaveAttribute("aria-disabled", "true");
|
||||||
|
fireEvent.click(joinButton);
|
||||||
|
await waitFor(() => expect(connectSpy).not.toHaveBeenCalled(), { interval: 1 });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("without an existing call", () => {
|
describe("without an existing call", () => {
|
||||||
|
|
Loading…
Reference in a new issue