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
|
@ -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>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue