From 22ee80992208ffc0a7470da52806e289c0ed4ba0 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 8 Aug 2019 16:39:15 +0100 Subject: [PATCH] Add way to report the content of a message Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/context_menus/MessageContextMenu.js | 21 +++ .../views/dialogs/ReportEventDialog.js | 128 ++++++++++++++++++ src/i18n/strings/en_EN.json | 3 + 3 files changed, 152 insertions(+) create mode 100644 src/components/views/dialogs/ReportEventDialog.js diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index 04bc7c75ef..4b7b1f8545 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -1,6 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2018 New Vector Ltd +Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -116,6 +117,14 @@ module.exports = React.createClass({ this.closeMenu(); }, + onReportEventClick: function() { + const ReportEventDialog = sdk.getComponent("dialogs.ReportEventDialog"); + Modal.createTrackedDialog('Report Event', '', ReportEventDialog, { + mxEvent: this.props.mxEvent, + }, 'mx_Dialog_reportEvent'); + this.closeMenu(); + }, + onViewSourceClick: function() { const ViewSource = sdk.getComponent('structures.ViewSource'); Modal.createTrackedDialog('View Event Source', '', ViewSource, { @@ -278,6 +287,8 @@ module.exports = React.createClass({ }, render: function() { + const cli = MatrixClientPeg.get(); + const me = cli.getUserId(); const mxEvent = this.props.mxEvent; const eventStatus = mxEvent.status; const editStatus = mxEvent.replacingEvent() && mxEvent.replacingEvent().status; @@ -445,6 +456,15 @@ module.exports = React.createClass({ ; } + let reportEventButton; + if (mxEvent.getSender() !== me) { + reportEventButton = ( +
+ { _t('Report Content') } +
+ ); + } + return (
{ resendButton } @@ -463,6 +483,7 @@ module.exports = React.createClass({ { externalURLButton } { collapseReplyThread } { e2eInfo } + { reportEventButton }
); }, diff --git a/src/components/views/dialogs/ReportEventDialog.js b/src/components/views/dialogs/ReportEventDialog.js new file mode 100644 index 0000000000..b118084729 --- /dev/null +++ b/src/components/views/dialogs/ReportEventDialog.js @@ -0,0 +1,128 @@ +/* +Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React, {PureComponent} from 'react'; +import sdk from '../../../index'; +import { _t } from '../../../languageHandler'; +import PropTypes from "prop-types"; +import {MatrixEvent} from "matrix-js-sdk"; +import MatrixClientPeg from "../../../MatrixClientPeg"; + +/* + * A dialog for reporting an event. + */ +export default class ReportEventDialog extends PureComponent { + static propTypes = { + mxEvent: PropTypes.instanceOf(MatrixEvent).isRequired, + onFinished: PropTypes.func.isRequired, + }; + + constructor(props, context) { + super(props, context); + + this.state = { + reason: "", + busy: false, + err: null, + }; + } + + _onReasonChange = ({target: {value: reason}}) => { + this.setState({ reason }); + }; + + _onCancel = () => { + this.props.onFinished(false); + }; + + _onSubmit = async () => { + if (!this.state.reason || !this.state.reason.trim()) { + this.setState({ + err: _t("Please fill why you're reporting."), + }); + return; + } + + this.setState({ + busy: true, + err: null, + }); + + try { + const ev = this.props.mxEvent; + await MatrixClientPeg.get().reportEvent(ev.getRoomId(), ev.getId(), -100, this.state.reason.trim()); + this.props.onFinished(true); + } catch (e) { + this.setState({ + busy: false, + err: e.message, + }); + } + }; + + render() { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); + const Loader = sdk.getComponent('elements.Spinner'); + const Field = sdk.getComponent('elements.Field'); + + let error = null; + if (this.state.err) { + error =
+ {this.state.err} +
; + } + + let progress = null; + if (this.state.busy) { + progress = ( +
+ +
+ ); + } + + return ( + +
+ + {progress} + {error} +
+ +
+ ); + } +} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8d43e7087c..c29af1959c 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1213,6 +1213,9 @@ "To help avoid duplicate issues, please view existing issues first (and add a +1) or create a new issue if you can't find it.": "To help avoid duplicate issues, please view existing issues first (and add a +1) or create a new issue if you can't find it.", "Report bugs & give feedback": "Report bugs & give feedback", "Go back": "Go back", + "Please fill why you're reporting.": "Please fill why you're reporting.", + "Report Content": "Report Content", + "Send report": "Send report", "Room Settings - %(roomName)s": "Room Settings - %(roomName)s", "Failed to upgrade room": "Failed to upgrade room", "The room upgrade could not be completed": "The room upgrade could not be completed",