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

Commit f882466

Browse files
authored
Add a few more UIComponent flags, and ensure they are used in existing code (#7937)
* UIComponent flag: Explore rooms To disable the room directory access on the Home space. Can be controlled with the existing ComponentVisibilityCustomisation * Make "plus menu" respect component visibility * UIComponent flag: Add integrations To disable the widgets section of the room info card and addwidget slashcommand. Can be controlled with the existing ComponentVisibilityCustomisation * Make sure invite users component applies to space rooms too * Appease the linter
1 parent d304e24 commit f882466

File tree

7 files changed

+83
-18
lines changed

7 files changed

+83
-18
lines changed

src/SlashCommands.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ import { User } from "matrix-js-sdk/src/models/user";
2222
import { Direction } from 'matrix-js-sdk/src/models/event-timeline';
2323
import { EventType } from "matrix-js-sdk/src/@types/event";
2424
import * as ContentHelpers from 'matrix-js-sdk/src/content-helpers';
25-
import { parseFragment as parseHtml, Element as ChildElement } from "parse5";
25+
import { Element as ChildElement, parseFragment as parseHtml } from "parse5";
2626
import { logger } from "matrix-js-sdk/src/logger";
2727
import { IContent } from 'matrix-js-sdk/src/models/event';
2828
import { SlashCommand as SlashCommandEvent } from "matrix-analytics-events/types/typescript/SlashCommand";
2929

3030
import { MatrixClientPeg } from './MatrixClientPeg';
3131
import dis from './dispatcher/dispatcher';
32-
import { _t, _td, newTranslatableError, ITranslatableError } from './languageHandler';
32+
import { _t, _td, ITranslatableError, newTranslatableError } from './languageHandler';
3333
import Modal from './Modal';
3434
import MultiInviter from './utils/MultiInviter';
3535
import { linkifyAndSanitizeHtml } from './HtmlUtils';
@@ -933,7 +933,7 @@ export const Commands = [
933933
command: 'addwidget',
934934
args: '<url | embed code | Jitsi url>',
935935
description: _td('Adds a custom widget by URL to the room'),
936-
isEnabled: () => SettingsStore.getValue(UIFeature.Widgets),
936+
isEnabled: () => SettingsStore.getValue(UIFeature.Widgets) && shouldShowComponent(UIComponent.AddIntegrations),
937937
runFn: function(roomId, widgetUrl) {
938938
if (!widgetUrl) {
939939
return reject(newTranslatableError("Please supply a widget URL or embed code"));

src/components/structures/LeftPanel.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ import RoomBreadcrumbs from "../views/rooms/RoomBreadcrumbs";
4444
import SettingsStore from "../../settings/SettingsStore";
4545
import UserMenu from "./UserMenu";
4646
import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts";
47+
import { shouldShowComponent } from "../../customisations/helpers/UIComponents";
48+
import { UIComponent } from "../../settings/UIFeature";
4749

4850
interface IProps {
4951
isMinimized: boolean;
@@ -368,7 +370,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
368370
let rightButton: JSX.Element;
369371
if (this.state.showBreadcrumbs === BreadcrumbsMode.Labs) {
370372
rightButton = <RecentlyViewedButton />;
371-
} else if (this.state.activeSpace === MetaSpace.Home) {
373+
} else if (this.state.activeSpace === MetaSpace.Home && shouldShowComponent(UIComponent.ExploreRooms)) {
372374
rightButton = <AccessibleTooltipButton
373375
className="mx_LeftPanel_exploreButton"
374376
onClick={this.onExplore}

src/components/views/right_panel/RoomSummaryCard.tsx

+8-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import React, { useCallback, useState, useEffect, useContext } from "react";
17+
import React, { useCallback, useContext, useEffect, useState } from "react";
1818
import classNames from "classnames";
1919
import { Room } from "matrix-js-sdk/src/models/room";
2020

@@ -38,7 +38,7 @@ import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
3838
import WidgetStore, { IApp } from "../../../stores/WidgetStore";
3939
import { E2EStatus } from "../../../utils/ShieldUtils";
4040
import RoomContext from "../../../contexts/RoomContext";
41-
import { UIFeature } from "../../../settings/UIFeature";
41+
import { UIComponent, UIFeature } from "../../../settings/UIFeature";
4242
import { ChevronFace, ContextMenuTooltipButton, useContextMenu } from "../../structures/ContextMenu";
4343
import WidgetContextMenu from "../context_menus/WidgetContextMenu";
4444
import { useRoomMemberCount } from "../../../hooks/useRoomMembers";
@@ -50,6 +50,7 @@ import UIStore from "../../../stores/UIStore";
5050
import ExportDialog from "../dialogs/ExportDialog";
5151
import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
5252
import PosthogTrackers from "../../../PosthogTrackers";
53+
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
5354

5455
interface IProps {
5556
room: Room;
@@ -327,7 +328,11 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, onClose }) => {
327328
</Button>
328329
</Group>
329330

330-
{ SettingsStore.getValue(UIFeature.Widgets) && <AppsSection room={room} /> }
331+
{
332+
SettingsStore.getValue(UIFeature.Widgets)
333+
&& shouldShowComponent(UIComponent.AddIntegrations)
334+
&& <AppsSection room={room} />
335+
}
331336
</BaseCard>;
332337
};
333338

src/components/views/rooms/NewRoomIntro.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ const NewRoomIntro = () => {
135135
}
136136

137137
let buttons;
138-
if (parentSpace) {
138+
if (parentSpace && shouldShowComponent(UIComponent.InviteUsers)) {
139139
buttons = <div className="mx_NewRoomIntro_buttons">
140140
<AccessibleButton
141141
className="mx_NewRoomIntro_inviteButton"

src/components/views/rooms/RoomListHeader.tsx

+36-8
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ import { BetaPill } from "../beta/BetaCard";
6363
import PosthogTrackers from "../../../PosthogTrackers";
6464
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
6565
import { useWebSearchMetrics } from "../dialogs/SpotlightDialog";
66+
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
67+
import { UIComponent } from "../../../settings/UIFeature";
6668

6769
const contextMenuBelow = (elementRect: DOMRect) => {
6870
// align the context menu's icons with the icon which opened the context menu
@@ -210,6 +212,14 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
210212
const communityId = CommunityPrototypeStore.instance.getSelectedCommunityId();
211213
const canAddRooms = activeSpace?.currentState?.maySendStateEvent(EventType.SpaceChild, cli.getUserId());
212214

215+
const canCreateRooms = shouldShowComponent(UIComponent.CreateRooms);
216+
const canExploreRooms = shouldShowComponent(UIComponent.ExploreRooms);
217+
218+
// If the user can't do anything on the plus menu, don't show it. This aims to target the
219+
// plus menu shown on the Home tab primarily: the user has options to use the menu for
220+
// communities and spaces, but is at risk of no options on the Home tab.
221+
const canShowPlusMenu = canCreateRooms || canExploreRooms || activeSpace || communityId;
222+
213223
let contextMenu: JSX.Element;
214224
if (mainMenuDisplayed) {
215225
let ContextMenuComponent;
@@ -320,12 +330,12 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
320330
</IconizedContextMenuOptionList>
321331
</IconizedContextMenu>;
322332
} else if (plusMenuDisplayed) {
323-
contextMenu = <IconizedContextMenu
324-
{...contextMenuBelow(plusMenuHandle.current.getBoundingClientRect())}
325-
onFinished={closePlusMenu}
326-
compact
327-
>
328-
<IconizedContextMenuOptionList first>
333+
let startChatOpt: JSX.Element;
334+
let createRoomOpt: JSX.Element;
335+
let joinRoomOpt: JSX.Element;
336+
337+
if (canCreateRooms) {
338+
startChatOpt = (
329339
<IconizedContextMenuOption
330340
label={_t("Start new chat")}
331341
iconClassName="mx_RoomListHeader_iconStartChat"
@@ -336,6 +346,8 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
336346
closePlusMenu();
337347
}}
338348
/>
349+
);
350+
createRoomOpt = (
339351
<IconizedContextMenuOption
340352
label={_t("Create new room")}
341353
iconClassName="mx_RoomListHeader_iconCreateRoom"
@@ -347,6 +359,10 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
347359
closePlusMenu();
348360
}}
349361
/>
362+
);
363+
}
364+
if (canExploreRooms) {
365+
joinRoomOpt = (
350366
<IconizedContextMenuOption
351367
label={_t("Join public room")}
352368
iconClassName="mx_RoomListHeader_iconExplore"
@@ -357,6 +373,18 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
357373
closePlusMenu();
358374
}}
359375
/>
376+
);
377+
}
378+
379+
contextMenu = <IconizedContextMenu
380+
{...contextMenuBelow(plusMenuHandle.current.getBoundingClientRect())}
381+
onFinished={closePlusMenu}
382+
compact
383+
>
384+
<IconizedContextMenuOptionList first>
385+
{ startChatOpt }
386+
{ createRoomOpt }
387+
{ joinRoomOpt }
360388
</IconizedContextMenuOptionList>
361389
</IconizedContextMenu>;
362390
}
@@ -397,13 +425,13 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
397425
return <div className="mx_RoomListHeader">
398426
{ contextMenuButton }
399427
{ pendingRoomJoinSpinner }
400-
<ContextMenuTooltipButton
428+
{ canShowPlusMenu && <ContextMenuTooltipButton
401429
inputRef={plusMenuHandle}
402430
onClick={openPlusMenu}
403431
isExpanded={plusMenuDisplayed}
404432
className="mx_RoomListHeader_plusButton"
405433
title={_t("Add")}
406-
/>
434+
/> }
407435

408436
{ contextMenu }
409437
</div>;

src/settings/UIFeature.ts

+26
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,33 @@ export enum UIFeature {
3636
}
3737

3838
export enum UIComponent {
39+
/**
40+
* Components that lead to a user being invited.
41+
*/
3942
InviteUsers = "UIComponent.sendInvites",
43+
44+
/**
45+
* Components that lead to a room being created that aren't already
46+
* guarded by some other condition (ie: "only if you can edit this
47+
* space" is *not* guarded by this component, but "start DM" is).
48+
*/
4049
CreateRooms = "UIComponent.roomCreation",
50+
51+
/**
52+
* Components that lead to a Space being created that aren't already
53+
* guarded by some other condition (ie: "only if you can add subspaces"
54+
* is *not* guarded by this component, but "create new space" is).
55+
*/
4156
CreateSpaces = "UIComponent.spaceCreation",
57+
58+
/**
59+
* Components that lead to the public room directory.
60+
*/
61+
ExploreRooms = "UIComponent.exploreRooms",
62+
63+
/**
64+
* Components that lead to the user being able to easily add widgets
65+
* and integrations to the room, such as from the room information card.
66+
*/
67+
AddIntegrations = "UIComponent.addIntegrations",
4268
}

src/utils/space.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ import SpacePreferencesDialog, { SpacePreferenceTab } from "../components/views/
4444
import PosthogTrackers from "../PosthogTrackers";
4545
import { ButtonEvent } from "../components/views/elements/AccessibleButton";
4646
import { AfterLeaveRoomPayload } from "../dispatcher/payloads/AfterLeaveRoomPayload";
47+
import { shouldShowComponent } from "../customisations/helpers/UIComponents";
48+
import { UIComponent } from "../settings/UIFeature";
4749

4850
export const shouldShowSpaceSettings = (space: Room) => {
4951
const userId = space.client.getUserId();
@@ -110,8 +112,10 @@ export const showCreateNewRoom = async (space: Room): Promise<boolean> => {
110112
};
111113

112114
export const shouldShowSpaceInvite = (space: Room) =>
113-
(space?.getMyMembership() === "join" && space.canInvite(space.client.getUserId())) ||
114-
space.getJoinRule() === JoinRule.Public;
115+
(
116+
(space?.getMyMembership() === "join" && space.canInvite(space.client.getUserId())) ||
117+
space.getJoinRule() === JoinRule.Public
118+
) && shouldShowComponent(UIComponent.InviteUsers);
115119

116120
export const showSpaceInvite = (space: Room, initialText = ""): void => {
117121
if (space.getJoinRule() === "public") {

0 commit comments

Comments
 (0)