From 11bd06403964958cea581029edc7bc75003fa7e6 Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Fri, 8 May 2015 09:20:58 +0900 Subject: [PATCH] Add commentsListController --- .../comments_list/comments_list_compact.html | 25 ++++ .../comments_list/comments_list_compact.js | 37 ++++++ .../comments_list_controller.html | 3 + .../comments_list/comments_list_controller.js | 109 ++++++++++++++++++ packages/telescope-comments/lib/parameters.js | 34 ++++++ .../lib/server/publications.js | 16 +++ packages/telescope-comments/lib/views.js | 33 ++++++ .../templates/profile/user_comments.html | 26 +---- .../client/templates/profile/user_comments.js | 60 +++------- .../lib/server/publications.js | 11 -- 10 files changed, 275 insertions(+), 79 deletions(-) create mode 100644 packages/telescope-comments/lib/client/templates/comments_list/comments_list_compact.html create mode 100644 packages/telescope-comments/lib/client/templates/comments_list/comments_list_compact.js create mode 100644 packages/telescope-comments/lib/client/templates/comments_list/comments_list_controller.html create mode 100644 packages/telescope-comments/lib/client/templates/comments_list/comments_list_controller.js create mode 100644 packages/telescope-comments/lib/parameters.js create mode 100644 packages/telescope-comments/lib/views.js diff --git a/packages/telescope-comments/lib/client/templates/comments_list/comments_list_compact.html b/packages/telescope-comments/lib/client/templates/comments_list/comments_list_compact.html new file mode 100644 index 000000000..20c758daa --- /dev/null +++ b/packages/telescope-comments/lib/client/templates/comments_list/comments_list_compact.html @@ -0,0 +1,25 @@ +- \ No newline at end of file diff --git a/packages/telescope-comments/lib/client/templates/comments_list/comments_list_compact.js b/packages/telescope-comments/lib/client/templates/comments_list/comments_list_compact.js new file mode 100644 index 000000000..b711309a0 --- /dev/null +++ b/packages/telescope-comments/lib/client/templates/comments_list/comments_list_compact.js @@ -0,0 +1,37 @@ +Template.comments_list_compact.helpers({ + commentsCursor: function () { + if (this.commentsCursor) { // not sure why this should ever be undefined, but it can apparently + var comments = this.commentsCursor.map(function (comment, index) { + comment.rank = index; + return comment; + }); + return comments; + } else { + console.log('commentsCursor not defined'); + } + }, + postTitle: function () { + var post = Posts.findOne(this.postId); + return post.title; + }, + fieldLabel: function () { + return this.controllerOptions.fieldLabel; + }, + fieldValue: function () { + var controllerOptions = Template.parentData(3).data.controllerOptions; + return controllerOptions.fieldValue(this); + } +}); + +Template.comments_list_compact.events({ + 'click .more-button': function (event) { + event.preventDefault(); + if (this.controllerInstance) { + // controller is a template + this.loadMoreHandler(this.controllerInstance); + } else { + // controller is router + this.loadMoreHandler(); + } + } +}); diff --git a/packages/telescope-comments/lib/client/templates/comments_list/comments_list_controller.html b/packages/telescope-comments/lib/client/templates/comments_list/comments_list_controller.html new file mode 100644 index 000000000..5f5f4b268 --- /dev/null +++ b/packages/telescope-comments/lib/client/templates/comments_list/comments_list_controller.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/packages/telescope-comments/lib/client/templates/comments_list/comments_list_controller.js b/packages/telescope-comments/lib/client/templates/comments_list/comments_list_controller.js new file mode 100644 index 000000000..3340b8c27 --- /dev/null +++ b/packages/telescope-comments/lib/client/templates/comments_list/comments_list_controller.js @@ -0,0 +1,109 @@ +// see https://www.discovermeteor.com/blog/template-level-subscriptions/ + +/* + +This template acts as the controller that sets and manages the reactive context +for the embedded commentsList template. It receives its parameters from a "caller" template. + +*/ + +Template.commentsListController.onCreated(function () { + + // 1. Initialization (*not* reactive!) + var instance = this; + + // initialize the reactive variables + instance.terms = new ReactiveVar(instance.data.terms); + instance.commentsLimit = new ReactiveVar(Settings.get('commentsPerPage', 10)); + + // 2. Autorun + + // Autorun 1: when terms change, reset the limit + instance.autorun(function () { + // add a dependency on data context to trigger the autorun + var terms = Template.currentData().terms; // ⚡ reactive ⚡ + instance.commentsLimit.set(Settings.get('commentsPerPage', 10)); + }); + + // Autorun 2: will re-run when limit or terms are changed + instance.autorun(function () { + + // get terms from data context + var terms = Template.currentData().terms; // ⚡ reactive ⚡ + + // get limit from local template variable + var commentsLimit = instance.commentsLimit.get(); // ⚡ reactive ⚡ + + // create new subscriptionTerms object using the new limit + var subscriptionTerms = _.extend(_.clone(terms), {limit: commentsLimit}); // extend terms with limit + + // use this new object to subscribe + var commentsSubscription = instance.subscribe('userComments', subscriptionTerms); + + var subscriptionsReady = instance.subscriptionsReady(); // ⚡ reactive ⚡ + + console.log('// ------ autorun running ------ //'); + console.log("terms: ", terms); + console.log("limit: ", commentsLimit); + console.log("ready: ", subscriptionsReady); + // Tracker.onInvalidate(console.trace.bind(console)); + + // if subscriptions are ready, set terms to subscriptionsTerms + if (subscriptionsReady) { + instance.terms.set(subscriptionTerms); + } + + }); + +}); + +Template.commentsListController.helpers({ + template: function () { + return !!this.template? this.template: "comments_list"; + }, + data: function () { + + var context = this; + + var instance = Template.instance(); + + var terms = instance.terms.get(); // ⚡ reactive ⚡ + var commentsReady = instance.subscriptionsReady(); // ⚡ reactive ⚡ + + var commentsLimit = terms.limit; + var parameters = Comments.getSubParams(terms); + var commentsCursor = Comments.find(parameters.find, parameters.options); + + var data = { + + // comments cursor + commentsCursor: commentsCursor, + + // comments subscription readiness, used to show spinner + commentsReady: commentsReady, + + // whether to show the load more button or not + hasMorecomments: commentsCursor.count() >= commentsLimit, + + // what to do when user clicks "load more" + loadMoreHandler: function (instance) { + event.preventDefault(); + + // increase limit by 5 and update it + var limit = instance.commentsLimit.get(); + limit += Settings.get('commentsPerPage', 10); + instance.commentsLimit.set(limit); + + }, + + // the current instance + controllerInstance: instance, + + controllerOptions: context.options // pass any options on to the template + + }; + + console.log(data) + return data; + } +}); \ No newline at end of file diff --git a/packages/telescope-comments/lib/parameters.js b/packages/telescope-comments/lib/parameters.js new file mode 100644 index 000000000..cb4e6a6ab --- /dev/null +++ b/packages/telescope-comments/lib/parameters.js @@ -0,0 +1,34 @@ +/** + * Gives an object containing the appropriate find + * and options arguments for the subscriptions's Comments.find() + * @param {Object} terms + */ +Comments.getSubParams = function (terms) { + + var maxLimit = 200; + + // console.log(terms) + + // note: using jquery's extend() with "deep" parameter set to true instead of shallow _.extend() + // see: http://api.jquery.com/jQuery.extend/ + + // initialize parameters by extending baseParameters object, to avoid passing it by reference + var parameters = Telescope.utils.deepExtend(true, {}, Comments.views.baseParameters); + + // get query parameters according to current view + if (typeof Comments.views[terms.view] !== 'undefined') + parameters = Telescope.utils.deepExtend(true, parameters, Comments.views[terms.view](terms)); + + // if a limit was provided with the terms, add it too (note: limit=0 means "no limit") + if (typeof terms.limit !== 'undefined') + _.extend(parameters.options, {limit: parseInt(terms.limit)}); + + // limit to "maxLimit" posts at most when limit is undefined, equal to 0, or superior to maxLimit + if(!parameters.options.limit || parameters.options.limit == 0 || parameters.options.limit > maxLimit) { + parameters.options.limit = maxLimit; + } + + // console.log(parameters); + + return parameters; +}; \ No newline at end of file diff --git a/packages/telescope-comments/lib/server/publications.js b/packages/telescope-comments/lib/server/publications.js index 419e2c2dd..594a4f3de 100644 --- a/packages/telescope-comments/lib/server/publications.js +++ b/packages/telescope-comments/lib/server/publications.js @@ -23,6 +23,22 @@ Meteor.publish('commentPost', function(commentId) { return []; }); +// Publish a user's comments and the posts that were commented on + +Meteor.publish('userComments', function(terms) { + if(Users.can.viewById(this.userId)){ + var parameters = Comments.getSubParams(terms); + var comments = Comments.find(parameters.find, parameters.options); + + // if there are comments, find out which posts were commented on + var commentedPostIds = comments.count() ? _.pluck(comments.fetch(), 'postId') : []; + return [ + comments, + Posts.find({_id: {$in: commentedPostIds}}) + ]; + } +}); + // Publish author of the current comment, and author of the post related to the current comment Meteor.publish('commentUsers', function(commentId) { diff --git a/packages/telescope-comments/lib/views.js b/packages/telescope-comments/lib/views.js new file mode 100644 index 000000000..1939bbd72 --- /dev/null +++ b/packages/telescope-comments/lib/views.js @@ -0,0 +1,33 @@ +/** + * Comment views are filters used for subscribing to and viewing comments + * @namespace Comments.views + */ +Comments.views = {}; + +/** + * Add a module to a comment view + * @param {string} viewName - The name of the view + * @param {function} [viewFunction] - The function used to calculate query terms. Takes terms and baseParameters arguments + */ +Comments.views.register = function (viewName, viewFunction) { + Comments.views[viewName] = viewFunction; +}; + +// will be common to all other view unless specific properties are overwritten +Comments.views.baseParameters = { + options: { + limit: 10 + } +}; + +Comments.views.register("postComments", function (terms) { + return { + find: {postId: terms.postId} + }; +}); + +Comments.views.register("userComments", function (terms) { + return { + find: {userId: terms.userId} + }; +}); \ No newline at end of file diff --git a/packages/telescope-users/lib/client/templates/profile/user_comments.html b/packages/telescope-users/lib/client/templates/profile/user_comments.html index ba76cb667..851525564 100644 --- a/packages/telescope-users/lib/client/templates/profile/user_comments.html +++ b/packages/telescope-users/lib/client/templates/profile/user_comments.html @@ -1,28 +1,6 @@ \ No newline at end of file diff --git a/packages/telescope-users/lib/client/templates/profile/user_comments.js b/packages/telescope-users/lib/client/templates/profile/user_comments.js index 366c810e7..463d52593 100644 --- a/packages/telescope-users/lib/client/templates/profile/user_comments.js +++ b/packages/telescope-users/lib/client/templates/profile/user_comments.js @@ -1,48 +1,20 @@ -Template.user_comments.created = function () { - Session.set('commentsShown', 5); - - var user = this.data; - var instance = this; - - instance.commentsShown = new ReactiveVar(5); - instance.comments = new ReactiveVar({}); - - this.autorun(function () { - - // get parameters - var limit = instance.commentsShown.get(); - - // subscribe - instance.subscription = Meteor.subscribe('userComments', user._id, limit); - - // set cursor - instance.comments.set(Comments.find({userId: user._id}, {limit: limit})); - }); -}; - Template.user_comments.helpers({ - comments: function () { - var comments = Template.instance().comments.get(); - if(!!comments){ - // extend comments with each commented post - var extendedComments = comments.map(function (comment) { - var post = Posts.findOne(comment.postId); - if(post) // post might not be available anymore - comment.postTitle = post.title; - return comment; - }); - return extendedComments; + arguments: function () { + var user = this; + return { + template: "comments_list_compact", + options: { + currentUser: user, + fieldLabel: i18n.t("commentedAt"), + fieldValue: function (comment) { + return moment(comment.createdAt).format("MM/DD/YYYY, HH:mm"); + } + }, + terms: { + view: 'userComments', + userId: user._id, + limit: 5 + } } - }, - hasMoreComments: function () { - return Template.instance().comments.get().count() >= Template.instance().commentsShown.get(); - } -}); - -Template.user_comments.events({ - 'click .comments-more': function (e) { - e.preventDefault(); - var commentsShown = Template.instance().commentsShown.get(); - Template.instance().commentsShown.set(commentsShown+5); } }); \ No newline at end of file diff --git a/packages/telescope-users/lib/server/publications.js b/packages/telescope-users/lib/server/publications.js index 784b93035..72b02219f 100644 --- a/packages/telescope-users/lib/server/publications.js +++ b/packages/telescope-users/lib/server/publications.js @@ -28,17 +28,6 @@ Meteor.publish('userDownvotedPosts', function(terms) { return posts; }); -Meteor.publish('userComments', function(userId, limit) { - var comments = Comments.find({userId: userId}, {limit: limit}); - // if there are comments, find out which posts were commented on - var commentedPostIds = comments.count() ? _.pluck(comments.fetch(), 'postId') : []; - return [ - comments, - Posts.find({_id: {$in: commentedPostIds}}) - ] -}); - - // Publish the current user Meteor.publish('currentUser', function() {