From d3dc2a33b48861139b3ecee0eb31537b6a58b4cf Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 28 Feb 2018 16:16:44 +0000 Subject: [PATCH] Fix bug preventing setting room power levels - don't use refs, use onChange of PowerSelector - store power levels as state in the RoomSetting component --- src/components/views/rooms/RoomSettings.js | 222 ++++++++++-------- .../views/rooms/RoomSettings-test.js | 2 - 2 files changed, 128 insertions(+), 96 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 2bd2fbb8f1..e2dad93698 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -131,7 +131,8 @@ module.exports = React.createClass({ join_rule: this._yankValueFromEvent("m.room.join_rules", "join_rule"), history_visibility: this._yankValueFromEvent("m.room.history_visibility", "history_visibility"), guest_access: this._yankValueFromEvent("m.room.guest_access", "guest_access"), - power_levels_changed: false, + powerLevels: this._yankContentFromEvent("m.room.power_levels", {}), + powerLevelsChanged: false, tags_changed: false, tags: tags, // isRoomPublished is loaded async in componentWillMount so when the component @@ -271,8 +272,8 @@ module.exports = React.createClass({ // power levels - const powerLevels = this._getPowerLevels(); - if (powerLevels) { + const powerLevels = this.state.powerLevels; + if (this.state.powerLevelsChanged) { promises.push(MatrixClientPeg.get().sendStateEvent( roomId, "m.room.power_levels", powerLevels, "", )); @@ -383,36 +384,32 @@ module.exports = React.createClass({ return strA !== strB; }, - _getPowerLevels: function() { - if (!this.state.power_levels_changed) return undefined; + onPowerLevelsChanged: function(value, powerLevelKey) { + const powerLevels = Object.assign({}, this.state.powerLevels); + const eventsLevelPrefix = "event_levels_"; - let powerLevels = this.props.room.currentState.getStateEvents('m.room.power_levels', ''); - powerLevels = powerLevels ? powerLevels.getContent() : {}; + value = parseInt(value); - for (const key of Object.keys(this.refs).filter((k) => k.startsWith("event_levels_"))) { - const eventType = key.substring("event_levels_".length); - powerLevels.events[eventType] = parseInt(this.refs[key].getValue()); + if (powerLevelKey.startsWith(eventsLevelPrefix)) { + // deep copy "events" object, Object.assign itself won't deep copy + powerLevels["events"] = Object.assign({}, this.state.powerLevels["events"] || {}); + powerLevels["events"][powerLevelKey.slice(eventsLevelPrefix.length)] = value; + } else { + powerLevels[powerLevelKey] = value; } - - const newPowerLevels = { - ban: parseInt(this.refs.ban.getValue()), - kick: parseInt(this.refs.kick.getValue()), - redact: parseInt(this.refs.redact.getValue()), - invite: parseInt(this.refs.invite.getValue()), - events_default: parseInt(this.refs.events_default.getValue()), - state_default: parseInt(this.refs.state_default.getValue()), - users_default: parseInt(this.refs.users_default.getValue()), - users: powerLevels.users, - events: powerLevels.events, - }; - - return newPowerLevels; + this.setState({ + powerLevels, + powerLevelsChanged: true, + }); }, - onPowerLevelsChanged: function() { - this.setState({ - power_levels_changed: true, - }); + _yankContentFromEvent: function(stateEventType, defaultValue) { + // E.g.("m.room.name") would yank the content of "m.room.name" + const event = this.props.room.currentState.getStateEvents(stateEventType, ''); + if (!event) { + return defaultValue; + } + return event.getContent() || defaultValue; }, _yankValueFromEvent: function(stateEventType, keyName, defaultValue) { @@ -632,29 +629,61 @@ module.exports = React.createClass({ const cli = MatrixClientPeg.get(); const roomState = this.props.room.currentState; - const user_id = cli.credentials.userId; + const myUserId = cli.credentials.userId; - const power_level_event = roomState.getStateEvents('m.room.power_levels', ''); - const power_levels = power_level_event ? power_level_event.getContent() : {}; - const events_levels = power_levels.events || {}; - const user_levels = power_levels.users || {}; + const powerLevels = this.state.powerLevels; + const eventsLevels = powerLevels.events || {}; + const userLevels = powerLevels.users || {}; - const ban_level = parseIntWithDefault(power_levels.ban, 50); - const kick_level = parseIntWithDefault(power_levels.kick, 50); - const redact_level = parseIntWithDefault(power_levels.redact, 50); - const invite_level = parseIntWithDefault(power_levels.invite, 50); - const send_level = parseIntWithDefault(power_levels.events_default, 0); - const state_level = power_level_event ? parseIntWithDefault(power_levels.state_default, 50) : 0; - const default_user_level = parseIntWithDefault(power_levels.users_default, 0); + const powerLevelDescriptors = { + users_default: { + desc: _t('The default role for new room members is'), + defaultValue: 0, + }, + events_default: { + desc: _t('To send messages, you must be a'), + defaultValue: 0, + }, + invite: { + desc: _t('To invite users into the room, you must be a'), + defaultValue: 50, + }, + state_default: { + desc: _t('To configure the room, you must be a'), + defaultValue: 50, + }, + kick: { + desc: _t('To kick users, you must be a'), + defaultValue: 50, + }, + ban: { + desc: _t('To ban users, you must be a'), + defaultValue: 50, + }, + redact: { + desc: _t('To remove other users\' messages, you must be a'), + defaultValue: 50, + }, + }; - this._populateDefaultPlEvents(events_levels, state_level, send_level); + const banLevel = parseIntWithDefault(powerLevels.ban, powerLevelDescriptors.ban.defaultValue); + const defaultUserLevel = parseIntWithDefault( + powerLevels.users_default, + powerLevelDescriptors.users_default.defaultValue, + ); - let current_user_level = user_levels[user_id]; - if (current_user_level === undefined) { - current_user_level = default_user_level; + this._populateDefaultPlEvents( + eventsLevels, + parseIntWithDefault(powerLevels.state_default, powerLevelDescriptors.state_default.defaultValue), + parseIntWithDefault(powerLevels.events_default, powerLevelDescriptors.events_default.defaultValue), + ); + + let currentUserLevel = userLevels[myUserId]; + if (currentUserLevel === undefined) { + currentUserLevel = defaultUserLevel; } - const can_change_levels = roomState.mayClientSendStateEvent("m.room.power_levels", cli); + const canChangeLevels = roomState.mayClientSendStateEvent("m.room.power_levels", cli); const canSetTag = !cli.isGuest(); @@ -667,15 +696,16 @@ module.exports = React.createClass({ />; let userLevelsSection; - if (Object.keys(user_levels).length) { + if (Object.keys(userLevels).length) { userLevelsSection =

{ _t('Privileged Users') }