From 87516fb950159589ea725a9ae4ab6ad3ae0848d5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Feb 2017 17:54:57 +0000 Subject: [PATCH 1/5] Add a button to un-ban users in RoomSettings https://github.com/vector-im/riot-web/issues/3091 --- src/components/views/rooms/RoomSettings.js | 57 ++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 4d1285678b..8b156f2ccc 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -35,6 +35,47 @@ function parseIntWithDefault(val, def) { return isNaN(res) ? def : res; } +const BannedUser = React.createClass({ + propTypes: { + member: React.PropTypes.string.isRequired, + }, + + _onUnbanClick: function() { + const ConfirmUserActionDialog = sdk.getComponent("dialogs.ConfirmUserActionDialog"); + Modal.createDialog(ConfirmUserActionDialog, { + member: this.props.member, + action: 'Unban', + danger: false, + onFinished: (proceed) => { + if (!proceed) return; + + MatrixClientPeg.get().unban( + this.props.member.roomId, this.props.member.userId, + ).catch((err) => { + const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createDialog(ErrorDialog, { + title: "Failed to unban", + description: err.message, + }); + }).done(); + }, + }); + }, + + render: function() { + return ( +
  • + + Unban + + {this.props.member.userId} +
  • + ); + } +}); + module.exports = React.createClass({ displayName: 'RoomSettings', @@ -74,6 +115,9 @@ module.exports = React.createClass({ componentWillMount: function() { ScalarMessaging.startListening(); + + MatrixClientPeg.get().on("RoomMember.membership", this._onRoomMemberMembership); + MatrixClientPeg.get().getRoomDirectoryVisibility( this.props.room.roomId ).done((result) => { @@ -102,6 +146,8 @@ module.exports = React.createClass({ componentWillUnmount: function() { ScalarMessaging.stopListening(); + MatrixClientPeg.get().removeListener("RoomMember.membership", this._onRoomMemberMembership); + dis.dispatch({ action: 'ui_opacity', sideOpacity: 1.0, @@ -501,6 +547,11 @@ module.exports = React.createClass({ }); }, + _onRoomMemberMembership: function() { + // Update, since our banned user list may have changed + this.forceUpdate(); + }, + _renderEncryptionSection: function() { var cli = MatrixClientPeg.get(); var roomState = this.props.room.currentState; @@ -611,11 +662,9 @@ module.exports = React.createClass({

    Banned users

    From 431e7a875db2d35f04162c616ee086201f360aba Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Feb 2017 18:10:40 +0000 Subject: [PATCH 2/5] Copyright --- src/components/views/rooms/RoomSettings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 8b156f2ccc..7a9cb2224c 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 Vector Creations Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From c082827fc7e3e11e4790c0306933c751c7a09c65 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 15 Feb 2017 17:12:51 +0000 Subject: [PATCH 3/5] Fix docs & use WithMatrixClient --- src/components/views/rooms/RoomSettings.js | 56 ++++++++++++---------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 7a9cb2224c..783d343890 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -17,7 +17,6 @@ limitations under the License. import q from 'q'; import React from 'react'; -import MatrixClientPeg from '../../../MatrixClientPeg'; import SdkConfig from '../../../SdkConfig'; import sdk from '../../../index'; import Modal from '../../../Modal'; @@ -27,6 +26,7 @@ import ScalarAuthClient from '../../../ScalarAuthClient'; import ScalarMessaging from '../../../ScalarMessaging'; import UserSettingsStore from '../../../UserSettingsStore'; import AccessibleButton from '../elements/AccessibleButton'; +import WithMatrixClient from '../../../wrappers/WithMatrixClient'; // parse a string as an integer; if the input is undefined, or cannot be parsed @@ -36,9 +36,12 @@ function parseIntWithDefault(val, def) { return isNaN(res) ? def : res; } -const BannedUser = React.createClass({ +const BannedUser = WithMatrixClient(React.createClass({ propTypes: { - member: React.PropTypes.string.isRequired, + /* MatrixClient instance */ + matrixClient: React.PropTypes.object.isRequired, + + member: React.PropTypes.object.isRequired, // js-sdk member object }, _onUnbanClick: function() { @@ -50,7 +53,7 @@ const BannedUser = React.createClass({ onFinished: (proceed) => { if (!proceed) return; - MatrixClientPeg.get().unban( + this.props.matrixClient.unban( this.props.member.roomId, this.props.member.userId, ).catch((err) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); @@ -75,12 +78,15 @@ const BannedUser = React.createClass({ ); } -}); +})); -module.exports = React.createClass({ +module.exports = WithMatrixClient(React.createClass({ displayName: 'RoomSettings', propTypes: { + /* MatrixClient instance */ + matrixClient: React.PropTypes.object.isRequired, + room: React.PropTypes.object.isRequired, onSaveClick: React.PropTypes.func, onCancelClick: React.PropTypes.func, @@ -117,9 +123,9 @@ module.exports = React.createClass({ componentWillMount: function() { ScalarMessaging.startListening(); - MatrixClientPeg.get().on("RoomMember.membership", this._onRoomMemberMembership); + this.props.matrixClient.on("RoomMember.membership", this._onRoomMemberMembership); - MatrixClientPeg.get().getRoomDirectoryVisibility( + this.props.matrixClient.getRoomDirectoryVisibility( this.props.room.roomId ).done((result) => { this.setState({ isRoomPublished: result.visibility === "public" }); @@ -147,7 +153,7 @@ module.exports = React.createClass({ componentWillUnmount: function() { ScalarMessaging.stopListening(); - MatrixClientPeg.get().removeListener("RoomMember.membership", this._onRoomMemberMembership); + this.props.matrixClient.removeListener("RoomMember.membership", this._onRoomMemberMembership); dis.dispatch({ action: 'ui_opacity', @@ -195,14 +201,14 @@ module.exports = React.createClass({ // name and topic if (this._hasDiff(this.state.name, originalState.name)) { - promises.push(MatrixClientPeg.get().setRoomName(roomId, this.state.name)); + promises.push(this.props.matrixClient.setRoomName(roomId, this.state.name)); } if (this._hasDiff(this.state.topic, originalState.topic)) { - promises.push(MatrixClientPeg.get().setRoomTopic(roomId, this.state.topic)); + promises.push(this.props.matrixClient.setRoomTopic(roomId, this.state.topic)); } if (this.state.history_visibility !== originalState.history_visibility) { - promises.push(MatrixClientPeg.get().sendStateEvent( + promises.push(this.props.matrixClient.sendStateEvent( roomId, "m.room.history_visibility", { history_visibility: this.state.history_visibility }, "" @@ -210,14 +216,14 @@ module.exports = React.createClass({ } if (this.state.isRoomPublished !== originalState.isRoomPublished) { - promises.push(MatrixClientPeg.get().setRoomDirectoryVisibility( + promises.push(this.props.matrixClient.setRoomDirectoryVisibility( roomId, this.state.isRoomPublished ? "public" : "private" )); } if (this.state.join_rule !== originalState.join_rule) { - promises.push(MatrixClientPeg.get().sendStateEvent( + promises.push(this.props.matrixClient.sendStateEvent( roomId, "m.room.join_rules", { join_rule: this.state.join_rule }, "" @@ -225,7 +231,7 @@ module.exports = React.createClass({ } if (this.state.guest_access !== originalState.guest_access) { - promises.push(MatrixClientPeg.get().sendStateEvent( + promises.push(this.props.matrixClient.sendStateEvent( roomId, "m.room.guest_access", { guest_access: this.state.guest_access }, "" @@ -236,7 +242,7 @@ module.exports = React.createClass({ // power levels var powerLevels = this._getPowerLevels(); if (powerLevels) { - promises.push(MatrixClientPeg.get().sendStateEvent( + promises.push(this.props.matrixClient.sendStateEvent( roomId, "m.room.power_levels", powerLevels, "" )); } @@ -249,12 +255,12 @@ module.exports = React.createClass({ switch (diff.place) { case "add": promises.push( - MatrixClientPeg.get().setRoomTag(roomId, diff.key, {}) + this.props.matrixClient.setRoomTag(roomId, diff.key, {}) ); break; case "del": promises.push( - MatrixClientPeg.get().deleteRoomTag(roomId, diff.key) + this.props.matrixClient.deleteRoomTag(roomId, diff.key) ); break; default: @@ -311,7 +317,7 @@ module.exports = React.createClass({ if (!encrypt) { return q(); } var roomId = this.props.room.roomId; - return MatrixClientPeg.get().sendStateEvent( + return this.props.matrixClient.sendStateEvent( roomId, "m.room.encryption", { algorithm: "m.megolm.v1.aes-sha2" } ); @@ -476,7 +482,7 @@ module.exports = React.createClass({ }, mayChangeRoomAccess: function() { - var cli = MatrixClientPeg.get(); + var cli = this.props.matrixClient; var roomState = this.props.room.currentState; return (roomState.mayClientSendStateEvent("m.room.join_rules", cli) && roomState.mayClientSendStateEvent("m.room.guest_access", cli)); @@ -513,7 +519,7 @@ module.exports = React.createClass({ onForgetClick() { // FIXME: duplicated with RoomTagContextualMenu (and dead code in RoomView) - MatrixClientPeg.get().forget(this.props.room.roomId).done(function() { + this.props.matrixClient.forget(this.props.room.roomId).done(function() { dis.dispatch({ action: 'view_next_room' }); }, function(err) { var errCode = err.errcode || "unknown error code"; @@ -554,7 +560,7 @@ module.exports = React.createClass({ }, _renderEncryptionSection: function() { - var cli = MatrixClientPeg.get(); + var cli = this.props.matrixClient; var roomState = this.props.room.currentState; var isEncrypted = cli.isRoomEncrypted(this.props.room.roomId); var isGlobalBlacklistUnverified = UserSettingsStore.getLocalSettings().blacklistUnverifiedDevices; @@ -608,7 +614,7 @@ module.exports = React.createClass({ var PowerSelector = sdk.getComponent('elements.PowerSelector'); var Loader = sdk.getComponent("elements.Spinner"); - var cli = MatrixClientPeg.get(); + var cli = this.props.matrixClient; var roomState = this.props.room.currentState; var user_id = cli.credentials.userId; @@ -833,7 +839,7 @@ module.exports = React.createClass({ - List this room in { MatrixClientPeg.get().getDomain() }'s room directory? + List this room in { this.props.matrixClient.getDomain() }'s room directory?
    @@ -943,4 +949,4 @@ module.exports = React.createClass({
    ); } -}); +})); From a5a056292dcb2ca2abd661153318e80d05a269a9 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 15 Feb 2017 18:58:59 +0000 Subject: [PATCH 4/5] Revert c082827fc7e3e11e4790c0306933c751c7a09c65 Revert the WithMatrixClient change: RoomView calls methods on the RoomSettings component and this breaks when RoomSettings is wrapped in a WithMatrixClient. --- src/components/views/rooms/RoomSettings.js | 56 ++++++++++------------ 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 783d343890..7a9cb2224c 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -17,6 +17,7 @@ limitations under the License. import q from 'q'; import React from 'react'; +import MatrixClientPeg from '../../../MatrixClientPeg'; import SdkConfig from '../../../SdkConfig'; import sdk from '../../../index'; import Modal from '../../../Modal'; @@ -26,7 +27,6 @@ import ScalarAuthClient from '../../../ScalarAuthClient'; import ScalarMessaging from '../../../ScalarMessaging'; import UserSettingsStore from '../../../UserSettingsStore'; import AccessibleButton from '../elements/AccessibleButton'; -import WithMatrixClient from '../../../wrappers/WithMatrixClient'; // parse a string as an integer; if the input is undefined, or cannot be parsed @@ -36,12 +36,9 @@ function parseIntWithDefault(val, def) { return isNaN(res) ? def : res; } -const BannedUser = WithMatrixClient(React.createClass({ +const BannedUser = React.createClass({ propTypes: { - /* MatrixClient instance */ - matrixClient: React.PropTypes.object.isRequired, - - member: React.PropTypes.object.isRequired, // js-sdk member object + member: React.PropTypes.string.isRequired, }, _onUnbanClick: function() { @@ -53,7 +50,7 @@ const BannedUser = WithMatrixClient(React.createClass({ onFinished: (proceed) => { if (!proceed) return; - this.props.matrixClient.unban( + MatrixClientPeg.get().unban( this.props.member.roomId, this.props.member.userId, ).catch((err) => { const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); @@ -78,15 +75,12 @@ const BannedUser = WithMatrixClient(React.createClass({ ); } -})); +}); -module.exports = WithMatrixClient(React.createClass({ +module.exports = React.createClass({ displayName: 'RoomSettings', propTypes: { - /* MatrixClient instance */ - matrixClient: React.PropTypes.object.isRequired, - room: React.PropTypes.object.isRequired, onSaveClick: React.PropTypes.func, onCancelClick: React.PropTypes.func, @@ -123,9 +117,9 @@ module.exports = WithMatrixClient(React.createClass({ componentWillMount: function() { ScalarMessaging.startListening(); - this.props.matrixClient.on("RoomMember.membership", this._onRoomMemberMembership); + MatrixClientPeg.get().on("RoomMember.membership", this._onRoomMemberMembership); - this.props.matrixClient.getRoomDirectoryVisibility( + MatrixClientPeg.get().getRoomDirectoryVisibility( this.props.room.roomId ).done((result) => { this.setState({ isRoomPublished: result.visibility === "public" }); @@ -153,7 +147,7 @@ module.exports = WithMatrixClient(React.createClass({ componentWillUnmount: function() { ScalarMessaging.stopListening(); - this.props.matrixClient.removeListener("RoomMember.membership", this._onRoomMemberMembership); + MatrixClientPeg.get().removeListener("RoomMember.membership", this._onRoomMemberMembership); dis.dispatch({ action: 'ui_opacity', @@ -201,14 +195,14 @@ module.exports = WithMatrixClient(React.createClass({ // name and topic if (this._hasDiff(this.state.name, originalState.name)) { - promises.push(this.props.matrixClient.setRoomName(roomId, this.state.name)); + promises.push(MatrixClientPeg.get().setRoomName(roomId, this.state.name)); } if (this._hasDiff(this.state.topic, originalState.topic)) { - promises.push(this.props.matrixClient.setRoomTopic(roomId, this.state.topic)); + promises.push(MatrixClientPeg.get().setRoomTopic(roomId, this.state.topic)); } if (this.state.history_visibility !== originalState.history_visibility) { - promises.push(this.props.matrixClient.sendStateEvent( + promises.push(MatrixClientPeg.get().sendStateEvent( roomId, "m.room.history_visibility", { history_visibility: this.state.history_visibility }, "" @@ -216,14 +210,14 @@ module.exports = WithMatrixClient(React.createClass({ } if (this.state.isRoomPublished !== originalState.isRoomPublished) { - promises.push(this.props.matrixClient.setRoomDirectoryVisibility( + promises.push(MatrixClientPeg.get().setRoomDirectoryVisibility( roomId, this.state.isRoomPublished ? "public" : "private" )); } if (this.state.join_rule !== originalState.join_rule) { - promises.push(this.props.matrixClient.sendStateEvent( + promises.push(MatrixClientPeg.get().sendStateEvent( roomId, "m.room.join_rules", { join_rule: this.state.join_rule }, "" @@ -231,7 +225,7 @@ module.exports = WithMatrixClient(React.createClass({ } if (this.state.guest_access !== originalState.guest_access) { - promises.push(this.props.matrixClient.sendStateEvent( + promises.push(MatrixClientPeg.get().sendStateEvent( roomId, "m.room.guest_access", { guest_access: this.state.guest_access }, "" @@ -242,7 +236,7 @@ module.exports = WithMatrixClient(React.createClass({ // power levels var powerLevels = this._getPowerLevels(); if (powerLevels) { - promises.push(this.props.matrixClient.sendStateEvent( + promises.push(MatrixClientPeg.get().sendStateEvent( roomId, "m.room.power_levels", powerLevels, "" )); } @@ -255,12 +249,12 @@ module.exports = WithMatrixClient(React.createClass({ switch (diff.place) { case "add": promises.push( - this.props.matrixClient.setRoomTag(roomId, diff.key, {}) + MatrixClientPeg.get().setRoomTag(roomId, diff.key, {}) ); break; case "del": promises.push( - this.props.matrixClient.deleteRoomTag(roomId, diff.key) + MatrixClientPeg.get().deleteRoomTag(roomId, diff.key) ); break; default: @@ -317,7 +311,7 @@ module.exports = WithMatrixClient(React.createClass({ if (!encrypt) { return q(); } var roomId = this.props.room.roomId; - return this.props.matrixClient.sendStateEvent( + return MatrixClientPeg.get().sendStateEvent( roomId, "m.room.encryption", { algorithm: "m.megolm.v1.aes-sha2" } ); @@ -482,7 +476,7 @@ module.exports = WithMatrixClient(React.createClass({ }, mayChangeRoomAccess: function() { - var cli = this.props.matrixClient; + var cli = MatrixClientPeg.get(); var roomState = this.props.room.currentState; return (roomState.mayClientSendStateEvent("m.room.join_rules", cli) && roomState.mayClientSendStateEvent("m.room.guest_access", cli)); @@ -519,7 +513,7 @@ module.exports = WithMatrixClient(React.createClass({ onForgetClick() { // FIXME: duplicated with RoomTagContextualMenu (and dead code in RoomView) - this.props.matrixClient.forget(this.props.room.roomId).done(function() { + MatrixClientPeg.get().forget(this.props.room.roomId).done(function() { dis.dispatch({ action: 'view_next_room' }); }, function(err) { var errCode = err.errcode || "unknown error code"; @@ -560,7 +554,7 @@ module.exports = WithMatrixClient(React.createClass({ }, _renderEncryptionSection: function() { - var cli = this.props.matrixClient; + var cli = MatrixClientPeg.get(); var roomState = this.props.room.currentState; var isEncrypted = cli.isRoomEncrypted(this.props.room.roomId); var isGlobalBlacklistUnverified = UserSettingsStore.getLocalSettings().blacklistUnverifiedDevices; @@ -614,7 +608,7 @@ module.exports = WithMatrixClient(React.createClass({ var PowerSelector = sdk.getComponent('elements.PowerSelector'); var Loader = sdk.getComponent("elements.Spinner"); - var cli = this.props.matrixClient; + var cli = MatrixClientPeg.get(); var roomState = this.props.room.currentState; var user_id = cli.credentials.userId; @@ -839,7 +833,7 @@ module.exports = WithMatrixClient(React.createClass({ - List this room in { this.props.matrixClient.getDomain() }'s room directory? + List this room in { MatrixClientPeg.get().getDomain() }'s room directory?
    @@ -949,4 +943,4 @@ module.exports = WithMatrixClient(React.createClass({
    ); } -})); +}); From 8698d40d3ce3ef665c704f6db14399fa635cc0de Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 15 Feb 2017 19:01:00 +0000 Subject: [PATCH 5/5] Fix docs & add MatrixClient check Addresses PR feedback without breaking RoomSettings --- src/components/views/rooms/RoomSettings.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomSettings.js b/src/components/views/rooms/RoomSettings.js index 7a9cb2224c..3247f5a90b 100644 --- a/src/components/views/rooms/RoomSettings.js +++ b/src/components/views/rooms/RoomSettings.js @@ -38,7 +38,7 @@ function parseIntWithDefault(val, def) { const BannedUser = React.createClass({ propTypes: { - member: React.PropTypes.string.isRequired, + member: React.PropTypes.object.isRequired, // js-sdk RoomMember }, _onUnbanClick: function() { @@ -147,7 +147,10 @@ module.exports = React.createClass({ componentWillUnmount: function() { ScalarMessaging.stopListening(); - MatrixClientPeg.get().removeListener("RoomMember.membership", this._onRoomMemberMembership); + const cli = MatrixClientPeg.get(); + if (cli) { + cli.removeListener("RoomMember.membership", this._onRoomMemberMembership); + } dis.dispatch({ action: 'ui_opacity',