Skip to content
This repository was archived by the owner on Oct 22, 2024. It is now read-only.

Commit bd793a0

Browse files
authored
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.
1 parent 4f39164 commit bd793a0

File tree

16 files changed

+75
-194
lines changed

16 files changed

+75
-194
lines changed

src/Notifier.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -513,12 +513,7 @@ class NotifierClass extends TypedEventEmitter<keyof EmittedEvents, EmittedEvents
513513
const thisUserHasConnectedDevice =
514514
room && MatrixRTCSession.callMembershipsForRoom(room).some((m) => m.sender === cli.getUserId());
515515

516-
if (
517-
EventType.CallNotify === ev.getType() &&
518-
SettingsStore.getValue("feature_group_calls") &&
519-
(ev.getAge() ?? 0) < 10000 &&
520-
!thisUserHasConnectedDevice
521-
) {
516+
if (EventType.CallNotify === ev.getType() && (ev.getAge() ?? 0) < 10000 && !thisUserHasConnectedDevice) {
522517
const content = ev.getContent();
523518
const roomId = ev.getRoomId();
524519
if (typeof content.call_id !== "string") {

src/components/structures/RoomView.tsx

+2-8
Original file line numberDiff line numberDiff line change
@@ -614,10 +614,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
614614
};
615615

616616
private getMainSplitContentType = (room: Room): MainSplitContentType => {
617-
if (
618-
(SettingsStore.getValue("feature_group_calls") && this.context.roomViewStore.isViewingCall()) ||
619-
isVideoRoom(room)
620-
) {
617+
if (this.context.roomViewStore.isViewingCall() || isVideoRoom(room)) {
621618
return MainSplitContentType.Call;
622619
}
623620
if (this.context.widgetLayoutStore.hasMaximisedWidget(room)) {
@@ -2183,10 +2180,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
21832180
}
21842181

21852182
const myMembership = this.state.room.getMyMembership();
2186-
if (
2187-
isVideoRoom(this.state.room) &&
2188-
!(SettingsStore.getValue("feature_video_rooms") && myMembership === KnownMembership.Join)
2189-
) {
2183+
if (isVideoRoom(this.state.room) && myMembership !== KnownMembership.Join) {
21902184
return (
21912185
<ErrorBoundary>
21922186
<div className="mx_MainSplit">

src/components/views/context_menus/RoomContextMenu.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import { shouldShowComponent } from "../../../customisations/helpers/UIComponent
4242
import { UIComponent } from "../../../settings/UIFeature";
4343
import { DeveloperToolsOption } from "./DeveloperToolsOption";
4444
import { tagRoom } from "../../../utils/room/tagRoom";
45-
import { useIsVideoRoom } from "../../../utils/video-rooms";
45+
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
4646
import { usePinnedEvents } from "../../../hooks/usePinnedEvents";
4747

4848
interface IProps extends IContextMenuProps {
@@ -105,7 +105,7 @@ const RoomContextMenu: React.FC<IProps> = ({ room, onFinished, ...props }) => {
105105
}
106106

107107
const isDm = DMRoomMap.shared().getUserIdForRoomId(room.roomId);
108-
const isVideoRoom = useIsVideoRoom(room);
108+
const isVideoRoom = calcIsVideoRoom(room);
109109
const canInvite = useEventEmitterState(cli, RoomMemberEvent.PowerLevel, () => room.canInvite(cli.getUserId()!));
110110
let inviteOption: JSX.Element | undefined;
111111
if (canInvite && !isDm && shouldShowComponent(UIComponent.InviteUsers)) {

src/components/views/right_panel/RightPanelTabs.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { Action } from "../../../dispatcher/actions";
2020
import SettingsStore from "../../../settings/SettingsStore";
2121
import { UIComponent, UIFeature } from "../../../settings/UIFeature";
2222
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
23-
import { useIsVideoRoom } from "../../../utils/video-rooms";
23+
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
2424

2525
function shouldShowTabsForPhase(phase?: RightPanelPhases): boolean {
2626
const tabs = [
@@ -48,7 +48,7 @@ export const RightPanelTabs: React.FC<Props> = ({ phase, room }): JSX.Element |
4848
}
4949
});
5050

51-
const isVideoRoom = useIsVideoRoom(room);
51+
const isVideoRoom = room !== undefined && calcIsVideoRoom(room);
5252

5353
if (!shouldShowTabsForPhase(phase)) return null;
5454

src/components/views/right_panel/RoomSummaryCard.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ import { useDispatcher } from "../../../hooks/useDispatcher";
7070
import { Action } from "../../../dispatcher/actions";
7171
import { Key } from "../../../Keyboard";
7272
import { useTransition } from "../../../hooks/useTransition";
73-
import { useIsVideoRoom } from "../../../utils/video-rooms";
73+
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
7474
import { usePinnedEvents } from "../../../hooks/usePinnedEvents";
7575
import { ReleaseAnnouncement } from "../../structures/ReleaseAnnouncement.tsx";
7676

@@ -219,7 +219,7 @@ const RoomSummaryCard: React.FC<IProps> = ({
219219
const isRoomEncrypted = useIsEncrypted(cli, room);
220220
const roomContext = useContext(RoomContext);
221221
const e2eStatus = roomContext.e2eStatus;
222-
const isVideoRoom = useIsVideoRoom(room);
222+
const isVideoRoom = calcIsVideoRoom(room);
223223

224224
const roomState = useRoomState(room);
225225
const directRoomsList = useAccountData<Record<string, string[]>>(room.client, EventType.Direct);

src/components/views/rooms/LegacyRoomHeader.tsx

+24-52
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,7 @@ const CallButtons: FC<CallButtonsProps> = ({ room }) => {
251251
const [busy, setBusy] = useState(false);
252252
const showButtons = useSettingValue<boolean>("showCallButtonsInComposer");
253253
const groupCallsEnabled = useFeatureEnabled("feature_group_calls");
254-
const videoRoomsEnabled = useFeatureEnabled("feature_video_rooms");
255-
const isVideoRoom = useMemo(() => videoRoomsEnabled && calcIsVideoRoom(room), [videoRoomsEnabled, room]);
254+
const isVideoRoom = useMemo(() => calcIsVideoRoom(room), [room]);
256255
const useElementCallExclusively = useMemo(() => {
257256
return SdkConfig.get("element_call").use_exclusively;
258257
}, []);
@@ -290,53 +289,13 @@ const CallButtons: FC<CallButtonsProps> = ({ room }) => {
290289

291290
if (isVideoRoom || !showButtons) {
292291
return null;
293-
} else if (groupCallsEnabled) {
294-
if (useElementCallExclusively) {
295-
if (hasGroupCall) {
296-
return makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_ongoing_call")));
297-
} else if (mayCreateElementCalls) {
298-
return makeVideoCallButton("element");
299-
} else {
300-
return makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_no_perms_start_video_call")));
301-
}
302-
} else if (hasLegacyCall || hasJitsiWidget) {
303-
return (
304-
<>
305-
{makeVoiceCallButton(new DisabledWithReason(_t("voip|disabled_ongoing_call")))}
306-
{makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_ongoing_call")))}
307-
</>
308-
);
309-
} else if (functionalMembers.length <= 1) {
310-
return (
311-
<>
312-
{makeVoiceCallButton(new DisabledWithReason(_t("voip|disabled_no_one_here")))}
313-
{makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_no_one_here")))}
314-
</>
315-
);
316-
} else if (functionalMembers.length === 2) {
317-
return (
318-
<>
319-
{makeVoiceCallButton("legacy_or_jitsi")}
320-
{makeVideoCallButton("legacy_or_element")}
321-
</>
322-
);
323-
} else if (mayEditWidgets) {
324-
return (
325-
<>
326-
{makeVoiceCallButton("legacy_or_jitsi")}
327-
{makeVideoCallButton(mayCreateElementCalls ? "jitsi_or_element" : "legacy_or_jitsi")}
328-
</>
329-
);
292+
} else if (groupCallsEnabled && useElementCallExclusively) {
293+
if (hasGroupCall) {
294+
return makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_ongoing_call")));
295+
} else if (mayCreateElementCalls) {
296+
return makeVideoCallButton("element");
330297
} else {
331-
const videoCallBehavior = mayCreateElementCalls
332-
? "element"
333-
: new DisabledWithReason(_t("voip|disabled_no_perms_start_video_call"));
334-
return (
335-
<>
336-
{makeVoiceCallButton(new DisabledWithReason(_t("voip|disabled_no_perms_start_voice_call")))}
337-
{makeVideoCallButton(videoCallBehavior)}
338-
</>
339-
);
298+
return makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_no_perms_start_video_call")));
340299
}
341300
} else if (hasLegacyCall || hasJitsiWidget) {
342301
return (
@@ -352,18 +311,31 @@ const CallButtons: FC<CallButtonsProps> = ({ room }) => {
352311
{makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_no_one_here")))}
353312
</>
354313
);
355-
} else if (functionalMembers.length === 2 || mayEditWidgets) {
314+
} else if (functionalMembers.length === 2) {
315+
return (
316+
<>
317+
{makeVoiceCallButton("legacy_or_jitsi")}
318+
{makeVideoCallButton(groupCallsEnabled ? "legacy_or_element" : "legacy_or_jitsi")}
319+
</>
320+
);
321+
} else if (mayEditWidgets) {
356322
return (
357323
<>
358324
{makeVoiceCallButton("legacy_or_jitsi")}
359-
{makeVideoCallButton("legacy_or_jitsi")}
325+
{makeVideoCallButton(
326+
groupCallsEnabled && mayCreateElementCalls ? "jitsi_or_element" : "legacy_or_jitsi",
327+
)}
360328
</>
361329
);
362330
} else {
331+
const videoCallBehavior =
332+
groupCallsEnabled && mayCreateElementCalls
333+
? "element"
334+
: new DisabledWithReason(_t("voip|disabled_no_perms_start_video_call"));
363335
return (
364336
<>
365337
{makeVoiceCallButton(new DisabledWithReason(_t("voip|disabled_no_perms_start_voice_call")))}
366-
{makeVideoCallButton(new DisabledWithReason(_t("voip|disabled_no_perms_start_video_call")))}
338+
{makeVideoCallButton(videoCallBehavior)}
367339
</>
368340
);
369341
}
@@ -745,7 +717,7 @@ export default class RoomHeader extends React.Component<IProps, IState> {
745717
}
746718

747719
public render(): React.ReactNode {
748-
const isVideoRoom = SettingsStore.getValue("feature_video_rooms") && calcIsVideoRoom(this.props.room);
720+
const isVideoRoom = calcIsVideoRoom(this.props.room);
749721

750722
let roomAvatar: JSX.Element | null = null;
751723
if (this.props.room) {

src/components/views/rooms/RoomHeader.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
4242
import PosthogTrackers from "../../../PosthogTrackers";
4343
import { VideoRoomChatButton } from "./RoomHeader/VideoRoomChatButton";
4444
import { RoomKnocksBar } from "./RoomKnocksBar";
45-
import { useIsVideoRoom } from "../../../utils/video-rooms";
45+
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
4646
import { notificationLevelToIndicator } from "../../../utils/notifications";
4747
import { CallGuestLinkButton } from "./RoomHeader/CallGuestLinkButton";
4848
import { ButtonEvent } from "../elements/AccessibleButton";
@@ -225,7 +225,7 @@ export default function RoomHeader({
225225
}
226226

227227
const roomContext = useContext(RoomContext);
228-
const isVideoRoom = useIsVideoRoom(room);
228+
const isVideoRoom = calcIsVideoRoom(room);
229229
const showChatButton =
230230
isVideoRoom ||
231231
roomContext.mainSplitContentType === MainSplitContentType.MaximisedWidget ||

src/components/views/rooms/RoomInfoLine.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { useAsyncMemo } from "../../../hooks/useAsyncMemo";
1717
import { useRoomState } from "../../../hooks/useRoomState";
1818
import { useRoomMemberCount, useMyRoomMembership } from "../../../hooks/useRoomMembers";
1919
import AccessibleButton from "../elements/AccessibleButton";
20-
import { useIsVideoRoom } from "../../../utils/video-rooms";
20+
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
2121

2222
interface IProps {
2323
room: Room;
@@ -37,7 +37,7 @@ const RoomInfoLine: FC<IProps> = ({ room }) => {
3737
const membership = useMyRoomMembership(room);
3838
const memberCount = useRoomMemberCount(room);
3939

40-
const isVideoRoom = useIsVideoRoom(room, true);
40+
const isVideoRoom = calcIsVideoRoom(room);
4141

4242
let iconClass: string;
4343
let roomType: string;

src/components/views/rooms/RoomPreviewCard.tsx

+7-23
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { UserTab } from "../dialogs/UserTab";
1717
import { EffectiveMembership, getEffectiveMembership } from "../../../utils/membership";
1818
import MatrixClientContext from "../../../contexts/MatrixClientContext";
1919
import { useDispatcher } from "../../../hooks/useDispatcher";
20-
import { useFeatureEnabled } from "../../../hooks/useSettings";
2120
import { useRoomState } from "../../../hooks/useRoomState";
2221
import { useMyRoomMembership } from "../../../hooks/useRoomMembers";
2322
import AccessibleButton from "../elements/AccessibleButton";
@@ -29,7 +28,7 @@ import RoomAvatar from "../avatars/RoomAvatar";
2928
import MemberAvatar from "../avatars/MemberAvatar";
3029
import { BetaPill } from "../beta/BetaCard";
3130
import RoomInfoLine from "./RoomInfoLine";
32-
import { useIsVideoRoom } from "../../../utils/video-rooms";
31+
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
3332

3433
interface IProps {
3534
room: Room;
@@ -43,8 +42,7 @@ interface IProps {
4342
// and viewing invite reasons to achieve parity with the default invite screen.
4443
const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButtonClicked }) => {
4544
const cli = useContext(MatrixClientContext);
46-
const videoRoomsEnabled = useFeatureEnabled("feature_video_rooms");
47-
const isVideoRoom = useIsVideoRoom(room, true);
45+
const isVideoRoom = calcIsVideoRoom(room);
4846
const myMembership = useMyRoomMembership(room);
4947
useDispatcher(defaultDispatcher, (payload) => {
5048
if (payload.action === Action.JoinRoomError && payload.roomId === room.roomId) {
@@ -164,24 +162,6 @@ const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButton
164162
avatarRow = <RoomAvatar room={room} size="50px" viewAvatarOnClick />;
165163
}
166164

167-
let notice: string | null = null;
168-
if (cannotJoin) {
169-
notice = _t("room|join_failed_needs_invite", {
170-
roomName: room.name,
171-
});
172-
} else if (isVideoRoom && !videoRoomsEnabled) {
173-
notice =
174-
myMembership === KnownMembership.Join
175-
? _t("room|view_failed_enable_video_rooms")
176-
: _t("room|join_failed_enable_video_rooms");
177-
178-
joinButtons = (
179-
<AccessibleButton kind="primary" onClick={viewLabs}>
180-
{_t("room|show_labs_settings")}
181-
</AccessibleButton>
182-
);
183-
}
184-
185165
return (
186166
<div className="mx_RoomPreviewCard">
187167
{inviterSection}
@@ -192,7 +172,11 @@ const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButton
192172
<RoomInfoLine room={room} />
193173
<RoomTopic room={room} className="mx_RoomPreviewCard_topic" />
194174
{room.getJoinRule() === "public" && <RoomFacePile room={room} />}
195-
{notice ? <div className="mx_RoomPreviewCard_notice">{notice}</div> : null}
175+
{cannotJoin ? (
176+
<div className="mx_RoomPreviewCard_notice">
177+
{_t("room|join_failed_needs_invite", { roomName: room.name })}
178+
</div>
179+
) : null}
196180
<div className="mx_RoomPreviewCard_joinButtons">{joinButtons}</div>
197181
</div>
198182
);

src/hooks/room/useRoomCall.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,10 @@ export const useRoomCall = (
133133
if (useElementCallExclusively && !hasJitsiWidget) {
134134
return [PlatformCallType.ElementCall];
135135
}
136-
if (hasGroupCall && WidgetType.CALL.matches(groupCall.widget.type)) {
137-
// only allow joining the ongoing Element call if there is one.
138-
return [PlatformCallType.ElementCall];
139-
}
136+
}
137+
if (hasGroupCall && WidgetType.CALL.matches(groupCall.widget.type)) {
138+
// only allow joining the ongoing Element call if there is one.
139+
return [PlatformCallType.ElementCall];
140140
}
141141
return options;
142142
}, [

src/i18n/strings/en_EN.json

-3
Original file line numberDiff line numberDiff line change
@@ -2019,7 +2019,6 @@
20192019
"inviter_unknown": "Unknown",
20202020
"invites_you_text": "<inviter/> invites you",
20212021
"join_button_account": "Sign Up",
2022-
"join_failed_enable_video_rooms": "To join, please enable video rooms in Labs first",
20232022
"join_failed_needs_invite": "To view %(roomName)s, you need an invite",
20242023
"join_the_discussion": "Join the discussion",
20252024
"join_title": "Join the room to participate",
@@ -2088,7 +2087,6 @@
20882087
},
20892088
"this_room_button": "Search this room"
20902089
},
2091-
"show_labs_settings": "Show Labs settings",
20922090
"status_bar": {
20932091
"delete_all": "Delete all",
20942092
"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 @@
21192117
},
21202118
"uploading_single_file": "Uploading %(filename)s"
21212119
},
2122-
"view_failed_enable_video_rooms": "To view, please enable video rooms in Labs first",
21232120
"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",
21242121
"waiting_for_join_title": "Waiting for users to join %(brand)s"
21252122
},

0 commit comments

Comments
 (0)