mirror of
https://github.com/wassname/talk.git
synced 2026-06-28 16:14:49 +08:00
82 lines
2.3 KiB
JavaScript
82 lines
2.3 KiB
JavaScript
const _ = require('lodash');
|
|
const DataLoader = require('dataloader');
|
|
|
|
const CommentModel = require('../../models/comment');
|
|
|
|
console.warn('Enabling the talk-plugin-deep-reply-count plugin introduces a signifigant performance impact on larger sites, use with care.');
|
|
|
|
// genDeepCommentCount will return the deep comment count for a given parent id.
|
|
const genDeepCommentCount = async (context, parent_ids) => {
|
|
|
|
// Get all the replies to the parent comments.
|
|
const replies = await CommentModel
|
|
.find({
|
|
parent_id: {
|
|
$in: _.uniq(parent_ids),
|
|
},
|
|
}, {
|
|
id: 1,
|
|
reply_count: 1,
|
|
parent_id: 1,
|
|
});
|
|
|
|
// Get all the replies that have comments on them.
|
|
const commentedOnReplies = replies.filter(({reply_count}) => {
|
|
return reply_count && reply_count > 0;
|
|
});
|
|
|
|
let deepReplyCount = [];
|
|
|
|
// And if there were any..
|
|
if (commentedOnReplies.length > 0) {
|
|
|
|
// Load the reply count for each of them.
|
|
deepReplyCount = await context.loaders.Comments.getDeepCount.loadMany(_.uniq(commentedOnReplies.map(({id}) => {
|
|
return id;
|
|
})));
|
|
}
|
|
|
|
// Get all the direct replies to the parent comments.
|
|
const allDirectReplies = _.groupBy(replies, 'parent_id');
|
|
|
|
// Collect all the ancestor replies.
|
|
const allAncestorReplies = _.groupBy(_.zip(commentedOnReplies, deepReplyCount), ([{parent_id}]) => {
|
|
return parent_id;
|
|
});
|
|
|
|
// Return the replies in an array matching that of the input parent_ids array.
|
|
return parent_ids.map((parent_id) => {
|
|
|
|
// Get the direct replies to this comment.
|
|
const directReplies = parent_id in allDirectReplies ? allDirectReplies[parent_id] : [];
|
|
const ancestorReplies = parent_id in allAncestorReplies ? allAncestorReplies[parent_id] : [];
|
|
|
|
// Reduce this array.
|
|
return ancestorReplies.reduce((acc, [, count]) => {
|
|
return acc + count;
|
|
}, directReplies.length);
|
|
});
|
|
};
|
|
|
|
module.exports = {
|
|
typeDefs: `
|
|
type Comment {
|
|
|
|
# deepReplyCount is the count of all decendant replies.
|
|
deepReplyCount: Int
|
|
}
|
|
`,
|
|
loaders: (context) => ({
|
|
Comments: {
|
|
getDeepCount: new DataLoader((parent_ids) => genDeepCommentCount(context, parent_ids)),
|
|
}
|
|
}),
|
|
resolvers: {
|
|
Comment: {
|
|
deepReplyCount({id}, args, {loaders: {Comments}}) {
|
|
return Comments.getDeepCount.load(id);
|
|
}
|
|
}
|
|
}
|
|
};
|