Element Call video rooms (#9267)
* Add an element_call_url config option * Add a labs flag for Element Call video rooms * Add Element Call as another video rooms backend * Consolidate event power level defaults * Remember to clean up participantsExpirationTimer * Fix a code smell * Test the clean method * Fix some strict mode errors * Test that clean still works when there are no state events * Test auto-approval of Element Call widget capabilities * Deduplicate some code to placate SonarCloud * Fix more strict mode errors * Test that calls disconnect when leaving the room * Test the get methods of JitsiCall and ElementCall more * Test Call.ts even more * Test creation of Element video rooms * Test that createRoom works for non-video-rooms * Test Call's get method rather than the methods of derived classes * Ensure that the clean method is able to preserve devices * Remove duplicate clean method * Fix lints * Fix some strict mode errors in RoomPreviewCard * Test RoomPreviewCard changes * Quick and dirty hotfix for the community testing session * Revert "Quick and dirty hotfix for the community testing session" This reverts commit 37056514fbc040aaf1bff2539da770a1c8ba72a2. * Fix the event schema for org.matrix.msc3401.call.member devices * Remove org.matrix.call_duplicate_session from Element Call capabilities It's no longer used by Element Call when running as a widget. * Replace element_call_url with a map * Make PiPs work for virtual widgets * Auto-approve room timeline capability Because Element Call uses this now * Create a reusable isVideoRoom util
This commit is contained in:
parent
db5716b776
commit
cb735c9439
37 changed files with 1699 additions and 1384 deletions
|
@ -105,10 +105,14 @@ const RoomContextMenu = ({ room, onFinished, ...props }: IProps) => {
|
|||
}
|
||||
|
||||
const isDm = DMRoomMap.shared().getUserIdForRoomId(room.roomId);
|
||||
const isVideoRoom = useFeatureEnabled("feature_video_rooms") && room.isElementVideoRoom();
|
||||
const videoRoomsEnabled = useFeatureEnabled("feature_video_rooms");
|
||||
const elementCallVideoRoomsEnabled = useFeatureEnabled("feature_element_call_video_rooms");
|
||||
const isVideoRoom = videoRoomsEnabled && (
|
||||
room.isElementVideoRoom() || (elementCallVideoRoomsEnabled && room.isCallRoom())
|
||||
);
|
||||
|
||||
let inviteOption: JSX.Element;
|
||||
if (room.canInvite(cli.getUserId()) && !isDm) {
|
||||
if (room.canInvite(cli.getUserId()!) && !isDm) {
|
||||
const onInviteClick = (ev: ButtonEvent) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
|
|
@ -35,6 +35,7 @@ import { ButtonEvent } from "../elements/AccessibleButton";
|
|||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||
import { BetaPill } from "../beta/BetaCard";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { useFeatureEnabled } from "../../../hooks/useSettings";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
|
||||
import { UIComponent } from "../../../settings/UIFeature";
|
||||
|
@ -48,9 +49,9 @@ interface IProps extends IContextMenuProps {
|
|||
|
||||
const SpaceContextMenu = ({ space, hideHeader, onFinished, ...props }: IProps) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const userId = cli.getUserId();
|
||||
const userId = cli.getUserId()!;
|
||||
|
||||
let inviteOption;
|
||||
let inviteOption: JSX.Element | null = null;
|
||||
if (space.getJoinRule() === "public" || space.canInvite(userId)) {
|
||||
const onInviteClick = (ev: ButtonEvent) => {
|
||||
ev.preventDefault();
|
||||
|
@ -71,8 +72,8 @@ const SpaceContextMenu = ({ space, hideHeader, onFinished, ...props }: IProps) =
|
|||
);
|
||||
}
|
||||
|
||||
let settingsOption;
|
||||
let leaveOption;
|
||||
let settingsOption: JSX.Element | null = null;
|
||||
let leaveOption: JSX.Element | null = null;
|
||||
if (shouldShowSpaceSettings(space)) {
|
||||
const onSettingsClick = (ev: ButtonEvent) => {
|
||||
ev.preventDefault();
|
||||
|
@ -110,7 +111,7 @@ const SpaceContextMenu = ({ space, hideHeader, onFinished, ...props }: IProps) =
|
|||
);
|
||||
}
|
||||
|
||||
let devtoolsOption;
|
||||
let devtoolsOption: JSX.Element | null = null;
|
||||
if (SettingsStore.getValue("developerMode")) {
|
||||
const onViewTimelineClick = (ev: ButtonEvent) => {
|
||||
ev.preventDefault();
|
||||
|
@ -134,12 +135,15 @@ const SpaceContextMenu = ({ space, hideHeader, onFinished, ...props }: IProps) =
|
|||
);
|
||||
}
|
||||
|
||||
const videoRoomsEnabled = useFeatureEnabled("feature_video_rooms");
|
||||
const elementCallVideoRoomsEnabled = useFeatureEnabled("feature_element_call_video_rooms");
|
||||
|
||||
const hasPermissionToAddSpaceChild = space.currentState.maySendStateEvent(EventType.SpaceChild, userId);
|
||||
const canAddRooms = hasPermissionToAddSpaceChild && shouldShowComponent(UIComponent.CreateRooms);
|
||||
const canAddVideoRooms = canAddRooms && SettingsStore.getValue("feature_video_rooms");
|
||||
const canAddVideoRooms = canAddRooms && videoRoomsEnabled;
|
||||
const canAddSubSpaces = hasPermissionToAddSpaceChild && shouldShowComponent(UIComponent.CreateSpaces);
|
||||
|
||||
let newRoomSection: JSX.Element;
|
||||
let newRoomSection: JSX.Element | null = null;
|
||||
if (canAddRooms || canAddSubSpaces) {
|
||||
const onNewRoomClick = (ev: ButtonEvent) => {
|
||||
ev.preventDefault();
|
||||
|
@ -154,7 +158,7 @@ const SpaceContextMenu = ({ space, hideHeader, onFinished, ...props }: IProps) =
|
|||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
showCreateNewRoom(space, RoomType.ElementVideo);
|
||||
showCreateNewRoom(space, elementCallVideoRoomsEnabled ? RoomType.UnstableCall : RoomType.ElementVideo);
|
||||
onFinished();
|
||||
};
|
||||
|
||||
|
@ -266,4 +270,3 @@ const SpaceContextMenu = ({ space, hideHeader, onFinished, ...props }: IProps) =
|
|||
};
|
||||
|
||||
export default SpaceContextMenu;
|
||||
|
||||
|
|
|
@ -146,10 +146,9 @@ const WidgetContextMenu: React.FC<IProps> = ({
|
|||
/>;
|
||||
}
|
||||
|
||||
let isAllowedWidget = SettingsStore.getValue("allowedWidgets", roomId)[app.eventId];
|
||||
if (isAllowedWidget === undefined) {
|
||||
isAllowedWidget = app.creatorUserId === cli.getUserId();
|
||||
}
|
||||
const isAllowedWidget =
|
||||
(app.eventId !== undefined && (SettingsStore.getValue("allowedWidgets", roomId)[app.eventId] ?? false))
|
||||
|| app.creatorUserId === cli.getUserId();
|
||||
|
||||
const isLocalWidget = WidgetType.JITSI.matches(app.type);
|
||||
let revokeButton;
|
||||
|
@ -157,7 +156,7 @@ const WidgetContextMenu: React.FC<IProps> = ({
|
|||
const onRevokeClick = () => {
|
||||
logger.info("Revoking permission for widget to load: " + app.eventId);
|
||||
const current = SettingsStore.getValue("allowedWidgets", roomId);
|
||||
current[app.eventId] = false;
|
||||
if (app.eventId !== undefined) current[app.eventId] = false;
|
||||
const level = SettingsStore.firstSupportedLevel("allowedWidgets");
|
||||
SettingsStore.setValue("allowedWidgets", roomId, level, current).catch(err => {
|
||||
logger.error(err);
|
||||
|
|
|
@ -78,7 +78,7 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
|
|||
}
|
||||
|
||||
public componentDidMount() {
|
||||
const driver = new StopGapWidgetDriver([], this.widget, WidgetKind.Modal);
|
||||
const driver = new StopGapWidgetDriver([], this.widget, WidgetKind.Modal, false);
|
||||
const messaging = new ClientWidgetApi(this.widget, this.appFrame.current, driver);
|
||||
this.setState({ messaging });
|
||||
}
|
||||
|
|
|
@ -165,10 +165,8 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
if (!props.room) return true; // user widgets always have permissions
|
||||
|
||||
const currentlyAllowedWidgets = SettingsStore.getValue("allowedWidgets", props.room.roomId);
|
||||
if (currentlyAllowedWidgets[props.app.eventId] === undefined) {
|
||||
return props.userId === props.creatorUserId;
|
||||
}
|
||||
return !!currentlyAllowedWidgets[props.app.eventId];
|
||||
const allowed = props.app.eventId !== undefined && (currentlyAllowedWidgets[props.app.eventId] ?? false);
|
||||
return allowed || props.userId === props.creatorUserId;
|
||||
};
|
||||
|
||||
private onUserLeftRoom() {
|
||||
|
@ -442,7 +440,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
const roomId = this.props.room?.roomId;
|
||||
logger.info("Granting permission for widget to load: " + this.props.app.eventId);
|
||||
const current = SettingsStore.getValue("allowedWidgets", roomId);
|
||||
current[this.props.app.eventId] = true;
|
||||
if (this.props.app.eventId !== undefined) current[this.props.app.eventId] = true;
|
||||
const level = SettingsStore.firstSupportedLevel("allowedWidgets");
|
||||
SettingsStore.setValue("allowedWidgets", roomId, level, current).then(() => {
|
||||
this.setState({ hasPermissionToLoad: true });
|
||||
|
|
|
@ -20,7 +20,7 @@ import { Room } from "matrix-js-sdk/src/models/room";
|
|||
|
||||
import WidgetUtils from '../../../utils/WidgetUtils';
|
||||
import AppTile from "./AppTile";
|
||||
import { IApp } from '../../../stores/WidgetStore';
|
||||
import WidgetStore from '../../../stores/WidgetStore';
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
|
||||
interface IProps {
|
||||
|
@ -37,44 +37,27 @@ export default class PersistentApp extends React.Component<IProps> {
|
|||
|
||||
constructor(props: IProps, context: ContextType<typeof MatrixClientContext>) {
|
||||
super(props, context);
|
||||
this.room = context.getRoom(this.props.persistentRoomId);
|
||||
this.room = context.getRoom(this.props.persistentRoomId)!;
|
||||
}
|
||||
|
||||
private get app(): IApp | null {
|
||||
// get the widget data
|
||||
const appEvent = WidgetUtils.getRoomWidgets(this.room).find(ev =>
|
||||
ev.getStateKey() === this.props.persistentWidgetId,
|
||||
);
|
||||
public render(): JSX.Element | null {
|
||||
const app = WidgetStore.instance.get(this.props.persistentWidgetId, this.props.persistentRoomId);
|
||||
if (!app) return null;
|
||||
|
||||
if (appEvent) {
|
||||
return WidgetUtils.makeAppConfig(
|
||||
appEvent.getStateKey(), appEvent.getContent(), appEvent.getSender(),
|
||||
this.room.roomId, appEvent.getId(),
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
const app = this.app;
|
||||
if (app) {
|
||||
return <AppTile
|
||||
key={app.id}
|
||||
app={app}
|
||||
fullWidth={true}
|
||||
room={this.room}
|
||||
userId={this.context.credentials.userId}
|
||||
creatorUserId={app.creatorUserId}
|
||||
widgetPageTitle={WidgetUtils.getWidgetDataTitle(app)}
|
||||
waitForIframeLoad={app.waitForIframeLoad}
|
||||
miniMode={true}
|
||||
showMenubar={false}
|
||||
pointerEvents={this.props.pointerEvents}
|
||||
movePersistedElement={this.props.movePersistedElement}
|
||||
/>;
|
||||
}
|
||||
return null;
|
||||
return <AppTile
|
||||
key={app.id}
|
||||
app={app}
|
||||
fullWidth={true}
|
||||
room={this.room}
|
||||
userId={this.context.credentials.userId}
|
||||
creatorUserId={app.creatorUserId}
|
||||
widgetPageTitle={WidgetUtils.getWidgetDataTitle(app)}
|
||||
waitForIframeLoad={app.waitForIframeLoad}
|
||||
miniMode={true}
|
||||
showMenubar={false}
|
||||
pointerEvents={this.props.pointerEvents}
|
||||
movePersistedElement={this.props.movePersistedElement}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -262,7 +262,11 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, onClose }) => {
|
|||
const isRoomEncrypted = useIsEncrypted(cli, room);
|
||||
const roomContext = useContext(RoomContext);
|
||||
const e2eStatus = roomContext.e2eStatus;
|
||||
const isVideoRoom = useFeatureEnabled("feature_video_rooms") && room.isElementVideoRoom();
|
||||
const videoRoomsEnabled = useFeatureEnabled("feature_video_rooms");
|
||||
const elementCallVideoRoomsEnabled = useFeatureEnabled("feature_element_call_video_rooms");
|
||||
const isVideoRoom = videoRoomsEnabled && (
|
||||
room.isElementVideoRoom() || (elementCallVideoRoomsEnabled && room.isCallRoom())
|
||||
);
|
||||
|
||||
const alias = room.getCanonicalAlias() || room.getAltAliases()[0] || "";
|
||||
const header = <React.Fragment>
|
||||
|
|
|
@ -47,6 +47,7 @@ import RoomLiveShareWarning from '../beacon/RoomLiveShareWarning';
|
|||
import { BetaPill } from "../beta/BetaCard";
|
||||
import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
|
||||
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
|
||||
import { isVideoRoom as calcIsVideoRoom } from "../../../utils/video-rooms";
|
||||
|
||||
export interface ISearchInfo {
|
||||
searchTerm: string;
|
||||
|
@ -312,7 +313,7 @@ export default class RoomHeader extends React.Component<IProps, IState> {
|
|||
|
||||
const e2eIcon = this.props.e2eStatus ? <E2EIcon status={this.props.e2eStatus} /> : undefined;
|
||||
|
||||
const isVideoRoom = SettingsStore.getValue("feature_video_rooms") && this.props.room.isElementVideoRoom();
|
||||
const isVideoRoom = SettingsStore.getValue("feature_video_rooms") && calcIsVideoRoom(this.props.room);
|
||||
const viewLabs = () => defaultDispatcher.dispatch({
|
||||
action: Action.ViewUserSettings,
|
||||
initialTabId: UserTab.Labs,
|
||||
|
|
|
@ -23,6 +23,7 @@ import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
|
|||
import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases";
|
||||
import { useAsyncMemo } from "../../../hooks/useAsyncMemo";
|
||||
import { useRoomState } from "../../../hooks/useRoomState";
|
||||
import { useFeatureEnabled } from "../../../hooks/useSettings";
|
||||
import { useRoomMemberCount, useMyRoomMembership } from "../../../hooks/useRoomMembers";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
|
||||
|
@ -44,9 +45,12 @@ const RoomInfoLine: FC<IProps> = ({ room }) => {
|
|||
const membership = useMyRoomMembership(room);
|
||||
const memberCount = useRoomMemberCount(room);
|
||||
|
||||
const elementCallVideoRoomsEnabled = useFeatureEnabled("feature_element_call_video_rooms");
|
||||
const isVideoRoom = room.isElementVideoRoom() || (elementCallVideoRoomsEnabled && room.isCallRoom());
|
||||
|
||||
let iconClass: string;
|
||||
let roomType: string;
|
||||
if (room.isElementVideoRoom()) {
|
||||
if (isVideoRoom) {
|
||||
iconClass = "mx_RoomInfoLine_video";
|
||||
roomType = _t("Video room");
|
||||
} else if (joinRule === JoinRule.Public) {
|
||||
|
|
|
@ -32,6 +32,7 @@ import { _t, _td } from "../../../languageHandler";
|
|||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import PosthogTrackers from "../../../PosthogTrackers";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { useFeatureEnabled } from "../../../hooks/useSettings";
|
||||
import { UIComponent } from "../../../settings/UIFeature";
|
||||
import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore";
|
||||
import { ITagMap } from "../../../stores/room-list/algorithms/models";
|
||||
|
@ -200,8 +201,10 @@ const UntaggedAuxButton = ({ tabIndex }: IAuxButtonProps) => {
|
|||
});
|
||||
|
||||
const showCreateRoom = shouldShowComponent(UIComponent.CreateRooms);
|
||||
const videoRoomsEnabled = useFeatureEnabled("feature_video_rooms");
|
||||
const elementCallVideoRoomsEnabled = useFeatureEnabled("feature_element_call_video_rooms");
|
||||
|
||||
let contextMenuContent: JSX.Element;
|
||||
let contextMenuContent: JSX.Element | null = null;
|
||||
if (menuDisplayed && activeSpace) {
|
||||
const canAddRooms = activeSpace.currentState.maySendStateEvent(EventType.SpaceChild,
|
||||
MatrixClientPeg.get().getUserId());
|
||||
|
@ -239,7 +242,7 @@ const UntaggedAuxButton = ({ tabIndex }: IAuxButtonProps) => {
|
|||
tooltip={canAddRooms ? undefined
|
||||
: _t("You do not have permissions to create new rooms in this space")}
|
||||
/>
|
||||
{ SettingsStore.getValue("feature_video_rooms") && (
|
||||
{ videoRoomsEnabled && (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("New video room")}
|
||||
iconClassName="mx_RoomList_iconNewVideoRoom"
|
||||
|
@ -247,7 +250,10 @@ const UntaggedAuxButton = ({ tabIndex }: IAuxButtonProps) => {
|
|||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
closeMenu();
|
||||
showCreateNewRoom(activeSpace, RoomType.ElementVideo);
|
||||
showCreateNewRoom(
|
||||
activeSpace,
|
||||
elementCallVideoRoomsEnabled ? RoomType.UnstableCall : RoomType.ElementVideo,
|
||||
);
|
||||
}}
|
||||
disabled={!canAddRooms}
|
||||
tooltip={canAddRooms ? undefined
|
||||
|
@ -287,7 +293,7 @@ const UntaggedAuxButton = ({ tabIndex }: IAuxButtonProps) => {
|
|||
PosthogTrackers.trackInteraction("WebRoomListRoomsSublistPlusMenuCreateRoomItem", e);
|
||||
}}
|
||||
/>
|
||||
{ SettingsStore.getValue("feature_video_rooms") && (
|
||||
{ videoRoomsEnabled && (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("New video room")}
|
||||
iconClassName="mx_RoomList_iconNewVideoRoom"
|
||||
|
@ -297,7 +303,7 @@ const UntaggedAuxButton = ({ tabIndex }: IAuxButtonProps) => {
|
|||
closeMenu();
|
||||
defaultDispatcher.dispatch({
|
||||
action: "view_create_room",
|
||||
type: RoomType.ElementVideo,
|
||||
type: elementCallVideoRoomsEnabled ? RoomType.UnstableCall : RoomType.ElementVideo,
|
||||
});
|
||||
}}
|
||||
>
|
||||
|
@ -319,7 +325,7 @@ const UntaggedAuxButton = ({ tabIndex }: IAuxButtonProps) => {
|
|||
</IconizedContextMenuOptionList>;
|
||||
}
|
||||
|
||||
let contextMenu: JSX.Element;
|
||||
let contextMenu: JSX.Element | null = null;
|
||||
if (menuDisplayed) {
|
||||
contextMenu = <IconizedContextMenu {...auxButtonContextMenuPosition(handle)} onFinished={closeMenu} compact>
|
||||
{ contextMenuContent }
|
||||
|
|
|
@ -127,6 +127,7 @@ const RoomListHeader = ({ onVisibilityChange }: IProps) => {
|
|||
return SpaceStore.instance.allRoomsInHome;
|
||||
});
|
||||
const videoRoomsEnabled = useFeatureEnabled("feature_video_rooms");
|
||||
const elementCallVideoRoomsEnabled = useFeatureEnabled("feature_element_call_video_rooms");
|
||||
const pendingActions = usePendingActions();
|
||||
|
||||
const canShowMainMenu = activeSpace || spaceKey === MetaSpace.Home;
|
||||
|
@ -211,7 +212,10 @@ const RoomListHeader = ({ onVisibilityChange }: IProps) => {
|
|||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
showCreateNewRoom(activeSpace, RoomType.ElementVideo);
|
||||
showCreateNewRoom(
|
||||
activeSpace,
|
||||
elementCallVideoRoomsEnabled ? RoomType.UnstableCall : RoomType.ElementVideo,
|
||||
);
|
||||
closePlusMenu();
|
||||
}}
|
||||
>
|
||||
|
@ -310,7 +314,7 @@ const RoomListHeader = ({ onVisibilityChange }: IProps) => {
|
|||
e.stopPropagation();
|
||||
defaultDispatcher.dispatch({
|
||||
action: "view_create_room",
|
||||
type: RoomType.ElementVideo,
|
||||
type: elementCallVideoRoomsEnabled ? RoomType.UnstableCall : RoomType.ElementVideo,
|
||||
});
|
||||
closePlusMenu();
|
||||
}}
|
||||
|
|
|
@ -51,6 +51,8 @@ interface IProps {
|
|||
const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButtonClicked }) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const videoRoomsEnabled = useFeatureEnabled("feature_video_rooms");
|
||||
const elementCallVideoRoomsEnabled = useFeatureEnabled("feature_element_call_video_rooms");
|
||||
const isVideoRoom = room.isElementVideoRoom() || (elementCallVideoRoomsEnabled && room.isCallRoom());
|
||||
const myMembership = useMyRoomMembership(room);
|
||||
useDispatcher(defaultDispatcher, payload => {
|
||||
if (payload.action === Action.JoinRoomError && payload.roomId === room.roomId) {
|
||||
|
@ -69,7 +71,7 @@ const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButton
|
|||
initialTabId: UserTab.Labs,
|
||||
});
|
||||
|
||||
let inviterSection: JSX.Element;
|
||||
let inviterSection: JSX.Element | null = null;
|
||||
let joinButtons: JSX.Element;
|
||||
if (myMembership === "join") {
|
||||
joinButtons = (
|
||||
|
@ -86,10 +88,11 @@ const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButton
|
|||
</AccessibleButton>
|
||||
);
|
||||
} else if (myMembership === "invite") {
|
||||
const inviteSender = room.getMember(cli.getUserId())?.events.member?.getSender();
|
||||
const inviter = inviteSender && room.getMember(inviteSender);
|
||||
const inviteSender = room.getMember(cli.getUserId()!)?.events.member?.getSender();
|
||||
|
||||
if (inviteSender) {
|
||||
const inviter = room.getMember(inviteSender);
|
||||
|
||||
inviterSection = <div className="mx_RoomPreviewCard_inviter">
|
||||
<MemberAvatar member={inviter} fallbackUserId={inviteSender} width={32} height={32} />
|
||||
<div>
|
||||
|
@ -102,10 +105,6 @@ const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButton
|
|||
{ inviteSender }
|
||||
</div> : null }
|
||||
</div>
|
||||
{ room.isElementVideoRoom()
|
||||
? <BetaPill onClick={viewLabs} tooltipTitle={_t("Video rooms are a beta feature")} />
|
||||
: null
|
||||
}
|
||||
</div>;
|
||||
}
|
||||
|
||||
|
@ -152,10 +151,11 @@ const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButton
|
|||
}
|
||||
|
||||
let avatarRow: JSX.Element;
|
||||
if (room.isElementVideoRoom()) {
|
||||
if (isVideoRoom) {
|
||||
avatarRow = <>
|
||||
<RoomAvatar room={room} height={50} width={50} viewAvatarOnClick />
|
||||
<div className="mx_RoomPreviewCard_video" />
|
||||
<BetaPill onClick={viewLabs} tooltipTitle={_t("Video rooms are a beta feature")} />
|
||||
</>;
|
||||
} else if (room.isSpaceRoom()) {
|
||||
avatarRow = <RoomAvatar room={room} height={80} width={80} viewAvatarOnClick />;
|
||||
|
@ -163,12 +163,12 @@ const RoomPreviewCard: FC<IProps> = ({ room, onJoinButtonClicked, onRejectButton
|
|||
avatarRow = <RoomAvatar room={room} height={50} width={50} viewAvatarOnClick />;
|
||||
}
|
||||
|
||||
let notice: string;
|
||||
let notice: string | null = null;
|
||||
if (cannotJoin) {
|
||||
notice = _t("To view %(roomName)s, you need an invite", {
|
||||
roomName: room.name,
|
||||
});
|
||||
} else if (room.isElementVideoRoom() && !videoRoomsEnabled) {
|
||||
} else if (isVideoRoom && !videoRoomsEnabled) {
|
||||
notice = myMembership === "join"
|
||||
? _t("To view, please enable video rooms in Labs first")
|
||||
: _t("To join, please enable video rooms in Labs first");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue