Allow joining calls and video rooms without enabling the labs flags (#95)
Since Element Call has now reached production on Element X, Element Web needs to be able to at least participate in group calls. Starting a group call or creating a video room will still require the labs flags, for now. Note that Jitsi-based video rooms are also affected by this change. This is not because we intend to delabs them (rather, we intend to get rid of them in favor of Element Call video rooms), but because it's easiest to handle both video room variants consistently.
This commit is contained in:
parent
4f391645e7
commit
bd793a0970
16 changed files with 74 additions and 193 deletions
|
@ -513,12 +513,7 @@ class NotifierClass extends TypedEventEmitter<keyof EmittedEvents, EmittedEvents
|
|||
const thisUserHasConnectedDevice =
|
||||
room && MatrixRTCSession.callMembershipsForRoom(room).some((m) => m.sender === cli.getUserId());
|
||||
|
||||
if (
|
||||
EventType.CallNotify === ev.getType() &&
|
||||
SettingsStore.getValue("feature_group_calls") &&
|
||||
(ev.getAge() ?? 0) < 10000 &&
|
||||
!thisUserHasConnectedDevice
|
||||
) {
|
||||
if (EventType.CallNotify === ev.getType() && (ev.getAge() ?? 0) < 10000 && !thisUserHasConnectedDevice) {
|
||||
const content = ev.getContent();
|
||||
const roomId = ev.getRoomId();
|
||||
if (typeof content.call_id !== "string") {
|
||||
|
|
|
@ -614,10 +614,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
};
|
||||
|
||||
private getMainSplitContentType = (room: Room): MainSplitContentType => {
|
||||
if (
|
||||
(SettingsStore.getValue("feature_group_calls") && this.context.roomViewStore.isViewingCall()) ||
|
||||
isVideoRoom(room)
|
||||
) {
|
||||
if (this.context.roomViewStore.isViewingCall() || isVideoRoom(room)) {
|
||||
return MainSplitContentType.Call;
|
||||
}
|
||||
if (this.context.widgetLayoutStore.hasMaximisedWidget(room)) {
|
||||
|
@ -2183,10 +2180,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
|||
}
|
||||
|
||||
const myMembership = this.state.room.getMyMembership();
|
||||
if (
|
||||
isVideoRoom(this.state.room) &&
|
||||
!(SettingsStore.getValue("feature_video_rooms") && myMembership === KnownMembership.Join)
|
||||
) {
|
||||
if (isVideoRoom(this.state.room) && myMembership !== KnownMembership.Join) {
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<div className="mx_MainSplit">
|
||||
|
|
|
@ -42,7 +42,7 @@ import { shouldShowComponent } from "../../../customisations/helpers/UIComponent
|
|||
import { UIComponent } from "../../../settings/UIFeature";
|
||||
import { DeveloperToolsOption } from "./DeveloperToolsOption";
|
||||
import { tagRoom } from "../../../utils/room/tagRoom";
|
||||
import { useIsVideoRoom } from "../../../utils/video-rooms";
|
||||
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
|
||||
import { usePinnedEvents } from "../../../hooks/usePinnedEvents";
|
||||
|
||||
interface IProps extends IContextMenuProps {
|
||||
|
@ -105,7 +105,7 @@ const RoomContextMenu: React.FC<IProps> = ({ room, onFinished, ...props }) => {
|
|||
}
|
||||
|
||||
const isDm = DMRoomMap.shared().getUserIdForRoomId(room.roomId);
|
||||
const isVideoRoom = useIsVideoRoom(room);
|
||||
const isVideoRoom = calcIsVideoRoom(room);
|
||||
const canInvite = useEventEmitterState(cli, RoomMemberEvent.PowerLevel, () => room.canInvite(cli.getUserId()!));
|
||||
let inviteOption: JSX.Element | undefined;
|
||||
if (canInvite && !isDm && shouldShowComponent(UIComponent.InviteUsers)) {
|
||||
|
|
|
@ -20,7 +20,7 @@ import { Action } from "../../../dispatcher/actions";
|
|||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { UIComponent, UIFeature } from "../../../settings/UIFeature";
|
||||
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
|
||||
import { useIsVideoRoom } from "../../../utils/video-rooms";
|
||||
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
|
||||
|
||||
function shouldShowTabsForPhase(phase?: RightPanelPhases): boolean {
|
||||
const tabs = [
|
||||
|
@ -48,7 +48,7 @@ export const RightPanelTabs: React.FC<Props> = ({ phase, room }): JSX.Element |
|
|||
}
|
||||
});
|
||||
|
||||
const isVideoRoom = useIsVideoRoom(room);
|
||||
const isVideoRoom = room !== undefined && calcIsVideoRoom(room);
|
||||
|
||||
if (!shouldShowTabsForPhase(phase)) return null;
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ import { useDispatcher } from "../../../hooks/useDispatcher";
|
|||
import { Action } from "../../../dispatcher/actions";
|
||||
import { Key } from "../../../Keyboard";
|
||||
import { useTransition } from "../../../hooks/useTransition";
|
||||
import { useIsVideoRoom } from "../../../utils/video-rooms";
|
||||
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
|
||||
import { usePinnedEvents } from "../../../hooks/usePinnedEvents";
|
||||
import { ReleaseAnnouncement } from "../../structures/ReleaseAnnouncement.tsx";
|
||||
|
||||
|
@ -219,7 +219,7 @@ const RoomSummaryCard: React.FC<IProps> = ({
|
|||
const isRoomEncrypted = useIsEncrypted(cli, room);
|
||||
const roomContext = useContext(RoomContext);
|
||||
const e2eStatus = roomContext.e2eStatus;
|
||||
const isVideoRoom = useIsVideoRoom(room);
|
||||
const isVideoRoom = calcIsVideoRoom(room);
|
||||
|
||||
const roomState = useRoomState(room);
|
||||
const directRoomsList = useAccountData<Record<string, string[]>>(room.client, EventType.Direct);
|
||||
|
|
|
@ -251,8 +251,7 @@ const CallButtons: FC<CallButtonsProps> = ({ room }) => {
|
|||
const [busy, setBusy] = useState(false);
|
||||
const showButtons = useSettingValue<boolean>("showCallButtonsInComposer");
|
||||
const groupCallsEnabled = useFeatureEnabled("feature_group_calls");
|
||||
const videoRoomsEnabled = useFeatureEnabled("feature_video_rooms");
|
||||
const isVideoRoom = useMemo(() => videoRoomsEnabled && calcIsVideoRoom(room), [videoRoomsEnabled, room]);
|
||||
const isVideoRoom = useMemo(() => calcIsVideoRoom(room), [room]);
|
||||
const useElementCallExclusively = useMemo(() => {
|
||||
return SdkConfig.get("element_call").use_exclusively;
|
||||
}, []);
|
||||
|
@ -290,53 +289,13 @@ const CallButtons: FC<CallButtonsProps> = ({ room }) => {
|
|||
|
||||
if (isVideoRoom || !showButtons) {
|
||||
return null;
|
||||
} else if (groupCallsEnabled) {
|
||||
if (useElementCallExclusively) {
|
||||
if (hasGroupCall) {
|
||||
return makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_ongoing_call")));
|
||||
} else if (mayCreateElementCalls) {
|
||||
return makeVideoCallButton("element");
|
||||
} else {
|
||||
return makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_no_perms_start_video_call")));
|
||||
}
|
||||
} else if (hasLegacyCall || hasJitsiWidget) {
|
||||
return (
|
||||
<>
|
||||
{makeVoiceCallButton(new DisabledWithReason(_t("voip|disabled_ongoing_call")))}
|
||||
{makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_ongoing_call")))}
|
||||
</>
|
||||
);
|
||||
} else if (functionalMembers.length <= 1) {
|
||||
return (
|
||||
<>
|
||||
{makeVoiceCallButton(new DisabledWithReason(_t("voip|disabled_no_one_here")))}
|
||||
{makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_no_one_here")))}
|
||||
</>
|
||||
);
|
||||
} else if (functionalMembers.length === 2) {
|
||||
return (
|
||||
<>
|
||||
{makeVoiceCallButton("legacy_or_jitsi")}
|
||||
{makeVideoCallButton("legacy_or_element")}
|
||||
</>
|
||||
);
|
||||
} else if (mayEditWidgets) {
|
||||
return (
|
||||
<>
|
||||
{makeVoiceCallButton("legacy_or_jitsi")}
|
||||
{makeVideoCallButton(mayCreateElementCalls ? "jitsi_or_element" : "legacy_or_jitsi")}
|
||||
</>
|
||||
);
|
||||
} else if (groupCallsEnabled && useElementCallExclusively) {
|
||||
if (hasGroupCall) {
|
||||
return makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_ongoing_call")));
|
||||
} else if (mayCreateElementCalls) {
|
||||
return makeVideoCallButton("element");
|
||||
} else {
|
||||
const videoCallBehavior = mayCreateElementCalls
|
||||
? "element"
|
||||
: new DisabledWithReason(_t("voip|disabled_no_perms_start_video_call"));
|
||||
return (
|
||||
<>
|
||||
{makeVoiceCallButton(new DisabledWithReason(_t("voip|disabled_no_perms_start_voice_call")))}
|
||||
{makeVideoCallButton(videoCallBehavior)}
|
||||
</>
|
||||
);
|
||||
return makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_no_perms_start_video_call")));
|
||||
}
|
||||
} else if (hasLegacyCall || hasJitsiWidget) {
|
||||
return (
|
||||
|
@ -352,18 +311,31 @@ const CallButtons: FC<CallButtonsProps> = ({ room }) => {
|
|||
{makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_no_one_here")))}
|
||||
</>
|
||||
);
|
||||
} else if (functionalMembers.length === 2 || mayEditWidgets) {
|
||||
} else if (functionalMembers.length === 2) {
|
||||
return (
|
||||
<>
|
||||
{makeVoiceCallButton("legacy_or_jitsi")}
|
||||
{makeVideoCallButton("legacy_or_jitsi")}
|
||||
{makeVideoCallButton(groupCallsEnabled ? "legacy_or_element" : "legacy_or_jitsi")}
|
||||
</>
|
||||
);
|
||||
} else if (mayEditWidgets) {
|
||||
return (
|
||||
<>
|
||||
{makeVoiceCallButton("legacy_or_jitsi")}
|
||||
{makeVideoCallButton(
|
||||
groupCallsEnabled && mayCreateElementCalls ? "jitsi_or_element" : "legacy_or_jitsi",
|
||||
)}
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
const videoCallBehavior =
|
||||
groupCallsEnabled && mayCreateElementCalls
|
||||
? "element"
|
||||
: new DisabledWithReason(_t("voip|disabled_no_perms_start_video_call"));
|
||||
return (
|
||||
<>
|
||||
{makeVoiceCallButton(new DisabledWithReason(_t("voip|disabled_no_perms_start_voice_call")))}
|
||||
{makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_no_perms_start_video_call")))}
|
||||
{makeVideoCallButton(videoCallBehavior)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -745,7 +717,7 @@ export default class RoomHeader extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
public render(): React.ReactNode {
|
||||
const isVideoRoom = SettingsStore.getValue("feature_video_rooms") && calcIsVideoRoom(this.props.room);
|
||||
const isVideoRoom = calcIsVideoRoom(this.props.room);
|
||||
|
||||
let roomAvatar: JSX.Element | null = null;
|
||||
if (this.props.room) {
|
||||
|
|
|
@ -42,7 +42,7 @@ import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
|
|||
import PosthogTrackers from "../../../PosthogTrackers";
|
||||
import { VideoRoomChatButton } from "./RoomHeader/VideoRoomChatButton";
|
||||
import { RoomKnocksBar } from "./RoomKnocksBar";
|
||||
import { useIsVideoRoom } from "../../../utils/video-rooms";
|
||||
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
|
||||
import { notificationLevelToIndicator } from "../../../utils/notifications";
|
||||
import { CallGuestLinkButton } from "./RoomHeader/CallGuestLinkButton";
|
||||
import { ButtonEvent } from "../elements/AccessibleButton";
|
||||
|
@ -225,7 +225,7 @@ export default function RoomHeader({
|
|||
}
|
||||
|
||||
const roomContext = useContext(RoomContext);
|
||||
const isVideoRoom = useIsVideoRoom(room);
|
||||
const isVideoRoom = calcIsVideoRoom(room);
|
||||
const showChatButton =
|
||||
isVideoRoom ||
|
||||
roomContext.mainSplitContentType === MainSplitContentType.MaximisedWidget ||
|
||||
|
|
|
@ -17,7 +17,7 @@ import { useAsyncMemo } from "../../../hooks/useAsyncMemo";
|
|||
import { useRoomState } from "../../../hooks/useRoomState";
|
||||
import { useRoomMemberCount, useMyRoomMembership } from "../../../hooks/useRoomMembers";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import { useIsVideoRoom } from "../../../utils/video-rooms";
|
||||
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
|
||||
|
||||
interface IProps {
|
||||
room: Room;
|
||||
|
@ -37,7 +37,7 @@ const RoomInfoLine: FC<IProps> = ({ room }) => {
|
|||
const membership = useMyRoomMembership(room);
|
||||
const memberCount = useRoomMemberCount(room);
|
||||
|
||||
const isVideoRoom = useIsVideoRoom(room, true);
|
||||
const isVideoRoom = calcIsVideoRoom(room);
|
||||
|
||||
let iconClass: string;
|
||||
let roomType: string;
|
||||
|
|
|
@ -17,7 +17,6 @@ import { UserTab } from "../dialogs/UserTab";
|
|||
import { EffectiveMembership, getEffectiveMembership } from "../../../utils/membership";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import { useDispatcher } from "../../../hooks/useDispatcher";
|
||||
import { useFeatureEnabled } from "../../../hooks/useSettings";
|
||||
import { useRoomState } from "../../../hooks/useRoomState";
|
||||
import { useMyRoomMembership } from "../../../hooks/useRoomMembers";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
|
@ -29,7 +28,7 @@ import RoomAvatar from "../avatars/RoomAvatar";
|
|||
import MemberAvatar from "../avatars/MemberAvatar";
|
||||
import { BetaPill } from "../beta/BetaCard";
|
||||
import RoomInfoLine from "./RoomInfoLine";
|
||||
import { useIsVideoRoom } from "../../../utils/video-rooms";
|
||||
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
|
||||
|
||||
interface IProps {
|
||||
room: Room;
|
||||
|
@ -43,8 +42,7 @@ interface IProps {
|
|||
// and viewing invite reasons to achieve parity with the default invite screen.
|
||||
const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButtonClicked }) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const videoRoomsEnabled = useFeatureEnabled("feature_video_rooms");
|
||||
const isVideoRoom = useIsVideoRoom(room, true);
|
||||
const isVideoRoom = calcIsVideoRoom(room);
|
||||
const myMembership = useMyRoomMembership(room);
|
||||
useDispatcher(defaultDispatcher, (payload) => {
|
||||
if (payload.action === Action.JoinRoomError && payload.roomId === room.roomId) {
|
||||
|
@ -164,24 +162,6 @@ const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButton
|
|||
avatarRow = <RoomAvatar room={room} size="50px" viewAvatarOnClick />;
|
||||
}
|
||||
|
||||
let notice: string | null = null;
|
||||
if (cannotJoin) {
|
||||
notice = _t("room|join_failed_needs_invite", {
|
||||
roomName: room.name,
|
||||
});
|
||||
} else if (isVideoRoom && !videoRoomsEnabled) {
|
||||
notice =
|
||||
myMembership === KnownMembership.Join
|
||||
? _t("room|view_failed_enable_video_rooms")
|
||||
: _t("room|join_failed_enable_video_rooms");
|
||||
|
||||
joinButtons = (
|
||||
<AccessibleButton kind="primary" onClick={viewLabs}>
|
||||
{_t("room|show_labs_settings")}
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_RoomPreviewCard">
|
||||
{inviterSection}
|
||||
|
@ -192,7 +172,11 @@ const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButton
|
|||
<RoomInfoLine room={room} />
|
||||
<RoomTopic room={room} className="mx_RoomPreviewCard_topic" />
|
||||
{room.getJoinRule() === "public" && <RoomFacePile room={room} />}
|
||||
{notice ? <div className="mx_RoomPreviewCard_notice">{notice}</div> : null}
|
||||
{cannotJoin ? (
|
||||
<div className="mx_RoomPreviewCard_notice">
|
||||
{_t("room|join_failed_needs_invite", { roomName: room.name })}
|
||||
</div>
|
||||
) : null}
|
||||
<div className="mx_RoomPreviewCard_joinButtons">{joinButtons}</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -133,10 +133,10 @@ export const useRoomCall = (
|
|||
if (useElementCallExclusively && !hasJitsiWidget) {
|
||||
return [PlatformCallType.ElementCall];
|
||||
}
|
||||
if (hasGroupCall && WidgetType.CALL.matches(groupCall.widget.type)) {
|
||||
// only allow joining the ongoing Element call if there is one.
|
||||
return [PlatformCallType.ElementCall];
|
||||
}
|
||||
}
|
||||
if (hasGroupCall && WidgetType.CALL.matches(groupCall.widget.type)) {
|
||||
// only allow joining the ongoing Element call if there is one.
|
||||
return [PlatformCallType.ElementCall];
|
||||
}
|
||||
return options;
|
||||
}, [
|
||||
|
|
|
@ -2019,7 +2019,6 @@
|
|||
"inviter_unknown": "Unknown",
|
||||
"invites_you_text": "<inviter/> invites you",
|
||||
"join_button_account": "Sign Up",
|
||||
"join_failed_enable_video_rooms": "To join, please enable video rooms in Labs first",
|
||||
"join_failed_needs_invite": "To view %(roomName)s, you need an invite",
|
||||
"join_the_discussion": "Join the discussion",
|
||||
"join_title": "Join the room to participate",
|
||||
|
@ -2088,7 +2087,6 @@
|
|||
},
|
||||
"this_room_button": "Search this room"
|
||||
},
|
||||
"show_labs_settings": "Show Labs settings",
|
||||
"status_bar": {
|
||||
"delete_all": "Delete all",
|
||||
"exceeded_resource_limit": "Your message wasn't sent because this homeserver has exceeded a resource limit. Please <a>contact your service administrator</a> to continue using the service.",
|
||||
|
@ -2119,7 +2117,6 @@
|
|||
},
|
||||
"uploading_single_file": "Uploading %(filename)s"
|
||||
},
|
||||
"view_failed_enable_video_rooms": "To view, please enable video rooms in Labs first",
|
||||
"waiting_for_join_subtitle": "Once invited users have joined %(brand)s, you will be able to chat and the room will be end-to-end encrypted",
|
||||
"waiting_for_join_title": "Waiting for users to join %(brand)s"
|
||||
},
|
||||
|
|
|
@ -338,7 +338,7 @@ export class JitsiCall extends Call {
|
|||
|
||||
public static get(room: Room): JitsiCall | null {
|
||||
// Only supported in video rooms
|
||||
if (SettingsStore.getValue("feature_video_rooms") && room.isElementVideoRoom()) {
|
||||
if (room.isElementVideoRoom()) {
|
||||
const apps = WidgetStore.instance.getApps(room.roomId);
|
||||
// The isVideoChannel field differentiates rich Jitsi calls from bare Jitsi widgets
|
||||
const jitsiWidget = apps.find((app) => WidgetType.JITSI.matches(app.type) && app.data?.isVideoChannel);
|
||||
|
@ -805,33 +805,24 @@ export class ElementCall extends Call {
|
|||
}
|
||||
|
||||
public static get(room: Room): ElementCall | null {
|
||||
// Only supported in the new group call experience or in video rooms.
|
||||
const apps = WidgetStore.instance.getApps(room.roomId);
|
||||
const hasEcWidget = apps.some((app) => WidgetType.CALL.matches(app.type));
|
||||
const session = room.client.matrixRTC.getRoomSession(room);
|
||||
|
||||
if (
|
||||
SettingsStore.getValue("feature_group_calls") ||
|
||||
(SettingsStore.getValue("feature_video_rooms") &&
|
||||
SettingsStore.getValue("feature_element_call_video_rooms") &&
|
||||
room.isCallRoom())
|
||||
) {
|
||||
const apps = WidgetStore.instance.getApps(room.roomId);
|
||||
const hasEcWidget = apps.some((app) => WidgetType.CALL.matches(app.type));
|
||||
const session = room.client.matrixRTC.getRoomSession(room);
|
||||
|
||||
// A call is present if we
|
||||
// - have a widget: This means the create function was called.
|
||||
// - or there is a running session where we have not yet created a widget for.
|
||||
// - or this is a call room. Then we also always want to show a call.
|
||||
if (hasEcWidget || session.memberships.length !== 0 || room.isCallRoom()) {
|
||||
// create a widget for the case we are joining a running call and don't have on yet.
|
||||
const availableOrCreatedWidget = ElementCall.createOrGetCallWidget(
|
||||
room.roomId,
|
||||
room.client,
|
||||
undefined,
|
||||
undefined,
|
||||
isVideoRoom(room),
|
||||
);
|
||||
return new ElementCall(session, availableOrCreatedWidget, room.client);
|
||||
}
|
||||
// A call is present if we
|
||||
// - have a widget: This means the create function was called.
|
||||
// - or there is a running session where we have not yet created a widget for.
|
||||
// - or this is a call room. Then we also always want to show a call.
|
||||
if (hasEcWidget || session.memberships.length !== 0 || room.isCallRoom()) {
|
||||
// create a widget for the case we are joining a running call and don't have on yet.
|
||||
const availableOrCreatedWidget = ElementCall.createOrGetCallWidget(
|
||||
room.roomId,
|
||||
room.client,
|
||||
undefined,
|
||||
undefined,
|
||||
isVideoRoom(room),
|
||||
);
|
||||
return new ElementCall(session, availableOrCreatedWidget, room.client);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -7,27 +7,8 @@ Please see LICENSE files in the repository root for full details.
|
|||
*/
|
||||
|
||||
import type { Room } from "matrix-js-sdk/src/matrix";
|
||||
import SettingsStore from "../settings/SettingsStore";
|
||||
import { useFeatureEnabled } from "../hooks/useSettings";
|
||||
|
||||
function checkIsVideoRoom(room: Room, elementCallVideoRoomsEnabled: boolean): boolean {
|
||||
return room.isElementVideoRoom() || (elementCallVideoRoomsEnabled && room.isCallRoom());
|
||||
}
|
||||
|
||||
export const isVideoRoom = (room: Room): boolean =>
|
||||
checkIsVideoRoom(room, SettingsStore.getValue("feature_element_call_video_rooms"));
|
||||
|
||||
/**
|
||||
* Returns whether the given room is a video room based on the current feature flags.
|
||||
* @param room The room to check.
|
||||
* @param skipVideoRoomsEnabledCheck If true, the check for the video rooms feature flag is skipped,
|
||||
* useful for suggesting to the user to enable the labs flag.
|
||||
* Determines whether the given room is a video room.
|
||||
*/
|
||||
export const useIsVideoRoom = (room?: Room, skipVideoRoomsEnabledCheck = false): boolean => {
|
||||
const videoRoomsEnabled = useFeatureEnabled("feature_video_rooms");
|
||||
const elementCallVideoRoomsEnabled = useFeatureEnabled("feature_element_call_video_rooms"); // react to updates as isVideoRoom reads the value itself
|
||||
|
||||
if (!room) return false;
|
||||
if (!videoRoomsEnabled && !skipVideoRoomsEnabledCheck) return false;
|
||||
return checkIsVideoRoom(room, elementCallVideoRoomsEnabled);
|
||||
};
|
||||
export const isVideoRoom = (room: Room): boolean => room.isElementVideoRoom() || room.isCallRoom();
|
||||
|
|
|
@ -423,15 +423,7 @@ describe("Notifier", () => {
|
|||
return callEvent;
|
||||
};
|
||||
|
||||
const setGroupCallsEnabled = (val: boolean) => {
|
||||
jest.spyOn(SettingsStore, "getValue").mockImplementation((name: string) => {
|
||||
if (name === "feature_group_calls") return val;
|
||||
});
|
||||
};
|
||||
|
||||
it("should show toast when group calls are supported", () => {
|
||||
setGroupCallsEnabled(true);
|
||||
|
||||
it("shows group call toast", () => {
|
||||
const notifyEvent = emitCallNotifyEvent();
|
||||
|
||||
expect(ToastStore.sharedInstance().addOrReplaceToast).toHaveBeenCalledWith(
|
||||
|
@ -445,16 +437,7 @@ describe("Notifier", () => {
|
|||
);
|
||||
});
|
||||
|
||||
it("should not show toast when group calls are not supported", () => {
|
||||
setGroupCallsEnabled(false);
|
||||
|
||||
emitCallNotifyEvent();
|
||||
|
||||
expect(ToastStore.sharedInstance().addOrReplaceToast).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should not show toast when group call is already connected", () => {
|
||||
setGroupCallsEnabled(true);
|
||||
const spyCallMemberships = jest.spyOn(MatrixRTCSession, "callMembershipsForRoom").mockReturnValue([
|
||||
new CallMembership(
|
||||
mkEvent({
|
||||
|
@ -483,8 +466,6 @@ describe("Notifier", () => {
|
|||
});
|
||||
|
||||
it("should not show toast when calling with non-group call event", () => {
|
||||
setGroupCallsEnabled(true);
|
||||
|
||||
emitCallNotifyEvent("event_type");
|
||||
|
||||
expect(ToastStore.sharedInstance().addOrReplaceToast).not.toHaveBeenCalled();
|
||||
|
|
|
@ -1039,10 +1039,13 @@ describe("<MatrixChat />", () => {
|
|||
});
|
||||
|
||||
describe("when encryption is force disabled", () => {
|
||||
const unencryptedRoom = new Room("!unencrypted:server.org", loginClient, userId);
|
||||
const encryptedRoom = new Room("!encrypted:server.org", loginClient, userId);
|
||||
let unencryptedRoom: Room;
|
||||
let encryptedRoom: Room;
|
||||
|
||||
beforeEach(() => {
|
||||
unencryptedRoom = new Room("!unencrypted:server.org", loginClient, userId);
|
||||
encryptedRoom = new Room("!encrypted:server.org", loginClient, userId);
|
||||
|
||||
loginClient.getClientWellKnown.mockReturnValue({
|
||||
"io.element.e2ee": {
|
||||
force_disable: true,
|
||||
|
|
|
@ -83,21 +83,4 @@ describe("RoomPreviewCard", () => {
|
|||
await renderPreview();
|
||||
expect(screen.queryByRole("button", { name: /beta/i })).toBeNull();
|
||||
});
|
||||
|
||||
it("shows instructions on Jitsi video rooms invites if video rooms are disabled", async () => {
|
||||
jest.spyOn(room, "getType").mockReturnValue(RoomType.ElementVideo);
|
||||
jest.spyOn(room, "getMyMembership").mockReturnValue(KnownMembership.Invite);
|
||||
|
||||
await renderPreview();
|
||||
screen.getByText(/enable video rooms in labs/i);
|
||||
});
|
||||
|
||||
it("shows instructions on Element video rooms invites if video rooms are disabled", async () => {
|
||||
jest.spyOn(room, "getType").mockReturnValue(RoomType.UnstableCall);
|
||||
jest.spyOn(room, "getMyMembership").mockReturnValue(KnownMembership.Invite);
|
||||
enabledFeatures = ["feature_element_call_video_rooms"];
|
||||
|
||||
await renderPreview();
|
||||
screen.getByText(/enable video rooms in labs/i);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue