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 should be a 'controlled' form element and updated by React
// to reflect the current value, rather than left freeform.
@@ -41,63 +46,83 @@ module.exports = React.createClass({
getInitialState: function() {
return {
levelRoleMap: {},
+ // List of power levels to show in the drop-down
+ options: [],
+ };
+ },
+
+ getDefaultProps: function() {
+ return {
+ maxValue: Infinity,
+ usersDefault: 0,
};
},
componentWillMount: function() {
+ this._initStateFromProps(this.props);
+ },
+
+ componentWillReceiveProps: function(newProps) {
+ this._initStateFromProps(newProps);
+ },
+
+ _initStateFromProps: function(newProps) {
// This needs to be done now because levelRoleMap has translated strings
- const levelRoleMap = Roles.levelRoleMap();
+ const levelRoleMap = Roles.levelRoleMap(newProps.usersDefault);
+ const options = Object.keys(levelRoleMap).filter((l) => {
+ return l === undefined || l <= newProps.maxValue;
+ });
+
this.setState({
levelRoleMap,
- custom: levelRoleMap[this.props.value] === undefined,
+ options,
+ custom: levelRoleMap[newProps.value] === undefined,
});
},
onSelectChange: function(event) {
this.setState({ custom: event.target.value === "SELECT_VALUE_CUSTOM" });
if (event.target.value !== "SELECT_VALUE_CUSTOM") {
- this.props.onChange(this.getValue());
+ this.props.onChange(event.target.value);
}
},
onCustomBlur: function(event) {
- this.props.onChange(this.getValue());
+ this.props.onChange(parseInt(this.refs.custom.value));
},
onCustomKeyDown: function(event) {
if (event.key == "Enter") {
- this.props.onChange(this.getValue());
+ this.props.onChange(parseInt(this.refs.custom.value));
}
},
- getValue: function() {
- let value;
- if (this.refs.select) {
- value = this.refs.select.value;
- if (this.refs.custom) {
- if (value === undefined) value = parseInt( this.refs.custom.value );
- }
- }
- return value;
- },
-
render: function() {
let customPicker;
if (this.state.custom) {
- let input;
if (this.props.disabled) {
- input = { this.props.value };
+ customPicker = { _t(
+ "Custom of %(powerLevel)s",
+ { powerLevel: this.props.value },
+ ) };
} else {
- input = ;
+ 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:") }