Attempt to clarify the affect that the users_default has on power levels
This modifies displayed power levels such that: - If users_default is !== 0: - the power level 0 is displayed as "Restricted (0)" - the power level users_default is displayed as "Default ({users_default})" - Otherwise: - the power level 0 is displayed as "Default (0)" When changing users_default, to say, 10, when the textual powers are rendered again, they will take users_default into account. So those previously at 10 and which would have previously have been rendered "Custom of 10" will now read "Default (10)". Conversely, those that were "Default (0)" will now read "Restricted (0)".
This commit is contained in:
parent
88010fa26c
commit
52af7a7659
5 changed files with 72 additions and 32 deletions
11
src/Roles.js
11
src/Roles.js
|
@ -15,19 +15,20 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { _t } from './languageHandler';
|
import { _t } from './languageHandler';
|
||||||
|
|
||||||
export function levelRoleMap() {
|
export function levelRoleMap(usersDefault) {
|
||||||
return {
|
return {
|
||||||
undefined: _t('Default'),
|
undefined: _t('Default'),
|
||||||
0: _t('User'),
|
0: _t('Restricted'),
|
||||||
|
[usersDefault]: _t('Default'),
|
||||||
50: _t('Moderator'),
|
50: _t('Moderator'),
|
||||||
100: _t('Admin'),
|
100: _t('Admin'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function textualPowerLevel(level, userDefault) {
|
export function textualPowerLevel(level, usersDefault) {
|
||||||
const LEVEL_ROLE_MAP = this.levelRoleMap();
|
const LEVEL_ROLE_MAP = this.levelRoleMap(usersDefault);
|
||||||
if (LEVEL_ROLE_MAP[level]) {
|
if (LEVEL_ROLE_MAP[level]) {
|
||||||
return LEVEL_ROLE_MAP[level] + (level !== undefined ? ` (${level})` : ` (${userDefault})`);
|
return LEVEL_ROLE_MAP[level] + (level !== undefined ? ` (${level})` : ` (${usersDefault})`);
|
||||||
} else {
|
} else {
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,11 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
value: React.PropTypes.number.isRequired,
|
value: React.PropTypes.number.isRequired,
|
||||||
|
// The maximum value that can be set with the power selector
|
||||||
|
maxValue: React.PropTypes.number.isRequired,
|
||||||
|
|
||||||
|
// Default user power level for the room
|
||||||
|
usersDefault: React.PropTypes.number.isRequired,
|
||||||
|
|
||||||
// if true, the <select/> should be a 'controlled' form element and updated by React
|
// if true, the <select/> should be a 'controlled' form element and updated by React
|
||||||
// to reflect the current value, rather than left freeform.
|
// to reflect the current value, rather than left freeform.
|
||||||
|
@ -42,21 +47,48 @@ module.exports = React.createClass({
|
||||||
return {
|
return {
|
||||||
levelRoleMap: {},
|
levelRoleMap: {},
|
||||||
reverseRoles: {},
|
reverseRoles: {},
|
||||||
|
// List of power levels to show in the drop-down
|
||||||
|
options: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultProps: function() {
|
||||||
|
return {
|
||||||
|
maxValue: Infinity,
|
||||||
|
usersDefault: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
|
this._initStateFromProps(this.props, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillReceiveProps: function(newProps) {
|
||||||
|
this._initStateFromProps(newProps);
|
||||||
|
},
|
||||||
|
|
||||||
|
_initStateFromProps: function(newProps, initial) {
|
||||||
// This needs to be done now because levelRoleMap has translated strings
|
// This needs to be done now because levelRoleMap has translated strings
|
||||||
const levelRoleMap = Roles.levelRoleMap();
|
const levelRoleMap = Roles.levelRoleMap(newProps.usersDefault);
|
||||||
const reverseRoles = {};
|
const reverseRoles = {};
|
||||||
Object.keys(levelRoleMap).forEach(function(key) {
|
Object.keys(levelRoleMap).forEach(function(key) {
|
||||||
reverseRoles[levelRoleMap[key]] = key;
|
reverseRoles[levelRoleMap[key]] = key;
|
||||||
});
|
});
|
||||||
|
const options = Object.keys(levelRoleMap).filter((l) => {
|
||||||
|
return l === undefined || l <= newProps.maxValue;
|
||||||
|
});
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
levelRoleMap,
|
levelRoleMap,
|
||||||
reverseRoles,
|
reverseRoles,
|
||||||
custom: levelRoleMap[this.props.value] === undefined,
|
options,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (initial) {
|
||||||
|
this.setState({
|
||||||
|
custom: levelRoleMap[newProps.value] === undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onSelectChange: function(event) {
|
onSelectChange: function(event) {
|
||||||
|
@ -94,7 +126,14 @@ module.exports = React.createClass({
|
||||||
if (this.props.disabled) {
|
if (this.props.disabled) {
|
||||||
input = <span>{ this.props.value }</span>;
|
input = <span>{ this.props.value }</span>;
|
||||||
} else {
|
} else {
|
||||||
input = <input ref="custom" type="text" size="3" defaultValue={this.props.value} onBlur={this.onCustomBlur} onKeyDown={this.onCustomKeyDown} />;
|
input = <input
|
||||||
|
ref="custom"
|
||||||
|
type="text"
|
||||||
|
size="3"
|
||||||
|
defaultValue={this.props.value}
|
||||||
|
onBlur={this.onCustomBlur}
|
||||||
|
onKeyDown={this.onCustomKeyDown}
|
||||||
|
/>;
|
||||||
}
|
}
|
||||||
customPicker = <span> of { input }</span>;
|
customPicker = <span> of { input }</span>;
|
||||||
}
|
}
|
||||||
|
@ -110,13 +149,10 @@ module.exports = React.createClass({
|
||||||
select = <span>{ selectValue }</span>;
|
select = <span>{ selectValue }</span>;
|
||||||
} else {
|
} else {
|
||||||
// Each level must have a definition in this.state.levelRoleMap
|
// Each level must have a definition in this.state.levelRoleMap
|
||||||
const levels = [0, 50, 100];
|
let options = this.state.options.map((level) => {
|
||||||
let options = levels.map((level) => {
|
|
||||||
return {
|
return {
|
||||||
value: this.state.levelRoleMap[level],
|
value: this.state.levelRoleMap[level],
|
||||||
// Give a userDefault (users_default in the power event) of 0 but
|
text: Roles.textualPowerLevel(level, this.props.usersDefault),
|
||||||
// because level !== undefined, this should never be used.
|
|
||||||
text: Roles.textualPowerLevel(level, 0),
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
options.push({ value: "Custom", text: _t("Custom level") });
|
options.push({ value: "Custom", text: _t("Custom level") });
|
||||||
|
|
|
@ -494,7 +494,6 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
const defaultPerms = {
|
const defaultPerms = {
|
||||||
can: {},
|
can: {},
|
||||||
muted: false,
|
muted: false,
|
||||||
modifyLevel: false,
|
|
||||||
};
|
};
|
||||||
const room = this.props.matrixClient.getRoom(member.roomId);
|
const room = this.props.matrixClient.getRoom(member.roomId);
|
||||||
if (!room) return defaultPerms;
|
if (!room) return defaultPerms;
|
||||||
|
@ -516,13 +515,15 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_calculateCanPermissions: function(me, them, powerLevels) {
|
_calculateCanPermissions: function(me, them, powerLevels) {
|
||||||
|
const isMe = me.userId === them.userId;
|
||||||
const can = {
|
const can = {
|
||||||
kick: false,
|
kick: false,
|
||||||
ban: false,
|
ban: false,
|
||||||
mute: false,
|
mute: false,
|
||||||
modifyLevel: false,
|
modifyLevel: false,
|
||||||
|
modifyLevelMax: 0,
|
||||||
};
|
};
|
||||||
const canAffectUser = them.powerLevel < me.powerLevel;
|
const canAffectUser = them.powerLevel < me.powerLevel || isMe;
|
||||||
if (!canAffectUser) {
|
if (!canAffectUser) {
|
||||||
//console.log("Cannot affect user: %s >= %s", them.powerLevel, me.powerLevel);
|
//console.log("Cannot affect user: %s >= %s", them.powerLevel, me.powerLevel);
|
||||||
return can;
|
return can;
|
||||||
|
@ -531,16 +532,13 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
(powerLevels.events ? powerLevels.events["m.room.power_levels"] : null) ||
|
(powerLevels.events ? powerLevels.events["m.room.power_levels"] : null) ||
|
||||||
powerLevels.state_default
|
powerLevels.state_default
|
||||||
);
|
);
|
||||||
const levelToSend = (
|
|
||||||
(powerLevels.events ? powerLevels.events["m.room.message"] : null) ||
|
|
||||||
powerLevels.events_default
|
|
||||||
);
|
|
||||||
|
|
||||||
can.kick = me.powerLevel >= powerLevels.kick;
|
can.kick = me.powerLevel >= powerLevels.kick;
|
||||||
can.ban = me.powerLevel >= powerLevels.ban;
|
can.ban = me.powerLevel >= powerLevels.ban;
|
||||||
can.mute = me.powerLevel >= editPowerLevel;
|
can.mute = me.powerLevel >= editPowerLevel;
|
||||||
can.toggleMod = me.powerLevel > them.powerLevel && them.powerLevel >= levelToSend;
|
can.modifyLevel = me.powerLevel >= editPowerLevel && (isMe || me.powerLevel > them.powerLevel);
|
||||||
can.modifyLevel = me.powerLevel > them.powerLevel && me.powerLevel >= editPowerLevel;
|
can.modifyLevelMax = me.powerLevel;
|
||||||
|
|
||||||
return can;
|
return can;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -832,8 +830,11 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
presenceCurrentlyActive = this.props.member.user.currentlyActive;
|
presenceCurrentlyActive = this.props.member.user.currentlyActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
let roomMemberDetails = null;
|
const room = this.props.matrixClient.getRoom(this.props.member.roomId);
|
||||||
|
const poweLevelEvent = room ? room.currentState.getStateEvents("m.room.power_levels", "") : null;
|
||||||
|
const powerLevelUsersDefault = poweLevelEvent.getContent().users_default;
|
||||||
|
|
||||||
|
let roomMemberDetails = null;
|
||||||
if (this.props.member.roomId) { // is in room
|
if (this.props.member.roomId) { // is in room
|
||||||
const PowerSelector = sdk.getComponent('elements.PowerSelector');
|
const PowerSelector = sdk.getComponent('elements.PowerSelector');
|
||||||
const PresenceLabel = sdk.getComponent('rooms.PresenceLabel');
|
const PresenceLabel = sdk.getComponent('rooms.PresenceLabel');
|
||||||
|
@ -842,7 +843,9 @@ module.exports = withMatrixClient(React.createClass({
|
||||||
{ _t("Level:") } <b>
|
{ _t("Level:") } <b>
|
||||||
<PowerSelector controlled={true}
|
<PowerSelector controlled={true}
|
||||||
value={parseInt(this.props.member.powerLevel)}
|
value={parseInt(this.props.member.powerLevel)}
|
||||||
|
maxValue={this.state.can.modifyLevelMax}
|
||||||
disabled={!this.state.can.modifyLevel}
|
disabled={!this.state.can.modifyLevel}
|
||||||
|
usersDefault={powerLevelUsersDefault}
|
||||||
onChange={this.onPowerChange} />
|
onChange={this.onPowerChange} />
|
||||||
</b>
|
</b>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -910,31 +910,31 @@ module.exports = React.createClass({
|
||||||
<div className="mx_RoomSettings_powerLevels mx_RoomSettings_settings">
|
<div className="mx_RoomSettings_powerLevels mx_RoomSettings_settings">
|
||||||
<div className="mx_RoomSettings_powerLevel">
|
<div className="mx_RoomSettings_powerLevel">
|
||||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('The default role for new room members is') } </span>
|
<span className="mx_RoomSettings_powerLevelKey">{ _t('The default role for new room members is') } </span>
|
||||||
<PowerSelector ref="users_default" value={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < default_user_level} onChange={this.onPowerLevelsChanged} />
|
<PowerSelector ref="users_default" value={default_user_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < default_user_level} onChange={this.onPowerLevelsChanged} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_RoomSettings_powerLevel">
|
<div className="mx_RoomSettings_powerLevel">
|
||||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To send messages, you must be a') } </span>
|
<span className="mx_RoomSettings_powerLevelKey">{ _t('To send messages, you must be a') } </span>
|
||||||
<PowerSelector ref="events_default" value={send_level} controlled={false} disabled={!can_change_levels || current_user_level < send_level} onChange={this.onPowerLevelsChanged} />
|
<PowerSelector ref="events_default" value={send_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < send_level} onChange={this.onPowerLevelsChanged} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_RoomSettings_powerLevel">
|
<div className="mx_RoomSettings_powerLevel">
|
||||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To invite users into the room, you must be a') } </span>
|
<span className="mx_RoomSettings_powerLevelKey">{ _t('To invite users into the room, you must be a') } </span>
|
||||||
<PowerSelector ref="invite" value={invite_level} controlled={false} disabled={!can_change_levels || current_user_level < invite_level} onChange={this.onPowerLevelsChanged} />
|
<PowerSelector ref="invite" value={invite_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < invite_level} onChange={this.onPowerLevelsChanged} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_RoomSettings_powerLevel">
|
<div className="mx_RoomSettings_powerLevel">
|
||||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To configure the room, you must be a') } </span>
|
<span className="mx_RoomSettings_powerLevelKey">{ _t('To configure the room, you must be a') } </span>
|
||||||
<PowerSelector ref="state_default" value={state_level} controlled={false} disabled={!can_change_levels || current_user_level < state_level} onChange={this.onPowerLevelsChanged} />
|
<PowerSelector ref="state_default" value={state_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < state_level} onChange={this.onPowerLevelsChanged} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_RoomSettings_powerLevel">
|
<div className="mx_RoomSettings_powerLevel">
|
||||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To kick users, you must be a') } </span>
|
<span className="mx_RoomSettings_powerLevelKey">{ _t('To kick users, you must be a') } </span>
|
||||||
<PowerSelector ref="kick" value={kick_level} controlled={false} disabled={!can_change_levels || current_user_level < kick_level} onChange={this.onPowerLevelsChanged} />
|
<PowerSelector ref="kick" value={kick_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < kick_level} onChange={this.onPowerLevelsChanged} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_RoomSettings_powerLevel">
|
<div className="mx_RoomSettings_powerLevel">
|
||||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To ban users, you must be a') } </span>
|
<span className="mx_RoomSettings_powerLevelKey">{ _t('To ban users, you must be a') } </span>
|
||||||
<PowerSelector ref="ban" value={ban_level} controlled={false} disabled={!can_change_levels || current_user_level < ban_level} onChange={this.onPowerLevelsChanged} />
|
<PowerSelector ref="ban" value={ban_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < ban_level} onChange={this.onPowerLevelsChanged} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_RoomSettings_powerLevel">
|
<div className="mx_RoomSettings_powerLevel">
|
||||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To remove other users\' messages, you must be a') } </span>
|
<span className="mx_RoomSettings_powerLevelKey">{ _t('To remove other users\' messages, you must be a') } </span>
|
||||||
<PowerSelector ref="redact" value={redact_level} controlled={false} disabled={!can_change_levels || current_user_level < redact_level} onChange={this.onPowerLevelsChanged} />
|
<PowerSelector ref="redact" value={redact_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < redact_level} onChange={this.onPowerLevelsChanged} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ Object.keys(events_levels).map(function(event_type, i) {
|
{ Object.keys(events_levels).map(function(event_type, i) {
|
||||||
|
@ -944,7 +944,7 @@ module.exports = React.createClass({
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomSettings_powerLevel" key={event_type}>
|
<div className="mx_RoomSettings_powerLevel" key={event_type}>
|
||||||
<span className="mx_RoomSettings_powerLevelKey">{ label } </span>
|
<span className="mx_RoomSettings_powerLevelKey">{ label } </span>
|
||||||
<PowerSelector ref={"event_levels_"+event_type} value={events_levels[event_type]} onChange={self.onPowerLevelsChanged}
|
<PowerSelector ref={"event_levels_"+event_type} value={events_levels[event_type]} usersDefault={default_user_level} onChange={self.onPowerLevelsChanged}
|
||||||
controlled={false} disabled={!can_change_levels || current_user_level < events_levels[event_type]} />
|
controlled={false} disabled={!can_change_levels || current_user_level < events_levels[event_type]} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
"This email address was not found": "This email address was not found",
|
"This email address was not found": "This email address was not found",
|
||||||
"Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Your email address does not appear to be associated with a Matrix ID on this Homeserver.",
|
"Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Your email address does not appear to be associated with a Matrix ID on this Homeserver.",
|
||||||
"Default": "Default",
|
"Default": "Default",
|
||||||
"User": "User",
|
"Restricted": "Restricted",
|
||||||
"Moderator": "Moderator",
|
"Moderator": "Moderator",
|
||||||
"Admin": "Admin",
|
"Admin": "Admin",
|
||||||
"Start a chat": "Start a chat",
|
"Start a chat": "Start a chat",
|
||||||
|
@ -150,7 +150,6 @@
|
||||||
"%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s",
|
"%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s",
|
||||||
"%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s",
|
"%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s",
|
||||||
"%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s",
|
"%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s",
|
||||||
"Communities": "Communities",
|
|
||||||
"Message Pinning": "Message Pinning",
|
"Message Pinning": "Message Pinning",
|
||||||
"%(displayName)s is typing": "%(displayName)s is typing",
|
"%(displayName)s is typing": "%(displayName)s is typing",
|
||||||
"%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing",
|
"%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing",
|
||||||
|
@ -524,6 +523,7 @@
|
||||||
"Unverify": "Unverify",
|
"Unverify": "Unverify",
|
||||||
"Verify...": "Verify...",
|
"Verify...": "Verify...",
|
||||||
"No results": "No results",
|
"No results": "No results",
|
||||||
|
"Communities": "Communities",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Integrations Error": "Integrations Error",
|
"Integrations Error": "Integrations Error",
|
||||||
"Could not connect to the integration server": "Could not connect to the integration server",
|
"Could not connect to the integration server": "Could not connect to the integration server",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue