mirror of
https://github.com/wassname/talk.git
synced 2026-07-28 11:27:05 +08:00
Handle comment flags
This commit is contained in:
@@ -14,10 +14,6 @@ const ascending = (a, b) => {
|
||||
|
||||
const descending = (a, b) => -ascending(a, b);
|
||||
|
||||
function truncate(s, length = 10) {
|
||||
return (s.length > length) ? `${s.substring(0, length)}...` : s;
|
||||
}
|
||||
|
||||
function queueHasComment(root, queue, id) {
|
||||
return root[queue].nodes.find((c) => c.id === id);
|
||||
}
|
||||
@@ -88,22 +84,16 @@ function getCommentQueues(comment) {
|
||||
return queues;
|
||||
}
|
||||
|
||||
function showNotification(queue, comment, user) {
|
||||
const text = `${user.username} ${comment.status.toLowerCase()} comment "${truncate(comment.body, 50)}"`;
|
||||
notification.info(text);
|
||||
}
|
||||
|
||||
export function handleCommentStatusChange(root, comment, {sort, notify, activeQueue}) {
|
||||
export function handleCommentStatusChange(root, comment, {sort, notify}) {
|
||||
let next = root;
|
||||
const nextQueues = getCommentQueues(comment);
|
||||
|
||||
let notificationShown = false;
|
||||
const showNotificationOnce = (...args) => {
|
||||
const showNotificationOnce = () => {
|
||||
if (notificationShown) {
|
||||
return;
|
||||
}
|
||||
const user = comment.status_history[comment.status_history.length - 1].assigned_by;
|
||||
showNotification(...[...args, user]);
|
||||
notification.info(notify.text);
|
||||
notificationShown = true;
|
||||
};
|
||||
|
||||
@@ -111,38 +101,25 @@ export function handleCommentStatusChange(root, comment, {sort, notify, activeQu
|
||||
if (nextQueues.indexOf(queue) >= 0) {
|
||||
if (!queueHasComment(next, queue, comment.id)) {
|
||||
next = addCommentToQueue(next, queue, comment, sort);
|
||||
if (notify && activeQueue === queue && shouldCommentBeAdded(next, queue, comment, sort)) {
|
||||
showNotificationOnce(queue, comment);
|
||||
if (notify && notify.activeQueue === queue && shouldCommentBeAdded(next, queue, comment, sort)) {
|
||||
showNotificationOnce(comment);
|
||||
}
|
||||
}
|
||||
} else if(queueHasComment(next, queue, comment.id)){
|
||||
next = removeCommentFromQueue(next, queue, comment.id);
|
||||
if (notify && activeQueue === queue) {
|
||||
showNotificationOnce(queue, comment);
|
||||
if (notify && notify.activeQueue === queue) {
|
||||
showNotificationOnce(comment);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
queue === 'all'
|
||||
notify
|
||||
&& (queue === 'all' || notify.anyQueue)
|
||||
&& queueHasComment(next, queue, comment.id)
|
||||
&& notify
|
||||
&& activeQueue === queue
|
||||
&& notify.activeQueue === queue
|
||||
) {
|
||||
showNotificationOnce(queue, comment);
|
||||
showNotificationOnce(comment);
|
||||
}
|
||||
|
||||
// TODO: Flagged notification
|
||||
});
|
||||
return next;
|
||||
}
|
||||
|
||||
export function handleCommentEdit(root, comment, {sort, activeQueue}) {
|
||||
if (
|
||||
queueHasComment(root, activeQueue, comment.id)
|
||||
|| comment.status.toLowerCase() === activeQueue && shouldCommentBeAdded(root, activeQueue, comment, sort)
|
||||
) {
|
||||
const text = `${comment.user.username} edited comment to "${truncate(comment.body, 50)}"`;
|
||||
notification.info(text);
|
||||
}
|
||||
return handleCommentStatusChange(root, comment, {sort, activeQueue});
|
||||
}
|
||||
|
||||
@@ -8,9 +8,10 @@ import {getDefinitionName} from 'coral-framework/utils';
|
||||
import * as notification from 'coral-admin/src/services/notification';
|
||||
import t, {timeago} from 'coral-framework/services/i18n';
|
||||
import update from 'immutability-helper';
|
||||
import truncate from 'lodash/truncate';
|
||||
|
||||
import {withSetUserStatus, withSuspendUser, withSetCommentStatus} from 'coral-framework/graphql/mutations';
|
||||
import {handleCommentStatusChange, handleCommentEdit} from '../../../graphql/utils';
|
||||
import {handleCommentStatusChange} from '../../../graphql/utils';
|
||||
|
||||
import {fetchSettings} from 'actions/settings';
|
||||
import {updateAssets} from 'actions/assets';
|
||||
@@ -44,16 +45,16 @@ class ModerationContainer extends Component {
|
||||
},
|
||||
updateQuery: (prev, {subscriptionData: {data: {commentStatusChanged: comment}}}) => {
|
||||
const user = comment.status_history[comment.status_history.length - 1].assigned_by;
|
||||
|
||||
const extraParams = this.props.auth.user.id === user.id
|
||||
const notify = this.props.auth.user.id === user.id
|
||||
? {}
|
||||
: {
|
||||
notify: true,
|
||||
activeQueue: this.activeTab,
|
||||
text: `${user.username} ${comment.status.toLowerCase()} comment "${truncate(comment.body, {lenght: 50})}"`,
|
||||
anyQueue: false,
|
||||
};
|
||||
return handleCommentStatusChange(prev, comment, {
|
||||
sort: this.props.moderation.sortOrder,
|
||||
...extraParams,
|
||||
notify,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -63,14 +64,37 @@ class ModerationContainer extends Component {
|
||||
variables: {
|
||||
asset_id: this.props.data.variables.asset_id,
|
||||
},
|
||||
updateQuery: (prev, {subscriptionData: {data: {commentEdited}}}) => {
|
||||
return handleCommentEdit(prev, commentEdited, {
|
||||
activeQueue: this.activeTab,
|
||||
updateQuery: (prev, {subscriptionData: {data: {commentEdited: comment}}}) => {
|
||||
return handleCommentStatusChange(prev, comment, {
|
||||
sort: this.props.moderation.sortOrder,
|
||||
notify: {
|
||||
activeQueue: this.activeTab,
|
||||
text: `${comment.user.username} edited comment to "${truncate(comment.body, {lenght: 50})}"`,
|
||||
anyQueue: false,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
this.subscriptions.push(sub1, sub2);
|
||||
const sub3 = this.props.data.subscribeToMore({
|
||||
document: COMMENTS_FLAGGED_SUBSCRIPTION,
|
||||
variables: {
|
||||
asset_id: this.props.data.variables.asset_id,
|
||||
},
|
||||
updateQuery: (prev, {subscriptionData: {data: {commentFlagged: comment}}}) => {
|
||||
const user = comment.actions[comment.actions.length - 1].user;
|
||||
return handleCommentStatusChange(prev, comment, {
|
||||
sort: this.props.moderation.sortOrder,
|
||||
notify: {
|
||||
activeQueue: this.activeTab,
|
||||
text: `${user.username} flagged comment "${truncate(comment.body, {lenght: 50})}"`,
|
||||
anyQueue: true,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
this.subscriptions.push(sub1, sub2, sub3);
|
||||
}
|
||||
|
||||
unsubscribe() {
|
||||
@@ -216,6 +240,15 @@ const COMMENTS_EDITED_SUBSCRIPTION = gql`
|
||||
${Comment.fragments.comment}
|
||||
`;
|
||||
|
||||
const COMMENTS_FLAGGED_SUBSCRIPTION = gql`
|
||||
subscription CommentFlagged($asset_id: ID){
|
||||
commentFlagged(asset_id: $asset_id){
|
||||
...${getDefinitionName(Comment.fragments.comment)}
|
||||
}
|
||||
}
|
||||
${Comment.fragments.comment}
|
||||
`;
|
||||
|
||||
const STATUS_CHANGED_SUBSCRIPTION = gql`
|
||||
subscription CommentStatusChanged($asset_id: ID){
|
||||
commentStatusChanged(asset_id: $asset_id){
|
||||
|
||||
@@ -13,7 +13,16 @@ const {CREATE_ACTION, DELETE_ACTION} = require('../../perms/constants');
|
||||
* @param {String} action_type type of the action
|
||||
* @return {Promise} resolves to the action created
|
||||
*/
|
||||
const createAction = async ({user = {}}, {item_id, item_type, action_type, group_id, metadata = {}}) => {
|
||||
const createAction = async ({user = {}, pubsub, loaders: {Comments}}, {item_id, item_type, action_type, group_id, metadata = {}}) => {
|
||||
|
||||
let comment;
|
||||
if (pubsub && item_type === 'COMMENTS') {
|
||||
comment = await Comments.get.load(item_id);
|
||||
if (!comment) {
|
||||
throw new Error('Comment not found');
|
||||
}
|
||||
}
|
||||
|
||||
let action = await ActionsService.insertUserAction({
|
||||
item_id,
|
||||
item_type,
|
||||
@@ -29,6 +38,10 @@ const createAction = async ({user = {}}, {item_id, item_type, action_type, group
|
||||
await UsersService.setStatus(item_id, 'PENDING');
|
||||
}
|
||||
|
||||
if (pubsub && comment) {
|
||||
pubsub.publish('commentFlagged', comment);
|
||||
}
|
||||
|
||||
return action;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ const Subscription = {
|
||||
commentStatusChanged(comment) {
|
||||
return comment;
|
||||
},
|
||||
commentFlagged(comment) {
|
||||
return comment;
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = Subscription;
|
||||
|
||||
+18
-1
@@ -12,7 +12,9 @@ const {deserializeUser} = require('../services/subscriptions');
|
||||
|
||||
const {
|
||||
SUBSCRIBE_COMMENT_STATUS,
|
||||
SUBSCRIBE_COMMENT_FLAGS,
|
||||
SUBSCRIBE_ALL_COMMENT_EDITS,
|
||||
SUBSCRIBE_ALL_COMMENT_ADDITIONS,
|
||||
} = require('../perms/constants');
|
||||
|
||||
/**
|
||||
@@ -27,7 +29,12 @@ const setupFunctions = plugins.get('server', 'setupFunctions').reduce((acc, {plu
|
||||
}, {
|
||||
commentAdded: (options, args) => ({
|
||||
commentAdded: {
|
||||
filter: (comment) => comment.asset_id === args.asset_id
|
||||
filter: (comment, context) => {
|
||||
if (!args.asset_id && (!context.user || !context.user.can(SUBSCRIBE_ALL_COMMENT_ADDITIONS))) {
|
||||
return false;
|
||||
}
|
||||
return !args.asset_id || comment.asset_id === args.asset_id;
|
||||
}
|
||||
},
|
||||
}),
|
||||
commentEdited: (options, args) => ({
|
||||
@@ -40,6 +47,16 @@ const setupFunctions = plugins.get('server', 'setupFunctions').reduce((acc, {plu
|
||||
}
|
||||
},
|
||||
}),
|
||||
commentFlagged: (options, args) => ({
|
||||
commentFlagged: {
|
||||
filter: ({comment}, context) => {
|
||||
if (!context.user || !context.user.can(SUBSCRIBE_COMMENT_FLAGS)) {
|
||||
return false;
|
||||
}
|
||||
return !args.asset_id || comment.asset_id === args.asset_id;
|
||||
}
|
||||
},
|
||||
}),
|
||||
commentStatusChanged: (options, args) => ({
|
||||
commentStatusChanged: {
|
||||
filter: ({comment}, context) => {
|
||||
|
||||
@@ -948,12 +948,19 @@ type RootMutation {
|
||||
type Subscription {
|
||||
|
||||
# Get an update whenever a comment was added.
|
||||
commentAdded(asset_id: ID!): Comment
|
||||
# `asset_id` is required except for users with the `ADMIN` or `MODERATOR` role.
|
||||
commentAdded(asset_id: ID): Comment
|
||||
|
||||
# Get an update whenever a comment was edited.
|
||||
# `asset_id` is required except for users with the `ADMIN` or `MODERATOR` role.
|
||||
commentEdited(asset_id: ID): Comment
|
||||
|
||||
# Get an update whenever a comment was flagged.
|
||||
# Requires the `ADMIN` or `MODERATOR` role.
|
||||
commentFlagged(asset_id: ID): Comment
|
||||
|
||||
# Get an update whenever the status of a comment changed due to a moderator action.
|
||||
# Requires the `ADMIN` or `MODERATOR` role.
|
||||
commentStatusChanged(asset_id: ID): Comment
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -26,6 +26,7 @@ module.exports = {
|
||||
|
||||
// subscriptions
|
||||
SUBSCRIBE_COMMENT_STATUS: 'SUBSCRIBE_COMMENT_STATUS',
|
||||
SUBSCRIBE_ALL_COMMENT_FLAGS: 'SUBSCRIBE_ALL_COMMENT_FLAGS',
|
||||
SUBSCRIBE_COMMENT_FLAGS: 'SUBSCRIBE_COMMENT_FLAGS',
|
||||
SUBSCRIBE_ALL_COMMENT_ADDITIONS: 'SUBSCRIBE_ALL_COMMENT_ADDITIONS',
|
||||
SUBSCRIBE_ALL_COMMENT_EDITS: 'SUBSCRIBE_ALL_COMMENT_EDITS',
|
||||
};
|
||||
|
||||
@@ -3,11 +3,13 @@ const types = require('./constants');
|
||||
|
||||
module.exports = (user, perm) => {
|
||||
switch (perm) {
|
||||
case types.SUBSCRIBE_COMMENT_FLAGS:
|
||||
return check(user, ['ADMIN', 'MODERATOR']);
|
||||
case types.SUBSCRIBE_COMMENT_STATUS:
|
||||
return check(user, ['ADMIN', 'MODERATOR']);
|
||||
case types.SUBSCRIBE_ALL_COMMENT_EDITS:
|
||||
return check(user, ['ADMIN', 'MODERATOR']);
|
||||
case types.SUBSCRIBE_ALL_COMMENT_FLAGS:
|
||||
case types.SUBSCRIBE_ALL_COMMENT_ADDITIONS:
|
||||
return check(user, ['ADMIN', 'MODERATOR']);
|
||||
default:
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user