diff --git a/src/views/preview/comment/compose-comment.jsx b/src/views/preview/comment/compose-comment.jsx
index a1d2e85db..9de5d1e59 100644
--- a/src/views/preview/comment/compose-comment.jsx
+++ b/src/views/preview/comment/compose-comment.jsx
@@ -10,6 +10,8 @@ const FlexRow = require('../../../components/flex-row/flex-row.jsx');
const Avatar = require('../../../components/avatar/avatar.jsx');
const InplaceInput = require('../../../components/forms/inplace-input.jsx');
const Button = require('../../../components/forms/button.jsx');
+const CommentingStatus = require('../../../components/commenting-status/commenting-status.jsx');
+const MuteModal = require('../../../components/modal/mute/modal.jsx');
const connect = require('react-redux').connect;
@@ -24,7 +26,8 @@ const MAX_COMMENT_LENGTH = 500;
const ComposeStatus = keyMirror({
EDITING: null,
SUBMITTING: null,
- REJECTED: null
+ REJECTED: null,
+ REJECTED_MUTE: null
});
class ComposeComment extends React.Component {
@@ -33,13 +36,17 @@ class ComposeComment extends React.Component {
bindAll(this, [
'handlePost',
'handleCancel',
- 'handleInput'
+ 'handleInput',
+ 'handleMuteClose',
+ 'handleMuteOpen'
+
]);
this.state = {
message: '',
status: ComposeStatus.EDITING,
error: null,
- appealId: null
+ appealId: null,
+ muteOpen: false
};
}
handleInput (event) {
@@ -67,13 +74,24 @@ class ComposeComment extends React.Component {
if (err || res.statusCode !== 200) {
body = {rejected: 'error'};
}
-
if (body.rejected && this.state.status === ComposeStatus.SUBMITTING) {
+ let muteOpen = false;
+ let muteExpiresAt = 0;
+ let rejectedStatus = ComposeStatus.REJECTED;
+ if (body.status && body.status.mute_status) {
+ muteExpiresAt = body.status.mute_status.muteExpiresAt;
+ rejectedStatus = ComposeStatus.REJECTED_MUTE;
+ if (this.shouldShowMuteModal(body.status.mute_status.offenses)) {
+ muteOpen = true;
+ }
+ }
// Note: does not reset the message state
this.setState({
- status: ComposeStatus.REJECTED,
+ status: rejectedStatus,
error: body.rejected,
- appealId: body.appealId
+ appealId: body.appealId,
+ muteOpen: muteOpen,
+ muteExpiresAt: muteExpiresAt
});
return;
}
@@ -92,6 +110,44 @@ class ComposeComment extends React.Component {
this.props.onAddComment(body);
});
}
+
+ handleMuteClose () {
+ this.setState({
+ muteOpen: false
+ });
+ }
+
+ handleMuteOpen () {
+ this.setState({
+ muteOpen: true
+ });
+ }
+
+ shouldShowMuteModal (offensesList) {
+ // We should show the mute modal whne the user is newly muted or hasn't seen it for a while.
+ // We don't want to show it more than about once a week.
+ // A newly muted user has only 1 offense and it happened in the last coulpe of minutes.
+ // If a user has more than 1 offense, it means that they have have been muted in the
+ // last week.
+ // Assumption: The offenses list is ordered by time with the most recent at the end.
+
+ // This check is here just in case we somehow get bad data back from a backend.
+ if (!offensesList) {
+ return false;
+ }
+
+ const numOffenses = offensesList.length;
+ // This isn't intended to be called if there are no offenses, but
+ // say no just in case.
+ if (numOffenses === 0) {
+ return false;
+ }
+
+ const mostRecent = offensesList[numOffenses - 1];
+ const creationTimeMinutesAgo = (Date.now() - (mostRecent.createdAt * 1000)) / (60 * 1000);
+ return creationTimeMinutesAgo < 2 && numOffenses === 1;
+ }
+
handleCancel () {
this.setState({
message: '',
@@ -103,70 +159,101 @@ class ComposeComment extends React.Component {
}
render () {
return (
-
+ For the next {this.state.muteExpiresAt} you
+ won't be able to post comments.
+ Once {this.state.muteExpiresAt} have passed,
+ you will be able to comment again.
+