add redact recent messages button in member info

This commit is contained in:
Bruno Windels 2019-09-09 15:10:50 +02:00 committed by David Baker
parent 86d7389b64
commit 0cba5da03d
2 changed files with 92 additions and 1 deletions

View file

@ -46,6 +46,8 @@ import SettingsStore from "../../../settings/SettingsStore";
import E2EIcon from "./E2EIcon"; import E2EIcon from "./E2EIcon";
import AutoHideScrollbar from "../../structures/AutoHideScrollbar"; import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
import MatrixClientPeg from "../../../MatrixClientPeg"; import MatrixClientPeg from "../../../MatrixClientPeg";
import Matrix from "matrix-js-sdk";
const EventTimeline = Matrix.EventTimeline;
module.exports = withMatrixClient(React.createClass({ module.exports = withMatrixClient(React.createClass({
displayName: 'MemberInfo', displayName: 'MemberInfo',
@ -63,6 +65,7 @@ module.exports = withMatrixClient(React.createClass({
mute: false, mute: false,
modifyLevel: false, modifyLevel: false,
synapseDeactivate: false, synapseDeactivate: false,
redactMessages: false,
}, },
muted: false, muted: false,
isTargetMod: false, isTargetMod: false,
@ -351,6 +354,73 @@ module.exports = withMatrixClient(React.createClass({
}); });
}, },
onRedactAllMessages: async function() {
const {roomId, userId} = this.props.member;
const room = this.context.matrixClient.getRoom(roomId);
if (!room) {
return;
}
let timeline = room.getLiveTimeline();
let eventsToRedact = [];
while (timeline) {
eventsToRedact = timeline.getEvents().reduce((events, event) => {
if (event.getSender() === userId && !event.isRedacted()) {
return events.concat(event);
} else {
return events;
}
}, eventsToRedact);
timeline = timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS);
}
const count = eventsToRedact.length;
const user = this.props.member.name;
if (count === 0) {
const InfoDialog = sdk.getComponent("dialogs.InfoDialog");
Modal.createTrackedDialog('No user messages found to remove', '', InfoDialog, {
title: _t("No recent messages by %(user)s found", {user}),
description:
<div>
<p>{ _t("Try scrolling up in the timeline to see if there are any earlier ones.") }</p>
</div>,
});
} else {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
const confirmed = await new Promise((resolve) => {
Modal.createTrackedDialog('Remove recent messages by user', '', QuestionDialog, {
title: _t("Remove recent messages by %(user)s", {user}),
description:
<div>
<p>{ _t("You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?", {count, user}) }</p>
<p>{ _t("For large amount of messages, this might take some time. Please don't refresh your client in the meantime.") }</p>
</div>,
button: _t("Remove %(count)s messages", {count}),
onFinished: resolve,
});
});
if (!confirmed) {
return;
}
// Submitting a large number of redactions freezes the UI,
// so first wait 200ms to allow to rerender after closing the dialog.
await new Promise(resolve => setTimeout(resolve, 200));
await Promise.all(eventsToRedact.map(async event => {
try {
await this.context.matrixClient.redactEvent(roomId, event.getId());
} catch (err) {
// log and swallow errors
console.error("Could not redact", event.getId());
console.error(err);
}
}));
console.log("Done redacting recent messages!");
}
},
_warnSelfDemote: function() { _warnSelfDemote: function() {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
return new Promise((resolve) => { return new Promise((resolve) => {
@ -597,6 +667,7 @@ module.exports = withMatrixClient(React.createClass({
mute: false, mute: false,
modifyLevel: false, modifyLevel: false,
modifyLevelMax: 0, modifyLevelMax: 0,
redactMessages: false,
}; };
// Calculate permissions for Synapse before doing the PL checks // Calculate permissions for Synapse before doing the PL checks
@ -618,6 +689,7 @@ module.exports = withMatrixClient(React.createClass({
can.mute = me.powerLevel >= editPowerLevel; can.mute = me.powerLevel >= editPowerLevel;
can.modifyLevel = me.powerLevel >= editPowerLevel && (isMe || me.powerLevel > them.powerLevel); can.modifyLevel = me.powerLevel >= editPowerLevel && (isMe || me.powerLevel > them.powerLevel);
can.modifyLevelMax = me.powerLevel; can.modifyLevelMax = me.powerLevel;
can.redactMessages = me.powerLevel >= powerLevels.redact;
return can; return can;
}, },
@ -807,6 +879,7 @@ module.exports = withMatrixClient(React.createClass({
let banButton; let banButton;
let muteButton; let muteButton;
let giveModButton; let giveModButton;
let redactButton;
let synapseDeactivateButton; let synapseDeactivateButton;
let spinner; let spinner;
@ -884,6 +957,16 @@ module.exports = withMatrixClient(React.createClass({
</AccessibleButton> </AccessibleButton>
); );
} }
if (this.state.can.redactMessages) {
redactButton = (
<AccessibleButton className="mx_MemberInfo_field" onClick={this.onRedactAllMessages}>
{ _t("Remove recent messages") }
</AccessibleButton>
);
}
if (this.state.can.ban) { if (this.state.can.ban) {
let label = _t("Ban"); let label = _t("Ban");
if (this.props.member.membership === 'ban') { if (this.props.member.membership === 'ban') {
@ -924,7 +1007,7 @@ module.exports = withMatrixClient(React.createClass({
} }
let adminTools; let adminTools;
if (kickButton || banButton || muteButton || giveModButton || synapseDeactivateButton) { if (kickButton || banButton || muteButton || giveModButton || synapseDeactivateButton || redactButton) {
adminTools = adminTools =
<div> <div>
<h3>{ _t("Admin Tools") }</h3> <h3>{ _t("Admin Tools") }</h3>
@ -933,6 +1016,7 @@ module.exports = withMatrixClient(React.createClass({
{ muteButton } { muteButton }
{ kickButton } { kickButton }
{ banButton } { banButton }
{ redactButton }
{ giveModButton } { giveModButton }
{ synapseDeactivateButton } { synapseDeactivateButton }
</div> </div>

View file

@ -724,6 +724,12 @@
"Unban this user?": "Unban this user?", "Unban this user?": "Unban this user?",
"Ban this user?": "Ban this user?", "Ban this user?": "Ban this user?",
"Failed to ban user": "Failed to ban user", "Failed to ban user": "Failed to ban user",
"No recent messages by %(user)s found": "No recent messages by %(user)s found",
"Try scrolling up in the timeline to see if there are any earlier ones.": "Try scrolling up in the timeline to see if there are any earlier ones.",
"Remove recent messages by %(user)s": "Remove recent messages by %(user)s",
"You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|other": "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?",
"For large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "For large amount of messages, this might take some time. Please don't refresh your client in the meantime.",
"Remove %(count)s messages|other": "Remove %(count)s messages",
"Demote yourself?": "Demote yourself?", "Demote yourself?": "Demote yourself?",
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.", "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.",
"Demote": "Demote", "Demote": "Demote",
@ -742,6 +748,7 @@
"Share Link to User": "Share Link to User", "Share Link to User": "Share Link to User",
"User Options": "User Options", "User Options": "User Options",
"Direct chats": "Direct chats", "Direct chats": "Direct chats",
"Remove recent messages": "Remove recent messages",
"Unmute": "Unmute", "Unmute": "Unmute",
"Mute": "Mute", "Mute": "Mute",
"Revoke Moderator": "Revoke Moderator", "Revoke Moderator": "Revoke Moderator",