From b5deac7b48ea00ec5c0c4e71531ba124efa334bd Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 19 Sep 2017 19:20:38 +0700 Subject: [PATCH] Bugfixes and show different notification for toxic comments Bugfixes: - Toxic comment flag was not added - GraphQL warnings for missing fields --- .../coral-embed-stream/src/graphql/index.js | 2 ++ client/talk-plugin-commentbox/CommentBox.js | 11 ++++++- graph/mutators/comment.js | 29 +++++++++++-------- .../client/components/CheckToxicityHook.js | 14 ++++++++- .../client/containers/CheckToxicityHook.js | 9 ++++++ .../client/index.js | 2 +- .../client/translations.yml | 4 +++ 7 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 plugins/talk-plugin-toxic-comments/client/containers/CheckToxicityHook.js diff --git a/client/coral-embed-stream/src/graphql/index.js b/client/coral-embed-stream/src/graphql/index.js index dc81b56a4..82d6ca9e3 100644 --- a/client/coral-embed-stream/src/graphql/index.js +++ b/client/coral-embed-stream/src/graphql/index.js @@ -123,6 +123,7 @@ export default { optimisticResponse: { createComment: { __typename: 'CreateCommentResponse', + errors: null, comment: { __typename: 'Comment', user: { @@ -132,6 +133,7 @@ export default { }, created_at: new Date().toISOString(), body, + actions: [], action_summaries: [], tags: tags.map((tag) => ({ tag: { diff --git a/client/talk-plugin-commentbox/CommentBox.js b/client/talk-plugin-commentbox/CommentBox.js index e5717e08a..409ad86ec 100644 --- a/client/talk-plugin-commentbox/CommentBox.js +++ b/client/talk-plugin-commentbox/CommentBox.js @@ -11,12 +11,20 @@ import {CommentForm} from './CommentForm'; export const name = 'talk-plugin-commentbox'; +const notifyReasons = ['LINKS', 'TRUST']; + +function shouldNotify(actions = []) { + return actions.some(({reason}) => notifyReasons.includes(reason)); +} + // Given a newly posted comment's status, show a notification to the user // if needed export const notifyForNewCommentStatus = (notify, comment) => { if (comment.status === 'REJECTED') { notify('error', t('comment_box.comment_post_banned_word')); - } else if (comment.status === 'PREMOD' || comment.status === 'SYSTEM_WITHHELD') { + } else if ( + comment.status === 'PREMOD' || + comment.status === 'SYSTEM_WITHHELD' && shouldNotify(comment.actions)) { notify('success', t('comment_box.comment_post_notif_premod')); } }; @@ -187,6 +195,7 @@ CommentBox.propTypes = { isReply: PropTypes.bool.isRequired, canPost: PropTypes.bool, notify: PropTypes.func.isRequired, + commentBox: PropTypes.object, }; const mapStateToProps = ({commentBox}) => ({commentBox}); diff --git a/graph/mutators/comment.js b/graph/mutators/comment.js index 75cad99b7..2aee766a5 100644 --- a/graph/mutators/comment.js +++ b/graph/mutators/comment.js @@ -393,13 +393,12 @@ const moderationPhases = [ ]; /** - * This resolves a given comment's status to take into account moderator actions - * are applied. + * This resolves a given comment's status and actions. * @param {Object} context graphql context * @param {String} body body of the comment * @param {String} [asset_id] asset for the comment * @param {Object} [wordlist={}] the results of the wordlist scan - * @return {Promise} resolves to the comment's status + * @return {Object} resolves to the comment's status and actions */ const resolveCommentModeration = async (context, comment) => { @@ -418,6 +417,8 @@ const resolveCommentModeration = async (context, comment) => { // Combine the asset and the settings to get the asset settings. const assetSettings = await AssetsService.rectifySettings(asset, settings); + let actions = comment.actions || []; + // Loop over all the moderation phases and see if we've resolved the status. for (const phase of moderationPhases) { const result = await phase(context, comment, { @@ -429,13 +430,14 @@ const resolveCommentModeration = async (context, comment) => { if (result) { - // Merge the comment and the result together. - comment = merge(comment, result); + if (result.actions) { + actions.push(...result.actions); + } // If this result contained a status, then we've finished resolving // phases! if (result.status) { - return comment.actions; + return {status: result.status, actions}; } } } @@ -454,17 +456,20 @@ const createPublicComment = async (context, comment) => { // We then take the wordlist and the comment into consideration when // considering what status to assign the new comment, and resolve the new // status to set the comment to. - let actions = await resolveCommentModeration(context, comment); + let {actions, status} = await resolveCommentModeration(context, comment); + + // Assign status to comment. + comment.status = status; // Then we actually create the comment with the new status. - comment = await createComment(context, comment); + const result = await createComment(context, comment); // Create all the actions that were determined during the moderation check // phase. - await createActions(comment.id, actions); + await createActions(result.id, actions); // Finally, we return the comment. - return comment; + return result; }; // createActions will for each of the provided actions, create the given action @@ -515,10 +520,10 @@ const edit = async (context, {id, asset_id, edit: {body}}) => { let comment = {id, asset_id, body}; // Determine the new status of the comment. - const actions = await resolveCommentModeration(context, comment); + const {actions, status} = await resolveCommentModeration(context, comment); // Execute the edit. - comment = await CommentsService.edit({id, author_id: context.user.id, body, status: comment.status}); + comment = await CommentsService.edit({id, author_id: context.user.id, body, status}); // Create all the actions that were determined during the moderation check // phase. diff --git a/plugins/talk-plugin-toxic-comments/client/components/CheckToxicityHook.js b/plugins/talk-plugin-toxic-comments/client/components/CheckToxicityHook.js index 22c378435..8572bdd5a 100644 --- a/plugins/talk-plugin-toxic-comments/client/components/CheckToxicityHook.js +++ b/plugins/talk-plugin-toxic-comments/client/components/CheckToxicityHook.js @@ -1,4 +1,6 @@ import React from 'react'; +import PropTypes from 'prop-types'; +import {t} from 'plugin-api/beta/client/services'; /** * CheckToxicityHook adds hooks to the `commentBox` @@ -20,7 +22,11 @@ export default class CheckToxicityHook extends React.Component { } }); - this.toxicityPostHook = this.props.registerHook('postSubmit', () => { + this.toxicityPostHook = this.props.registerHook('postSubmit', (result) => { + const actions = result.createComment.comment && result.createComment.comment.actions; + if (actions && actions.some(({reason}) => reason === 'TOXIC_COMMENT')) { + this.props.notify('error', t('talk-plugin-toxic-comments.still_toxic')); + } // Reset `checked` after comment was successfully posted. this.checked = false; @@ -36,3 +42,9 @@ export default class CheckToxicityHook extends React.Component { return null; } } + +CheckToxicityHook.propTypes = { + notify: PropTypes.func.isRequired, + registerHook: PropTypes.func.isRequired, + unregisterHook: PropTypes.func.isRequired, +}; diff --git a/plugins/talk-plugin-toxic-comments/client/containers/CheckToxicityHook.js b/plugins/talk-plugin-toxic-comments/client/containers/CheckToxicityHook.js new file mode 100644 index 000000000..f2b010b0d --- /dev/null +++ b/plugins/talk-plugin-toxic-comments/client/containers/CheckToxicityHook.js @@ -0,0 +1,9 @@ +import {bindActionCreators} from 'redux'; +import {connect} from 'plugin-api/beta/client/hocs'; +import {notify} from 'plugin-api/beta/client/actions/notification'; +import CheckToxicityHook from '../components/CheckToxicityHook'; + +const mapDispatchToProps = (dispatch) => + bindActionCreators({notify}, dispatch); + +export default connect(null, mapDispatchToProps)(CheckToxicityHook); diff --git a/plugins/talk-plugin-toxic-comments/client/index.js b/plugins/talk-plugin-toxic-comments/client/index.js index c364a2a00..bb0417606 100644 --- a/plugins/talk-plugin-toxic-comments/client/index.js +++ b/plugins/talk-plugin-toxic-comments/client/index.js @@ -1,5 +1,5 @@ import translations from './translations.yml'; -import CheckToxicityHook from './components/CheckToxicityHook'; +import CheckToxicityHook from './containers/CheckToxicityHook'; export default { translations, diff --git a/plugins/talk-plugin-toxic-comments/client/translations.yml b/plugins/talk-plugin-toxic-comments/client/translations.yml index ebcc31903..787095046 100644 --- a/plugins/talk-plugin-toxic-comments/client/translations.yml +++ b/plugins/talk-plugin-toxic-comments/client/translations.yml @@ -3,4 +3,8 @@ en: COMMENT_IS_TOXIC: | Are you sure? The language in this comment might violate our community guidelines. You can edit the comment or submit it for moderator review. + talk-plugin-toxic-comments: + still_toxic: | + This edited comment might still violate our community guidelines. + Our moderation team will review your comment shortly. es: