diff --git a/app/assets/javascripts/app/collections/likes.js b/app/assets/javascripts/app/collections/likes.js index 76168237b..7eabdc6e4 100644 --- a/app/assets/javascripts/app/collections/likes.js +++ b/app/assets/javascripts/app/collections/likes.js @@ -4,7 +4,10 @@ app.collections.Likes = Backbone.Collection.extend({ model: app.models.Like, initialize : function(models, options) { - this.url = "/posts/" + options.post.id + "/likes"; //not delegating to post.url() because when it is in a stream collection it delegates to that url + this.url = (options.post != null) ? + // not delegating to post.url() because when it is in a stream collection it delegates to that url + "/posts/" + options.post.id + "/likes" : + "/comments/" + options.comment.id + "/likes"; } }); // @license-end diff --git a/app/assets/javascripts/app/models/comment.js b/app/assets/javascripts/app/models/comment.js index d382b731f..da1e017b5 100644 --- a/app/assets/javascripts/app/models/comment.js +++ b/app/assets/javascripts/app/models/comment.js @@ -1,6 +1,53 @@ // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later app.models.Comment = Backbone.Model.extend({ - urlRoot: "/comments" + urlRoot: "/comments", + + initialize: function() { + this.likes = new app.collections.Likes(this.get("likes"), {comment: this}); + }, + + // Copied from Post.Interaction. To be merged in an "interactable" class once comments can be commented too + likesCount: function() { + return this.get("likes_count"); + }, + + userLike: function() { + return this.likes.select(function(like) { + return like.get("author") && like.get("author").guid === app.currentUser.get("guid"); + })[0]; + }, + + toggleLike: function() { + if (this.userLike()) { + this.unlike(); + } else { + this.like(); + } + }, + + like: function() { + var self = this; + this.likes.create({}, { + success: function() { + self.post.set({participation: true}); + self.trigger("change"); + self.set({"likes_count": self.get("likes_count") + 1}); + self.likes.trigger("change"); + }, + error: function(model, response) { + app.flashMessages.handleAjaxError(response); + } + }); + }, + + unlike: function() { + var self = this; + this.userLike().destroy({success: function() { + self.trigger("change"); + self.set({"likes_count": self.get("likes_count") - 1}); + self.likes.trigger("change"); + }}); + } }); // @license-end diff --git a/app/assets/javascripts/app/views/comment_view.js b/app/assets/javascripts/app/views/comment_view.js index a75150290..1cd04ab62 100644 --- a/app/assets/javascripts/app/views/comment_view.js +++ b/app/assets/javascripts/app/views/comment_view.js @@ -9,7 +9,8 @@ app.views.Comment = app.views.Content.extend({ events : function() { return _.extend({}, app.views.Content.prototype.events, { "click .comment_delete": "destroyModel", - "click .comment_report": "report" + "click .comment_report": "report", + "click .like": "toggleLike" }); }, @@ -35,6 +36,11 @@ app.views.Comment = app.views.Content.extend({ canRemove : function() { return app.currentUser.authenticated() && (this.ownComment() || this.postOwner()); + }, + + toggleLike: function(evt) { + if (evt) { evt.preventDefault(); } + this.model.toggleLike(); } }); diff --git a/app/assets/templates/comment_tpl.jst.hbs b/app/assets/templates/comment_tpl.jst.hbs index 36d56ef1c..dd9480548 100644 --- a/app/assets/templates/comment_tpl.jst.hbs +++ b/app/assets/templates/comment_tpl.jst.hbs @@ -36,5 +36,15 @@