From 798f13a071eacc16b62b563594de954ab8b27c2a Mon Sep 17 00:00:00 2001 From: Charly Nguyen Date: Mon, 21 Aug 2023 09:27:47 +0200 Subject: [PATCH] Allow setting knock room visibility Signed-off-by: Charly Nguyen --- res/css/views/dialogs/_CreateRoomDialog.pcss | 5 ++ res/css/views/settings/_JoinRuleSettings.pcss | 5 ++ .../views/dialogs/CreateRoomDialog.tsx | 19 ++++ .../dialogs/spotlight/SpotlightDialog.tsx | 36 +++++++- .../views/elements/LabelledCheckbox.tsx | 7 +- .../views/settings/JoinRuleSettings.tsx | 46 +++++++++- src/i18n/strings/en_EN.json | 3 + .../views/dialogs/CreateRoomDialog-test.tsx | 87 ++++++++++++------- .../views/dialogs/SpotlightDialog-test.tsx | 73 ++++++++++++++++ .../views/elements/LabelledCheckbox-test.tsx | 12 +++ .../views/settings/JoinRuleSettings-test.tsx | 73 +++++++++++++++- 11 files changed, 325 insertions(+), 41 deletions(-) diff --git a/res/css/views/dialogs/_CreateRoomDialog.pcss b/res/css/views/dialogs/_CreateRoomDialog.pcss index 437044cc8fe..4e3d90cffe6 100644 --- a/res/css/views/dialogs/_CreateRoomDialog.pcss +++ b/res/css/views/dialogs/_CreateRoomDialog.pcss @@ -113,3 +113,8 @@ limitations under the License. font-size: $font-12px; } } + +.mx_CreateRoomDialog_labelledCheckbox { + color: $muted-fg-color; + margin-top: var(--cpd-space-6x); +} diff --git a/res/css/views/settings/_JoinRuleSettings.pcss b/res/css/views/settings/_JoinRuleSettings.pcss index de06580ea7e..8841dd522bb 100644 --- a/res/css/views/settings/_JoinRuleSettings.pcss +++ b/res/css/views/settings/_JoinRuleSettings.pcss @@ -79,3 +79,8 @@ limitations under the License. } } } + +.mx_JoinRuleSettings_labelledCheckbox { + font: var(--cpd-font-body-md-regular); + margin-top: var(--cpd-space-2x); +} diff --git a/src/components/views/dialogs/CreateRoomDialog.tsx b/src/components/views/dialogs/CreateRoomDialog.tsx index 276f1195b3d..6546d06a43e 100644 --- a/src/components/views/dialogs/CreateRoomDialog.tsx +++ b/src/components/views/dialogs/CreateRoomDialog.tsx @@ -33,6 +33,7 @@ import { getKeyBindingsManager } from "../../../KeyBindingsManager"; import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts"; import { privateShouldBeEncrypted } from "../../../utils/rooms"; import SettingsStore from "../../../settings/SettingsStore"; +import LabelledCheckbox from "../elements/LabelledCheckbox"; interface IProps { type?: RoomType; @@ -129,6 +130,7 @@ export default class CreateRoomDialog extends React.Component { if (this.state.joinRule === JoinRule.Knock) { opts.joinRule = JoinRule.Knock; + createOpts.visibility = this.state.isPublic ? Visibility.Public : Visibility.Private; } return opts; @@ -215,6 +217,10 @@ export default class CreateRoomDialog extends React.Component { return result; }; + private onIsPublicChange = (isPublic: boolean): void => { + this.setState({ isPublic }); + }; + private static validateRoomName = withValidation({ rules: [ { @@ -298,6 +304,18 @@ export default class CreateRoomDialog extends React.Component { ); } + let visibilitySection: JSX.Element | undefined; + if (this.state.joinRule === JoinRule.Knock) { + visibilitySection = ( + + ); + } + let e2eeSection: JSX.Element | undefined; if (this.state.joinRule !== JoinRule.Public) { let microcopy: string; @@ -383,6 +401,7 @@ export default class CreateRoomDialog extends React.Component { /> {publicPrivateLabel} + {visibilitySection} {e2eeSection} {aliasField}
diff --git a/src/components/views/dialogs/spotlight/SpotlightDialog.tsx b/src/components/views/dialogs/spotlight/SpotlightDialog.tsx index ac6365b8776..11bf7ee8a08 100644 --- a/src/components/views/dialogs/spotlight/SpotlightDialog.tsx +++ b/src/components/views/dialogs/spotlight/SpotlightDialog.tsx @@ -24,6 +24,7 @@ import { RoomType, Room, HierarchyRoom, + JoinRule, } from "matrix-js-sdk/src/matrix"; import { normalize } from "matrix-js-sdk/src/utils"; import React, { ChangeEvent, RefObject, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react"; @@ -276,6 +277,10 @@ const roomAriaUnreadLabel = (room: Room, notification: RoomNotificationState): s } }; +const canAskToJoin = (joinRule?: JoinRule): boolean => { + return SettingsStore.getValue("feature_ask_to_join") && JoinRule.Knock === joinRule; +}; + interface IDirectoryOpts { limit: number; query: string; @@ -514,7 +519,14 @@ const SpotlightDialog: React.FC = ({ initialText = "", initialFilter = n }, [results, filter]); const viewRoom = ( - room: { roomId: string; roomAlias?: string; autoJoin?: boolean; shouldPeek?: boolean; viaServers?: string[] }, + room: { + roomId: string; + roomAlias?: string; + autoJoin?: boolean; + shouldPeek?: boolean; + viaServers?: string[]; + joinRule?: IPublicRoomsChunkRoom["join_rule"]; + }, persist = false, viaKeyboard = false, ): void => { @@ -538,10 +550,15 @@ const SpotlightDialog: React.FC = ({ initialText = "", initialFilter = n metricsViaKeyboard: viaKeyboard, room_id: room.roomId, room_alias: room.roomAlias, - auto_join: room.autoJoin, + auto_join: room.autoJoin && !canAskToJoin(room.joinRule), should_peek: room.shouldPeek, via_servers: room.viaServers, }); + + if (canAskToJoin(room.joinRule)) { + defaultDispatcher.dispatch({ action: Action.PromptAskToJoin }); + } + onFinished(); }; @@ -651,12 +668,15 @@ const SpotlightDialog: React.FC = ({ initialText = "", initialFilter = n } if (isPublicRoomResult(result)) { const clientRoom = cli.getRoom(result.publicRoom.room_id); + const joinRule = result.publicRoom.join_rule; // Element Web currently does not allow guests to join rooms, so we // instead show them view buttons for all rooms. If the room is not // world readable, a modal will appear asking you to register first. If // it is readable, the preview appears as normal. const showViewButton = - clientRoom?.getMyMembership() === "join" || result.publicRoom.world_readable || cli.isGuest(); + clientRoom?.getMyMembership() === "join" || + (result.publicRoom.world_readable && !canAskToJoin(joinRule)) || + cli.isGuest(); const listener = (ev: ButtonEvent): void => { ev.stopPropagation(); @@ -669,12 +689,20 @@ const SpotlightDialog: React.FC = ({ initialText = "", initialFilter = n autoJoin: !result.publicRoom.world_readable && !cli.isGuest(), shouldPeek: result.publicRoom.world_readable || cli.isGuest(), viaServers: config ? [config.roomServer] : undefined, + joinRule, }, true, ev.type !== "click", ); }; + let buttonLabel; + if (showViewButton) { + buttonLabel = _t("action|view"); + } else { + buttonLabel = canAskToJoin(joinRule) ? _t("action|ask_to_join") : _t("action|join"); + } + return (