diff --git a/Changelog.md b/Changelog.md index a7add57e1..a827350e5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Note: Although this is a minor release, the configuration file changed because t * Load jQuery in the head on mobile [#7086](https://github.com/diaspora/diaspora/pull/7086) * Use translation for NodeInfo services [#7102](https://github.com/diaspora/diaspora/pull/7102) * Adopt new Mapbox tile URIs [#7066](https://github.com/diaspora/diaspora/pull/7066) +* Refactored post interactions on the single post view [#7089](https://github.com/diaspora/diaspora/pull/7089) ## Bug fixes * Post comments no longer get collapsed when interacting with a post [#7040](https://github.com/diaspora/diaspora/pull/7040) diff --git a/app/assets/javascripts/app/views/comment_stream_view.js b/app/assets/javascripts/app/views/comment_stream_view.js index 24f05ee93..0119b3329 100644 --- a/app/assets/javascripts/app/views/comment_stream_view.js +++ b/app/assets/javascripts/app/views/comment_stream_view.js @@ -13,9 +13,8 @@ app.views.CommentStream = app.views.Base.extend({ "click .toggle_post_comments": "expandComments" }, - initialize: function(options) { - this.commentTemplate = options.commentTemplate; - + initialize: function() { + this.CommentView = app.views.Comment; this.setupBindings(); }, @@ -84,7 +83,7 @@ app.views.CommentStream = app.views.Base.extend({ // on post ownership in the Comment view. comment.set({parent : this.model.toJSON()}); - var commentHtml = new app.views.Comment({model: comment}).render().el; + var commentHtml = new this.CommentView({model: comment}).render().el; var commentBlocks = this.$(".comments div.comment.media"); this._moveInsertPoint(comment.get("created_at"), commentBlocks); if (this._insertPoint >= commentBlocks.length) { diff --git a/app/assets/javascripts/app/views/single-post-viewer/single_post_comment_stream.js b/app/assets/javascripts/app/views/single-post-viewer/single_post_comment_stream.js index 63ef065f6..49ddf11db 100644 --- a/app/assets/javascripts/app/views/single-post-viewer/single_post_comment_stream.js +++ b/app/assets/javascripts/app/views/single-post-viewer/single_post_comment_stream.js @@ -4,7 +4,10 @@ app.views.SinglePostCommentStream = app.views.CommentStream.extend({ tooltipSelector: "time, .control-icons a", initialize: function(){ + this.CommentView = app.views.ExpandedComment; $(window).on('hashchange',this.highlightPermalinkComment); + this.setupBindings(); + this.model.comments.on("reset", this.render, this); }, highlightPermalinkComment: function() { @@ -24,16 +27,6 @@ app.views.SinglePostCommentStream = app.views.CommentStream.extend({ _.defer(this.highlightPermalinkComment); }, - appendComment: function(comment) { - // Set the post as the comment's parent, so we can check - // on post ownership in the Comment view. - comment.set({parent : this.model.toJSON()}); - - this.$(".comments").append(new app.views.ExpandedComment({ - model: comment - }).render().el); - }, - presenter: function(){ return _.extend(this.defaultPresenter(), { moreCommentsCount : 0, diff --git a/app/assets/javascripts/app/views/single-post-viewer/single_post_interaction_counts.js b/app/assets/javascripts/app/views/single-post-viewer/single_post_interaction_counts.js new file mode 100644 index 000000000..42348627c --- /dev/null +++ b/app/assets/javascripts/app/views/single-post-viewer/single_post_interaction_counts.js @@ -0,0 +1,22 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later + +app.views.SinglePostInteractionCounts = app.views.Base.extend({ + templateName: "single-post-viewer/single-post-interaction-counts", + tooltipSelector: ".avatar.micro", + + initialize: function() { + this.model.interactions.on("change", this.render, this); + }, + + presenter: function() { + var interactions = this.model.interactions; + return { + likes: interactions.likes.toJSON(), + reshares: interactions.reshares.toJSON(), + commentsCount: interactions.commentsCount(), + likesCount: interactions.likesCount(), + resharesCount: interactions.resharesCount() + }; + } +}); +// @license-end diff --git a/app/assets/javascripts/app/views/single-post-viewer/single_post_interactions.js b/app/assets/javascripts/app/views/single-post-viewer/single_post_interactions.js index 9549a74a5..ec9ea8f2f 100644 --- a/app/assets/javascripts/app/views/single-post-viewer/single_post_interactions.js +++ b/app/assets/javascripts/app/views/single-post-viewer/single_post_interactions.js @@ -2,28 +2,19 @@ app.views.SinglePostInteractions = app.views.Base.extend({ templateName: "single-post-viewer/single-post-interactions", - tooltipSelector: ".avatar.micro", className: "framed-content", subviews: { - '#comments': 'commentStreamView' + "#comments": "commentStreamView", + "#interaction-counts": "interactionCountsView" }, - initialize : function() { - this.model.interactions.on('change', this.render, this); - this.commentStreamView = new app.views.SinglePostCommentStream({model: this.model}); + commentStreamView: function() { + return new app.views.SinglePostCommentStream({model: this.model}); }, - presenter : function(){ - var interactions = this.model.interactions; - return { - likes : interactions.likes.toJSON(), - comments : interactions.comments.toJSON(), - reshares : interactions.reshares.toJSON(), - commentsCount : interactions.commentsCount(), - likesCount : interactions.likesCount(), - resharesCount : interactions.resharesCount(), - }; - }, + interactionCountsView: function() { + return new app.views.SinglePostInteractionCounts({model: this.model}); + } }); // @license-end diff --git a/app/assets/templates/single-post-viewer/single-post-interaction-counts_tpl.jst.hbs b/app/assets/templates/single-post-viewer/single-post-interaction-counts_tpl.jst.hbs new file mode 100644 index 000000000..221274487 --- /dev/null +++ b/app/assets/templates/single-post-viewer/single-post-interaction-counts_tpl.jst.hbs @@ -0,0 +1,42 @@ +{{#if resharesCount}} +
+
+ + {{resharesCount}} +
+
+ {{#each reshares}} + {{#linkToAuthor author}} + {{{personImage this "small" "micro"}}} + {{/linkToAuthor}} + {{/each}} +
+
+{{/if}} +{{#if likesCount}} +
+
+ + {{likesCount}} +
+
+ {{#each likes}} + {{#linkToAuthor author}} + {{{personImage this "small" "micro"}}} + {{/linkToAuthor}} + {{/each}} +
+
+{{/if}} +{{#if commentsCount}} +
+
+ + {{commentsCount}} +
+
+{{else}} +
+

{{t "comments.no_comments" }}

+
+{{/if}} diff --git a/app/assets/templates/single-post-viewer/single-post-interactions_tpl.jst.hbs b/app/assets/templates/single-post-viewer/single-post-interactions_tpl.jst.hbs index 0e9fa60a8..a71be6f84 100644 --- a/app/assets/templates/single-post-viewer/single-post-interactions_tpl.jst.hbs +++ b/app/assets/templates/single-post-viewer/single-post-interactions_tpl.jst.hbs @@ -1,44 +1,4 @@ -{{#if resharesCount}} -
-
- - {{resharesCount}} -
-
- {{#each reshares}} - {{#linkToAuthor author}} - {{{personImage this 'small' 'micro'}}} - {{/linkToAuthor}} - {{/each}} -
-
-{{/if}} -{{#if likesCount}} -
-
- - {{likesCount}} -
-
- {{#each likes}} - {{#linkToAuthor author}} - {{{personImage this 'small' 'micro'}}} - {{/linkToAuthor}} - {{/each}} -
-
-{{/if}} -{{#if commentsCount}} -
-
- - {{commentsCount}} -
-
-{{else}} -
-

{{t "comments.no_comments" }}

-
-{{/if}} -
+
+
+
diff --git a/spec/javascripts/app/views/comment_stream_view_spec.js b/spec/javascripts/app/views/comment_stream_view_spec.js index 93e20c55f..0317f7f0b 100644 --- a/spec/javascripts/app/views/comment_stream_view_spec.js +++ b/spec/javascripts/app/views/comment_stream_view_spec.js @@ -79,6 +79,19 @@ describe("app.views.CommentStream", function(){ expect(comment.set).toHaveBeenCalled(); }); + it("uses this.CommentView for the Comment view", function() { + var comment = factory.comment(); + this.view.CommentView = app.views.Comment; + spyOn(app.views.Comment.prototype, "initialize"); + this.view.appendComment(comment); + expect(app.views.Comment.prototype.initialize).toHaveBeenCalled(); + + this.view.CommentView = app.views.StatusMessage; + spyOn(app.views.StatusMessage.prototype, "initialize"); + this.view.appendComment(comment); + expect(app.views.StatusMessage.prototype.initialize).toHaveBeenCalled(); + }); + it("sorts comments in the right order", function() { this.view.render(); this.view.appendComment(factory.comment({"created_at": new Date(2000).toJSON(), "text": "2"})); diff --git a/spec/javascripts/app/views/single-post-view/single_post_comment_stream_spec.js b/spec/javascripts/app/views/single-post-view/single_post_comment_stream_spec.js new file mode 100644 index 000000000..3e32ca3ee --- /dev/null +++ b/spec/javascripts/app/views/single-post-view/single_post_comment_stream_spec.js @@ -0,0 +1,26 @@ +describe("app.views.SinglePostCommentStream", function() { + beforeEach(function() { + this.post = factory.post(); + this.view = new app.views.SinglePostCommentStream({model: this.post}); + }); + + describe("initialize", function() { + it("sets this.CommentView to app.views.ExpandedComment", function() { + expect(this.view.CommentView).toBe(app.views.ExpandedComment); + }); + + it("calls render when the comments collection has been resetted", function() { + spyOn(app.views.SinglePostCommentStream.prototype, "render"); + this.view.initialize(); + expect(app.views.SinglePostCommentStream.prototype.render).not.toHaveBeenCalled(); + this.post.comments.reset(); + expect(app.views.SinglePostCommentStream.prototype.render).toHaveBeenCalled(); + }); + + it("calls setupBindings", function() { + spyOn(app.views.SinglePostCommentStream.prototype, "setupBindings"); + this.view.initialize(); + expect(app.views.SinglePostCommentStream.prototype.setupBindings).toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/javascripts/app/views/single_post_content_view_spec.js b/spec/javascripts/app/views/single-post-view/single_post_content_view_spec.js similarity index 78% rename from spec/javascripts/app/views/single_post_content_view_spec.js rename to spec/javascripts/app/views/single-post-view/single_post_content_view_spec.js index 956866424..28ea9b57c 100644 --- a/spec/javascripts/app/views/single_post_content_view_spec.js +++ b/spec/javascripts/app/views/single-post-view/single_post_content_view_spec.js @@ -1,15 +1,15 @@ describe("app.views.SinglePostContent", function() { - beforeEach(function(){ + beforeEach(function() { this.post = factory.post(); - this.view = new app.views.SinglePostContent({model : this.post}); + this.view = new app.views.SinglePostContent({model: this.post}); }); describe("map", function() { context("with location provided", function() { - beforeEach(function(){ - this.post.set({location : factory.location()}); + beforeEach(function() { + this.post.set({location: factory.location()}); spec.content().html(this.view.render().el); - gon.appConfig = { map: {mapbox: {enabled: false }}}; + gon.appConfig = {map: {mapbox: {enabled: false}}}; }); it("initializes the leaflet map", function() { @@ -24,7 +24,7 @@ describe("app.views.SinglePostContent", function() { }); context("without location provided", function() { - beforeEach(function(){ + beforeEach(function() { spec.content().html(this.view.render().el); }); diff --git a/spec/javascripts/app/views/single-post-view/single_post_interaction_counts_spec.js b/spec/javascripts/app/views/single-post-view/single_post_interaction_counts_spec.js new file mode 100644 index 000000000..35abf7afe --- /dev/null +++ b/spec/javascripts/app/views/single-post-view/single_post_interaction_counts_spec.js @@ -0,0 +1,16 @@ +describe("app.views.SinglePostInteractionCounts", function() { + beforeEach(function() { + this.post = factory.post(); + this.view = new app.views.SinglePostInteractionCounts({model: this.post}); + }); + + describe("initialize", function() { + it("calls render when the interactions change", function() { + spyOn(app.views.SinglePostInteractionCounts.prototype, "render"); + this.view.initialize(); + expect(app.views.SinglePostInteractionCounts.prototype.render).not.toHaveBeenCalled(); + this.post.interactions.trigger("change"); + expect(app.views.SinglePostInteractionCounts.prototype.render).toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/javascripts/app/views/single-post-view/single_post_interactions_spec.js b/spec/javascripts/app/views/single-post-view/single_post_interactions_spec.js new file mode 100644 index 000000000..507317a20 --- /dev/null +++ b/spec/javascripts/app/views/single-post-view/single_post_interactions_spec.js @@ -0,0 +1,34 @@ +describe("app.views.SinglePostInteractions", function() { + beforeEach(function() { + this.post = factory.post(); + this.view = new app.views.SinglePostInteractions({model: this.post}); + }); + + describe("render", function() { + it("initializes the SinglePostInteractionCounts view", function() { + spyOn(app.views.SinglePostInteractionCounts.prototype, "initialize"); + this.view.render(); + expect(app.views.SinglePostInteractionCounts.prototype.initialize).toHaveBeenCalled(); + }); + + it("initializes the SinglePostCommentStream view", function() { + spyOn(app.views.SinglePostCommentStream.prototype, "initialize"); + this.view.render(); + expect(app.views.SinglePostCommentStream.prototype.initialize).toHaveBeenCalled(); + }); + }); + + describe("interaction changes", function() { + it("don't drop the comment textbox value", function() { + this.view.render(); + this.view.$("textarea").val("great post!"); + expect(this.view.$("#likes").length).toBe(0); + + this.view.model.interactions.set({"likes_count": 1}); + this.view.model.interactions.trigger("change"); + + expect(this.view.$("#likes").length).toBe(1); + expect(this.view.$("textarea").val()).toEqual("great post!"); + }); + }); +});