Allow creating knock rooms (#11182)

Signed-off-by: Charly Nguyen <charly.nguyen@nordeck.net>
This commit is contained in:
Charly Nguyen
2023-07-10 10:01:03 +02:00
committed by GitHub
parent 01bd80fe59
commit fd749172e1
13 changed files with 197 additions and 3 deletions

View File

@@ -286,6 +286,8 @@ function textForJoinRulesEvent(ev: MatrixEvent, client: MatrixClient, allowJSX:
_t("%(senderDisplayName)s made the room invite only.", {
senderDisplayName,
});
case JoinRule.Knock:
return () => _t("%(senderDisplayName)s changed the join rule to ask to join.", { senderDisplayName });
case JoinRule.Restricted:
if (allowJSX) {
return () => (

View File

@@ -34,6 +34,7 @@ import JoinRuleDropdown from "../elements/JoinRuleDropdown";
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
import { privateShouldBeEncrypted } from "../../../utils/rooms";
import SettingsStore from "../../../settings/SettingsStore";
interface IProps {
type?: RoomType;
@@ -59,6 +60,7 @@ interface IState {
}
export default class CreateRoomDialog extends React.Component<IProps, IState> {
private readonly askToJoinEnabled: boolean;
private readonly supportsRestricted: boolean;
private nameField = createRef<Field>();
private aliasField = createRef<RoomAliasField>();
@@ -66,6 +68,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
public constructor(props: IProps) {
super(props);
this.askToJoinEnabled = SettingsStore.getValue("feature_ask_to_join");
this.supportsRestricted = !!this.props.parentSpace;
let joinRule = JoinRule.Invite;
@@ -126,6 +129,10 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
opts.joinRule = JoinRule.Restricted;
}
if (this.state.joinRule === JoinRule.Knock) {
opts.joinRule = JoinRule.Knock;
}
return opts;
}
@@ -283,6 +290,14 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
{_t("You can change this at any time from room settings.")}
</p>
);
} else if (this.state.joinRule === JoinRule.Knock) {
publicPrivateLabel = (
<p>
{_t(
"Anyone can request to join, but admins or moderators need to grant access. You can change this later.",
)}
</p>
);
}
let e2eeSection: JSX.Element | undefined;
@@ -332,7 +347,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
let title: string;
if (isVideoRoom) {
title = _t("Create a video room");
} else if (this.props.parentSpace) {
} else if (this.props.parentSpace || this.state.joinRule === JoinRule.Knock) {
title = _t("Create a room");
} else {
title = this.state.joinRule === JoinRule.Public ? _t("Create a public room") : _t("Create a private room");
@@ -365,6 +380,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
<JoinRuleDropdown
label={_t("Room visibility")}
labelInvite={_t("Private room (invite only)")}
labelKnock={this.askToJoinEnabled ? _t("Ask to join") : undefined}
labelPublic={_t("Public room")}
labelRestricted={this.supportsRestricted ? _t("Visible to space members") : undefined}
value={this.state.joinRule}

View File

@@ -19,12 +19,14 @@ import { JoinRule } from "matrix-js-sdk/src/@types/partials";
import Dropdown from "./Dropdown";
import { NonEmptyArray } from "../../../@types/common";
import { Icon as AskToJoinIcon } from "../../../../res/img/element-icons/ask-to-join.svg";
interface IProps {
value: JoinRule;
label: string;
width?: number;
labelInvite: string;
labelKnock?: string;
labelPublic: string;
labelRestricted?: string; // if omitted then this option will be hidden, e.g if unsupported
onChange(value: JoinRule): void;
@@ -33,6 +35,7 @@ interface IProps {
const JoinRuleDropdown: React.FC<IProps> = ({
label,
labelInvite,
labelKnock,
labelPublic,
labelRestricted,
value,
@@ -48,6 +51,17 @@ const JoinRuleDropdown: React.FC<IProps> = ({
</div>,
] as NonEmptyArray<ReactElement & { key: string }>;
if (labelKnock) {
options.unshift(
(
<div key={JoinRule.Knock} className="mx_JoinRuleDropdown_knock">
<AskToJoinIcon className="mx_Icon mx_Icon_16 mx_JoinRuleDropdown_icon" />
{labelKnock}
</div>
) as ReactElement & { key: string },
);
}
if (labelRestricted) {
options.unshift(
(

View File

@@ -222,6 +222,10 @@ export default async function createRoom(client: MatrixClient, opts: IOpts): Pro
});
}
if (opts.joinRule === JoinRule.Knock) {
createOpts.room_version = PreferredRoomVersions.KnockRooms;
}
if (opts.parentSpace) {
createOpts.initial_state.push(makeSpaceParentEvent(opts.parentSpace, true));
if (!opts.historyVisibility) {

View File

@@ -527,6 +527,7 @@
"%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s upgraded this room.",
"%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s made the room public to whoever knows the link.",
"%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s made the room invite only.",
"%(senderDisplayName)s changed the join rule to ask to join.": "%(senderDisplayName)s changed the join rule to ask to join.",
"%(senderDisplayName)s changed who can join this room. <a>View settings</a>.": "%(senderDisplayName)s changed who can join this room. <a>View settings</a>.",
"%(senderDisplayName)s changed who can join this room.": "%(senderDisplayName)s changed who can join this room.",
"%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s changed the join rule to %(rule)s",
@@ -1003,6 +1004,7 @@
"Insert a trailing colon after user mentions at the start of a message": "Insert a trailing colon after user mentions at the start of a message",
"Hide notification dot (only display counters badges)": "Hide notification dot (only display counters badges)",
"Enable intentional mentions": "Enable intentional mentions",
"Enable ask to join": "Enable ask to join",
"Use a more compact 'Modern' layout": "Use a more compact 'Modern' layout",
"Show a placeholder for removed messages": "Show a placeholder for removed messages",
"Show join/leave messages (invites/removes/bans unaffected)": "Show join/leave messages (invites/removes/bans unaffected)",
@@ -2783,6 +2785,7 @@
"Anyone will be able to find and join this room, not just members of <SpaceName/>.": "Anyone will be able to find and join this room, not just members of <SpaceName/>.",
"Anyone will be able to find and join this room.": "Anyone will be able to find and join this room.",
"Only people invited will be able to find and join this room.": "Only people invited will be able to find and join this room.",
"Anyone can request to join, but admins or moderators need to grant access. You can change this later.": "Anyone can request to join, but admins or moderators need to grant access. You can change this later.",
"You can't disable this later. The room will be encrypted but the embedded call will not.": "You can't disable this later. The room will be encrypted but the embedded call will not.",
"You can't disable this later. Bridges & most bots won't work yet.": "You can't disable this later. Bridges & most bots won't work yet.",
"Your server requires encryption to be enabled in private rooms.": "Your server requires encryption to be enabled in private rooms.",
@@ -2796,6 +2799,7 @@
"Topic (optional)": "Topic (optional)",
"Room visibility": "Room visibility",
"Private room (invite only)": "Private room (invite only)",
"Ask to join": "Ask to join",
"Visible to space members": "Visible to space members",
"Block anyone not part of %(serverName)s from ever joining this room.": "Block anyone not part of %(serverName)s from ever joining this room.",
"Create video room": "Create video room",

View File

@@ -556,6 +556,13 @@ export const SETTINGS: { [setting: string]: ISetting } = {
["org.matrix.msc3952_intentional_mentions"],
]),
},
"feature_ask_to_join": {
default: false,
displayName: _td("Enable ask to join"),
isFeature: true,
labsGroup: LabGroup.Rooms,
supportedLevels: LEVELS_FEATURE,
},
"useCompactLayout": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
displayName: _td("Use a more compact 'Modern' layout"),

View File

@@ -23,6 +23,11 @@ limitations under the License.
* Loosely follows https://spec.matrix.org/latest/rooms/#feature-matrix
*/
export class PreferredRoomVersions {
/**
* The room version to use when creating "knock" rooms.
*/
public static readonly KnockRooms = "7";
/**
* The room version to use when creating "restricted" rooms.
*/