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 linterpull/21833/head
parent
d304e24a45
commit
f882466329
|
@ -22,14 +22,14 @@ import { User } from "matrix-js-sdk/src/models/user";
|
|||
import { Direction } from 'matrix-js-sdk/src/models/event-timeline';
|
||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||
import * as ContentHelpers from 'matrix-js-sdk/src/content-helpers';
|
||||
import { parseFragment as parseHtml, Element as ChildElement } from "parse5";
|
||||
import { Element as ChildElement, parseFragment as parseHtml } from "parse5";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { IContent } from 'matrix-js-sdk/src/models/event';
|
||||
import { SlashCommand as SlashCommandEvent } from "matrix-analytics-events/types/typescript/SlashCommand";
|
||||
|
||||
import { MatrixClientPeg } from './MatrixClientPeg';
|
||||
import dis from './dispatcher/dispatcher';
|
||||
import { _t, _td, newTranslatableError, ITranslatableError } from './languageHandler';
|
||||
import { _t, _td, ITranslatableError, newTranslatableError } from './languageHandler';
|
||||
import Modal from './Modal';
|
||||
import MultiInviter from './utils/MultiInviter';
|
||||
import { linkifyAndSanitizeHtml } from './HtmlUtils';
|
||||
|
@ -933,7 +933,7 @@ export const Commands = [
|
|||
command: 'addwidget',
|
||||
args: '<url | embed code | Jitsi url>',
|
||||
description: _td('Adds a custom widget by URL to the room'),
|
||||
isEnabled: () => SettingsStore.getValue(UIFeature.Widgets),
|
||||
isEnabled: () => SettingsStore.getValue(UIFeature.Widgets) && shouldShowComponent(UIComponent.AddIntegrations),
|
||||
runFn: function(roomId, widgetUrl) {
|
||||
if (!widgetUrl) {
|
||||
return reject(newTranslatableError("Please supply a widget URL or embed code"));
|
||||
|
|
|
@ -44,6 +44,8 @@ import RoomBreadcrumbs from "../views/rooms/RoomBreadcrumbs";
|
|||
import SettingsStore from "../../settings/SettingsStore";
|
||||
import UserMenu from "./UserMenu";
|
||||
import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts";
|
||||
import { shouldShowComponent } from "../../customisations/helpers/UIComponents";
|
||||
import { UIComponent } from "../../settings/UIFeature";
|
||||
|
||||
interface IProps {
|
||||
isMinimized: boolean;
|
||||
|
@ -368,7 +370,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
|||
let rightButton: JSX.Element;
|
||||
if (this.state.showBreadcrumbs === BreadcrumbsMode.Labs) {
|
||||
rightButton = <RecentlyViewedButton />;
|
||||
} else if (this.state.activeSpace === MetaSpace.Home) {
|
||||
} else if (this.state.activeSpace === MetaSpace.Home && shouldShowComponent(UIComponent.ExploreRooms)) {
|
||||
rightButton = <AccessibleTooltipButton
|
||||
className="mx_LeftPanel_exploreButton"
|
||||
onClick={this.onExplore}
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useState, useEffect, useContext } from "react";
|
||||
import React, { useCallback, useContext, useEffect, useState } from "react";
|
||||
import classNames from "classnames";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
|
||||
|
@ -38,7 +38,7 @@ import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
|||
import WidgetStore, { IApp } from "../../../stores/WidgetStore";
|
||||
import { E2EStatus } from "../../../utils/ShieldUtils";
|
||||
import RoomContext from "../../../contexts/RoomContext";
|
||||
import { UIFeature } from "../../../settings/UIFeature";
|
||||
import { UIComponent, UIFeature } from "../../../settings/UIFeature";
|
||||
import { ChevronFace, ContextMenuTooltipButton, useContextMenu } from "../../structures/ContextMenu";
|
||||
import WidgetContextMenu from "../context_menus/WidgetContextMenu";
|
||||
import { useRoomMemberCount } from "../../../hooks/useRoomMembers";
|
||||
|
@ -50,6 +50,7 @@ import UIStore from "../../../stores/UIStore";
|
|||
import ExportDialog from "../dialogs/ExportDialog";
|
||||
import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
|
||||
import PosthogTrackers from "../../../PosthogTrackers";
|
||||
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
|
||||
|
||||
interface IProps {
|
||||
room: Room;
|
||||
|
@ -327,7 +328,11 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, onClose }) => {
|
|||
</Button>
|
||||
</Group>
|
||||
|
||||
{ SettingsStore.getValue(UIFeature.Widgets) && <AppsSection room={room} /> }
|
||||
{
|
||||
SettingsStore.getValue(UIFeature.Widgets)
|
||||
&& shouldShowComponent(UIComponent.AddIntegrations)
|
||||
&& <AppsSection room={room} />
|
||||
}
|
||||
</BaseCard>;
|
||||
};
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ const NewRoomIntro = () => {
|
|||
}
|
||||
|
||||
let buttons;
|
||||
if (parentSpace) {
|
||||
if (parentSpace && shouldShowComponent(UIComponent.InviteUsers)) {
|
||||
buttons = <div className="mx_NewRoomIntro_buttons">
|
||||
<AccessibleButton
|
||||
className="mx_NewRoomIntro_inviteButton"
|
||||
|
|
|
@ -63,6 +63,8 @@ import { BetaPill } from "../beta/BetaCard";
|
|||
import PosthogTrackers from "../../../PosthogTrackers";
|
||||
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
|
||||
import { useWebSearchMetrics } from "../dialogs/SpotlightDialog";
|
||||
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
|
||||
import { UIComponent } from "../../../settings/UIFeature";
|
||||
|
||||
const contextMenuBelow = (elementRect: DOMRect) => {
|
||||
// align the context menu's icons with the icon which opened the context menu
|
||||
|
@ -210,6 +212,14 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
|
|||
const communityId = CommunityPrototypeStore.instance.getSelectedCommunityId();
|
||||
const canAddRooms = activeSpace?.currentState?.maySendStateEvent(EventType.SpaceChild, cli.getUserId());
|
||||
|
||||
const canCreateRooms = shouldShowComponent(UIComponent.CreateRooms);
|
||||
const canExploreRooms = shouldShowComponent(UIComponent.ExploreRooms);
|
||||
|
||||
// If the user can't do anything on the plus menu, don't show it. This aims to target the
|
||||
// plus menu shown on the Home tab primarily: the user has options to use the menu for
|
||||
// communities and spaces, but is at risk of no options on the Home tab.
|
||||
const canShowPlusMenu = canCreateRooms || canExploreRooms || activeSpace || communityId;
|
||||
|
||||
let contextMenu: JSX.Element;
|
||||
if (mainMenuDisplayed) {
|
||||
let ContextMenuComponent;
|
||||
|
@ -320,12 +330,12 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
|
|||
</IconizedContextMenuOptionList>
|
||||
</IconizedContextMenu>;
|
||||
} else if (plusMenuDisplayed) {
|
||||
contextMenu = <IconizedContextMenu
|
||||
{...contextMenuBelow(plusMenuHandle.current.getBoundingClientRect())}
|
||||
onFinished={closePlusMenu}
|
||||
compact
|
||||
>
|
||||
<IconizedContextMenuOptionList first>
|
||||
let startChatOpt: JSX.Element;
|
||||
let createRoomOpt: JSX.Element;
|
||||
let joinRoomOpt: JSX.Element;
|
||||
|
||||
if (canCreateRooms) {
|
||||
startChatOpt = (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("Start new chat")}
|
||||
iconClassName="mx_RoomListHeader_iconStartChat"
|
||||
|
@ -336,6 +346,8 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
|
|||
closePlusMenu();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
createRoomOpt = (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("Create new room")}
|
||||
iconClassName="mx_RoomListHeader_iconCreateRoom"
|
||||
|
@ -347,6 +359,10 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
|
|||
closePlusMenu();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (canExploreRooms) {
|
||||
joinRoomOpt = (
|
||||
<IconizedContextMenuOption
|
||||
label={_t("Join public room")}
|
||||
iconClassName="mx_RoomListHeader_iconExplore"
|
||||
|
@ -357,6 +373,18 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
|
|||
closePlusMenu();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
contextMenu = <IconizedContextMenu
|
||||
{...contextMenuBelow(plusMenuHandle.current.getBoundingClientRect())}
|
||||
onFinished={closePlusMenu}
|
||||
compact
|
||||
>
|
||||
<IconizedContextMenuOptionList first>
|
||||
{ startChatOpt }
|
||||
{ createRoomOpt }
|
||||
{ joinRoomOpt }
|
||||
</IconizedContextMenuOptionList>
|
||||
</IconizedContextMenu>;
|
||||
}
|
||||
|
@ -397,13 +425,13 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
|
|||
return <div className="mx_RoomListHeader">
|
||||
{ contextMenuButton }
|
||||
{ pendingRoomJoinSpinner }
|
||||
<ContextMenuTooltipButton
|
||||
{ canShowPlusMenu && <ContextMenuTooltipButton
|
||||
inputRef={plusMenuHandle}
|
||||
onClick={openPlusMenu}
|
||||
isExpanded={plusMenuDisplayed}
|
||||
className="mx_RoomListHeader_plusButton"
|
||||
title={_t("Add")}
|
||||
/>
|
||||
/> }
|
||||
|
||||
{ contextMenu }
|
||||
</div>;
|
||||
|
|
|
@ -36,7 +36,33 @@ export enum UIFeature {
|
|||
}
|
||||
|
||||
export enum UIComponent {
|
||||
/**
|
||||
* Components that lead to a user being invited.
|
||||
*/
|
||||
InviteUsers = "UIComponent.sendInvites",
|
||||
|
||||
/**
|
||||
* Components that lead to a room being created that aren't already
|
||||
* guarded by some other condition (ie: "only if you can edit this
|
||||
* space" is *not* guarded by this component, but "start DM" is).
|
||||
*/
|
||||
CreateRooms = "UIComponent.roomCreation",
|
||||
|
||||
/**
|
||||
* Components that lead to a Space being created that aren't already
|
||||
* guarded by some other condition (ie: "only if you can add subspaces"
|
||||
* is *not* guarded by this component, but "create new space" is).
|
||||
*/
|
||||
CreateSpaces = "UIComponent.spaceCreation",
|
||||
|
||||
/**
|
||||
* Components that lead to the public room directory.
|
||||
*/
|
||||
ExploreRooms = "UIComponent.exploreRooms",
|
||||
|
||||
/**
|
||||
* Components that lead to the user being able to easily add widgets
|
||||
* and integrations to the room, such as from the room information card.
|
||||
*/
|
||||
AddIntegrations = "UIComponent.addIntegrations",
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ import SpacePreferencesDialog, { SpacePreferenceTab } from "../components/views/
|
|||
import PosthogTrackers from "../PosthogTrackers";
|
||||
import { ButtonEvent } from "../components/views/elements/AccessibleButton";
|
||||
import { AfterLeaveRoomPayload } from "../dispatcher/payloads/AfterLeaveRoomPayload";
|
||||
import { shouldShowComponent } from "../customisations/helpers/UIComponents";
|
||||
import { UIComponent } from "../settings/UIFeature";
|
||||
|
||||
export const shouldShowSpaceSettings = (space: Room) => {
|
||||
const userId = space.client.getUserId();
|
||||
|
@ -110,8 +112,10 @@ export const showCreateNewRoom = async (space: Room): Promise<boolean> => {
|
|||
};
|
||||
|
||||
export const shouldShowSpaceInvite = (space: Room) =>
|
||||
(space?.getMyMembership() === "join" && space.canInvite(space.client.getUserId())) ||
|
||||
space.getJoinRule() === JoinRule.Public;
|
||||
(
|
||||
(space?.getMyMembership() === "join" && space.canInvite(space.client.getUserId())) ||
|
||||
space.getJoinRule() === JoinRule.Public
|
||||
) && shouldShowComponent(UIComponent.InviteUsers);
|
||||
|
||||
export const showSpaceInvite = (space: Room, initialText = ""): void => {
|
||||
if (space.getJoinRule() === "public") {
|
||||
|
|
Loading…
Reference in New Issue