Merge pull request #6509 from AugierLe42e/fix-mobile-comment

Refactor mobile comment section
This commit is contained in:
Steffen van Bergerem 2016-02-05 11:27:51 +01:00
commit 0c05b474c5
28 changed files with 379 additions and 249 deletions

View file

@ -78,6 +78,7 @@ Contributions are very welcome, the hard work is done!
* Change login/registration/forgot password button color [#6504](https://github.com/diaspora/diaspora/pull/6504) * Change login/registration/forgot password button color [#6504](https://github.com/diaspora/diaspora/pull/6504)
* A note regarding ignoring users was added to the failure messages on commenting/liking [#6646](https://github.com/diaspora/diaspora/pull/6646) * A note regarding ignoring users was added to the failure messages on commenting/liking [#6646](https://github.com/diaspora/diaspora/pull/6646)
* Replace sidetiq with sidekiq-cron [#6616](https://github.com/diaspora/diaspora/pull/6616) * Replace sidetiq with sidekiq-cron [#6616](https://github.com/diaspora/diaspora/pull/6616)
* Refactor mobile comment section [#6509](https://github.com/diaspora/diaspora/pull/6509)
## Bug fixes ## Bug fixes
* Destroy Participation when removing interactions with a post [#5852](https://github.com/diaspora/diaspora/pull/5852) * Destroy Participation when removing interactions with a post [#5852](https://github.com/diaspora/diaspora/pull/5852)

View file

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 B

View file

@ -59,7 +59,7 @@ $(document).ready(function(){
$(".like-action", ".stream").bind("tap click", function(evt){ $(".like-action", ".stream").bind("tap click", function(evt){
evt.preventDefault(); evt.preventDefault();
var link = $(this), var link = $(this),
likeCounter = $(this).closest(".stream_element").find("like_count"), likeCounter = $(this).closest(".stream_element").find(".like-count"),
href = link.attr("href"); href = link.attr("href");
if(!link.hasClass("loading")){ if(!link.hasClass("loading")){
@ -74,7 +74,7 @@ $(document).ready(function(){
link.attr("href", href + "/" + data["id"]); link.attr("href", href + "/" + data["id"]);
if(likeCounter){ if(likeCounter){
likeCounter.text(parseInt(likeCounter.text) + 1); likeCounter.text(parseInt(likeCounter.text(), 10) + 1);
} }
} }
}); });
@ -90,7 +90,7 @@ $(document).ready(function(){
link.attr("href", href.replace(/\/\d+$/, '')); link.attr("href", href.replace(/\/\d+$/, ''));
if(likeCounter){ if(likeCounter){
likeCounter.text(parseInt(likeCounter.text) - 1); likeCounter.text(parseInt(likeCounter.text(), 10) - 1);
} }
} }
}); });
@ -99,7 +99,7 @@ $(document).ready(function(){
}); });
/* Reshare */ /* Reshare */
$(".reshare-action", ".stream").bind("tap click", function(evt){ $(".reshare-action:not(.disabled)", ".stream").bind("tap click", function(evt){
evt.preventDefault(); evt.preventDefault();
var link = $(this), var link = $(this),

View file

@ -7,6 +7,8 @@
(function() { (function() {
Diaspora.Mobile = {}; Diaspora.Mobile = {};
Diaspora.Mobile.Comments = { Diaspora.Mobile.Comments = {
stream: function(){ return $(".stream"); },
initialize: function() { initialize: function() {
var self = this; var self = this;
$(".stream").on("tap click", "a.back_to_stream_element_top", function() { $(".stream").on("tap click", "a.back_to_stream_element_top", function() {
@ -17,96 +19,135 @@
}, 1000); }, 1000);
}); });
$(".stream").on("tap click", "a.show_comments", function(evt){ this.stream().on("tap click", "a.show-comments", function(evt){
evt.preventDefault(); evt.preventDefault();
self.toggleComments($(this)); self.toggleComments($(this));
}); });
$(".stream").on("tap click", "a.comment-action", function(evt) { this.stream().on("tap click", "a.comment-action", function(evt) {
evt.preventDefault(); evt.preventDefault();
self.showCommentBox($(this)); self.showCommentBox($(this));
var bottomBar = $(this).closest(".bottom_bar").first(); var bottomBar = $(this).closest(".bottom-bar").first();
var commentContainer = bottomBar.find(".comment_container").first(); var commentContainer = bottomBar.find(".comment-container").first();
self.scrollToOffset(commentContainer); self.scrollToOffset(commentContainer);
}); });
$(".stream").on("submit", ".new_comment", this.submitComment); this.stream().on("submit", ".new_comment", this.submitComment);
}, },
submitComment: function(evt) { submitComment: function(evt){
evt.preventDefault(); evt.preventDefault();
var form = $(this); var form = $(this);
var commentBox = form.find(".comment_box"); var commentBox = form.find(".comment_box");
var commentText = $.trim(commentBox.val()); var commentText = $.trim(commentBox.val());
if (commentText) { if(!commentText){
$.post(form.attr("action")+"?format=mobile", form.serialize(), function(data) {
Diaspora.Mobile.Comments.updateStream(form, data);
}, "html");
return true;
}
else {
commentBox.focus(); commentBox.focus();
return false; return false;
} }
$.post(form.attr("action") + "?format=mobile", form.serialize(), function(data){
Diaspora.Mobile.Comments.updateStream(form, data);
}, "html").fail(function(){
Diaspora.Mobile.Comments.resetCommentBox(this);
});
autosize($(".add-comment-switcher:not(.hidden) textarea"));
}, },
toggleComments: function(toggleReactionsLink) { toggleComments: function(toggleReactionsLink) {
if(toggleReactionsLink.hasClass("loading")) { return; } if(toggleReactionsLink.hasClass("loading")) { return; }
if (toggleReactionsLink.hasClass("active")) {
if(toggleReactionsLink.hasClass("active")) {
this.hideComments(toggleReactionsLink); this.hideComments(toggleReactionsLink);
toggleReactionsLink.parents(".bottom-bar").find(".add-comment-switcher").addClass("hidden");
} else { } else {
this.showComments(toggleReactionsLink); this.showComments(toggleReactionsLink);
} }
}, },
hideComments: function(toggleReactionsLink) { hideComments: function(toggleReactionsLink) {
var bottomBar = toggleReactionsLink.closest(".bottom_bar").first(), var bottomBar = toggleReactionsLink.closest(".bottom-bar").first();
commentsContainer = this.commentsContainerLazy(bottomBar), this.bottomBarLazy(bottomBar).deactivate();
existingCommentsContainer = commentsContainer();
existingCommentsContainer.hide();
toggleReactionsLink.removeClass("active"); toggleReactionsLink.removeClass("active");
}, },
showComments: function(toggleReactionsLink) { showComments: function(toggleReactionsLink) {
var bottomBar = toggleReactionsLink.closest(".bottom_bar").first(), var bottomBar = toggleReactionsLink.closest(".bottom-bar").first(),
commentsContainer = this.commentsContainerLazy(bottomBar), bottomBarContainer = this.bottomBarLazy(bottomBar),
existingCommentsContainer = commentsContainer(), existingCommentsContainer = bottomBarContainer.getCommentsContainer(),
commentActionLink = bottomBar.find("a.comment-action"); commentActionLink = bottomBar.find("a.comment-action");
bottomBarContainer.activate();
bottomBarContainer.showLoader();
if (existingCommentsContainer.length > 0) { if (existingCommentsContainer.length > 0) {
this.showLoadedComments(toggleReactionsLink, existingCommentsContainer, commentActionLink); this.showLoadedComments(toggleReactionsLink, existingCommentsContainer, commentActionLink);
bottomBarContainer.hideLoader();
} else { } else {
this.showUnloadedComments(toggleReactionsLink, bottomBar, commentActionLink); this.showUnloadedComments(toggleReactionsLink, bottomBar, commentActionLink);
} }
}, },
showLoadedComments: function(toggleReactionsLink, existingCommentsContainer, commentActionLink) { showLoadedComments: function(toggleReactionsLink, existingCommentsContainer, commentActionLink) {
toggleReactionsLink.addClass("active");
existingCommentsContainer.show();
this.showCommentBox(commentActionLink); this.showCommentBox(commentActionLink);
existingCommentsContainer.find("time.timeago").timeago(); existingCommentsContainer.find("time.timeago").timeago();
}, },
showUnloadedComments: function(toggleReactionsLink, bottomBar, commentActionLink) { showUnloadedComments: function(toggleReactionsLink, bottomBar, commentActionLink) {
toggleReactionsLink.addClass("loading"); toggleReactionsLink.addClass("loading");
var commentsContainer = this.commentsContainerLazy(bottomBar); var bottomBarContainer = this.bottomBarLazy(bottomBar);
var self = this; var self = this;
$.ajax({ $.ajax({
url: toggleReactionsLink.attr("href"), url: toggleReactionsLink.attr("href"),
success: function (data) { success: function (data) {
toggleReactionsLink.addClass("active").removeClass("loading"); toggleReactionsLink.addClass("active").removeClass("loading");
$(data).insertAfter(bottomBar.children(".show_comments").first()); $(data).insertAfter(bottomBar.children(".show-comments").first());
self.showCommentBox(commentActionLink); self.showCommentBox(commentActionLink);
commentsContainer().find("time.timeago").timeago(); bottomBarContainer.getCommentsContainer().find("time.timeago").timeago();
bottomBarContainer.activate();
}, },
error: function() { error: function(){
toggleReactionsLink.removeClass("loading"); bottomBarContainer.deactivate();
} }
}).always(function(){
toggleReactionsLink.removeClass("loading");
bottomBarContainer.hideLoader();
}); });
}, },
commentsContainerLazy: function(bottomBar) { bottomBarLazy: function(bottomBar) {
return function() { return {
return bottomBar.find(".comment_container").first(); loader: function(){
return bottomBar.find(".ajax-loader");
},
getCommentsContainer: function(){
return bottomBar.find(".comment-container").first();
},
getShowCommentsLink: function(){
return bottomBar.find("a.show-comments");
},
showLoader: function(){
this.loader().removeClass("hidden");
},
hideLoader: function(){
this.loader().addClass("hidden");
},
activate: function(){
bottomBar.addClass("active").removeClass("inactive");
this.getShowCommentsLink().addClass("active");
this.getShowCommentsLink().find("i").removeClass("entypo-chevron-down").addClass("entypo-chevron-up");
},
deactivate: function(){
bottomBar.removeClass("active").addClass("inactive");
this.getShowCommentsLink().removeClass("active");
this.getShowCommentsLink().find("i").addClass("entypo-chevron-down").removeClass("entypo-chevron-up");
}
}; };
}, },
@ -121,72 +162,76 @@
}, },
showCommentBox: function(link){ showCommentBox: function(link){
if(!link.hasClass("inactive") || link.hasClass("loading")) { return; } var bottomBar = link.closest(".bottom-bar").first();
var self = this;
$.ajax({
url: link.attr("href"),
beforeSend: function(){
link.addClass("loading");
},
context: link,
success: function(data) {
self.appendCommentBox.call(this, link, data);
},
error: function() {
link.removeClass("loading");
}
});
},
appendCommentBox: function(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]; var textArea = bottomBar.find("textarea.comment_box").first()[0];
bottomBar.find(".add-comment-switcher").removeClass("hidden");
autosize(textArea); autosize(textArea);
}, },
updateStream: function(form, data) { updateStream: function(form, data) {
var bottomBar = form.closest(".bottom_bar").first(); var bottomBar = form.closest(".bottom-bar").first();
this.addNewComments(bottomBar, data); this.addNewComments(bottomBar, data);
this.updateCommentCount(bottomBar); this.updateCommentCount(bottomBar);
this.updateReactionCount(bottomBar); this.increaseReactionCount(bottomBar);
this.handleCommentShowing(form, bottomBar); this.handleCommentShowing(form, bottomBar);
bottomBar.find("time.timeago").timeago(); bottomBar.find("time.timeago").timeago();
}, },
addNewComments: function(bottomBar, data) { addNewComments: function(bottomBar, data) {
if ($(".comment_container", bottomBar).length === 0) { if ($(".comment-container", bottomBar).length === 0) {
$(".show_comments", bottomBar).after($("<div/>", {"class": "comment_container"})); $(".show-comments", bottomBar).after($("<div/>", {"class": "comment-container"}));
$(".comment_container", bottomBar).append($("<ul/>", {"class": "comments"})); $(".comment-container", bottomBar).append($("<ul/>", {"class": "comments"}));
} }
$(".comment_container .comments", bottomBar).append(data); $(".comment-container .comments", bottomBar).append(data);
}, },
// Fix for no comments // Fix for no comments
updateCommentCount: function(bottomBar) { updateCommentCount: function(bottomBar) {
var commentCount = bottomBar.find(".comment_count"); var commentCount = bottomBar.find(".comment-count");
commentCount.text(commentCount.text().replace(/(\d+)/, function (match) { commentCount.text(commentCount.text().replace(/(\d+)/, function (match) {
return parseInt(match) + 1; return parseInt(match, 10) + 1;
})); }));
}, },
// Fix for no reactions // Fix for no reactions
updateReactionCount: function(bottomBar) { increaseReactionCount: function(bottomBar) {
var toggleReactionsLink = bottomBar.find(".show_comments").first(); var toggleReactionsLink = bottomBar.find(".show-comments").first();
toggleReactionsLink.text(toggleReactionsLink.text().replace(/(\d+)/, function (match) { var count = toggleReactionsLink.text().match(/.*(\d+).*/);
return parseInt(match) + 1; var text = "";
}));
// No previous comment
if(!count){
text = Diaspora.I18n.t("stream.reactions", {count: 1});
var parent = toggleReactionsLink.parent();
var postGuid = bottomBar.parents(".stream_element").data("guid");
toggleReactionsLink.remove();
toggleReactionsLink = $("<a/>", {"class": "show-comments", "href": Routes.postComments(postGuid) + ".mobile"})
.html(text + "<i class='entypo-chevron-up'/>");
parent.prepend(toggleReactionsLink);
bottomBar.removeClass("inactive").addClass("active");
}
else {
count = parseInt(count, 10) + 1;
text = Diaspora.I18n.t("stream.reactions", {count: count});
toggleReactionsLink.html(text + "<i class='entypo-chevron-up'/>");
}
}, },
handleCommentShowing: function(form, bottomBar) { handleCommentShowing: function(form, bottomBar) {
var formContainer = form.parent(); var formContainer = form.parent();
formContainer.remove(); formContainer.find("textarea.form-control").first().val("");
this.resetCommentBox(formContainer);
var commentActionLink = bottomBar.find("a.comment-action").first(); var commentActionLink = bottomBar.find("a.comment-action").first();
commentActionLink.addClass("inactive"); commentActionLink.addClass("inactive");
var toggleReactionsLink = bottomBar.find(".show_comments").first(); this.showComments(bottomBar.find(".show-comments").first());
this.showComments(toggleReactionsLink); },
resetCommentBox: function(el){
var commentButton = el.find("input.comment-button").first();
commentButton.attr("value", commentButton.data("reset-with"));
commentButton.removeAttr("disabled");
commentButton.blur();
} }
}; };
})(); })();

View file

@ -14,7 +14,7 @@ $(document).ready(function(){
$("#new_status_message .counter").remove(); $("#new_status_message .counter").remove();
$.each(selectedServices, function() { $.each(selectedServices, function() {
serviceMaxChars = parseInt($(this).attr("maxchar")); serviceMaxChars = parseInt($(this).attr("maxchar"), 10);
if(publisherMaxChars > serviceMaxChars) { if(publisherMaxChars > serviceMaxChars) {
publisherMaxChars = serviceMaxChars; publisherMaxChars = serviceMaxChars;
} }

View file

@ -10,9 +10,11 @@ $background-grey: #eee;
$background-blue: #e7f2f7; $background-blue: #e7f2f7;
$grey: #2b2b2b; $grey: #2b2b2b;
$medium-gray: #ccc;
$light-grey: #ddd; $light-grey: #ddd;
$border-grey: $light-grey; $border-grey: $light-grey;
$border-medium-grey: $medium-gray;
$border-dark-grey: $text-grey; $border-dark-grey: $text-grey;
$link-grey: #777; $link-grey: #777;

View file

@ -1,4 +1,4 @@
.bottom_bar { .bottom-bar {
border-radius: 0 0 5px 5px; border-radius: 0 0 5px 5px;
z-index: 3; z-index: 3;
display: block; display: block;
@ -8,44 +8,99 @@
margin-top: 10px; margin-top: 10px;
border-top: 1px solid $border-grey; border-top: 1px solid $border-grey;
min-height: 22px; min-height: 22px;
overflow: hidden;
> a, .show_comments { > a,
.show-comments,
.show-comments > [class^="entypo"] {
@include transition(color); @include transition(color);
color: $text-grey; color: $text-grey;
font-weight: bold; font-weight: bold;
} }
.show_comments { .show-comments {
position: relative; position: relative;
top: 3px; top: 3px;
}
a.show_comments.active:not(.bottom_collapse) { > [class^="entypo"] { margin-left: .5em; }
color: $text;
padding-right: 14px; &:hover,
background: { &:active,
image: image-url("mobile/arrow_down_small.png"); &:focus {
position: center right; outline: none;
repeat: no-repeat; text-decoration: none;
}
&.active:not(.bottom_collapse),
&.active:not(.bottom_collapse) > [class^="entypo"] {
color: $text;
} }
} }
.floater { .post-stats {
top: -5px; top: -5px;
float: right; float: right;
height: 28px;
overflow: hidden;
position: relative; position: relative;
display: flex;
margin-bottom: -15px;
.count {
background-color: $background-grey;
text-align: center;
z-index: 2;
}
.icon-count-group {
display: flex;
flex-flow: column;
justify-content: center;
margin: 0 7px;
}
[class^="entypo"] { [class^="entypo"] {
height: 90%;
margin: 0 4px;
color: $text-grey; color: $text-grey;
font-size: 24px; font-size: 24px;
&:hover, &:active, &:focus{ text-decoration: none; } height: 28px;
&:last-child { margin-right: 1px; } margin: 0;
&.entypo-reshare.active { color: $blue; } width: 100%;
&.entypo-heart.active { color: $red; }
} }
[class^="entypo"]:hover,
[class^="entypo"]:active,
[class^="entypo"]:focus {
text-decoration: none;
}
.entypo-reshare.active { color: $blue; }
.entypo-heart.active { color: $red; }
}
.post-action {
height: 28px;
.disabled { color: $medium-gray; }
}
.add-comment-switcher { padding-top: 10px; }
&.inactive .post-stats .count,
&.inactive .comment-container {
display: none;
}
}
.stream_element .comments {
margin: 0;
padding: 0;
width: 100%;
.content { padding: 0; }
.comment {
border-top: 1px solid $border-medium-grey;
padding: 10px 0 0;
&:first-child { padding-top: 20px; }
} }
} }

View file

@ -6,6 +6,7 @@
@import "_flash_messages"; @import "_flash_messages";
@import 'entypo'; @import 'entypo';
@import 'icons'; @import 'icons';
@import 'spinner';
@import "mobile/header"; @import "mobile/header";
@import "mobile/tags"; @import "mobile/tags";
@ -36,6 +37,8 @@ h3 { margin-top: 0; }
.clear { clear: both; } .clear { clear: both; }
#main { padding: 56px 10px 0 10px; } #main { padding: 56px 10px 0 10px; }
textarea { resize: vertical; }
.avatar { .avatar {
border-radius: 4px; border-radius: 4px;
} }
@ -93,6 +96,14 @@ h3 { margin-top: 0; }
z-index: 2; z-index: 2;
} }
.ajax-loader {
border-top: 1px solid $border-medium-grey;
margin-top: 10px;
padding-top: 10px;
text-align: center;
width: 100%;
}
.stream_element:not(.shield-active) .shield{ .stream_element:not(.shield-active) .shield{
display: none; display: none;
} }
@ -101,31 +112,6 @@ h3 { margin-top: 0; }
display: none; display: none;
} }
.new_comment {
padding: 10px;
}
.stream_element .comments {
width: 100%;
margin: 0;
top: 3px;
.content {
padding: 0;
}
.comment {
padding: {
top: 10px;
bottom: 5px;
}
}
}
.comment {
border: {
top: 1px solid #ccc; };
}
.login_error, .login_error,
.login_alert { .login_alert {
color: #DF0101; color: #DF0101;
@ -357,7 +343,7 @@ h3 { margin-top: 0; }
} }
} }
.bottom_bar { .bottom-bar {
position: static; position: static;
} }
} }
@ -423,34 +409,12 @@ select {
padding: 7px; padding: 7px;
} }
.new_comment {
padding: 10px 0;
padding-top: 20px;
}
.comment.add_comment_bottom_link_container { .comment.add_comment_bottom_link_container {
position: relative; position: relative;
text-align: center; text-align: center;
padding: 25px !important; padding: 25px !important;
} }
.post_stats {
position: absolute;
right: 8px;
top: 31px;
z-index: 2;
span {
color: $text-dark-grey;
font-weight: bold;
padding: 2px 7px;
margin: 5px 6px;
background: {
color: $background-grey;
}
}
}
.additional_photo_count { .additional_photo_count {
opacity: 0.5; opacity: 0.5;

View file

@ -10,7 +10,11 @@ module MobileHelper
link_to "", reshares_path(root_guid: absolute_root.guid), link_to "", reshares_path(root_guid: absolute_root.guid),
title: t("reshares.reshare.reshare_confirmation", author: absolute_root.author_name), title: t("reshares.reshare.reshare_confirmation", author: absolute_root.author_name),
class: "entypo-reshare reshare-action #{klass}" class: "entypo-reshare reshare-action #{klass}"
else
content_tag :div, nil, class: "entypo-reshare reshare-action disabled"
end end
else
content_tag :div, nil, class: "entypo-reshare reshare-action disabled"
end end
end end
@ -26,14 +30,19 @@ module MobileHelper
link_to "", new_post_comment_path(post), class: "entypo-comment comment-action inactive" link_to "", new_post_comment_path(post), class: "entypo-comment comment-action inactive"
end end
def reactions_link(post) def reactions_link(post, klass="")
reactions_count = post.comments_count + post.likes_count reactions_count = post.comments_count + post.likes_count
if reactions_count > 0 if klass == "active"
link_to "#{t('reactions', count: reactions_count)}", entypo_class = "entypo-chevron-up"
post_comments_path(post, format: "mobile"),
class: "show_comments"
else else
html = "<span class='show_comments'>" entypo_class = "entypo-chevron-down"
end
if reactions_count > 0
link_to "#{t('reactions', count: reactions_count)}<i class='#{entypo_class}'></i>".html_safe,
post_comments_path(post, format: "mobile"),
class: "show-comments #{klass}"
else
html = "<span class='show-comments'>"
html << "#{t('reactions', count: reactions_count)}" html << "#{t('reactions', count: reactions_count)}"
html << "</span>" html << "</span>"
end end

View file

@ -3,13 +3,13 @@
-# the COPYRIGHT file. -# the COPYRIGHT file.
.add_comment_bottom_link_container .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? - 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 %fieldset
= hidden_field_tag :post_id, post_id, id: "post_id_on_#{post_id}" = hidden_field_tag :post_id, post_id, id: "post-id-on-#{post_id}"
.form-group .form-group.clearfix
= text_area_tag :text, nil, class: "col-md-12 comment_box form-control form-group", id: "comment_text_on_#{post_id}", placeholder: t(".comment") = text_area_tag :text, nil, class: "col-md-12 comment_box form-control",
= submit_tag t(".comment"), :id => "comment_submit_#{post_id}", "data-disable-with" => t(".commenting"), :class => "btn btn-primary btn-block" id: "comment-text-on-#{post_id}", placeholder: t(".comment")
= submit_tag t(".comment"), :id => "comment-submit-#{post_id}", "data-disable-with" => t(".commenting"),
"data-reset-with" => t(".comment"), :class => "btn btn-primary btn-block comment-button"

View file

@ -0,0 +1,13 @@
.post-stats
- if post.public?
.icon-count-group
.post-action= mobile_reshare_icon(post)
%span.reshare-count.count= post.reshares.size
.icon-count-group
.post-action= mobile_comment_icon(post)
%span.comment-count.count= post.comments.size
.icon-count-group
.post-action= mobile_like_icon(post)
%span.like-count.count= post.likes.size

View file

@ -1 +1,3 @@
= render :partial => 'shared/post_stats', :locals => { :post => @post} .comment-container
%ul.comments
= render partial: "comments/comment", collection: @post.comments.for_a_stream, locals: {post: @post}

View file

@ -1 +1 @@
= render :partial => 'new_comment', :locals =>{:post_id => params[:post_id]} = render partial: "new_comment", locals: {post_id: params[:post_id]}

View file

@ -1,7 +1,7 @@
.nav.navbar-inverse.navbar-fixed-top#main-nav .nav.navbar-inverse.navbar-fixed-top#main-nav
.container-fluid .container-fluid
.navbar .navbar
= link_to(image_tag("mobile/asterisk_white_mobile.png", class: "img-responsive"), = link_to(image_tag("branding/logos/asterisk_white_mobile.png", class: "img-responsive"),
stream_path, id: "header-title", class: "navbar-brand") stream_path, id: "header-title", class: "navbar-brand")
- if user_signed_in? - if user_signed_in?

View file

@ -12,7 +12,7 @@
- if user_signed_in? && @person != current_user.person - if user_signed_in? && @person != current_user.person
= render 'aspect_memberships/aspect_membership_dropdown' = render 'aspect_memberships/aspect_membership_dropdown'
.clear .clear
.bottom_bar .bottom-bar
- if !@person.tag_string.blank? && user_signed_in? - if !@person.tag_string.blank? && user_signed_in?
= Diaspora::Taggable.format_tags(@person.tag_string) = Diaspora::Taggable.format_tags(@person.tag_string)
.row .row

View file

@ -1,14 +0,0 @@
.comment_container
.post_stats
- if @post.public?
%span.reshare_count
= @post.reshares.size
%span.comment_count
= @post.comments.size
%span.like_count
= @post.likes.size
%ul.comments
= render partial: "comments/comment", collection: @post.comments.for_a_stream, locals: {post: @post}

View file

@ -2,6 +2,4 @@
-# licensed under the Affero General Public License version 3 or later. See -# licensed under the Affero General Public License version 3 or later. See
-# the COPYRIGHT file. -# the COPYRIGHT file.
= render :partial => 'shared/stream_element', = render partial: "shared/stream_element", collection: posts, as: :post
:collection => posts,
:as => :post

View file

@ -19,13 +19,21 @@
- if post.is_a?(StatusMessage) - if post.is_a?(StatusMessage)
= render "status_messages/status_message", post: post, photos: post.photos = render "status_messages/status_message", post: post, photos: post.photos
.bottom_bar.nsfw-hidden .bottom-bar.nsfw-hidden{class: ("inactive" unless defined?(expanded_info) && expanded_info)}
.floater = render partial: "comments/post_stats", locals: {post: post}
= mobile_reshare_icon(post)
= mobile_comment_icon(post)
= mobile_like_icon(post)
!= reactions_link(post)
- if defined?(expanded_info) && expanded_info - if defined?(expanded_info) && expanded_info
= render partial: "shared/post_stats", locals: {post: @post} != reactions_link(post, "active")
.comment-container
%ul.comments
= render partial: "comments/comment", collection: @post.comments.for_a_stream, locals: {post: @post}
- else
!= reactions_link(post)
.ajax-loader.hidden
.loader
.spinner
.add-comment-switcher{class: ("hidden" unless defined?(expanded_info) && expanded_info)}
= render partial: "comments/new_comment", locals: {post_id: post.id}

View file

@ -259,6 +259,11 @@ en:
stop_following_confirm: "Stop following #<%= tag %>?" stop_following_confirm: "Stop following #<%= tag %>?"
follow_error: "Couldnt follow #<%= tag %> :(" follow_error: "Couldnt follow #<%= tag %> :("
stop_following_error: "Couldnt stop following #<%= tag %> :(" stop_following_error: "Couldnt stop following #<%= tag %> :("
reactions:
zero: "<%= count%> reactions"
one: "<%= count%> reaction"
other: "<%= count%> reactions"
header: header:
home: "Home" home: "Home"

View file

@ -17,5 +17,5 @@ Feature: Browsing Diaspora as a logged out user mobile
Scenario: Visiting a profile page Scenario: Visiting a profile page
When I am on "bob@bob.bob"'s page When I am on "bob@bob.bob"'s page
Then I should see "public stuff" within ".ltr" Then I should see "public stuff" within ".ltr"
And I click on selector "a.show_comments" And I click on selector "a.show-comments"
And I should see "this also" within ".comment" And I should see "this also" within ".comment"

View file

@ -14,26 +14,26 @@ Feature: reactions mobile post
And I sign in as "bob@bob.bob" on the mobile website And I sign in as "bob@bob.bob" on the mobile website
Scenario: like on a mobile post Scenario: like on a mobile post
When I should see "No reactions" within ".show_comments" When I should see "No reactions" within ".show-comments"
And I click on selector "span.show_comments" And I click on selector "span.show-comments"
And I click on selector "a.like-action.inactive" And I click on selector "a.like-action.inactive"
Then I should see a "a.like-action.active" Then I should see a "a.like-action.active"
When I go to the stream page When I go to the stream page
And I should see "1 reaction" within ".show_comments" And I should see "1 reaction" within ".show-comments"
And I click on selector "a.show_comments" And I click on selector "a.show-comments"
Then I should see "1" within ".like_count" Then I should see "1" within ".like-count"
Scenario: comment and delete a mobile post Scenario: comment and delete a mobile post
When I click on selector "a.comment-action.inactive" When I click on selector "a.comment-action.inactive"
And I fill in the following: And I fill in the following:
| text | is that a poodle? | | text | is that a poodle? |
And I press "Comment" And I press "Comment"
Then I should see "is that a poodle?" within ".comment_container" Then I should see "is that a poodle?" within ".comment-container"
When I go to the stream page When I go to the stream page
And I should see "1 reaction" within ".show_comments" And I should see "1 reaction" within ".show-comments"
And I click on selector "a.show_comments" And I click on selector "a.show-comments"
And I should see "1" within ".comment_count" And I should see "1" within ".comment-count"
When I click on selector "a.comment-action" When I click on selector "a.comment-action"
And I click on selector "a.remove" And I click on selector "a.remove"
And I confirm the alert And I confirm the alert
Then I should not see "1 reaction" within ".show_comments" Then I should not see "1 reaction" within ".show-comments"

View file

@ -16,18 +16,18 @@ Feature: resharing from the mobile
And I sign in as "alice@alice.alice" And I sign in as "alice@alice.alice"
Scenario: Resharing a post from a single post page Scenario: Resharing a post from a single post page
And I click on selector "a.reshare-action.inactive" And I click on selector ".reshare-action.inactive"
And I confirm the alert And I confirm the alert
Then I should see a "a.reshare-action.active" Then I should see a ".reshare-action.active"
When I go to the stream page When I go to the stream page
Then I should see "Reshared via" within ".reshare_via" Then I should see "Reshared via" within ".reshare_via"
Scenario: Resharing a post from a single post page that is reshared Scenario: Resharing a post from a single post page that is reshared
Given the post with text "reshare this!" is reshared by "eve@eve.eve" Given the post with text "reshare this!" is reshared by "eve@eve.eve"
And a user with email "alice@alice.alice" is connected with "eve@eve.eve" And a user with email "alice@alice.alice" is connected with "eve@eve.eve"
And I click on the first selector "a.reshare-action.inactive" And I click on the first selector ".reshare-action.inactive"
And I confirm the alert And I confirm the alert
Then I should see a "a.reshare-action.active" Then I should see a ".reshare-action.active"
When I go to the stream page When I go to the stream page
Then I should see "Reshared via" within ".reshare_via" Then I should see "Reshared via" within ".reshare_via"
@ -45,3 +45,12 @@ Feature: resharing from the mobile
And I sign in as "eve@eve.eve" on the mobile website And I sign in as "eve@eve.eve" on the mobile website
And I toggle the mobile view And I toggle the mobile view
Then I should see "Original post deleted by author" within ".reshare" Then I should see "Original post deleted by author" within ".reshare"
Scenario: Not resharing own post
Given I sign in as "bob@bob.bob"
Then I should see a ".reshare-action.disabled"
When I click on selector ".reshare-action"
Then I should not see any alert
And I should not see a ".reshare-action.active"
When I go to the stream page
Then I should not see a ".reshare_via"

View file

@ -142,6 +142,10 @@ And /^I reject the alert$/ do
page.driver.browser.switch_to.alert.dismiss page.driver.browser.switch_to.alert.dismiss
end end
And /^I should not see any alert$/ do
expect { page.driver.browser.switch_to.alert }.to raise_error(Selenium::WebDriver::Error::NoAlertPresentError)
end
When /^(.*) in the mention modal$/ do |action| When /^(.*) in the mention modal$/ do |action|
within('#mentionModal') do within('#mentionModal') do
step action step action

View file

@ -2,7 +2,7 @@ describe("Diaspora.Mobile.Comments", function(){
describe("toggleComments", function() { describe("toggleComments", function() {
beforeEach(function() { beforeEach(function() {
spec.loadFixture("aspects_index_mobile_post_with_comments"); spec.loadFixture("aspects_index_mobile_post_with_comments");
this.link = $(".stream .show_comments").first(); this.link = $(".stream .show-comments").first();
spyOn(Diaspora.Mobile.Comments, "showComments"); spyOn(Diaspora.Mobile.Comments, "showComments");
spyOn(Diaspora.Mobile.Comments, "hideComments"); spyOn(Diaspora.Mobile.Comments, "hideComments");
}); });
@ -31,27 +31,27 @@ describe("Diaspora.Mobile.Comments", function(){
describe("showUnloadedComments", function() { describe("showUnloadedComments", function() {
beforeEach(function() { beforeEach(function() {
spec.loadFixture("aspects_index_mobile_post_with_comments"); spec.loadFixture("aspects_index_mobile_post_with_comments");
this.link = $(".stream .show_comments").first(); this.link = $(".stream .show-comments").first();
this.bottomBar = this.link.closest(".bottom_bar").first(); this.bottomBar = this.link.closest(".bottom-bar").first();
this.commentActionLink = this.bottomBar.find("a.comment-action"); this.commentActionLink = this.bottomBar.find("a.comment-action");
}); });
it("adds the 'loading' class to the link", function() { it("adds the 'loading' class to the link", function() {
Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink); Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
expect($(".show_comments").first()).toHaveClass("loading"); expect($(".show-comments").first()).toHaveClass("loading");
}); });
it("removes the 'loading' class if the request failed", function() { it("removes the 'loading' class if the request failed", function() {
Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink); Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
jasmine.Ajax.requests.mostRecent().respondWith({status: 400}); jasmine.Ajax.requests.mostRecent().respondWith({status: 400});
expect($(".show_comments").first()).not.toHaveClass("loading"); expect($(".show-comments").first()).not.toHaveClass("loading");
}); });
it("adds the 'active' class if the request succeeded", function() { it("adds the 'active' class if the request succeeded", function() {
Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink); Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
jasmine.Ajax.requests.mostRecent().respondWith({status: 200, contentType: "text/plain", responseText: "test"}); jasmine.Ajax.requests.mostRecent().respondWith({status: 200, contentType: "text/plain", responseText: "test"});
expect($(".show_comments").first()).toHaveClass("active"); expect($(".show-comments").first()).toHaveClass("active");
expect($(".show_comments").first()).not.toHaveClass("loading"); expect($(".show-comments").first()).not.toHaveClass("loading");
}); });
it("calls showCommentBox", function() { it("calls showCommentBox", function() {
@ -70,50 +70,12 @@ describe("Diaspora.Mobile.Comments", function(){
}); });
expect($(".stream .stream_element").first()).toContainElement(".commentContainerForTest"); expect($(".stream .stream_element").first()).toContainElement(".commentContainerForTest");
}); });
});
describe("showCommentBox", function() { it("shows and hides the mobile spinner", function(){
beforeEach(function() { Diaspora.Mobile.Comments.showComments(this.link);
spec.loadFixture("aspects_index_mobile_post_with_comments"); expect($(".ajax-loader").first()).toBeVisible();
this.link = $(".stream .comment-action").first();
});
it("adds the 'loading' class to the link", function() {
Diaspora.Mobile.Comments.showCommentBox(this.link);
expect($(".comment-action").first()).toHaveClass("loading");
});
it("removes the 'loading' class if the request failed", function() {
Diaspora.Mobile.Comments.showCommentBox(this.link);
jasmine.Ajax.requests.mostRecent().respondWith({status: 400});
expect($(".comment-action").first()).not.toHaveClass("loading");
});
it("fires an AJAX call", function() {
spyOn(jQuery, "ajax");
Diaspora.Mobile.Comments.showCommentBox(this.link);
expect(jQuery.ajax).toHaveBeenCalled();
});
it("calls appendCommentBox", function() {
spyOn(Diaspora.Mobile.Comments, "appendCommentBox");
Diaspora.Mobile.Comments.showCommentBox(this.link);
jasmine.Ajax.requests.mostRecent().respondWith({status: 200, contentType: "text/plain", responseText: "test"}); jasmine.Ajax.requests.mostRecent().respondWith({status: 200, contentType: "text/plain", responseText: "test"});
expect(Diaspora.Mobile.Comments.appendCommentBox).toHaveBeenCalledWith(this.link, "test"); expect($(".ajax-loader").first()).not.toBeVisible();
});
it("doesn't do anything if the link class is 'loading'", function() {
spyOn(jQuery, "ajax");
this.link.addClass("loading");
Diaspora.Mobile.Comments.showCommentBox(this.link);
expect(jQuery.ajax).not.toHaveBeenCalled();
});
it("doesn't do anything if the link class is not 'inactive'", function() {
spyOn(jQuery, "ajax");
this.link.removeClass("inactive");
Diaspora.Mobile.Comments.showCommentBox(this.link);
expect(jQuery.ajax).not.toHaveBeenCalled();
}); });
}); });
@ -138,4 +100,71 @@ describe("Diaspora.Mobile.Comments", function(){
expect(jQuery.ajax).not.toHaveBeenCalled(); expect(jQuery.ajax).not.toHaveBeenCalled();
}); });
}); });
describe("increaseReactionCount", function(){
beforeEach(function() {
spec.loadFixture("aspects_index_mobile_post_with_comments");
this.bottomBar = $(".bottom-bar").first();
this.toggleReactionsLink = this.bottomBar.find(".show-comments").first();
});
it("Increase reaction count from 1", function(){
expect(this.toggleReactionsLink.text().trim()).toBe("5 reactions");
Diaspora.Mobile.Comments.increaseReactionCount(this.bottomBar);
expect(this.toggleReactionsLink.text().trim()).toBe("6 reactions");
});
it("Creates the reaction link when no reactions", function(){
var parent = this.toggleReactionsLink.parent();
var postGuid = this.bottomBar.parents(".stream_element").data("guid");
this.toggleReactionsLink.remove();
parent.prepend($("<span/>", {"class": "show-comments"}).text("No reaction"));
Diaspora.Mobile.Comments.increaseReactionCount(this.bottomBar);
this.toggleReactionsLink = this.bottomBar.find(".show-comments").first();
expect(this.toggleReactionsLink.text().trim()).toBe("1 reaction");
expect(this.toggleReactionsLink.attr("href")).toBe("/posts/" + postGuid + "/comments.mobile");
});
});
describe("bottomBarLazy", function(){
beforeEach(function() {
spec.loadFixture("aspects_index_mobile_post_with_comments");
this.bottomBar = $(".bottom-bar").first();
this.bottomBarLazy = Diaspora.Mobile.Comments.bottomBarLazy(this.bottomBar);
});
it("shows and hides the loader", function(){
expect(this.bottomBarLazy.loader()).toHaveClass("hidden");
this.bottomBarLazy.showLoader();
expect(this.bottomBarLazy.loader()).not.toHaveClass("hidden");
this.bottomBarLazy.hideLoader();
expect(this.bottomBarLazy.loader()).toHaveClass("hidden");
});
it("activates the bottom bar", function(){
expect(this.bottomBar).toHaveClass("inactive");
expect(this.bottomBar).not.toHaveClass("active");
expect(this.bottomBarLazy.getShowCommentsLink()).not.toHaveClass("active");
expect(this.bottomBarLazy.getShowCommentsLink().find("i")).toHaveClass("entypo-chevron-down");
this.bottomBarLazy.activate();
expect(this.bottomBar).not.toHaveClass("inactive");
expect(this.bottomBar).toHaveClass("active");
expect(this.bottomBarLazy.getShowCommentsLink()).toHaveClass("active");
expect(this.bottomBarLazy.getShowCommentsLink().find("i")).toHaveClass("entypo-chevron-up");
});
it("deactivates the bottom bar", function(){
this.bottomBarLazy.activate();
expect(this.bottomBar).not.toHaveClass("inactive");
expect(this.bottomBar).toHaveClass("active");
expect(this.bottomBarLazy.getShowCommentsLink()).toHaveClass("active");
expect(this.bottomBarLazy.getShowCommentsLink().find("i")).toHaveClass("entypo-chevron-up");
this.bottomBarLazy.deactivate();
expect(this.bottomBar).toHaveClass("inactive");
expect(this.bottomBar).not.toHaveClass("active");
expect(this.bottomBarLazy.getShowCommentsLink()).not.toHaveClass("active");
expect(this.bottomBarLazy.getShowCommentsLink().find("i")).toHaveClass("entypo-chevron-down");
});
});
}); });