Initial work for locking flag type and providing translations

This commit is contained in:
Wyatt Johnson
2017-10-03 17:20:40 -06:00
parent 8a02618d8a
commit 00de72a6eb
13 changed files with 80 additions and 53 deletions
@@ -7,6 +7,7 @@ import {PopupMenu, Button} from 'coral-ui';
import ClickOutside from 'coral-framework/components/ClickOutside';
import cn from 'classnames';
import styles from './styles.css';
import * as REASONS from '../helpers/flagReasons';
const name = 'talk-plugin-flags';
@@ -88,10 +89,9 @@ export default class FlagButton extends Component {
let action = {
item_id,
item_type: itemType,
reason: null,
message
};
if (reason === 'COMMENT_NOAGREE') {
if (reason === REASONS.comment.noagree) {
postDontAgree(action)
.then(({data}) => {
if (itemType === 'COMMENTS') {
@@ -118,7 +118,7 @@ export default class FlagButton extends Component {
onPopupOptionClick = (sets) => (e) => {
// If flagging a user, indicate that this is referencing the username rather than the bio
if(sets === 'itemType' && e.target.value === 'users') {
if (sets === 'itemType' && e.target.value === 'users') {
this.setState({field: 'username'});
}
+16 -2
View File
@@ -1,12 +1,26 @@
const DataLoader = require('dataloader');
const TagsService = require('../../services/tags');
const plugins = require('../../services/plugins');
const debug = require('debug')('talk:graph:loaders:tags');
const PLUGIN_TAGS = plugins.get('server', 'tags').reduce((acc, {plugin, tags}) => {
debug(`added plugin '${plugin.name}'`);
acc = acc.concat(tags);
return acc;
}, []);
/**
* Get all the tags for the context for the dataloader.
*/
const genAll = (context, queries) => {
return Promise.all(queries.map(({id, item_type, asset_id}) => {
return TagsService.getAll({id, item_type, asset_id});
return Promise.all(queries.map(async ({id, item_type, asset_id}) => {
let tags = await TagsService.getAll({id, item_type, asset_id});
// Merge in the global plugin tags as well.
tags = tags.concat(PLUGIN_TAGS);
return tags;
}));
};
+1 -13
View File
@@ -17,22 +17,12 @@ const {
ADD_COMMENT_TAG,
EDIT_COMMENT
} = require('../../perms/constants');
const debug = require('debug')('talk:graph:mutators:comment');
const {
DISABLE_AUTOFLAG_SUSPECT_WORDS
} = require('../../config');
const debug = require('debug')('talk:graph:mutators:tags');
const plugins = require('../../services/plugins');
const pluginTags = plugins.get('server', 'tags').reduce((acc, {plugin, tags}) => {
debug(`added plugin '${plugin.name}'`);
acc = acc.concat(tags);
return acc;
}, []);
const resolveTagsForComment = async ({user, loaders: {Tags}}, {asset_id, tags = []}) => {
const item_type = 'COMMENTS';
@@ -48,8 +38,6 @@ const resolveTagsForComment = async ({user, loaders: {Tags}}, {asset_id, tags =
globalTags = [];
}
globalTags = globalTags.concat(pluginTags);
// Merge in the tags for the given comment.
tags = tags.map((name) => {
+1 -1
View File
@@ -11,7 +11,7 @@ const modify = async ({user, loaders: {Tags}}, operation, {name, id, item_type,
const tags = await Tags.getAll.load({id, item_type, asset_id});
// Resolve the TagLink that should be used to insert to the user. This will
// addtionally return with an ownership property that can be used to determine
// additionally return with an ownership property that can be used to determine
// that the user who adds this tag must also be the owner of the resource.
let {tagLink, ownership} = TagsService.resolveLink(user, tags, {name, item_type});
+1 -7
View File
@@ -1,9 +1,3 @@
const DontAgreeAction = {
// Stored in the metadata, extract and return.
reason({metadata: {reason}}) {
return reason;
}
};
const DontAgreeAction = {};
module.exports = DontAgreeAction;
+1 -5
View File
@@ -1,7 +1,3 @@
const DontAgreeActionSummary = {
reason({group_id}) {
return group_id;
}
};
const DontAgreeActionSummary = {};
module.exports = DontAgreeActionSummary;
+2 -2
View File
@@ -13,8 +13,8 @@ const RootMutation = {
createFlag: async (_, {flag: {item_id, item_type, reason, message}}, {mutators: {Action}}) => ({
flag: Action.create({item_id, item_type, action_type: 'FLAG', group_id: reason, metadata: {message}}),
}),
createDontAgree: async (_, {dontagree: {item_id, item_type, reason, message}}, {mutators: {Action}}) => ({
dontagree: await Action.create({item_id, item_type, action_type: 'DONTAGREE', group_id: reason, metadata: {message}}),
createDontAgree: async (_, {dontagree: {item_id, item_type, message}}, {mutators: {Action}}) => ({
dontagree: await Action.create({item_id, item_type, action_type: 'DONTAGREE', metadata: {message}}),
}),
deleteAction: async (_, {id}, {mutators: {Action}}) => {
await Action.delete({id});
+33 -12
View File
@@ -518,6 +518,36 @@ type FlagAssetActionSummary implements AssetActionSummary {
actionableItemCount: Int
}
enum FLAG_REASON {
# The current user thinks that the flagged username is offensive.
USERNAME_OFFENSIVE
# The current user does not like the flagged username.
USERNAME_NOLIKE
# The current user thinks that the flagged username is being used to
# impersonate another user.
USERNAME_IMPERSONATING
# The current user thinks that the flagged username is spam.
USERNAME_SPAM
# The current user thinks that the flagged username is wrong for another
# reason.
USERNAME_OTHER
# The current user thinks that the flagged comment is offensive.
COMMENT_OFFENSIVE
# The current user thinks that the flagged comment is spam.
COMMENT_SPAM
# The current user thinks that the flagged comment is wrong for another
# reason.
COMMENT_OTHER
}
# A FLAG action that contains flag metadata.
type FlagAction implements Action {
@@ -525,7 +555,7 @@ type FlagAction implements Action {
id: ID!
# The reason for which the Flag Action was created.
reason: String
reason: FLAG_REASON
# An optional message sent with the flagging action by the user.
message: String
@@ -546,9 +576,6 @@ type DontAgreeAction implements Action {
# The ID of the DontAgree Action.
id: ID!
# The reason for which the DontAgree Action was created.
reason: String
# An optional message sent with the flagging action by the user.
message: String
@@ -569,7 +596,7 @@ type FlagActionSummary implements ActionSummary {
count: Int!
# The reason for which the Flag Action was created.
reason: String
reason: FLAG_REASON
# The flag by the current user against the parent entity with this reason.
current_user: FlagAction
@@ -581,9 +608,6 @@ type DontAgreeActionSummary implements ActionSummary {
# The total count of flags with this reason.
count: Int!
# The reason for which the Flag Action was created.
reason: String
# The don't agree action by the current user against the parent entity with this reason.
current_user: DontAgreeAction
}
@@ -948,7 +972,7 @@ input CreateFlagInput {
item_type: ACTION_ITEM_TYPE!
# The reason for flagging the item.
reason: String!
reason: FLAG_REASON
# An optional message sent with the flagging action by the user.
message: String
@@ -987,9 +1011,6 @@ input CreateDontAgreeInput {
# The type of the item for which we are to create the don't agree.
item_type: ACTION_ITEM_TYPE!
# The reason for not agreeing with the item.
reason: String
# An optional message sent with the don't agree action by the user.
message: String
}
+13
View File
@@ -248,6 +248,19 @@ en:
loading_results: "Loading Results"
marketing: "This looks like an ad/marketing"
moderate_this_stream: "Moderate this stream"
flags:
reasons:
user:
username_offensive: "Username is offensive"
username_nolike: "Does not like"
username_impersonating: "Username is impersonating another user"
username_spam: "Usernams contains spam"
username_other: "Other"
comment:
comment_offensive: "Contains offensive content"
comment_spam: "Contains spam"
comment_noagree: "Does not agree"
comment_other: "Other"
modqueue:
account: "account flags"
actions: Actions
@@ -57,27 +57,23 @@ module.exports = {
hooks: {
RootMutation: {
addTag: {
async post(obj, {tag: {name, id, item_type}}, {user, mutators: {Comment}, pubsub}, info, result) {
async post(obj, {tag: {name, id, item_type}}, {user, mutators: {Comment}, pubsub}, _info) {
if (name === 'FEATURED' && item_type === 'COMMENTS') {
const comment = await Comment.setStatus({id: id, status: 'ACCEPTED'});
if (comment) {
pubsub.publish('commentFeatured', {comment, user});
}
return result;
}
return result;
},
},
removeTag: {
async post(obj, {tag: {name, id, item_type}}, {user, loaders: {Comments}, pubsub}, info, result) {
async post(obj, {tag: {name, id, item_type}}, {user, loaders: {Comments}, pubsub}, _info) {
if (name === 'FEATURED' && item_type === 'COMMENTS') {
const comment = await Comments.get.load(id);
if (comment) {
pubsub.publish('commentUnfeatured', {comment, user});
}
return result;
}
return result;
},
},
},
@@ -35,7 +35,7 @@ class FlagDetails extends Component {
<ul className={styles.info}>
{reasons.map((reason) =>
<li key={reason} className={styles.lessDetail}>
{reason} {summaries[reason].userFlagged && `(${summaries[reason].count})`}
{t(`flags.reasons.comment.${reason.toLowerCase()}`)} {summaries[reason].userFlagged && `(${summaries[reason].count})`}
</li>
)}
</ul>
@@ -1,5 +1,6 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {t} from 'plugin-api/beta/client/services';
import styles from './UserFlagDetails.css';
class UserFlagDetails extends Component {
@@ -25,7 +26,7 @@ class UserFlagDetails extends Component {
{Object.keys(summaries)
.map((reason) => (
<li key={reason}>
{reason} ({summaries[reason].count})
{t(`flags.reasons.comment.${reason.toLowerCase()}`)} ({summaries[reason].count})
<ul className={styles.subDetail}>
{summaries[reason].actions.map((action) =>
<li key={action.user.id}>
@@ -12,4 +12,8 @@ en:
still_toxic: |
This edited comment might still violate our community guidelines.
Our moderation team will review your comment shortly.
flags:
reasons:
comment:
toxic_comment: "Contains toxic language"
es: