From a92401f157874bfc7f1182365da43ac6f632f6d5 Mon Sep 17 00:00:00 2001 From: danielgrippi Date: Wed, 4 Jan 2012 10:32:19 -0800 Subject: [PATCH] prevent further pagination if user has fetched all posts for a given stream --- public/javascripts/app/views/stream_view.js | 13 +++++- .../javascripts/app/views/stream_view_spec.js | 40 ++++++++++++++++--- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/public/javascripts/app/views/stream_view.js b/public/javascripts/app/views/stream_view.js index 36b513746..43b887b8c 100644 --- a/public/javascripts/app/views/stream_view.js +++ b/public/javascripts/app/views/stream_view.js @@ -23,7 +23,7 @@ app.views.Stream = Backbone.View.extend({ }, infScroll : function() { - if(this.isLoading()) { return } + if(this.allContentLoaded || this.isLoading()) { return } var $window = $(window); var distFromTop = $window.height() + $window.scrollTop(); @@ -41,6 +41,8 @@ app.views.Stream = Backbone.View.extend({ return this._loading && !this._loading.isResolved(); }, + allContentLoaded : false, + addPost : function(post) { var postView = new app.views.Post({ model: post }); @@ -53,8 +55,15 @@ app.views.Stream = Backbone.View.extend({ return this; }, - collectionFetched: function() { + collectionFetched: function(collection, response) { this.$("#paginate").remove(); + + if(collection.parse(response).length == 0) { + this.allContentLoaded = true; + $(window).unbind('scroll') + return + } + $(this.el).append($("", { href: this.collection.url(), id: "paginate" diff --git a/spec/javascripts/app/views/stream_view_spec.js b/spec/javascripts/app/views/stream_view_spec.js index 5e9a78246..5fa69b01d 100644 --- a/spec/javascripts/app/views/stream_view_spec.js +++ b/spec/javascripts/app/views/stream_view_spec.js @@ -3,10 +3,9 @@ describe("app.views.Stream", function(){ // should be jasmine helper window.current_user = app.user({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}}); - var posts = $.parseJSON(spec.readFixture("multi_stream_json"))["posts"]; - - this.collection = new app.collections.Stream(posts); + this.posts = $.parseJSON(spec.readFixture("multi_stream_json"))["posts"]; + this.collection = new app.collections.Stream(this.posts); this.view = new app.views.Stream({collection : this.collection}); // do this manually because we've moved loadMore into render?? @@ -17,8 +16,11 @@ describe("app.views.Stream", function(){ }) describe("initialize", function(){ - it("binds an infinite scroll listener", function(){ + spyOn($.fn, "scroll"); + + new app.views.Stream(); + expect($.fn.scroll).toHaveBeenCalled() }) }) @@ -57,12 +59,20 @@ describe("app.views.Stream", function(){ expect(this.view.collection.fetch).toHaveBeenCalled(); }) - it("does not call fetch", function(){ + it("does not call fetch if the collection is loading", function(){ spyOn(this.view, "isLoading").andReturn(true) this.view.infScroll(); expect(this.view.collection.fetch).not.toHaveBeenCalled(); }) + + it("does not call fetch if all content has been fetched", function(){ + spyOn(this.view, "isLoading").andReturn(false) + this.view.allContentLoaded = true; + + this.view.infScroll(); + expect(this.view.collection.fetch).not.toHaveBeenCalled(); + }) }) it("does not fetch new content when the user is not at the bottom of the page", function(){ @@ -75,4 +85,24 @@ describe("app.views.Stream", function(){ expect(this.view.collection.fetch).not.toHaveBeenCalled(); }) }) + + describe("collectionFetched", function(){ + it("sets this.allContentLoaded if there are no more posts left to load", function(){ + expect(this.view.allContentLoaded).toBe(false) + this.view.collectionFetched(this.collection, {posts : []}) + expect(this.view.allContentLoaded).toBe(true) + }) + + it("unbinds scroll if there are no more posts left to load", function(){ + spyOn($.fn, "unbind") + this.view.collectionFetched(this.collection, {posts : []}) + expect($.fn.unbind).toHaveBeenCalled() + }) + + it("does not set this.allContentLoaded if there was a non-empty response from the server", function(){ + expect(this.view.allContentLoaded).toBe(false) + this.view.collectionFetched(this.collection, {posts : this.posts}) + expect(this.view.allContentLoaded).toBe(false) + }) + }) })