Merge pull request #6779 from matrix-org/t3chguy/fix/18908

This commit is contained in:
Michael Telatynski 2021-09-10 19:32:03 +01:00 committed by GitHub
commit ac0ba2d597
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 43 deletions

View file

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

View file

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

View file

@ -56,7 +56,7 @@ export const createSpace = async (
power_level_content_override: { power_level_content_override: {
// Only allow Admins to write to the timeline to prevent hidden sync spam // Only allow Admins to write to the timeline to prevent hidden sync spam
events_default: 100, events_default: 100,
...isPublic ? { invite: 0 } : {}, invite: isPublic ? 0 : 50,
}, },
room_alias_name: isPublic && alias ? alias.substr(1, alias.indexOf(":") - 1) : undefined, room_alias_name: isPublic && alias ? alias.substr(1, alias.indexOf(":") - 1) : undefined,
topic, topic,

View file

@ -1432,16 +1432,6 @@
"Notification sound": "Notification sound", "Notification sound": "Notification sound",
"Set a new custom sound": "Set a new custom sound", "Set a new custom sound": "Set a new custom sound",
"Browse": "Browse", "Browse": "Browse",
"Change room avatar": "Change room avatar",
"Change room name": "Change room name",
"Change main address for the room": "Change main address for the room",
"Change history visibility": "Change history visibility",
"Change permissions": "Change permissions",
"Change topic": "Change topic",
"Upgrade the room": "Upgrade the room",
"Enable room encryption": "Enable room encryption",
"Change server ACLs": "Change server ACLs",
"Modify widgets": "Modify widgets",
"Failed to unban": "Failed to unban", "Failed to unban": "Failed to unban",
"Unban": "Unban", "Unban": "Unban",
"Banned by %(displayName)s": "Banned by %(displayName)s", "Banned by %(displayName)s": "Banned by %(displayName)s",
@ -1450,6 +1440,20 @@
"An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.", "An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.",
"Error changing power level": "Error changing power level", "Error changing power level": "Error changing power level",
"An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.": "An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.", "An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.": "An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.",
"Change space avatar": "Change space avatar",
"Change room avatar": "Change room avatar",
"Change space name": "Change space name",
"Change room name": "Change room name",
"Change main address for the space": "Change main address for the space",
"Change main address for the room": "Change main address for the room",
"Change history visibility": "Change history visibility",
"Change permissions": "Change permissions",
"Change description": "Change description",
"Change topic": "Change topic",
"Upgrade the room": "Upgrade the room",
"Enable room encryption": "Enable room encryption",
"Change server ACLs": "Change server ACLs",
"Modify widgets": "Modify widgets",
"Default role": "Default role", "Default role": "Default role",
"Send messages": "Send messages", "Send messages": "Send messages",
"Invite users": "Invite users", "Invite users": "Invite users",
@ -1464,6 +1468,7 @@
"Banned users": "Banned users", "Banned users": "Banned users",
"Send %(eventType)s events": "Send %(eventType)s events", "Send %(eventType)s events": "Send %(eventType)s events",
"Permissions": "Permissions", "Permissions": "Permissions",
"Select the roles required to change various parts of the space": "Select the roles required to change various parts of the space",
"Select the roles required to change various parts of the room": "Select the roles required to change various parts of the room", "Select the roles required to change various parts of the room": "Select the roles required to change various parts of the room",
"Are you sure you want to add encryption to this public room?": "Are you sure you want to add encryption to this public room?", "Are you sure you want to add encryption to this public room?": "Are you sure you want to add encryption to this public room?",
"<b>It's not recommended to add encryption to public rooms.</b>Anyone can find and join public rooms, so anyone can read messages in them. You'll get none of the benefits of encryption, and you won't be able to turn it off later. Encrypting messages in a public room will make receiving and sending messages slower.": "<b>It's not recommended to add encryption to public rooms.</b>Anyone can find and join public rooms, so anyone can read messages in them. You'll get none of the benefits of encryption, and you won't be able to turn it off later. Encrypting messages in a public room will make receiving and sending messages slower.", "<b>It's not recommended to add encryption to public rooms.</b>Anyone can find and join public rooms, so anyone can read messages in them. You'll get none of the benefits of encryption, and you won't be able to turn it off later. Encrypting messages in a public room will make receiving and sending messages slower.": "<b>It's not recommended to add encryption to public rooms.</b>Anyone can find and join public rooms, so anyone can read messages in them. You'll get none of the benefits of encryption, and you won't be able to turn it off later. Encrypting messages in a public room will make receiving and sending messages slower.",