From 58736586e49e2ea9d03adee4d16100492e3aa5a2 Mon Sep 17 00:00:00 2001 From: Benjamin Goering Date: Mon, 10 Apr 2017 15:41:53 -0700 Subject: [PATCH] Asset commentCount and totalCommentCount can be personalized by notIgnoredBy --- .../graphql/queries/streamQuery.graphql | 4 +- graph/loaders/comments.js | 59 +++++++++++++++++++ graph/resolvers/asset.js | 12 ++-- graph/typeDefs.graphql | 4 +- 4 files changed, 71 insertions(+), 8 deletions(-) diff --git a/client/coral-framework/graphql/queries/streamQuery.graphql b/client/coral-framework/graphql/queries/streamQuery.graphql index 9b95a9c2b..a96f7f634 100644 --- a/client/coral-framework/graphql/queries/streamQuery.graphql +++ b/client/coral-framework/graphql/queries/streamQuery.graphql @@ -36,8 +36,8 @@ query AssetQuery($asset_id: ID, $asset_url: String, $comment_id: ID!, $has_comme charCount requireEmailConfirmation } - commentCount - totalCommentCount + commentCount(notIgnoredBy: $notIgnoredBy) + totalCommentCount(notIgnoredBy: $notIgnoredBy) comments(limit: 10, notIgnoredBy: $notIgnoredBy) { ...commentView replyCount(notIgnoredBy: $notIgnoredBy) diff --git a/graph/loaders/comments.js b/graph/loaders/comments.js index 13aa47fb4..c9fe1c302 100644 --- a/graph/loaders/comments.js +++ b/graph/loaders/comments.js @@ -40,6 +40,34 @@ const getCountsByAssetID = (context, asset_ids) => { .then((results) => results.map((result) => result ? result.count : 0)); }; +/** + * Returns the count of all public comments on an asset id, also filtering by personalization options. + * + * @param {Array} id The ID of the asset + * @param {Array} notIgnoredBy Exclude comments ignored by this User ID + */ +const getCountsByAssetIDPersonalized = async (context, {assetId, notIgnoredBy}) => { + const query = { + asset_id: assetId, + status: { + $in: ['NONE', 'ACCEPTED'], + }, + }; + if (notIgnoredBy) { + const user = context.user; + if (user.id !== notIgnoredBy) { + throw new Error(`You are not authorized to query for comments counts notIgnoredBy ${notIgnoredBy}`); + } + + // load afresh, as `user` may be from cache and not have recent ignores + const freshUser = await UsersService.findById(user.id); + const ignoredUsers = freshUser.ignoresUsers; + query.author_id = {$nin: ignoredUsers}; + } + const count = await CommentModel.where(query).count(); + return count; +}; + /** * Returns the comment count for all comments that are public based on their * asset ids. @@ -73,6 +101,35 @@ const getParentCountsByAssetID = (context, asset_ids) => { .then((results) => results.map((result) => result ? result.count : 0)); }; +/** + * Returns the count of top-level comments on an asset id, also filtering by personalization options. + * + * @param {Array} id The ID of the asset + * @param {Array} notIgnoredBy Exclude comments ignored by this User ID + */ +const getParentCountByAssetIDPersonalized = async (context, {assetId, notIgnoredBy}) => { + const query = { + asset_id: assetId, + parent_id: null, + status: { + $in: ['NONE', 'ACCEPTED'], + }, + }; + if (notIgnoredBy) { + const user = context.user; + if (user.id !== notIgnoredBy) { + throw new Error(`You are not authorized to query for comments counts notIgnoredBy ${notIgnoredBy}`); + } + + // load afresh, as `user` may be from cache and not have recent ignores + const freshUser = await UsersService.findById(user.id); + const ignoredUsers = freshUser.ignoresUsers; + query.author_id = {$nin: ignoredUsers}; + } + const count = await CommentModel.where(query).count(); + return count; +}; + /** * Returns the comment count for all comments that are public based on their * parent ids. @@ -388,7 +445,9 @@ module.exports = (context) => ({ getByQuery: (query) => getCommentsByQuery(context, query), getCountByQuery: (query) => getCommentCountByQuery(context, query), countByAssetID: new SharedCounterDataLoader('Comments.totalCommentCount', 3600, (ids) => getCountsByAssetID(context, ids)), + countByAssetIDPersonalized: (query) => getCountsByAssetIDPersonalized(context, query), parentCountByAssetID: new SharedCounterDataLoader('Comments.countByAssetID', 3600, (ids) => getParentCountsByAssetID(context, ids)), + parentCountByAssetIDPersonalized: (query) => getParentCountByAssetIDPersonalized(context, query), countByParentID: new SharedCounterDataLoader('Comments.countByParentID', 3600, (ids) => getCountsByParentID(context, ids)), countByParentIDPersonalized: (query) => getCountByParentIDPersonalized(context, query), genRecentReplies: new DataLoader((ids) => genRecentReplies(context, ids)), diff --git a/graph/resolvers/asset.js b/graph/resolvers/asset.js index 6459f53cd..811181aa6 100644 --- a/graph/resolvers/asset.js +++ b/graph/resolvers/asset.js @@ -11,18 +11,22 @@ const Asset = { notIgnoredBy, }); }, - commentCount({id, commentCount}, _, {loaders: {Comments}}) { + commentCount({id, commentCount}, {notIgnoredBy}, {loaders: {Comments}}) { + if (notIgnoredBy) { + return Comments.parentCountByAssetIDPersonalized({assetId: id, notIgnoredBy}); + } if (commentCount != null) { return commentCount; } - return Comments.parentCountByAssetID.load(id); }, - totalCommentCount({id, totalCommentCount}, _, {loaders: {Comments}}) { + totalCommentCount({id, totalCommentCount}, {notIgnoredBy}, {loaders: {Comments}}) { + if (notIgnoredBy) { + return Comments.countByAssetIDPersonalized({assetId: id, notIgnoredBy}); + } if (totalCommentCount != null) { return totalCommentCount; } - return Comments.countByAssetID.load(id); }, settings({settings = null}, _, {loaders: {Settings}}) { diff --git a/graph/typeDefs.graphql b/graph/typeDefs.graphql index 1980a3bbc..7f988054b 100644 --- a/graph/typeDefs.graphql +++ b/graph/typeDefs.graphql @@ -423,10 +423,10 @@ type Asset { comments(sort: SORT_ORDER = REVERSE_CHRONOLOGICAL, limit: Int = 10, notIgnoredBy: String): [Comment] # The count of top level comments on the asset. - commentCount: Int + commentCount(notIgnoredBy: String): Int # The total count of all comments made on the asset. - totalCommentCount: Int + totalCommentCount(notIgnoredBy: String): Int # The settings (rectified with the global settings) that should be applied to # this asset.