mirror of
https://github.com/wassname/talk.git
synced 2026-06-30 19:26:42 +08:00
Bugfixes and show different notification for toxic comments
Bugfixes: - Toxic comment flag was not added - GraphQL warnings for missing fields
This commit is contained in:
@@ -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: {
|
||||
|
||||
@@ -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});
|
||||
|
||||
+17
-12
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
@@ -1,5 +1,5 @@
|
||||
import translations from './translations.yml';
|
||||
import CheckToxicityHook from './components/CheckToxicityHook';
|
||||
import CheckToxicityHook from './containers/CheckToxicityHook';
|
||||
|
||||
export default {
|
||||
translations,
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user