diaspora/app/assets/javascripts/app/views/infinite_stream_view.js
Steffen van Bergerem ab6732cac1 JSHint eqeqeq
2015-02-08 23:41:32 +01:00

110 lines
3 KiB
JavaScript

// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
// Abstract Infinite Scroll View Super Class
// Requires:
// a stream model, assigned to this.stream
// a stream's posts, assigned to this.collection
// a postClass to be declared
// a #paginate div in the layout
// a call to setupInfiniteScroll
app.views.InfScroll = app.views.Base.extend({
setupInfiniteScroll : function() {
this.postViews = this.postViews || [];
this._resetPostFragments();
this.bind("loadMore", this.fetchAndshowLoader, this);
this.stream.bind("fetched", this.finishedLoading, this);
this.stream.bind("allItemsLoaded", this.unbindInfScroll, this);
this.collection.bind("add", this.addPostView, this);
var throttledScroll = _.throttle(_.bind(this.infScroll, this), 200);
$(window).scroll(throttledScroll);
},
_resetPostFragments: function() {
this.appendedPosts = document.createDocumentFragment();
this.prependedPosts = document.createDocumentFragment();
},
postRenderTemplate : function() {
if(this.stream.isFetching()) { this.showLoader() }
},
createPostView : function(post){
var postView = new this.postClass({ model: post, stream: this.stream });
if (this.collection.at(0).id === post.id) {
// post is first in collection - insert view at top of the list
this.postViews.unshift(postView);
} else {
this.postViews.push(postView);
}
return postView;
},
// called for every item inserted in this.collection
addPostView : function(post) {
var el = this.createPostView(post).render().el;
if (this.collection.at(0).id === post.id) {
this.prependedPosts.insertBefore(el, this.prependedPosts.firstChild);
} else {
this.appendedPosts.appendChild(el);
}
},
unbindInfScroll : function() {
$(window).unbind("scroll");
},
renderTemplate : function(){
this.renderInitialPosts();
},
renderInitialPosts : function(){
this.$el.empty();
var els = document.createDocumentFragment();
this.stream.items.each(_.bind(function(post){
els.appendChild(this.createPostView(post).render().el);
}, this));
this.$el.html(els);
},
fetchAndshowLoader : function(){
if( this.stream.isFetching() ) return false;
this.stream.fetch();
this.showLoader();
},
showLoader: function(){
$("#paginate .loader").removeClass("hidden");
},
finishedAdding: function() {
this.$el.prepend(this.prependedPosts);
this.$el.append(this.appendedPosts);
this._resetPostFragments();
},
finishedLoading: function() {
this.finishedAdding();
this.hideLoader();
},
hideLoader: function() {
$("#paginate .loader").addClass("hidden");
},
infScroll : function() {
var $window = $(window)
, distFromTop = $window.height() + $window.scrollTop()
, distFromBottom = $(document).height() - distFromTop
, bufferPx = 500;
if(distFromBottom < bufferPx) {
this.trigger("loadMore");
}
}
});
// @license-end