Adapt and re-use the RolesRoomSettingsTab for Spaces

This commit is contained in:
Michael Telatynski 2021-09-10 09:41:58 +01:00
parent 6d38256c6a
commit 558b292c25
3 changed files with 83 additions and 42 deletions

View file

@ -29,10 +29,12 @@ import SpaceSettingsVisibilityTab from "../spaces/SpaceSettingsVisibilityTab";
import SettingsStore from "../../../settings/SettingsStore";
import { UIFeature } from "../../../settings/UIFeature";
import AdvancedRoomSettingsTab from "../settings/tabs/room/AdvancedRoomSettingsTab";
import RolesRoomSettingsTab from "../settings/tabs/room/RolesRoomSettingsTab";
export enum SpaceSettingsTab {
General = "SPACE_GENERAL_TAB",
Visibility = "SPACE_VISIBILITY_TAB",
Roles = "SPACE_ROLES_TAB",
Advanced = "SPACE_ADVANCED_TAB",
}
@ -62,6 +64,12 @@ const SpaceSettingsDialog: React.FC<IProps> = ({ matrixClient: cli, space, onFin
"mx_SpaceSettingsDialog_visibilityIcon",
<SpaceSettingsVisibilityTab matrixClient={cli} space={space} />,
),
new Tab(
SpaceSettingsTab.Roles,
_td("Roles & Permissions"),
"mx_RoomSettingsDialog_rolesIcon",
<RolesRoomSettingsTab roomId={space.roomId} />,
),
SettingsStore.getValue(UIFeature.AdvancedSettings)
? new Tab(
SpaceSettingsTab.Advanced,

View file

@ -28,36 +28,31 @@ import { compare } from "../../../../../utils/strings";
import ErrorDialog from '../../../dialogs/ErrorDialog';
import PowerSelector from "../../../elements/PowerSelector";
const plEventsToLabels = {
// These will be translated for us later.
[EventType.RoomAvatar]: _td("Change room avatar"),
[EventType.RoomName]: _td("Change room name"),
[EventType.RoomCanonicalAlias]: _td("Change main address for the room"),
[EventType.RoomHistoryVisibility]: _td("Change history visibility"),
[EventType.RoomPowerLevels]: _td("Change permissions"),
[EventType.RoomTopic]: _td("Change topic"),
[EventType.RoomTombstone]: _td("Upgrade the room"),
[EventType.RoomEncryption]: _td("Enable room encryption"),
[EventType.RoomServerAcl]: _td("Change server ACLs"),
interface IEventShowOpts {
isState?: boolean;
hideForSpace?: boolean;
}
// TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
"im.vector.modular.widgets": _td("Modify widgets"),
};
interface IPowerLevelDescriptor {
desc: string;
defaultValue: number;
hideForSpace?: boolean;
}
const plEventsToShow = {
const plEventsToShow: Record<string, IEventShowOpts> = {
// If an event is listed here, it will be shown in the PL settings. Defaults will be calculated.
[EventType.RoomAvatar]: { isState: true },
[EventType.RoomName]: { isState: true },
[EventType.RoomCanonicalAlias]: { isState: true },
[EventType.RoomHistoryVisibility]: { isState: true },
[EventType.RoomHistoryVisibility]: { isState: true, hideForSpace: true },
[EventType.RoomPowerLevels]: { isState: true },
[EventType.RoomTopic]: { isState: true },
[EventType.RoomTombstone]: { isState: true },
[EventType.RoomEncryption]: { isState: true },
[EventType.RoomServerAcl]: { isState: true },
[EventType.RoomTombstone]: { isState: true, hideForSpace: true },
[EventType.RoomEncryption]: { isState: true, hideForSpace: true },
[EventType.RoomServerAcl]: { isState: true, hideForSpace: true },
// TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
"im.vector.modular.widgets": { isState: true },
"im.vector.modular.widgets": { isState: true, hideForSpace: true },
};
// parse a string as an integer; if the input is undefined, or cannot be parsed
@ -145,7 +140,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
private onPowerLevelsChanged = (inputValue: string, powerLevelKey: string) => {
const client = MatrixClientPeg.get();
const room = client.getRoom(this.props.roomId);
const plEvent = room.currentState.getStateEvents('m.room.power_levels', '');
const plEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, '');
let plContent = plEvent ? (plEvent.getContent() || {}) : {};
// Clone the power levels just in case
@ -173,7 +168,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
parentObj[keyPath[keyPath.length - 1]] = value;
}
client.sendStateEvent(this.props.roomId, "m.room.power_levels", plContent).catch(e => {
client.sendStateEvent(this.props.roomId, EventType.RoomPowerLevels, plContent).catch(e => {
console.error(e);
Modal.createTrackedDialog('Power level requirement change failed', '', ErrorDialog, {
@ -189,7 +184,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
private onUserPowerLevelChanged = (value: string, powerLevelKey: string) => {
const client = MatrixClientPeg.get();
const room = client.getRoom(this.props.roomId);
const plEvent = room.currentState.getStateEvents('m.room.power_levels', '');
const plEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, '');
let plContent = plEvent ? (plEvent.getContent() || {}) : {};
// Clone the power levels just in case
@ -199,7 +194,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
if (!plContent['users']) plContent['users'] = {};
plContent['users'][powerLevelKey] = value;
client.sendStateEvent(this.props.roomId, "m.room.power_levels", plContent).catch(e => {
client.sendStateEvent(this.props.roomId, EventType.RoomPowerLevels, plContent).catch(e => {
console.error(e);
Modal.createTrackedDialog('Power level change failed', '', ErrorDialog, {
@ -215,11 +210,31 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
render() {
const client = MatrixClientPeg.get();
const room = client.getRoom(this.props.roomId);
const plEvent = room.currentState.getStateEvents('m.room.power_levels', '');
const plContent = plEvent ? (plEvent.getContent() || {}) : {};
const canChangeLevels = room.currentState.mayClientSendStateEvent('m.room.power_levels', client);
const isSpaceRoom = room.isSpaceRoom();
const powerLevelDescriptors = {
const plEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, '');
const plContent = plEvent ? (plEvent.getContent() || {}) : {};
const canChangeLevels = room.currentState.mayClientSendStateEvent(EventType.RoomPowerLevels, client);
const plEventsToLabels = {
// These will be translated for us later.
[EventType.RoomAvatar]: isSpaceRoom ? _td("Change space avatar") : _td("Change room avatar"),
[EventType.RoomName]: isSpaceRoom ? _td("Change space name") : _td("Change room name"),
[EventType.RoomCanonicalAlias]: isSpaceRoom
? _td("Change main address for the space")
: _td("Change main address for the room"),
[EventType.RoomHistoryVisibility]: _td("Change history visibility"),
[EventType.RoomPowerLevels]: _td("Change permissions"),
[EventType.RoomTopic]: isSpaceRoom ? _td("Change description") : _td("Change topic"),
[EventType.RoomTombstone]: _td("Upgrade the room"),
[EventType.RoomEncryption]: _td("Enable room encryption"),
[EventType.RoomServerAcl]: _td("Change server ACLs"),
// TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
"im.vector.modular.widgets": isSpaceRoom ? null : _td("Modify widgets"),
};
const powerLevelDescriptors: Record<string, IPowerLevelDescriptor> = {
"users_default": {
desc: _t('Default role'),
defaultValue: 0,
@ -227,6 +242,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
"events_default": {
desc: _t('Send messages'),
defaultValue: 0,
hideForSpace: true,
},
"invite": {
desc: _t('Invite users'),
@ -247,10 +263,12 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
"redact": {
desc: _t('Remove messages sent by others'),
defaultValue: 50,
hideForSpace: true,
},
"notifications.room": {
desc: _t('Notify everyone'),
defaultValue: 50,
hideForSpace: true,
},
};
@ -361,6 +379,9 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
const powerSelectors = Object.keys(powerLevelDescriptors).map((key, index) => {
const descriptor = powerLevelDescriptors[key];
if (isSpaceRoom && descriptor.hideForSpace) {
return null;
}
const keyPath = key.split('.');
let currentObj = plContent;
@ -382,14 +403,18 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
onChange={this.onPowerLevelsChanged}
/>
</div>;
});
}).filter(Boolean);
// hide the power level selector for enabling E2EE if it the room is already encrypted
if (client.isRoomEncrypted(this.props.roomId)) {
delete eventsLevels["m.room.encryption"];
delete eventsLevels[EventType.RoomEncryption];
}
const eventPowerSelectors = Object.keys(eventsLevels).map((eventType, i) => {
if (isSpaceRoom && plEventsToShow[eventType].hideForSpace) {
return null;
}
let label = plEventsToLabels[eventType];
if (label) {
label = _t(label);
@ -408,7 +433,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
/>
</div>
);
});
}).filter(Boolean);
return (
<div className="mx_SettingsTab mx_RolesRoomSettingsTab">
@ -418,7 +443,10 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
{ bannedUsersSection }
<div className='mx_SettingsTab_section mx_SettingsTab_subsectionText'>
<span className='mx_SettingsTab_subheading'>{ _t("Permissions") }</span>
<p>{ _t('Select the roles required to change various parts of the room') }</p>
<p>{ isSpaceRoom
? _t('Select the roles required to change various parts of the space')
: _t('Select the roles required to change various parts of the room')
}</p>
{ powerSelectors }
{ eventPowerSelectors }
</div>