diff --git a/features/show_more.feature b/features/show_more.feature new file mode 100644 index 000000000..e842267e7 --- /dev/null +++ b/features/show_more.feature @@ -0,0 +1,24 @@ +@javascript +Feature: collapsing and expanding long posts + In order to tame the lengths of posts in my stream + As a rocket scientist + I want long posts to be collapsed and expand on click + + Background: + Given a user with username "bob" + And I sign in as "bob@bob.bob" + And I am on the home page + + Scenario: post a very long message + Given I post an extremely long status message + And I go to the home page + + Then the post should be collapsed + + Scenario: expand a very long message + Given I post an extremely long status message + And I go to the home page + And I expand the post + + Then the post should be expanded + diff --git a/features/step_definitions/posts_steps.rb b/features/step_definitions/posts_steps.rb index 3e81c8840..ee7e2854f 100644 --- a/features/step_definitions/posts_steps.rb +++ b/features/step_definitions/posts_steps.rb @@ -2,6 +2,14 @@ Then /^the post "([^"]*)" should be marked nsfw$/ do |text| assert_nsfw(text) end +Then /^the post should be collapsed$/ do + first_post_collapsed? +end + +Then /^the post should be expanded$/ do + first_post_expanded? +end + Then /^I should see an uploaded image within the photo drop zone$/ do find("#photodropzone img")["src"].should include("uploads/images") end @@ -32,6 +40,9 @@ When /^I click on the first block button/ do find(".block_user").click end +When /^I expand the post$/ do + expand_first_post +end Then /^I should see "([^"]*)" as the first post in my stream$/ do |text| first_post_text.should include(text) @@ -43,4 +54,8 @@ end When /^I click the publisher and post "([^"]*)"$/ do |text| click_and_post(text) -end \ No newline at end of file +end + +When /^I post an extremely long status message$/ do + click_and_post("I am a very interesting message " * 64) +end diff --git a/features/support/publishing_cuke_helpers.rb b/features/support/publishing_cuke_helpers.rb index 9895813a4..8f1762434 100644 --- a/features/support/publishing_cuke_helpers.rb +++ b/features/support/publishing_cuke_helpers.rb @@ -17,6 +17,22 @@ module PublishingCukeHelpers ') end + def expand_first_post + find(".stream_element:first .expander").click + wait_until{ !find(".expander").visible? } + end + + def first_post_collapsed? + find(".stream_element:first .collapsible").should have_css(".expander") + find(".stream_element:first .collapsible").has_selector?(".collapsed") + end + + def first_post_expanded? + find(".stream_element:first .expander").should_not be_visible + find(".stream_element:first .collapsible").has_no_selector?(".collapsed") + find(".stream_element:first .collapsible").has_selector?(".opened") + end + def first_post_text find('.stream_element:first .post-content').text() end diff --git a/public/javascripts/app/views/comment_view.js b/public/javascripts/app/views/comment_view.js index 5c04227cb..c85faf7a2 100644 --- a/public/javascripts/app/views/comment_view.js +++ b/public/javascripts/app/views/comment_view.js @@ -4,8 +4,10 @@ app.views.Comment = app.views.Content.extend({ className : "comment media", - events : { - "click .comment_delete": "destroyModel" + events : function() { + return _.extend(app.views.Content.prototype.events, { + "click .comment_delete": "destroyModel" + }); }, presenter : function() { diff --git a/public/javascripts/app/views/content_view.js b/public/javascripts/app/views/content_view.js index 3bc7f0760..bb66c08f1 100644 --- a/public/javascripts/app/views/content_view.js +++ b/public/javascripts/app/views/content_view.js @@ -1,7 +1,8 @@ app.views.Content = app.views.StreamObject.extend({ events: { - "click .oembed .thumb": "showOembedContent" + "click .oembed .thumb": "showOembedContent", + "click .expander": "expandPost" }, presenter : function(){ @@ -41,7 +42,17 @@ app.views.Content = app.views.StreamObject.extend({ var paramSeparator = ( /\?/.test(insertHTML.attr("src")) ) ? "&" : "?"; insertHTML.attr("src", insertHTML.attr("src") + paramSeparator + "autoplay=1"); oembed.html( insertHTML ); + }, + + expandPost: function(evt) { + var el = $(this.el).find('.collapsible'); + el.removeClass('collapsed').addClass('opened'); + el.animate({'height':el.data('orig-height')}, 550, function() { + el.css('height','auto'); + }); + $(evt.currentTarget).hide(); } + }); app.views.StatusMessage = app.views.Content.extend({ diff --git a/public/javascripts/app/views/stream_object_view.js b/public/javascripts/app/views/stream_object_view.js index 054cdee88..1f46e732b 100644 --- a/public/javascripts/app/views/stream_object_view.js +++ b/public/javascripts/app/views/stream_object_view.js @@ -1,34 +1,5 @@ app.views.StreamObject = app.views.Base.extend({ - postRenderTemplate : function() { - // collapse long posts - this.$(".collapsible").expander({ - slicePoint: 400, - widow: 12, - expandPrefix: "", - expandText: Diaspora.I18n.t("show_more"), - userCollapse: false, - beforeExpand: function() { - if ($(this).find('.summary').length == 0) { // Sigh. See comments in the spec. - var readMoreDiv = $(this).find('.read-more'); - var lastElementBeforeReadMore = readMoreDiv.prev(); - var firstElementAfterReadMore = readMoreDiv.next().children().first(); - - if (lastElementBeforeReadMore.is('p')) { - lastElementBeforeReadMore.append(firstElementAfterReadMore.html()); - firstElementAfterReadMore.remove(); - - } else if (lastElementBeforeReadMore.is('ul') && firstElementAfterReadMore.is('ul')) { - var firstBullet = firstElementAfterReadMore.children().first(); - lastElementBeforeReadMore.find('li').last().append(firstBullet.html()); - firstBullet.remove(); - } - readMoreDiv.remove(); - } - } - }); - }, - destroyModel: function(evt) { if (evt) { evt.preventDefault(); diff --git a/public/javascripts/app/views/stream_view.js b/public/javascripts/app/views/stream_view.js index 0c3b71d74..b3095b540 100644 --- a/public/javascripts/app/views/stream_view.js +++ b/public/javascripts/app/views/stream_view.js @@ -16,6 +16,7 @@ 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()) { @@ -52,6 +53,35 @@ app.views.Stream = Backbone.View.extend({ return this; }, + + postRender : function() { + // collapse long posts + var collHeight = 190, + 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( + $('
') + .addClass('expander') + .text( Diaspora.I18n.t("show_more") ) + ); + } + }); + }, appendLoader: function(){ $("#paginate").html($("