Add 'show all' links to the SPV to fetch missing likes and reshares
This commit is contained in:
parent
6bab65e603
commit
6b162110ce
6 changed files with 222 additions and 2 deletions
|
|
@ -4,8 +4,15 @@ app.views.SinglePostInteractionCounts = app.views.Base.extend({
|
||||||
templateName: "single-post-viewer/single-post-interaction-counts",
|
templateName: "single-post-viewer/single-post-interaction-counts",
|
||||||
tooltipSelector: ".avatar.micro",
|
tooltipSelector: ".avatar.micro",
|
||||||
|
|
||||||
|
events: {
|
||||||
|
"click #show-all-likes": "showAllLikes",
|
||||||
|
"click #show-all-reshares": "showAllReshares"
|
||||||
|
},
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
this.model.interactions.on("change", this.render, this);
|
this.model.interactions.on("change", this.render, this);
|
||||||
|
this.model.interactions.likes.on("change", this.render, this);
|
||||||
|
this.model.interactions.reshares.on("change", this.render, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
presenter: function() {
|
presenter: function() {
|
||||||
|
|
@ -15,8 +22,28 @@ app.views.SinglePostInteractionCounts = app.views.Base.extend({
|
||||||
reshares: interactions.reshares.toJSON(),
|
reshares: interactions.reshares.toJSON(),
|
||||||
commentsCount: interactions.commentsCount(),
|
commentsCount: interactions.commentsCount(),
|
||||||
likesCount: interactions.likesCount(),
|
likesCount: interactions.likesCount(),
|
||||||
resharesCount: interactions.resharesCount()
|
resharesCount: interactions.resharesCount(),
|
||||||
|
showMoreLikes: interactions.likes.length < interactions.likesCount(),
|
||||||
|
showMoreReshares: interactions.reshares.length < interactions.resharesCount()
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
_showAll: function(interactionType, models) {
|
||||||
|
this.$("#show-all-" + interactionType).addClass("hidden");
|
||||||
|
this.$("#" + interactionType + " .loader").removeClass("hidden");
|
||||||
|
models.fetch({success: function() {
|
||||||
|
models.trigger("change");
|
||||||
|
}});
|
||||||
|
},
|
||||||
|
|
||||||
|
showAllLikes: function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
this._showAll("likes", this.model.interactions.likes);
|
||||||
|
},
|
||||||
|
|
||||||
|
showAllReshares: function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
this._showAll("reshares", this.model.interactions.reshares);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// @license-end
|
// @license-end
|
||||||
|
|
|
||||||
|
|
@ -157,5 +157,11 @@
|
||||||
.author-name:hover {
|
.author-name:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
height: $line-height-computed;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
width: $line-height-computed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,12 @@
|
||||||
{{{personImage this "small" "micro"}}}
|
{{{personImage this "small" "micro"}}}
|
||||||
{{/linkToAuthor}}
|
{{/linkToAuthor}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
{{#if showMoreReshares}}
|
||||||
|
<div class="loader hidden">
|
||||||
|
<div class="spinner"></div>
|
||||||
|
</div>
|
||||||
|
<div id="show-all-reshares" class="btn btn-sm btn-link">{{t "show_all"}}</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
@ -25,6 +31,12 @@
|
||||||
{{{personImage this "small" "micro"}}}
|
{{{personImage this "small" "micro"}}}
|
||||||
{{/linkToAuthor}}
|
{{/linkToAuthor}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
{{#if showMoreLikes}}
|
||||||
|
<div class="loader hidden">
|
||||||
|
<div class="spinner"></div>
|
||||||
|
</div>
|
||||||
|
<div id="show-all-likes" class="btn btn-sm btn-link">{{t "show_all"}}</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ en:
|
||||||
comma: ","
|
comma: ","
|
||||||
edit: "Edit"
|
edit: "Edit"
|
||||||
no_results: "No results found"
|
no_results: "No results found"
|
||||||
|
show_all: "Show all"
|
||||||
|
|
||||||
admins:
|
admins:
|
||||||
dashboard:
|
dashboard:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
describe("app.views.SinglePostInteractionCounts", function() {
|
describe("app.views.SinglePostInteractionCounts", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.post = factory.post();
|
this.post = factory.postWithInteractions();
|
||||||
this.view = new app.views.SinglePostInteractionCounts({model: this.post});
|
this.view = new app.views.SinglePostInteractionCounts({model: this.post});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -12,5 +12,151 @@ describe("app.views.SinglePostInteractionCounts", function() {
|
||||||
this.post.interactions.trigger("change");
|
this.post.interactions.trigger("change");
|
||||||
expect(app.views.SinglePostInteractionCounts.prototype.render).toHaveBeenCalled();
|
expect(app.views.SinglePostInteractionCounts.prototype.render).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("calls render when the likes change", function() {
|
||||||
|
spyOn(app.views.SinglePostInteractionCounts.prototype, "render");
|
||||||
|
this.view.initialize();
|
||||||
|
expect(app.views.SinglePostInteractionCounts.prototype.render).not.toHaveBeenCalled();
|
||||||
|
this.post.interactions.likes.trigger("change");
|
||||||
|
expect(app.views.SinglePostInteractionCounts.prototype.render).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls render when the reshares change", function() {
|
||||||
|
spyOn(app.views.SinglePostInteractionCounts.prototype, "render");
|
||||||
|
this.view.initialize();
|
||||||
|
expect(app.views.SinglePostInteractionCounts.prototype.render).not.toHaveBeenCalled();
|
||||||
|
this.post.interactions.reshares.trigger("change");
|
||||||
|
expect(app.views.SinglePostInteractionCounts.prototype.render).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("render", function() {
|
||||||
|
it("doesn't show a #show-all-likes link if there are no additional likes", function() {
|
||||||
|
this.view.render();
|
||||||
|
expect(this.view.$("#show-all-likes").length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows a #show-all-likes link if there are additional likes", function() {
|
||||||
|
this.view.model.interactions.set("likes_count", this.view.model.interactions.likes.length + 1);
|
||||||
|
this.view.render();
|
||||||
|
expect(this.view.$("#show-all-likes").length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("doesn't show a #show-all-reshares link if there are no additional reshares", function() {
|
||||||
|
this.view.render();
|
||||||
|
expect(this.view.$("#show-all-reshares").length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows a #show-all-reshares link if there are additional reshares", function() {
|
||||||
|
this.view.model.interactions.set("reshares_count", this.view.model.interactions.reshares.length + 1);
|
||||||
|
this.view.render();
|
||||||
|
expect(this.view.$("#show-all-reshares").length).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("showAllLikes", function() {
|
||||||
|
it("is called when clicking #show-all-likes", function() {
|
||||||
|
spyOn(this.view, "showAllLikes");
|
||||||
|
this.view.delegateEvents();
|
||||||
|
this.view.model.interactions.set("likes_count", this.view.model.interactions.likes.length + 1);
|
||||||
|
this.view.render();
|
||||||
|
expect(this.view.showAllLikes).not.toHaveBeenCalled();
|
||||||
|
this.view.$("#show-all-likes").click();
|
||||||
|
expect(this.view.showAllLikes).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls _showAll", function() {
|
||||||
|
spyOn(this.view, "_showAll");
|
||||||
|
this.view.showAllLikes($.Event());
|
||||||
|
expect(this.view._showAll).toHaveBeenCalledWith("likes", this.view.model.interactions.likes);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("showAllReshares", function() {
|
||||||
|
it("is called when clicking #show-all-reshares", function() {
|
||||||
|
spyOn(this.view, "showAllReshares");
|
||||||
|
this.view.delegateEvents();
|
||||||
|
this.view.model.interactions.set("reshares_count", this.view.model.interactions.reshares.length + 1);
|
||||||
|
this.view.render();
|
||||||
|
expect(this.view.showAllReshares).not.toHaveBeenCalled();
|
||||||
|
this.view.$("#show-all-reshares").click();
|
||||||
|
expect(this.view.showAllReshares).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls _showAll", function() {
|
||||||
|
spyOn(this.view, "_showAll");
|
||||||
|
this.view.showAllReshares($.Event());
|
||||||
|
expect(this.view._showAll).toHaveBeenCalledWith("reshares", this.view.model.interactions.reshares);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("_showAll", function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.view.model.interactions.set("likes_count", this.view.model.interactions.likes.length + 1);
|
||||||
|
this.view.model.interactions.set("reshares_count", this.view.model.interactions.reshares.length + 1);
|
||||||
|
this.view.render();
|
||||||
|
});
|
||||||
|
|
||||||
|
context("with likes", function() {
|
||||||
|
it("hides the #show-all-likes link", function() {
|
||||||
|
expect(this.view.$("#show-all-likes")).not.toHaveClass("hidden");
|
||||||
|
expect(this.view.$("#show-all-reshares")).not.toHaveClass("hidden");
|
||||||
|
this.view._showAll("likes", this.view.model.interactions.likes);
|
||||||
|
expect(this.view.$("#show-all-likes")).toHaveClass("hidden");
|
||||||
|
expect(this.view.$("#show-all-reshares")).not.toHaveClass("hidden");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows the likes loader", function() {
|
||||||
|
expect(this.view.$("#likes .loader")).toHaveClass("hidden");
|
||||||
|
expect(this.view.$("#reshares .loader")).toHaveClass("hidden");
|
||||||
|
this.view._showAll("likes", this.view.model.interactions.likes);
|
||||||
|
expect(this.view.$("#likes .loader")).not.toHaveClass("hidden");
|
||||||
|
expect(this.view.$("#reshares .loader")).toHaveClass("hidden");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls #fetch on the model", function() {
|
||||||
|
spyOn(this.view.model.interactions.likes, "fetch");
|
||||||
|
this.view._showAll("likes", this.view.model.interactions.likes);
|
||||||
|
expect(this.view.model.interactions.likes.fetch).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("triggers 'change' after a successfull fetch", function() {
|
||||||
|
spyOn(this.view.model.interactions.likes, "trigger");
|
||||||
|
this.view._showAll("likes", this.view.model.interactions.likes);
|
||||||
|
jasmine.Ajax.requests.mostRecent().respondWith({status: 200, responseText: "{\"id\": 1}"});
|
||||||
|
expect(this.view.model.interactions.likes.trigger).toHaveBeenCalledWith("change");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context("with reshares", function() {
|
||||||
|
it("hides the #show-all-reshares link", function() {
|
||||||
|
expect(this.view.$("#show-all-likes")).not.toHaveClass("hidden");
|
||||||
|
expect(this.view.$("#show-all-reshares")).not.toHaveClass("hidden");
|
||||||
|
this.view._showAll("reshares", this.view.model.interactions.reshares);
|
||||||
|
expect(this.view.$("#show-all-likes")).not.toHaveClass("hidden");
|
||||||
|
expect(this.view.$("#show-all-reshares")).toHaveClass("hidden");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows the reshares loader", function() {
|
||||||
|
expect(this.view.$("#likes .loader")).toHaveClass("hidden");
|
||||||
|
expect(this.view.$("#reshares .loader")).toHaveClass("hidden");
|
||||||
|
this.view._showAll("reshares", this.view.model.interactions.reshares);
|
||||||
|
expect(this.view.$("#likes .loader")).toHaveClass("hidden");
|
||||||
|
expect(this.view.$("#reshares .loader")).not.toHaveClass("hidden");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls #fetch on the model", function() {
|
||||||
|
spyOn(this.view.model.interactions.reshares, "fetch");
|
||||||
|
this.view._showAll("reshares", this.view.model.interactions.reshares);
|
||||||
|
expect(this.view.model.interactions.reshares.fetch).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("triggers 'change' after a successfull fetch", function() {
|
||||||
|
spyOn(this.view.model.interactions.reshares, "trigger");
|
||||||
|
this.view._showAll("reshares", this.view.model.interactions.reshares);
|
||||||
|
jasmine.Ajax.requests.mostRecent().respondWith({status: 200, responseText: "{\"id\": 1}"});
|
||||||
|
expect(this.view.model.interactions.reshares.trigger).toHaveBeenCalledWith("change");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,16 @@ var factory = {
|
||||||
return _.extend(defaultAttrs, overrides);
|
return _.extend(defaultAttrs, overrides);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
reshare: function(overrides) {
|
||||||
|
var defaultAttrs = {
|
||||||
|
"created_at": "2012-01-04T00:55:30Z",
|
||||||
|
"author": this.author(),
|
||||||
|
"guid": this.guid(),
|
||||||
|
"id": this.id.next()
|
||||||
|
};
|
||||||
|
return _.extend(defaultAttrs, overrides);
|
||||||
|
},
|
||||||
|
|
||||||
aspectMembershipAttrs: function(overrides) {
|
aspectMembershipAttrs: function(overrides) {
|
||||||
var id = this.id.next();
|
var id = this.id.next();
|
||||||
var defaultAttrs = {
|
var defaultAttrs = {
|
||||||
|
|
@ -207,6 +217,24 @@ var factory = {
|
||||||
return new app.models.Post(_.extend(defaultAttrs, overrides));
|
return new app.models.Post(_.extend(defaultAttrs, overrides));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
postWithInteractions: function(overrides) {
|
||||||
|
var likes = _.range(10).map(function() { return factory.like(); });
|
||||||
|
var reshares = _.range(15).map(function() { return factory.reshare(); });
|
||||||
|
var comments = _.range(20).map(function() { return factory.comment(); });
|
||||||
|
var defaultAttrs = _.extend(factory.postAttrs(), {
|
||||||
|
"author": this.author(),
|
||||||
|
"interactions": {
|
||||||
|
"reshares_count": 15,
|
||||||
|
"likes_count": 10,
|
||||||
|
"comments_count": 20,
|
||||||
|
"comments": comments,
|
||||||
|
"likes": likes,
|
||||||
|
"reshares": reshares
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return new app.models.Post(_.extend(defaultAttrs, overrides));
|
||||||
|
},
|
||||||
|
|
||||||
statusMessage : function(overrides){
|
statusMessage : function(overrides){
|
||||||
//intentionally doesn't have an author to mirror creation process, maybe we should change the creation process
|
//intentionally doesn't have an author to mirror creation process, maybe we should change the creation process
|
||||||
return new app.models.StatusMessage(_.extend(factory.postAttrs(), overrides));
|
return new app.models.StatusMessage(_.extend(factory.postAttrs(), overrides));
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue