From 7dc70c73114f1163fc8c07fe1efc87e5a79762c2 Mon Sep 17 00:00:00 2001 From: theworldbright Date: Sat, 6 Jun 2015 16:23:36 +0900 Subject: [PATCH 1/3] Fix #5483 Please see https://github.com/diaspora/diaspora/issues/5483#issuecomment-109277476 (+5 squashed commits) Squashed commits: [62f38a6] Wrap all handlers with document.ready() Also add the copyright at the top of the file. [e861587] Split up show_comments handling Currently there are two classes that have the class show_comments. I renamed one to "back_to_stream_element_top" as it is responsible for scrolling the user all the way up to the top when clicked. The other which toggles the reactions will remain as "show_comments". [a8dbc4e] Remove unused "cancel new comment" action [db575cc] Move comment related js to mobile_comments.js [de44f81] Move add comment container to new comment partial --- app/assets/javascripts/mobile/mobile.js | 142 +---------------- .../javascripts/mobile/mobile_comments.js | 144 ++++++++++++++++++ app/views/comments/_new_comment.mobile.haml | 19 ++- app/views/shared/_post_stats.mobile.haml | 7 - 4 files changed, 157 insertions(+), 155 deletions(-) create mode 100644 app/assets/javascripts/mobile/mobile_comments.js diff --git a/app/assets/javascripts/mobile/mobile.js b/app/assets/javascripts/mobile/mobile.js index 124cb86fd..596bfa673 100644 --- a/app/assets/javascripts/mobile/mobile.js +++ b/app/assets/javascripts/mobile/mobile.js @@ -20,6 +20,7 @@ //= require mobile/mobile_file_uploader //= require mobile/profile_aspects //= require mobile/tag_following +//= require mobile/mobile_comments.js $(document).ready(function(){ @@ -127,147 +128,6 @@ $(document).ready(function(){ } }); - /* Show comments */ - $("a.show_comments", ".stream").bind("tap click", function(evt){ - evt.preventDefault(); - var link = $(this), - parent = link.closest(".bottom_bar").first(), - commentsContainer = function(){ return parent.find(".comment_container").first(); }, - existingCommentsContainer = commentsContainer(); - - if( link.hasClass('active') ) { - existingCommentsContainer.hide(); - if(!link.hasClass('bottom_collapse')){ - link.removeClass('active'); - } else { - parent.find(".show_comments").first().removeClass('active'); - } - - $('html,body').scrollTop(parent.offset().top - parent.closest(".stream_element").height() - 8); - - } else if( existingCommentsContainer.length > 0) { - - if(!existingCommentsContainer.hasClass('noComments')) { - $.ajax({ - url: link.attr('href'), - success: function(data){ - parent.append($(data).find('.comments_container').html()); - link.addClass('active'); - existingCommentsContainer.show(); - scrollToOffset(parent, commentsContainer()); - commentsContainer().find('time.timeago').timeago(); - } - }); - } else { - existingCommentsContainer.show(); - existingCommentsContainer.find('time.timeago').timeago(); - } - - link.addClass('active'); - - } else { - $.ajax({ - url: link.attr('href'), - success: function(data){ - parent.append(data); - link.addClass('active'); - scrollToOffset(parent, commentsContainer()); - commentsContainer().find('time.timeago').timeago(); - } - }); - } - }); - - var scrollToOffset = function(parent, commentsContainer){ - var commentCount = commentsContainer.find("li.comment").length; - if( commentCount > 3 ) { - var lastComment = commentsContainer.find("li:nth-child("+(commentCount-4)+")"); - $('html,body').animate({ - scrollTop: lastComment.offset().top - }, 1000); - } - }; - - $(".stream").delegate("a.comment_action", "tap click", function(evt){ - evt.preventDefault(); - var link = $(this); - - if(link.hasClass('inactive')) { - var parent = link.closest(".bottom_bar").first(), - container = link.closest('.bottom_bar').find('.add_comment_bottom_link_container').first(); - - $.ajax({ - url: link.attr('href'), - beforeSend: function(){ - link.addClass('loading'); - }, - context: link, - success: function(data){ - var textarea = function(target) { return target.closest(".stream_element").find('textarea.comment_box').first()[0] }; - link.removeClass('loading'); - - if(!link.hasClass("add_comment_bottom_link")){ - link.removeClass('inactive'); - } - - container.hide(); - parent.append(data); - - MBP.autogrow(textarea($(this))); - } - }); - } - }); - - $(".stream").delegate("a.cancel_new_comment", "tap click", function(evt){ - evt.preventDefault(); - var link = $(this), - form = link.closest("form"), - commentActionLink = link.closest(".bottom_bar").find("a.comment_action").first(), - container = link.closest('.bottom_bar').find('.add_comment_bottom_link_container'); - - if(container.length > 0 ){ - container.first().show(); - } - - commentActionLink.addClass("inactive"); - form.remove(); - }); - - $(document).on("submit", ".new_comment", function(evt){ - evt.preventDefault(); - var form = $(this); - - $.post(form.attr('action')+"?format=mobile", form.serialize(), function(data){ - var bottomBar = form.closest('.bottom_bar').first(), - container = bottomBar.find('.add_comment_bottom_link_container'), - commentActionLink = bottomBar.find("a.comment_action").first(), - reactionLink = bottomBar.find(".show_comments").first(), - commentCount = bottomBar.find(".comment_count"); - - if(container.length > 0) { - container.before(data); - form.remove(); - container.show(); - - } else { - var comments = $(""); - container = $("
"); - - comments.html(data); - container.append(comments); - form.remove(); - container.appendTo(bottomBar); - } - - reactionLink.text(reactionLink.text().replace(/(\d+)/, function(match){ return parseInt(match) + 1; })); - commentCount.text(commentCount.text().replace(/(\d+)/, function(match){ return parseInt(match) + 1; })); - commentActionLink.addClass("inactive"); - bottomBar.find('time.timeago').timeago(); - }, 'html'); - }); - - $(".service_icon").bind("tap click", function() { var service = $(this).toggleClass("dim"), selectedServices = $("#new_status_message .service_icon:not(.dim)"), diff --git a/app/assets/javascripts/mobile/mobile_comments.js b/app/assets/javascripts/mobile/mobile_comments.js new file mode 100644 index 000000000..31cf703f1 --- /dev/null +++ b/app/assets/javascripts/mobile/mobile_comments.js @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2010-2011, Diaspora Inc. This file is + * licensed under the Affero General Public License version 3 or later. See + * the COPYRIGHT file. + */ + +$(document).ready(function() { + + $(".stream").on("tap click", "a.back_to_stream_element_top", function(evt) { + var bottomBar = $(this).closest(".bottom_bar").first(); + var streamElement = bottomBar.parent(); + $("html, body").animate({ + scrollTop: streamElement.offset().top - 54 + }, 1000); + }); + + $(".stream").on("tap click", "a.show_comments", function(evt){ + evt.preventDefault(); + var toggleReactionsLink = $(this), + bottomBar = toggleReactionsLink.closest(".bottom_bar").first(), + commentActionLink = bottomBar.find("a.comment_action"), + commentsContainer = function() { return bottomBar.find(".comment_container").first(); }, + existingCommentsContainer = commentsContainer(); + if (toggleReactionsLink.hasClass("active")) { + existingCommentsContainer.hide(); + toggleReactionsLink.removeClass("active"); + } else if (existingCommentsContainer.length > 0) { + existingCommentsContainer.show(); + showCommentBox(commentActionLink); + toggleReactionsLink.addClass('active'); + commentsContainer().find("time.timeago").timeago(); + } else { + $.ajax({ + url: toggleReactionsLink.attr('href'), + success: function(data) { + $(data).insertAfter(bottomBar.children(".show_comments").first()); + showCommentBox(commentActionLink); + toggleReactionsLink.addClass("active"); + commentsContainer().find("time.timeago").timeago(); + } + }); + } + }); + + var scrollToOffset = function(commentsContainer){ + var commentCount = commentsContainer.find("li.comment").length; + if ( commentCount > 3 ) { + var lastComment = commentsContainer.find("li:nth-child("+(commentCount-3)+")"); + $('html,body').animate({ + scrollTop: lastComment.offset().top + }, 1000); + } + }; + + $(".stream").on("tap click", "a.comment_action", function(evt){ + evt.preventDefault(); + showCommentBox(this); + var bottomBar = $(this).closest(".bottom_bar").first(); + scrollToOffset(bottomBar.find(".comment_container").first()); + }); + + function showCommentBox(link){ + var link = $(link); + if(link.hasClass("inactive")) { + $.ajax({ + url: link.attr("href"), + beforeSend: function(){ + link.addClass("loading"); + }, + context: link, + success: function(data){ + appendCommentBox.call(this, link, data); + } + }); + } + } + + function appendCommentBox(link, data) { + link.removeClass("loading"); + link.removeClass("inactive"); + var bottomBar = link.closest(".bottom_bar").first(); + bottomBar.append(data); + var textArea = bottomBar.find("textarea.comment_box").first()[0]; + MBP.autogrow(textArea); + scrollToFirstComment(bottomBar); + } + + function scrollToFirstComment(bottomBar) { + $("html, body").animate({ + scrollTop: bottomBar.offset().top - 54 + }, 500); + } + + $(".stream").on("submit", ".new_comment", function(evt) { + evt.preventDefault(); + var form = $(this); + $.post(form.attr('action')+"?format=mobile", form.serialize(), function(data) { + updateStream(form, data); + }, 'html'); + }); + + function updateStream(form, data) { + var bottomBar = form.closest(".bottom_bar").first(); + addNewComments(bottomBar, data); + updateCommentCount(bottomBar); + updateReactionCount(bottomBar); + handleNewCommentBox(form, bottomBar); + bottomBar.find("time.timeago").timeago(); + } + + function addNewComments(bottomBar, data) { + var commentsContainer = bottomBar.find(".comment_container").first(); + var comments = commentsContainer.find(".comments").first(); + comments.append(data); + } + + // Fix for no comments + function updateCommentCount(bottomBar) { + var commentCount = bottomBar.find(".comment_count"); + commentCount.text(commentCount.text().replace(/(\d+)/, function (match) { + return parseInt(match) + 1; + })); + } + // Fix for no reactions + function updateReactionCount(bottomBar) { + var toggleReactionsLink = bottomBar.find(".show_comments").first(); + toggleReactionsLink.text(toggleReactionsLink.text().replace(/(\d+)/, function (match) { + return parseInt(match) + 1; + })); + } + + function handleNewCommentBox(form, bottomBar) { + form.parent().remove(); + var commentActionLink = bottomBar.find("a.comment_action").first(); + commentActionLink.addClass("inactive"); + showCommentBoxIfApplicable(bottomBar, commentActionLink); + } + function showCommentBoxIfApplicable(bottomBar, commentActionLink) { + var toggleReactionsLink = bottomBar.find(".show_comments").first(); + if (toggleReactionsLink.hasClass("active")) { + showCommentBox(commentActionLink); + } + } +}); diff --git a/app/views/comments/_new_comment.mobile.haml b/app/views/comments/_new_comment.mobile.haml index bba1aa86a..d03012883 100644 --- a/app/views/comments/_new_comment.mobile.haml +++ b/app/views/comments/_new_comment.mobile.haml @@ -2,10 +2,15 @@ -# licensed under the Affero General Public License version 3 or later. See -# the COPYRIGHT file. -= form_tag( post_comments_path(post_id), id: "new_comment_on_#{post_id}", class: 'new_comment', autocomplete: "off") do - %fieldset - .control-group - = hidden_field_tag :post_id, post_id, id: "post_id_on_#{post_id}" - = text_area_tag :text, nil, class: "col-md-12 comment_box form-control form-group", id: "comment_text_on_#{post_id}", placeholder: t('.comment'), autofocus: true - = submit_tag t('.comment'), id: "comment_submit_#{post_id}", 'data-disable-with' => t('.commenting'), class: "btn btn-primary pull-right" - .clearfix +.add_comment_bottom_link_container + - if user_signed_in? + = form_tag( post_comments_path(post_id), id: "new_comment_on_#{post_id}", class: 'new_comment', autocomplete: "off") do + %fieldset + .control-group + = hidden_field_tag :post_id, post_id, id: "post_id_on_#{post_id}" + = text_area_tag :text, nil, class: "col-md-12 comment_box form-control form-group", id: "comment_text_on_#{post_id}", placeholder: t('.comment'), autofocus: true + = submit_tag t('.comment'), id: "comment_submit_#{post_id}", 'data-disable-with' => t('.commenting'), class: "btn btn-primary pull-right" + .clearfix + + = link_to "#", class: "back_to_stream_element_top" do + = image_tag "mobile/arrow_up_small.png" diff --git a/app/views/shared/_post_stats.mobile.haml b/app/views/shared/_post_stats.mobile.haml index 3f96807b3..a0a0d0c50 100644 --- a/app/views/shared/_post_stats.mobile.haml +++ b/app/views/shared/_post_stats.mobile.haml @@ -12,10 +12,3 @@ %ul.comments = render partial: "comments/comment", collection: @post.comments.for_a_stream, locals: {post: @post} - - %li.comment.add_comment_bottom_link_container - = link_to "#", class: "show_comments bottom_collapse active" do - = image_tag "mobile/arrow_up_small.png" - - - if user_signed_in? - = link_to t("comments.new_comment.comment"), new_post_comment_path(@post), class: "add_comment_bottom_link btn btn-default comment_action inactive" From 5fa4519e93c080e80eebaab69f72e00c1bdd5985 Mon Sep 17 00:00:00 2001 From: theworldbright Date: Sat, 6 Jun 2015 17:32:08 +0900 Subject: [PATCH 2/3] Fix #5757 (+2 squashed commits) Squashed commits: [e10acde] Open reactions after commenting [aceea75] Fix hound remarks and reactions tests The ".comment_action" should be active when the user clicks on "a.show comments" [d1deae5] Fix hound remarks [f5db5dd] Keep current instead of scrolling to first comment [be63092] Remove unused evt parameter --- .../javascripts/mobile/mobile_comments.js | 129 ++++++++++-------- app/views/comments/_new_comment.mobile.haml | 2 +- features/mobile/reactions.feature | 2 +- 3 files changed, 74 insertions(+), 59 deletions(-) diff --git a/app/assets/javascripts/mobile/mobile_comments.js b/app/assets/javascripts/mobile/mobile_comments.js index 31cf703f1..ea1402819 100644 --- a/app/assets/javascripts/mobile/mobile_comments.js +++ b/app/assets/javascripts/mobile/mobile_comments.js @@ -6,7 +6,7 @@ $(document).ready(function() { - $(".stream").on("tap click", "a.back_to_stream_element_top", function(evt) { + $(".stream").on("tap click", "a.back_to_stream_element_top", function() { var bottomBar = $(this).closest(".bottom_bar").first(); var streamElement = bottomBar.parent(); $("html, body").animate({ @@ -16,60 +16,86 @@ $(document).ready(function() { $(".stream").on("tap click", "a.show_comments", function(evt){ evt.preventDefault(); - var toggleReactionsLink = $(this), - bottomBar = toggleReactionsLink.closest(".bottom_bar").first(), - commentActionLink = bottomBar.find("a.comment_action"), - commentsContainer = function() { return bottomBar.find(".comment_container").first(); }, - existingCommentsContainer = commentsContainer(); - if (toggleReactionsLink.hasClass("active")) { - existingCommentsContainer.hide(); - toggleReactionsLink.removeClass("active"); - } else if (existingCommentsContainer.length > 0) { - existingCommentsContainer.show(); - showCommentBox(commentActionLink); - toggleReactionsLink.addClass('active'); - commentsContainer().find("time.timeago").timeago(); - } else { - $.ajax({ - url: toggleReactionsLink.attr('href'), - success: function(data) { - $(data).insertAfter(bottomBar.children(".show_comments").first()); - showCommentBox(commentActionLink); - toggleReactionsLink.addClass("active"); - commentsContainer().find("time.timeago").timeago(); - } - }); - } + toggleComments($(this)); }); + function toggleComments(toggleReactionsLink) { + if (toggleReactionsLink.hasClass("active")) { + hideComments(toggleReactionsLink); + } else { + showComments(toggleReactionsLink); + } + } + function hideComments(toggleReactionsLink) { + var bottomBar = toggleReactionsLink.closest(".bottom_bar").first(), + commentsContainer = commentsContainerLazy(bottomBar), + existingCommentsContainer = commentsContainer(); + existingCommentsContainer.hide(); + toggleReactionsLink.removeClass("active"); + } + function showComments(toggleReactionsLink) { + var bottomBar = toggleReactionsLink.closest(".bottom_bar").first(), + commentsContainer = commentsContainerLazy(bottomBar), + existingCommentsContainer = commentsContainer(), + commentActionLink = bottomBar.find("a.comment_action"); + if (existingCommentsContainer.length > 0) { + showLoadedComments(toggleReactionsLink, existingCommentsContainer, commentActionLink); + } else { + showUnloadedComments(toggleReactionsLink, bottomBar, commentActionLink); + } + } + function showLoadedComments(toggleReactionsLink, existingCommentsContainer, commentActionLink) { + existingCommentsContainer.show(); + showCommentBox(commentActionLink); + toggleReactionsLink.addClass("active"); + existingCommentsContainer.find("time.timeago").timeago(); + } + function showUnloadedComments(toggleReactionsLink, bottomBar, commentActionLink) { + var commentsContainer = commentsContainerLazy(bottomBar); + $.ajax({ + url: toggleReactionsLink.attr("href"), + success: function (data) { + $(data).insertAfter(bottomBar.children(".show_comments").first()); + showCommentBox(commentActionLink); + toggleReactionsLink.addClass("active"); + commentsContainer().find("time.timeago").timeago(); + } + }); + } + function commentsContainerLazy(bottomBar) { + return function() { + return bottomBar.find(".comment_container").first(); + }; + } + + $(".stream").on("tap click", "a.comment_action", function(evt) { + evt.preventDefault(); + showCommentBox(this); + var bottomBar = $(this).closest(".bottom_bar").first(); + var commentContainer = bottomBar.find(".comment_container").first(); + scrollToOffset(commentContainer); + }); var scrollToOffset = function(commentsContainer){ var commentCount = commentsContainer.find("li.comment").length; if ( commentCount > 3 ) { var lastComment = commentsContainer.find("li:nth-child("+(commentCount-3)+")"); - $('html,body').animate({ + $("html,body").animate({ scrollTop: lastComment.offset().top }, 1000); } }; - $(".stream").on("tap click", "a.comment_action", function(evt){ - evt.preventDefault(); - showCommentBox(this); - var bottomBar = $(this).closest(".bottom_bar").first(); - scrollToOffset(bottomBar.find(".comment_container").first()); - }); - function showCommentBox(link){ - var link = $(link); - if(link.hasClass("inactive")) { + var commentActionLink = $(link); + if(commentActionLink.hasClass("inactive")) { $.ajax({ - url: link.attr("href"), + url: commentActionLink.attr("href"), beforeSend: function(){ - link.addClass("loading"); + commentActionLink.addClass("loading"); }, - context: link, + context: commentActionLink, success: function(data){ - appendCommentBox.call(this, link, data); + appendCommentBox.call(this, commentActionLink, data); } }); } @@ -82,21 +108,14 @@ $(document).ready(function() { bottomBar.append(data); var textArea = bottomBar.find("textarea.comment_box").first()[0]; MBP.autogrow(textArea); - scrollToFirstComment(bottomBar); - } - - function scrollToFirstComment(bottomBar) { - $("html, body").animate({ - scrollTop: bottomBar.offset().top - 54 - }, 500); } $(".stream").on("submit", ".new_comment", function(evt) { evt.preventDefault(); var form = $(this); - $.post(form.attr('action')+"?format=mobile", form.serialize(), function(data) { + $.post(form.attr("action")+"?format=mobile", form.serialize(), function(data) { updateStream(form, data); - }, 'html'); + }, "html"); }); function updateStream(form, data) { @@ -104,7 +123,7 @@ $(document).ready(function() { addNewComments(bottomBar, data); updateCommentCount(bottomBar); updateReactionCount(bottomBar); - handleNewCommentBox(form, bottomBar); + handleCommentShowing(form, bottomBar); bottomBar.find("time.timeago").timeago(); } @@ -129,16 +148,12 @@ $(document).ready(function() { })); } - function handleNewCommentBox(form, bottomBar) { - form.parent().remove(); + function handleCommentShowing(form, bottomBar) { + var formContainer = form.parent(); + formContainer.remove(); var commentActionLink = bottomBar.find("a.comment_action").first(); commentActionLink.addClass("inactive"); - showCommentBoxIfApplicable(bottomBar, commentActionLink); - } - function showCommentBoxIfApplicable(bottomBar, commentActionLink) { var toggleReactionsLink = bottomBar.find(".show_comments").first(); - if (toggleReactionsLink.hasClass("active")) { - showCommentBox(commentActionLink); - } + showComments(toggleReactionsLink); } }); diff --git a/app/views/comments/_new_comment.mobile.haml b/app/views/comments/_new_comment.mobile.haml index d03012883..cb535dc23 100644 --- a/app/views/comments/_new_comment.mobile.haml +++ b/app/views/comments/_new_comment.mobile.haml @@ -8,7 +8,7 @@ %fieldset .control-group = hidden_field_tag :post_id, post_id, id: "post_id_on_#{post_id}" - = text_area_tag :text, nil, class: "col-md-12 comment_box form-control form-group", id: "comment_text_on_#{post_id}", placeholder: t('.comment'), autofocus: true + = text_area_tag :text, nil, class: "col-md-12 comment_box form-control form-group", id: "comment_text_on_#{post_id}", placeholder: t('.comment') = submit_tag t('.comment'), id: "comment_submit_#{post_id}", 'data-disable-with' => t('.commenting'), class: "btn btn-primary pull-right" .clearfix diff --git a/features/mobile/reactions.feature b/features/mobile/reactions.feature index 3fceef45a..f6ff67f9d 100644 --- a/features/mobile/reactions.feature +++ b/features/mobile/reactions.feature @@ -33,7 +33,7 @@ Feature: reactions mobile post And I should see "1 reaction" within ".show_comments" And I click on selector "a.show_comments" And I should see "1" within ".comment_count" - When I click on selector "a.image_link.comment_action.inactive" + When I click on selector "a.image_link.comment_action" And I click on selector "a.remove" And I confirm the alert Then I should not see "1 reaction" within ".show_comments" From 3ac66128ad85a77fb02ab40aff93eddbd6a16a80 Mon Sep 17 00:00:00 2001 From: theworldbright Date: Sat, 6 Jun 2015 16:21:59 +0900 Subject: [PATCH 3/3] Restyle button and adjust position of back up arrow Squashed commits: [47c4a02] Remove styling for return to top of post button --- app/assets/stylesheets/mobile/mobile.scss | 7 ------- app/views/comments/_new_comment.mobile.haml | 12 ++++++------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/app/assets/stylesheets/mobile/mobile.scss b/app/assets/stylesheets/mobile/mobile.scss index 3a65e1022..7b2ce2f79 100644 --- a/app/assets/stylesheets/mobile/mobile.scss +++ b/app/assets/stylesheets/mobile/mobile.scss @@ -392,13 +392,6 @@ h3 { margin-top: 0; } } } - .show_comments.bottom_collapse { - position: absolute; - right: 10px; - top: 14px; - padding: 5px 10px; - } - #bottom_bar_tabs { display: table; width: 100%; diff --git a/app/views/comments/_new_comment.mobile.haml b/app/views/comments/_new_comment.mobile.haml index cb535dc23..7e8ea3d4c 100644 --- a/app/views/comments/_new_comment.mobile.haml +++ b/app/views/comments/_new_comment.mobile.haml @@ -3,14 +3,14 @@ -# the COPYRIGHT file. .add_comment_bottom_link_container + = link_to "#", class: "back_to_stream_element_top pull-right" do + = image_tag "mobile/arrow_up_small.png" + - if user_signed_in? - = form_tag( post_comments_path(post_id), id: "new_comment_on_#{post_id}", class: 'new_comment', autocomplete: "off") do + = form_tag( post_comments_path(post_id), id: "new_comment_on_#{post_id}", class: "new_comment", autocomplete: "off") do %fieldset .control-group = hidden_field_tag :post_id, post_id, id: "post_id_on_#{post_id}" - = text_area_tag :text, nil, class: "col-md-12 comment_box form-control form-group", id: "comment_text_on_#{post_id}", placeholder: t('.comment') - = submit_tag t('.comment'), id: "comment_submit_#{post_id}", 'data-disable-with' => t('.commenting'), class: "btn btn-primary pull-right" + = text_area_tag :text, nil, class: "col-md-12 comment_box form-control form-group", id: "comment_text_on_#{post_id}", placeholder: t(".comment") + = submit_tag t(".comment"), id: "comment_submit_#{post_id}", 'data-disable-with' => t(".commenting"), class: "btn btn-primary btn-block" .clearfix - - = link_to "#", class: "back_to_stream_element_top" do - = image_tag "mobile/arrow_up_small.png"