refactored stream and Stream View
streamView no longer abuses render with fetching moved post collapsing into contentView subtle nicification.
This commit is contained in:
parent
27513cf319
commit
3479cb7bdd
7 changed files with 68 additions and 75 deletions
|
|
@ -16,7 +16,7 @@ app.models.Stream = Backbone.Collection.extend({
|
|||
},
|
||||
|
||||
fetch: function() {
|
||||
if(this.deferred && !this.deferred.isResolved()){ return false }
|
||||
if(this.isFetching()){ return false }
|
||||
var url = this.url()
|
||||
this.deferred = this.posts.fetch({
|
||||
add : true,
|
||||
|
|
@ -24,6 +24,10 @@ app.models.Stream = Backbone.Collection.extend({
|
|||
}).done(_.bind(this.triggerFetchedEvents, this))
|
||||
},
|
||||
|
||||
isFetching : function(){
|
||||
return this.deferred && this.deferred.state() == "pending"
|
||||
},
|
||||
|
||||
triggerFetchedEvents : function(resp){
|
||||
this.trigger("fetched", this);
|
||||
// all loaded?
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ app.Router = Backbone.Router.extend({
|
|||
|
||||
stream : function() {
|
||||
app.stream = new app.models.Stream();
|
||||
app.stream.fetch();
|
||||
app.page = new app.views.Stream({model : app.stream});
|
||||
app.publisher = app.publisher || new app.views.Publisher({collection : app.stream.posts});
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,10 @@ app.views.Base = Backbone.View.extend({
|
|||
renderTemplate : function(){
|
||||
var presenter = _.isFunction(this.presenter) ? this.presenter() : this.presenter
|
||||
this.template = JST[this.templateName]
|
||||
if(!this.template) {console.log("no template for " + this.templateName) }
|
||||
$(this.el)
|
||||
if(!this.template) {
|
||||
console.log(this.templateName ? ("no template for " + this.templateName) : "no templateName specified")
|
||||
}
|
||||
this.$el
|
||||
.html(this.template(presenter))
|
||||
.attr("data-template", _.last(this.templateName.split("/")));
|
||||
this.postRenderTemplate();
|
||||
|
|
|
|||
|
|
@ -52,8 +52,35 @@ app.views.Content = app.views.StreamObject.extend({
|
|||
el.css('height','auto');
|
||||
});
|
||||
$(evt.currentTarget).hide();
|
||||
}
|
||||
},
|
||||
|
||||
collapseOversized : function() {
|
||||
var collHeight = 200
|
||||
, elem = this.$(".collapsible")
|
||||
, oembed = elem.find(".oembed")
|
||||
, addHeight = 0;
|
||||
|
||||
if($.trim(oembed.html()) != "") {
|
||||
addHeight = oembed.height();
|
||||
}
|
||||
|
||||
// only collapse if height exceeds collHeight+20%
|
||||
if( elem.height() > ((collHeight*1.2)+addHeight) && !elem.is(".opened") ) {
|
||||
elem.data("orig-height", elem.height() );
|
||||
elem
|
||||
.height( Math.max(collHeight, addHeight) )
|
||||
.addClass("collapsed")
|
||||
.append(
|
||||
$('<div />')
|
||||
.addClass('expander')
|
||||
.text( Diaspora.I18n.t("show_more") )
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
postRenderTemplate : function(){
|
||||
_.defer(_.bind(this.collapseOversized, this))
|
||||
}
|
||||
});
|
||||
|
||||
app.views.StatusMessage = app.views.Content.extend({
|
||||
|
|
|
|||
|
|
@ -25,12 +25,12 @@ app.views.StreamPost = app.views.Post.extend({
|
|||
this.model.bind('remove', this.remove, this);
|
||||
|
||||
//subviews
|
||||
this.commentStreamView = new app.views.CommentStream({ model : this.model});
|
||||
this.commentStreamView = new app.views.CommentStream({model : this.model});
|
||||
},
|
||||
|
||||
|
||||
likesInfoView : function(){
|
||||
return new app.views.LikesInfo({ model : this.model});
|
||||
return new app.views.LikesInfo({model : this.model});
|
||||
},
|
||||
|
||||
feedbackView : function(){
|
||||
|
|
@ -39,9 +39,10 @@ app.views.StreamPost = app.views.Post.extend({
|
|||
},
|
||||
|
||||
postContentView: function(){
|
||||
var normalizedClass = this.model.get("post_type").replace(/::/, "__");
|
||||
var postClass = app.views[normalizedClass] || app.views.StatusMessage;
|
||||
return new postClass({ model : this.model });
|
||||
var normalizedClass = this.model.get("post_type").replace(/::/, "__")
|
||||
, postClass = app.views[normalizedClass] || app.views.StatusMessage;
|
||||
|
||||
return new postClass({ model : this.model })
|
||||
},
|
||||
|
||||
removeNsfwShield: function(evt){
|
||||
|
|
|
|||
|
|
@ -1,9 +1,4 @@
|
|||
app.views.Stream = Backbone.View.extend({
|
||||
|
||||
events: {
|
||||
"click #paginate": "render"
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
this.stream = this.model
|
||||
this.collection = this.model.posts
|
||||
|
|
@ -16,71 +11,36 @@ app.views.Stream = Backbone.View.extend({
|
|||
|
||||
setupEvents : function(){
|
||||
this.stream.bind("fetched", this.removeLoader, this)
|
||||
this.stream.bind("fetched", this.postRender, this)
|
||||
this.stream.bind("allPostsLoaded", this.unbindInfScroll, this)
|
||||
this.collection.bind("add", this.addPost, this);
|
||||
if(window.app.user()) {
|
||||
app.user().bind("nsfwChanged", function() {
|
||||
_.map(this.postViews, function(view){ view.render() })
|
||||
}, this)
|
||||
|
||||
app.currentUser.bind("nsfwChanged", reRenderPostViews, this)
|
||||
function reRenderPostViews() {
|
||||
_.map(this.postViews, function(view){ view.render() })
|
||||
}
|
||||
},
|
||||
|
||||
addPost : function(post) {
|
||||
var postView = new app.views.StreamPost({ model: post });
|
||||
|
||||
$(this.el)[
|
||||
(this.collection.at(0).id == post.id)
|
||||
? "prepend"
|
||||
: "append"
|
||||
](postView.render().el);
|
||||
var postView = new app.views.StreamPost({ model: post })
|
||||
, placeInStream = (this.collection.at(0).id == post.id) ? "prepend" : "append";
|
||||
|
||||
this.$el[placeInStream](postView.render().el);
|
||||
this.postViews.push(postView)
|
||||
return this;
|
||||
},
|
||||
|
||||
unbindInfScroll : function() {
|
||||
$(window).unbind("scroll");
|
||||
},
|
||||
|
||||
render : function(evt) {
|
||||
if(evt) { evt.preventDefault(); }
|
||||
|
||||
// fetch more posts from the stream model
|
||||
if(this.stream.fetch()) {
|
||||
this.appendLoader()
|
||||
};
|
||||
|
||||
render : function() {
|
||||
if(this.stream.isFetching()) { this.appendLoader() }
|
||||
return this;
|
||||
},
|
||||
|
||||
postRender : function() {
|
||||
// collapse long posts
|
||||
var collHeight = 420,
|
||||
collElem = $(this.el).find(".collapsible");
|
||||
|
||||
_.each(collElem, function(elem) {
|
||||
var elem = $(elem),
|
||||
oembed = elem.find(".oembed"),
|
||||
addHeight = 0;
|
||||
|
||||
if( $.trim(oembed.html()) != "" ) {
|
||||
addHeight = oembed.height();
|
||||
}
|
||||
|
||||
// only collapse if height exceeds collHeight+20%
|
||||
if( elem.height() > ((collHeight*1.2)+addHeight) && !elem.is(".opened") ) {
|
||||
elem.data("orig-height", elem.height() );
|
||||
elem
|
||||
.height( Math.max(collHeight, addHeight) )
|
||||
.addClass("collapsed")
|
||||
.append(
|
||||
$('<div />')
|
||||
.addClass('expander')
|
||||
.text( Diaspora.I18n.t("show_more") )
|
||||
);
|
||||
}
|
||||
});
|
||||
fetchAndAppendLoader : function(){
|
||||
if(this.stream.isFetching()) { return false }
|
||||
this.stream.fetch()
|
||||
this.appendLoader()
|
||||
},
|
||||
|
||||
appendLoader: function(){
|
||||
|
|
@ -96,24 +56,22 @@ app.views.Stream = Backbone.View.extend({
|
|||
|
||||
setupLightbox : function(){
|
||||
this.lightbox = Diaspora.BaseWidget.instantiate("Lightbox");
|
||||
$(this.el).delegate("a.stream-photo-link", "click", this.lightbox.lightboxImageClicked);
|
||||
this.$el.delegate("a.stream-photo-link", "click", this.lightbox.lightboxImageClicked);
|
||||
},
|
||||
|
||||
setupInfiniteScroll : function() {
|
||||
var throttledScroll = _.throttle($.proxy(this.infScroll, this), 200);
|
||||
var throttledScroll = _.throttle(_.bind(this.infScroll, this), 200);
|
||||
$(window).scroll(throttledScroll);
|
||||
},
|
||||
|
||||
infScroll : function() {
|
||||
var $window = $(window);
|
||||
var distFromTop = $window.height() + $window.scrollTop();
|
||||
var distFromBottom = $(document).height() - distFromTop;
|
||||
var bufferPx = 500;
|
||||
var $window = $(window)
|
||||
, distFromTop = $window.height() + $window.scrollTop()
|
||||
, distFromBottom = $(document).height() - distFromTop
|
||||
, bufferPx = 500;
|
||||
|
||||
if(distFromBottom < bufferPx) {
|
||||
this.render();
|
||||
this.fetchAndAppendLoader()
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,13 +40,13 @@ describe("app.views.Stream", function() {
|
|||
describe("infScroll", function() {
|
||||
// NOTE: inf scroll happens at 500px
|
||||
|
||||
it("calls render when the user is at the bottom of the page", function() {
|
||||
it("fetches moar when the user is at the bottom of the page", function() {
|
||||
spyOn($.fn, "height").andReturn(0);
|
||||
spyOn($.fn, "scrollTop").andReturn(100);
|
||||
spyOn(this.view, "render");
|
||||
spyOn(this.view, "fetchAndAppendLoader");
|
||||
|
||||
this.view.infScroll();
|
||||
expect(this.view.render).toHaveBeenCalled();
|
||||
expect(this.view.fetchAndAppendLoader).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue