Implement kick/ban/[un]mute buttons on member list dialogs.
parent
3657029fc7
commit
2e2cecdd4f
|
@ -67,6 +67,23 @@ module.exports = React.createClass({
|
|||
if (this.state.active >= 0) {
|
||||
activeAgo = this.getDuration(this.state.active);
|
||||
}
|
||||
var kickButton, banButton, muteButton;
|
||||
if (this.state.can.kick) {
|
||||
kickButton = <div className="mx_MemberInfo_button" onClick={this.onKick}>
|
||||
Kick
|
||||
</div>;
|
||||
}
|
||||
if (this.state.can.ban) {
|
||||
banButton = <div className="mx_MemberInfo_button" onClick={this.onBan}>
|
||||
Ban
|
||||
</div>;
|
||||
}
|
||||
if (this.state.can.mute) {
|
||||
var muteLabel = this.state.muted ? "Unmute" : "Mute";
|
||||
muteButton = <div className="mx_MemberInfo_button" onClick={this.onMuteToggle}>
|
||||
{muteLabel}
|
||||
</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_MemberInfo">
|
||||
|
@ -81,6 +98,9 @@ module.exports = React.createClass({
|
|||
<div className="mx_MemberInfo_field">Presence: {this.state.presence}</div>
|
||||
<div className="mx_MemberInfo_field">Last active: {activeAgo}</div>
|
||||
<div className="mx_MemberInfo_button" onClick={this.onChatClick}>Start chat</div>
|
||||
{muteButton}
|
||||
{kickButton}
|
||||
{banButton}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -18,15 +18,25 @@ limitations under the License.
|
|||
* State vars:
|
||||
* 'presence' : string (online|offline|unavailable etc)
|
||||
* 'active' : number (ms ago; can be -1)
|
||||
* 'can': {
|
||||
* kick: boolean,
|
||||
* ban: boolean,
|
||||
* mute: boolean
|
||||
* },
|
||||
* 'muted': boolean
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
||||
var dis = require("../../dispatcher");
|
||||
var Modal = require("../../Modal");
|
||||
var ComponentBroker = require('../../ComponentBroker');
|
||||
var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
|
||||
|
||||
module.exports = {
|
||||
componentDidMount: function() {
|
||||
var self = this;
|
||||
// listen for presence changes
|
||||
function updateUserState(event, user) {
|
||||
if (!self.props.member) { return; }
|
||||
|
||||
|
@ -40,20 +50,116 @@ module.exports = {
|
|||
MatrixClientPeg.get().on("User.presence", updateUserState);
|
||||
this.userPresenceFn = updateUserState;
|
||||
|
||||
if (this.props.member) {
|
||||
var usr = MatrixClientPeg.get().getUser(this.props.member.userId);
|
||||
if (!usr) {
|
||||
// listen for power level changes
|
||||
function updatePowerLevel(event, member) {
|
||||
if (!self.props.member) { return; }
|
||||
|
||||
if (member.roomId !== self.props.member.roomId) {
|
||||
return;
|
||||
}
|
||||
// only interested in changes to us or them
|
||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
if ([myUserId, self.props.member.userId].indexOf(member.userId) === -1) {
|
||||
return;
|
||||
}
|
||||
self.setState({
|
||||
can: self._calculateOpsPermissions(),
|
||||
muted: self._isMuted(self.props.member)
|
||||
});
|
||||
}
|
||||
MatrixClientPeg.get().on("RoomMember.powerLevel", updatePowerLevel);
|
||||
this.updatePowerLevelFn = updatePowerLevel;
|
||||
|
||||
// work out the current state
|
||||
if (this.props.member) {
|
||||
var usr = MatrixClientPeg.get().getUser(this.props.member.userId) || {};
|
||||
this.setState({
|
||||
presence: usr.presence,
|
||||
active: usr.lastActiveAgo
|
||||
presence: usr.presence || "offline",
|
||||
active: usr.lastActiveAgo || -1,
|
||||
can: this._calculateOpsPermissions(),
|
||||
muted: this._isMuted(this.props.member)
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
MatrixClientPeg.get().removeListener("User.presence", this.userPresenceFn);
|
||||
MatrixClientPeg.get().removeListener(
|
||||
"RoomMember.powerLevel", this.updatePowerLevelFn
|
||||
);
|
||||
},
|
||||
|
||||
onKick: function() {
|
||||
var roomId = this.props.member.roomId;
|
||||
var target = this.props.member.userId;
|
||||
var self = this;
|
||||
MatrixClientPeg.get().kick(roomId, target).done(function() {
|
||||
// NO-OP; rely on the m.room.member event coming down else we could
|
||||
// get out of sync if we force setState here!
|
||||
console.log("Kick success");
|
||||
}, function(err) {
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Kick error",
|
||||
description: err.message
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
onBan: function() {
|
||||
var roomId = this.props.member.roomId;
|
||||
var target = this.props.member.userId;
|
||||
var self = this;
|
||||
MatrixClientPeg.get().ban(roomId, target).done(function() {
|
||||
// NO-OP; rely on the m.room.member event coming down else we could
|
||||
// get out of sync if we force setState here!
|
||||
console.log("Ban success");
|
||||
}, function(err) {
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Ban error",
|
||||
description: err.message
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
onMuteToggle: function() {
|
||||
var roomId = this.props.member.roomId;
|
||||
var target = this.props.member.userId;
|
||||
var self = this;
|
||||
var room = MatrixClientPeg.get().getRoom(roomId);
|
||||
if (!room) {
|
||||
return;
|
||||
}
|
||||
var powerLevelEvent = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", ""
|
||||
);
|
||||
if (!powerLevelEvent) {
|
||||
return;
|
||||
}
|
||||
var isMuted = this.state.muted;
|
||||
var powerLevels = powerLevelEvent.getContent();
|
||||
var levelToSend = (
|
||||
(powerLevels.events ? powerLevels.events["m.room.message"] : null) ||
|
||||
powerLevels.events_default
|
||||
);
|
||||
var level;
|
||||
if (isMuted) { // unmute
|
||||
level = levelToSend;
|
||||
}
|
||||
else { // mute
|
||||
level = levelToSend - 1;
|
||||
}
|
||||
|
||||
MatrixClientPeg.get().setPowerLevel(roomId, target, level, powerLevelEvent).done(
|
||||
function() {
|
||||
// NO-OP; rely on the m.room.member event coming down else we could
|
||||
// get out of sync if we force setState here!
|
||||
console.log("Mute toggle success");
|
||||
}, function(err) {
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
title: "Mute error",
|
||||
description: err.message
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
onChatClick: function() {
|
||||
|
@ -108,8 +214,72 @@ module.exports = {
|
|||
getInitialState: function() {
|
||||
return {
|
||||
presence: "offline",
|
||||
active: -1
|
||||
active: -1,
|
||||
can: {
|
||||
kick: false,
|
||||
ban: false,
|
||||
mute: false
|
||||
},
|
||||
muted: false
|
||||
}
|
||||
},
|
||||
|
||||
_isMuted: function(member) {
|
||||
var room = MatrixClientPeg.get().getRoom(member.roomId);
|
||||
if (!room) {
|
||||
return false;
|
||||
}
|
||||
var powerLevels = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", ""
|
||||
);
|
||||
if (!powerLevels) {
|
||||
return false;
|
||||
}
|
||||
powerLevels = powerLevels.getContent();
|
||||
var levelToSend = (
|
||||
(powerLevels.events ? powerLevels.events["m.room.message"] : null) ||
|
||||
powerLevels.events_default
|
||||
);
|
||||
return member.powerLevel < levelToSend;
|
||||
},
|
||||
|
||||
_calculateOpsPermissions: function() {
|
||||
var can = {
|
||||
kick: false,
|
||||
ban: false,
|
||||
mute: false
|
||||
};
|
||||
var them = this.props.member;
|
||||
var room = MatrixClientPeg.get().getRoom(this.props.member.roomId);
|
||||
if (!room) {
|
||||
console.error("No room found");
|
||||
return can;
|
||||
}
|
||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
||||
var me = room.getMember(myUserId);
|
||||
var powerLevels = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", ""
|
||||
);
|
||||
if (powerLevels) {
|
||||
powerLevels = powerLevels.getContent();
|
||||
}
|
||||
else {
|
||||
console.log("No power level event found in %s", room.roomId);
|
||||
return can; // no power level event, don't allow anything.
|
||||
}
|
||||
var canAffectUser = them.powerLevel < me.powerLevel;
|
||||
if (!canAffectUser) {
|
||||
console.log("Cannot affect user: %s >= %s", them.powerLevel, me.powerLevel);
|
||||
return can;
|
||||
}
|
||||
var editPowerLevel = (
|
||||
(powerLevels.events ? powerLevels.events["m.room.power_levels"] : null) ||
|
||||
powerLevels.state_default
|
||||
);
|
||||
can.kick = me.powerLevel >= powerLevels.kick;
|
||||
can.ban = me.powerLevel >= powerLevels.ban;
|
||||
can.mute = me.powerLevel >= editPowerLevel;
|
||||
return can;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue