Iterate SecurityRoomSettingsTab and ManageRestrictedJoinRuleDialog

This commit is contained in:
Michael Telatynski 2021-07-06 10:10:25 +01:00
parent 692347843d
commit c5ca98a3ad
4 changed files with 106 additions and 76 deletions

View file

@ -104,7 +104,7 @@ limitations under the License.
} }
} }
.mx_ManageRestrictedJoinRuleDialog_section_experimental { .mx_ManageRestrictedJoinRuleDialog_section_info {
position: relative; position: relative;
border-radius: 8px; border-radius: 8px;
margin: 12px 0; margin: 12px 0;
@ -131,17 +131,20 @@ limitations under the License.
} }
.mx_ManageRestrictedJoinRuleDialog_footer { .mx_ManageRestrictedJoinRuleDialog_footer {
display: flex;
margin-top: 20px; margin-top: 20px;
align-self: end;
.mx_ManageRestrictedJoinRuleDialog_footer_buttons {
display: flex;
width: max-content;
margin-left: auto;
.mx_AccessibleButton { .mx_AccessibleButton {
display: inline-block; display: inline-block;
align-self: center;
& + .mx_AccessibleButton { & + .mx_AccessibleButton {
margin-left: 24px; margin-left: 24px;
} }
} }
} }
}
} }

View file

@ -102,6 +102,13 @@ const ManageRestrictedJoinRuleDialog: React.FC<IProps> = ({ room, selected = [],
setNewSelected(new Set(newSelected)); setNewSelected(new Set(newSelected));
}; };
let inviteOnlyWarning;
if (newSelected.size < 1) {
inviteOnlyWarning = <div className="mx_ManageRestrictedJoinRuleDialog_section_info">
{ _t("You're removing all spaces. Access will default to invite only") }
</div>;
}
return <BaseDialog return <BaseDialog
title={_t("Select spaces")} title={_t("Select spaces")}
className="mx_ManageRestrictedJoinRuleDialog" className="mx_ManageRestrictedJoinRuleDialog"
@ -142,7 +149,7 @@ const ManageRestrictedJoinRuleDialog: React.FC<IProps> = ({ room, selected = [],
{ filteredOtherEntries.length > 0 ? ( { filteredOtherEntries.length > 0 ? (
<div className="mx_ManageRestrictedJoinRuleDialog_section"> <div className="mx_ManageRestrictedJoinRuleDialog_section">
<h3>{ _t("Other spaces or rooms you might not know") }</h3> <h3>{ _t("Other spaces or rooms you might not know") }</h3>
<div className="mx_ManageRestrictedJoinRuleDialog_section_experimental"> <div className="mx_ManageRestrictedJoinRuleDialog_section_info">
<div>{ _t("These are likely ones other room admins are a part of.") }</div> <div>{ _t("These are likely ones other room admins are a part of.") }</div>
</div> </div>
{ filteredOtherEntries.map(space => { { filteredOtherEntries.map(space => {
@ -167,6 +174,8 @@ const ManageRestrictedJoinRuleDialog: React.FC<IProps> = ({ room, selected = [],
</AutoHideScrollbar> </AutoHideScrollbar>
<div className="mx_ManageRestrictedJoinRuleDialog_footer"> <div className="mx_ManageRestrictedJoinRuleDialog_footer">
{ inviteOnlyWarning }
<div className="mx_ManageRestrictedJoinRuleDialog_footer_buttons">
<AccessibleButton kind="primary_outline" onClick={() => onFinished()}> <AccessibleButton kind="primary_outline" onClick={() => onFinished()}>
{ _t("Cancel") } { _t("Cancel") }
</AccessibleButton> </AccessibleButton>
@ -174,6 +183,7 @@ const ManageRestrictedJoinRuleDialog: React.FC<IProps> = ({ room, selected = [],
{ _t("Confirm") } { _t("Confirm") }
</AccessibleButton> </AccessibleButton>
</div> </div>
</div>
</MatrixClientContext.Provider> </MatrixClientContext.Provider>
</BaseDialog>; </BaseDialog>;
}; };

View file

@ -101,19 +101,14 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
); );
const encrypted = MatrixClientPeg.get().isRoomEncrypted(this.props.roomId); const encrypted = MatrixClientPeg.get().isRoomEncrypted(this.props.roomId);
this.setState({ joinRule, restrictedAllowRoomIds, guestAccess, history, encrypted }); const restrictedRoomCapabilities = SpaceStore.instance.restrictedJoinRuleSupport;
const roomSupportsRestricted = Array.isArray(restrictedRoomCapabilities?.support)
&& restrictedRoomCapabilities.support.includes(room.getVersion());
const preferredRestrictionVersion = roomSupportsRestricted ? null : restrictedRoomCapabilities.preferred;
this.setState({ joinRule, restrictedAllowRoomIds, guestAccess, history, encrypted,
roomSupportsRestricted, preferredRestrictionVersion });
this.hasAliases().then(hasAliases => this.setState({ hasAliases })); this.hasAliases().then(hasAliases => this.setState({ hasAliases }));
cli.getCapabilities().then(capabilities => {
const roomCapabilities = capabilities["org.matrix.msc3244.room_capabilities"];
const roomSupportsRestricted = roomCapabilities && Array.isArray(roomCapabilities["restricted"]?.support) &&
roomCapabilities["restricted"].support.includes(room.getVersion());
const preferredRestrictionVersion = roomSupportsRestricted
? roomCapabilities?.["restricted"].preferred
: undefined;
this.setState({ roomSupportsRestricted, preferredRestrictionVersion });
});
} }
private pullContentPropertyFromEvent<T>(event: MatrixEvent, key: string, defaultValue: T): T { private pullContentPropertyFromEvent<T>(event: MatrixEvent, key: string, defaultValue: T): T {
@ -169,23 +164,16 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
private onJoinRuleChange = async (joinRule: JoinRule) => { private onJoinRuleChange = async (joinRule: JoinRule) => {
const beforeJoinRule = this.state.joinRule; const beforeJoinRule = this.state.joinRule;
if (beforeJoinRule === joinRule) return;
let restrictedAllowRoomIds: string[];
if (joinRule === JoinRule.Restricted) { if (joinRule === JoinRule.Restricted) {
const matrixClient = MatrixClientPeg.get(); const matrixClient = MatrixClientPeg.get();
const roomId = this.props.roomId; const roomId = this.props.roomId;
const room = matrixClient.getRoom(roomId); const room = matrixClient.getRoom(roomId);
if (this.state.roomSupportsRestricted) { if (beforeJoinRule === JoinRule.Restricted || this.state.roomSupportsRestricted) {
// Have the user pick which spaces to allow joins from // Have the user pick which spaces to allow joins from
const { finished } = Modal.createTrackedDialog('Set restricted', '', ManageRestrictedJoinRuleDialog, { restrictedAllowRoomIds = await this.editRestrictedRoomIds();
matrixClient,
room,
// if they have are viewing this room from the context of a space then default to that
selected: SpaceStore.instance.activeSpace ? [SpaceStore.instance.activeSpace.roomId] : [],
}, "mx_ManageRestrictedJoinRuleDialog_wrapper");
const [restrictedAllowRoomIds] = await finished;
if (!Array.isArray(restrictedAllowRoomIds)) return; if (!Array.isArray(restrictedAllowRoomIds)) return;
} else if (this.state.preferredRestrictionVersion) { } else if (this.state.preferredRestrictionVersion) {
// Block this action on a room upgrade otherwise it'd make their room unjoinable // Block this action on a room upgrade otherwise it'd make their room unjoinable
@ -204,19 +192,18 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
} }
} }
if (beforeJoinRule === joinRule && !restrictedAllowRoomIds) return;
const content: IContent = { const content: IContent = {
join_rule: joinRule, join_rule: joinRule,
}; };
let restrictedAllowRoomIds: string[];
// pre-set the accepted spaces with the currently viewed one as per the microcopy // pre-set the accepted spaces with the currently viewed one as per the microcopy
if (joinRule === JoinRule.Restricted && SpaceStore.instance.activeSpace) { if (joinRule === JoinRule.Restricted) {
const spaceRoomId = SpaceStore.instance.activeSpace.roomId; content.allow = restrictedAllowRoomIds.map(roomId => ({
restrictedAllowRoomIds = [spaceRoomId];
content.allow = [{
"type": RestrictedAllowType.RoomMembership, "type": RestrictedAllowType.RoomMembership,
"room_id": spaceRoomId, "room_id": roomId,
}]; }));
} }
this.setState({ joinRule, restrictedAllowRoomIds }); this.setState({ joinRule, restrictedAllowRoomIds });
@ -296,17 +283,31 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
} }
} }
private onEditRestrictedClick = () => { private editRestrictedRoomIds = async (): Promise<string[] | undefined> => {
let selected = this.state.restrictedAllowRoomIds;
if (!selected?.length && SpaceStore.instance.activeSpace) {
selected = [SpaceStore.instance.activeSpace.roomId];
}
const matrixClient = MatrixClientPeg.get(); const matrixClient = MatrixClientPeg.get();
Modal.createTrackedDialog('Edit restricted', '', ManageRestrictedJoinRuleDialog, { const { finished } = Modal.createTrackedDialog('Edit restricted', '', ManageRestrictedJoinRuleDialog, {
matrixClient, matrixClient,
room: matrixClient.getRoom(this.props.roomId), room: matrixClient.getRoom(this.props.roomId),
selected: this.state.restrictedAllowRoomIds, selected,
onFinished: (restrictedAllowRoomIds?: string[]) => {
if (!Array.isArray(restrictedAllowRoomIds)) return;
this.onRestrictedRoomIdsChange(restrictedAllowRoomIds);
},
}, "mx_ManageRestrictedJoinRuleDialog_wrapper"); }, "mx_ManageRestrictedJoinRuleDialog_wrapper");
const [restrictedAllowRoomIds] = await finished;
return restrictedAllowRoomIds;
};
private onEditRestrictedClick = async () => {
const restrictedAllowRoomIds = await this.editRestrictedRoomIds();
if (!Array.isArray(restrictedAllowRoomIds)) return;
if (restrictedAllowRoomIds.length > 0) {
this.onRestrictedRoomIdsChange(restrictedAllowRoomIds);
} else {
this.onJoinRuleChange(JoinRule.Invite);
}
}; };
private renderJoinRule() { private renderJoinRule() {
@ -332,6 +333,8 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
value: JoinRule.Invite, value: JoinRule.Invite,
label: _t("Private (invite only)"), label: _t("Private (invite only)"),
description: _t("Only invited people can join."), description: _t("Only invited people can join."),
checked: this.state.joinRule === JoinRule.Invite
|| (this.state.joinRule === JoinRule.Restricted && !this.state.restrictedAllowRoomIds?.length),
}, { }, {
value: JoinRule.Public, value: JoinRule.Public,
label: _t("Public (anyone)"), label: _t("Public (anyone)"),
@ -350,28 +353,23 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
} }
let description; let description;
if (joinRule === JoinRule.Restricted) { if (joinRule === JoinRule.Restricted && this.state.restrictedAllowRoomIds?.length) {
let spacesWhichCanAccess;
if (this.state.restrictedAllowRoomIds?.length) {
const shownSpaces = this.state.restrictedAllowRoomIds const shownSpaces = this.state.restrictedAllowRoomIds
.map(roomId => client.getRoom(roomId)) .map(roomId => client.getRoom(roomId))
.filter(Boolean) .filter(room => room?.isSpaceRoom())
.slice(0, 4); .slice(0, 4);
spacesWhichCanAccess = <div className="mx_SecurityRoomSettingsTab_spacesWithAccess"> let moreText;
<h4>{ _t("Spaces with access") }</h4> if (shownSpaces.length < this.state.restrictedAllowRoomIds.length) {
{ shownSpaces.map(room => { if (shownSpaces.length > 0) {
return <span key={room.roomId}> moreText = _t("& %(count)s more", {
<RoomAvatar room={room} height={32} width={32} />
{ room.name }
</span>;
})}
{ shownSpaces.length < this.state.restrictedAllowRoomIds.length && <span>
{ _t("& %(count)s more", {
count: this.state.restrictedAllowRoomIds.length - shownSpaces.length, count: this.state.restrictedAllowRoomIds.length - shownSpaces.length,
}) } });
</span> } } else {
</div>; moreText = _t("Currently, %(count)s spaces have access", {
count: this.state.restrictedAllowRoomIds.length,
});
}
} }
description = <div> description = <div>
@ -386,7 +384,17 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
</AccessibleButton>, </AccessibleButton>,
}) } }) }
</span> </span>
{ spacesWhichCanAccess }
<div className="mx_SecurityRoomSettingsTab_spacesWithAccess">
<h4>{ _t("Spaces with access") }</h4>
{ shownSpaces.map(room => {
return <span key={room.roomId}>
<RoomAvatar room={room} height={32} width={32} />
{ room.name }
</span>;
})}
{ moreText && <span>{ moreText }</span> }
</div>
</div>; </div>;
} else if (SpaceStore.instance.activeSpace) { } else if (SpaceStore.instance.activeSpace) {
description = _t("Anyone in %(spaceName)s can find and join. You can select other spaces too.", { description = _t("Anyone in %(spaceName)s can find and join. You can select other spaces too.", {
@ -403,6 +411,8 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
{ upgradeRequiredPill } { upgradeRequiredPill }
</>, </>,
description, description,
// if there are 0 allowed spaces then render it as invite only instead
checked: this.state.joinRule === JoinRule.Restricted && !!this.state.restrictedAllowRoomIds?.length,
}); });
} }
@ -478,7 +488,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
const state = client.getRoom(this.props.roomId).currentState; const state = client.getRoom(this.props.roomId).currentState;
const canSetGuestAccess = state.mayClientSendStateEvent(EventType.RoomGuestAccess, client); const canSetGuestAccess = state.mayClientSendStateEvent(EventType.RoomGuestAccess, client);
return <> return <div className="mx_SettingsTab_section">
<LabelledToggleSwitch <LabelledToggleSwitch
value={guestAccess === GuestAccess.CanJoin} value={guestAccess === GuestAccess.CanJoin}
onChange={this.onGuestAccessChange} onChange={this.onGuestAccessChange}
@ -489,7 +499,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
{ _t("People with supported clients will be able to join " + { _t("People with supported clients will be able to join " +
"the room without having a registered account.") } "the room without having a registered account.") }
</p> </p>
</>; </div>;
} }
render() { render() {

View file

@ -1455,9 +1455,12 @@
"Public (anyone)": "Public (anyone)", "Public (anyone)": "Public (anyone)",
"Anyone can find and join.": "Anyone can find and join.", "Anyone can find and join.": "Anyone can find and join.",
"Upgrade required": "Upgrade required", "Upgrade required": "Upgrade required",
"Spaces with access": "Spaces with access",
"& %(count)s more|other": "& %(count)s more", "& %(count)s more|other": "& %(count)s more",
"& %(count)s more|one": "& %(count)s more",
"Currently, %(count)s spaces have access|other": "Currently, %(count)s spaces have access",
"Currently, %(count)s spaces have access|one": "Currently, %(count)s space has access",
"Anyone in a space can find and join. <a>Edit which spaces can access here.</a>": "Anyone in a space can find and join. <a>Edit which spaces can access here.</a>", "Anyone in a space can find and join. <a>Edit which spaces can access here.</a>": "Anyone in a space can find and join. <a>Edit which spaces can access here.</a>",
"Spaces with access": "Spaces with access",
"Anyone in %(spaceName)s can find and join. You can select other spaces too.": "Anyone in %(spaceName)s can find and join. You can select other spaces too.", "Anyone in %(spaceName)s can find and join. You can select other spaces too.": "Anyone in %(spaceName)s can find and join. You can select other spaces too.",
"Anyone in a space can find and join. You can select multiple spaces.": "Anyone in a space can find and join. You can select multiple spaces.", "Anyone in a space can find and join. You can select multiple spaces.": "Anyone in a space can find and join. You can select multiple spaces.",
"Space members": "Space members", "Space members": "Space members",
@ -2187,8 +2190,11 @@
"Community ID": "Community ID", "Community ID": "Community ID",
"example": "example", "example": "example",
"Please enter a name for the room": "Please enter a name for the room", "Please enter a name for the room": "Please enter a name for the room",
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.",
"Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.", "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.",
"Everyone in <SpaceName/> will be able to find and join this room.": "Everyone in <SpaceName/> will be able to find and join this room.",
"You can change this at any time from room settings.": "You can change this at any time from room settings.",
"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/>.",
"Only people invited will be able to find and join this room.": "Only people invited will be able to find and join this room.",
"You cant disable this later. Bridges & most bots wont work yet.": "You cant disable this later. Bridges & most bots wont work yet.", "You cant disable this later. Bridges & most bots wont work yet.": "You cant disable this later. Bridges & most bots wont work yet.",
"Your server requires encryption to be enabled in private rooms.": "Your server requires encryption to be enabled in private rooms.", "Your server requires encryption to be enabled in private rooms.": "Your server requires encryption to be enabled in private rooms.",
"Enable end-to-end encryption": "Enable end-to-end encryption", "Enable end-to-end encryption": "Enable end-to-end encryption",
@ -2355,6 +2361,7 @@
"%(count)s members|one": "%(count)s member", "%(count)s members|one": "%(count)s member",
"%(count)s rooms|other": "%(count)s rooms", "%(count)s rooms|other": "%(count)s rooms",
"%(count)s rooms|one": "%(count)s room", "%(count)s rooms|one": "%(count)s room",
"You're removing all spaces. Access will default to invite only": "You're removing all spaces. Access will default to invite only",
"Select spaces": "Select spaces", "Select spaces": "Select spaces",
"Decide which spaces can access this room. If a space is selected its members will be able to find and join <RoomName/>.": "Decide which spaces can access this room. If a space is selected its members will be able to find and join <RoomName/>.", "Decide which spaces can access this room. If a space is selected its members will be able to find and join <RoomName/>.": "Decide which spaces can access this room. If a space is selected its members will be able to find and join <RoomName/>.",
"Search spaces": "Search spaces", "Search spaces": "Search spaces",