diff --git a/src/Roles.js b/src/Roles.js index 83d8192c67..438b6c1236 100644 --- a/src/Roles.js +++ b/src/Roles.js @@ -15,19 +15,20 @@ limitations under the License. */ import { _t } from './languageHandler'; -export function levelRoleMap() { +export function levelRoleMap(usersDefault) { return { undefined: _t('Default'), - 0: _t('User'), + 0: _t('Restricted'), + [usersDefault]: _t('Default'), 50: _t('Moderator'), 100: _t('Admin'), }; } -export function textualPowerLevel(level, userDefault) { - const LEVEL_ROLE_MAP = this.levelRoleMap(); +export function textualPowerLevel(level, usersDefault) { + const LEVEL_ROLE_MAP = this.levelRoleMap(usersDefault); if (LEVEL_ROLE_MAP[level]) { - return LEVEL_ROLE_MAP[level] + (level !== undefined ? ` (${level})` : ` (${userDefault})`); + return LEVEL_ROLE_MAP[level] + (level !== undefined ? ` (${level})` : ` (${usersDefault})`); } else { return level; } diff --git a/src/components/views/elements/PowerSelector.js b/src/components/views/elements/PowerSelector.js index 8dd848db00..d5c167fac9 100644 --- a/src/components/views/elements/PowerSelector.js +++ b/src/components/views/elements/PowerSelector.js @@ -25,6 +25,11 @@ module.exports = React.createClass({ propTypes: { 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 ; + customPicker = = + ; } - customPicker = of { input }; } let selectValue; if (this.state.custom) { selectValue = "SELECT_VALUE_CUSTOM"; } else { - selectValue = this.state.levelRoleMap[selectValue] ? + selectValue = this.state.levelRoleMap[this.props.value] ? this.props.value : "SELECT_VALUE_CUSTOM"; } let select; @@ -105,13 +130,10 @@ module.exports = React.createClass({ select = { this.state.levelRoleMap[selectValue] }; } else { // Each level must have a definition in this.state.levelRoleMap - const levels = [0, 50, 100]; - let options = levels.map((level) => { + let options = this.state.options.map((level) => { return { value: level, - // Give a userDefault (users_default in the power event) of 0 but - // because level !== undefined, this should never be used. - text: Roles.textualPowerLevel(level, 0), + text: Roles.textualPowerLevel(level, this.props.usersDefault), }; }); options.push({ value: "SELECT_VALUE_CUSTOM", text: _t("Custom level") }); diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index c043b3714d..4d875ea24a 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -494,7 +494,6 @@ module.exports = withMatrixClient(React.createClass({ const defaultPerms = { can: {}, muted: false, - modifyLevel: false, }; const room = this.props.matrixClient.getRoom(member.roomId); if (!room) return defaultPerms; @@ -516,13 +515,15 @@ module.exports = withMatrixClient(React.createClass({ }, _calculateCanPermissions: function(me, them, powerLevels) { + const isMe = me.userId === them.userId; const can = { kick: false, ban: false, mute: false, modifyLevel: false, + modifyLevelMax: 0, }; - const canAffectUser = them.powerLevel < me.powerLevel; + const canAffectUser = them.powerLevel < me.powerLevel || isMe; if (!canAffectUser) { //console.log("Cannot affect user: %s >= %s", them.powerLevel, me.powerLevel); return can; @@ -531,16 +532,13 @@ module.exports = withMatrixClient(React.createClass({ (powerLevels.events ? powerLevels.events["m.room.power_levels"] : null) || powerLevels.state_default ); - const levelToSend = ( - (powerLevels.events ? powerLevels.events["m.room.message"] : null) || - powerLevels.events_default - ); can.kick = me.powerLevel >= powerLevels.kick; can.ban = me.powerLevel >= powerLevels.ban; can.mute = me.powerLevel >= editPowerLevel; - can.toggleMod = me.powerLevel > them.powerLevel && them.powerLevel >= levelToSend; - can.modifyLevel = me.powerLevel > them.powerLevel && me.powerLevel >= editPowerLevel; + can.modifyLevel = me.powerLevel >= editPowerLevel && (isMe || me.powerLevel > them.powerLevel); + can.modifyLevelMax = me.powerLevel; + return can; }, @@ -832,8 +830,11 @@ module.exports = withMatrixClient(React.createClass({ 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 const PowerSelector = sdk.getComponent('elements.PowerSelector'); const PresenceLabel = sdk.getComponent('rooms.PresenceLabel'); @@ -842,7 +843,9 @@ module.exports = withMatrixClient(React.createClass({ { _t("Level:") } diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index c7e839ab40..40a3209362 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -910,31 +910,31 @@ module.exports = React.createClass({
{ _t('The default role for new room members is') } - +
{ _t('To send messages, you must be a') } - +
{ _t('To invite users into the room, you must be a') } - +
{ _t('To configure the room, you must be a') } - +
{ _t('To kick users, you must be a') } - +
{ _t('To ban users, you must be a') } - +
{ _t('To remove other users\' messages, you must be a') } - +
{ Object.keys(events_levels).map(function(event_type, i) { @@ -944,7 +944,7 @@ module.exports = React.createClass({ return (
{ label } -
); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 37605cf1e8..04b30c1a07 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -63,7 +63,7 @@ "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.", "Default": "Default", - "User": "User", + "Restricted": "Restricted", "Moderator": "Moderator", "Admin": "Admin", "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 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", - "Communities": "Communities", "Message Pinning": "Message Pinning", "%(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", @@ -525,6 +524,7 @@ "Unverify": "Unverify", "Verify...": "Verify...", "No results": "No results", + "Communities": "Communities", "Home": "Home", "Integrations Error": "Integrations Error", "Could not connect to the integration server": "Could not connect to the integration server", @@ -581,6 +581,7 @@ "%(items)s and %(count)s others|other": "%(items)s and %(count)s others", "%(items)s and %(count)s others|one": "%(items)s and one other", "%(items)s and %(lastItem)s": "%(items)s and %(lastItem)s", + "Custom of %(powerLevel)s": "Custom of %(powerLevel)s", "Custom level": "Custom level", "Room directory": "Room directory", "Start chat": "Start chat",