Skip to content
Extraits de code Groupes Projets
Valider 750e26e8 rédigé par danielgrippi's avatar danielgrippi
Parcourir les fichiers

Merge branch 'stream-js-cleanup'

Conflicts:
	public/javascripts/app/models/stream.js
parents b583a7a4 c219cee9
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -10,7 +10,9 @@
#gs-shim{:title => popover_with_close_html("3. #{t('.stay_updated')}"), 'data-content' => t('.stay_updated_explanation')}
#main_stream.stream{:data => {:guids => stream.aspect_ids.join(',')}}
#main_stream.stream
#paginate
- if current_user.contacts.size < 2
= render 'aspects/no_contacts_message'
......
......@@ -7,19 +7,33 @@ app.models.Stream = Backbone.Collection.extend({
return _.any(this.posts.models) ? this.timeFilteredPath() : this.basePath()
},
_fetching : false,
fetch: function() {
var self = this
// we're fetching the collection... there is probably a better way to do this
self._fetching = true;
this.posts
.fetch({
add : true,
url : self.url()
})
.done(
function(response){
self.trigger("fetched", self, response);
function(resp){
// we're done fetching... there is probably a better way to handle this
self._fetching = false;
self.trigger("fetched", self);
// all loaded?
if(resp.posts && (resp.posts.author || resp.posts.length == 0)) {
self.trigger("allPostsLoaded", self);
}
}
)
return this;
},
basePath : function(){
......
......@@ -14,10 +14,12 @@ app.Router = Backbone.Router.extend({
stream : function() {
app.stream = new app.models.Stream()
app.page = new app.views.Stream().render();
$("#main_stream").html(app.page.el);
app.page = new app.views.Stream({model : app.stream}).render();
app.publisher = app.publisher || new app.views.Publisher({collection : app.stream.posts});
var streamFacesView = new app.views.StreamFaces({collection : app.stream.posts}).render();
$("#main_stream").html(app.page.el);
$('#selected_aspect_contacts .content').html(streamFacesView.el);
}
});
......
......@@ -12,6 +12,9 @@ app.views.CommentStream = app.views.Base.extend({
initialize: function(options) {
this.model.comments.bind('add', this.appendComment, this);
// add autoexpanders to new comment textarea
this.$('textarea').autoResize();
},
postRenderTemplate : function() {
......
......@@ -12,7 +12,7 @@ app.views.Publisher = Backbone.View.extend({
},
initialize : function(){
this.collection = this.collection || new app.collections.Posts;
this.collection = this.collection //takes a Posts collection
return this;
},
......
......@@ -4,16 +4,20 @@ app.views.Stream = Backbone.View.extend({
},
initialize: function(options) {
this.stream = app.stream || new app.models.Stream()
this.collection = this.stream.posts
this.publisher = new app.views.Publisher({collection : this.collection});
this.stream = this.model
this.collection = this.model.posts
this.stream.bind("fetched", this.collectionFetched, this)
this.collection.bind("add", this.addPost, this);
this.setupEvents()
this.setupInfiniteScroll()
this.setupLightbox()
},
setupEvents : function(){
this.stream.bind("fetched", this.removeLoader, this)
this.stream.bind("allPostsLoaded", this.unbindInfScroll, this)
this.collection.bind("add", this.addPost, this);
},
addPost : function(post) {
var postView = new app.views.Post({ model: post });
......@@ -26,51 +30,30 @@ app.views.Stream = Backbone.View.extend({
return this;
},
isLoading : function(){
return this._loading && !this._loading.isResolved();
},
allContentLoaded : false,
collectionFetched: function(collection, response) {
this.removeLoader()
if(!collection.parse(response).length || collection.parse(response).length == 0) {
this.allContentLoaded = true;
$(window).unbind('scroll')
return
}
$(this.el).append($("<a>", {
href: this.stream.url(),
id: "paginate"
}).text('Load more posts'));
unbindInfScroll : function() {
$("window").unbind("scroll");
},
render : function(evt) {
if(evt) { evt.preventDefault(); }
this.addLoader();
this._loading = this.stream.fetch();
// fetch more posts from the stream model
if(this.stream.fetch()) {
this.appendLoader()
};
return this;
},
addLoader: function(){
if(this.$("#paginate").length == 0) {
$(this.el).append($("<div>", {
"id" : "paginate"
}));
}
this.$("#paginate").html($("<img>", {
appendLoader: function(){
$("#paginate").html($("<img>", {
src : "/images/static-loader.png",
"class" : "loader"
}));
},
removeLoader : function(){
this.$("#paginate").remove();
removeLoader: function() {
$("#paginate").empty();
},
setupLightbox : function(){
......@@ -80,13 +63,11 @@ app.views.Stream = Backbone.View.extend({
setupInfiniteScroll : function() {
var throttledScroll = _.throttle($.proxy(this.infScroll, this), 200);
$(window).scroll(throttledScroll);
$("window").scroll(throttledScroll);
},
infScroll : function() {
if(this.allContentLoaded || this.isLoading()) { return }
var $window = $(window);
var $window = $("window");
var distFromTop = $window.height() + $window.scrollTop();
var distFromBottom = $(document).height() - distFromTop;
var bufferPx = 500;
......
......@@ -9,7 +9,7 @@ describe("app.models.Stream", function() {
beforeEach(function(){
postFetch = new $.Deferred()
spyOn(this.stream.posts, "fetch").andCallFake(function(){
spyOn(this.stream.posts, "fetch").andCallFake(function(){
return postFetch
})
})
......@@ -32,7 +32,23 @@ describe("app.models.Stream", function() {
var fetchedSpy = jasmine.createSpy()
this.stream.bind('fetched', fetchedSpy)
this.stream.fetch()
postFetch.resolve()
postFetch.resolve({posts : [1,2,3]})
expect(fetchedSpy).toHaveBeenCalled()
})
it("triggers allPostsLoaded on the stream when zero posts are returned", function(){
var fetchedSpy = jasmine.createSpy()
this.stream.bind('allPostsLoaded', fetchedSpy)
this.stream.fetch()
postFetch.resolve({posts : []})
expect(fetchedSpy).toHaveBeenCalled()
})
it("triggers allPostsLoaded on the stream when a Post is returned", function(){
var fetchedSpy = jasmine.createSpy()
this.stream.bind('allPostsLoaded', fetchedSpy)
this.stream.fetch()
postFetch.resolve({posts : factory.post().attributes})
expect(fetchedSpy).toHaveBeenCalled()
})
});
......
......@@ -4,11 +4,10 @@ describe("app.views.Stream", function(){
this.posts = $.parseJSON(spec.readFixture("multi_stream_json"))["posts"];
app.stream = new app.models.Stream()
app.stream.add(this.posts);
this.stream = new app.models.Stream()
this.stream.add(this.posts);
this.collection = app.stream.posts
this.view = new app.views.Stream({collection : this.collection});
this.view = new app.views.Stream({model : this.stream});
app.stream.bind("fetched", this.collectionFetched, this) //untested
......@@ -20,16 +19,15 @@ describe("app.views.Stream", function(){
describe("initialize", function(){
it("binds an infinite scroll listener", function(){
spyOn($.fn, "scroll");
new app.views.Stream();
new app.views.Stream({model : this.stream});
expect($.fn.scroll).toHaveBeenCalled()
})
})
describe("#render", function(){
beforeEach(function(){
this.statusMessage = this.collection.models[0];
this.reshare = this.collection.models[1];
this.statusMessage = this.stream.posts.models[0];
this.reshare = this.stream.posts.models[1];
this.statusElement = $(this.view.$("#" + this.statusMessage.get("guid")));
this.reshareElement = $(this.view.$("#" + this.reshare.get("guid")));
})
......@@ -44,77 +42,31 @@ describe("app.views.Stream", function(){
describe("infScroll", function(){
// NOTE: inf scroll happens at 500px
beforeEach(function(){
spyOn(this.view.collection, "fetch").andReturn($.Deferred())
})
context("when the user is at the bottom of the page", function(){
beforeEach(function(){
spyOn($.fn, "height").andReturn(0)
spyOn($.fn, "scrollTop").andReturn(100)
})
it("calls fetch", function(){
spyOn(this.view, "isLoading").andReturn(false)
this.view.infScroll();
expect(this.view.collection.fetch).toHaveBeenCalled();
})
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(){
spyOn(this.view, "isLoading").andReturn(false)
spyOn($.fn, "height").andReturn(0);
spyOn($.fn, "scrollTop").andReturn(-500);
it("calls render 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")
this.view.infScroll();
expect(this.view.collection.fetch).not.toHaveBeenCalled();
expect(this.view.render).toHaveBeenCalled();
})
})
describe("collectionFetched", function(){
context("unbinding scroll", function(){
beforeEach(function(){
spyOn($.fn, "unbind")
})
it("unbinds scroll if there are no more posts left to load", function(){
this.view.collectionFetched(this.collection, {posts : []})
expect($.fn.unbind).toHaveBeenCalled()
})
it("does not fetch new content when the user is fetching one post", function(){
this.view.collectionFetched(this.collection, {posts : {}})
expect($.fn.unbind).toHaveBeenCalled()
})
})
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)
describe("removeLoader", function() {
it("emptys the pagination div when the stream is fetched", function(){
$("#jasmine_content").append($('<div id="paginate">OMG</div>'))
expect($("#paginate").text()).toBe("OMG")
this.view.stream.trigger("fetched")
expect($("#paginate")).toBeEmpty()
})
})
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)
describe("unbindInfScroll", function(){
it("unbinds scroll", function() {
spyOn($.fn, "unbind")
this.view.unbindInfScroll()
expect($.fn.unbind.mostRecentCall.object.selector).toBe("window")
expect($.fn.unbind).toHaveBeenCalledWith("scroll")
})
})
})
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter