Skip to content
Extraits de code Groupes Projets
Valider 05e87b31 rédigé par Jonne Haß's avatar Jonne Haß
Parcourir les fichiers

Merge pull request #6363 from svbergerem/mobile-view-multiple-reaction-boxes

Mobile view multiple reaction boxes
parents 1dee5429 696eebbe
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -57,6 +57,7 @@ With the port to Bootstrap 3, app/views/terms/default.haml has a new structure. ...@@ -57,6 +57,7 @@ With the port to Bootstrap 3, app/views/terms/default.haml has a new structure.
* Improve accessibility of a couple pages [#6227](https://github.com/diaspora/diaspora/pull/6227) * Improve accessibility of a couple pages [#6227](https://github.com/diaspora/diaspora/pull/6227)
* Capitalize "Powered by diaspora" [#6254](https://github.com/diaspora/diaspora/pull/6254) * Capitalize "Powered by diaspora" [#6254](https://github.com/diaspora/diaspora/pull/6254)
* Display username and avatar for NSFW posts in mobile view [#6245](https://github.com/diaspora/diaspora/6245) * Display username and avatar for NSFW posts in mobile view [#6245](https://github.com/diaspora/diaspora/6245)
* Prevent multiple comment boxes on mobile [#6363](https://github.com/diaspora/diaspora/pull/6363)
## Features ## Features
* Support color themes [#6033](https://github.com/diaspora/diaspora/pull/6033) * Support color themes [#6033](https://github.com/diaspora/diaspora/pull/6033)
......
...@@ -77,9 +77,12 @@ Diaspora.I18n = { ...@@ -77,9 +77,12 @@ Diaspora.I18n = {
reset: function() { reset: function() {
this.locale.data = {}; this.locale.data = {};
this.locale.fallback.data = {};
if( arguments.length > 0 && !(_.isEmpty(arguments[0])) ) if(arguments.length > 0 && !(_.isEmpty(arguments[0]))) {
this.locale.data = arguments[0]; this.locale.data = arguments[0];
this.locale.fallback.data = arguments[0];
}
} }
}; };
// @license-end // @license-end
......
...@@ -4,162 +4,180 @@ ...@@ -4,162 +4,180 @@
* the COPYRIGHT file. * the COPYRIGHT file.
*/ */
$(document).ready(function() { (function() {
Diaspora.Mobile = {};
Diaspora.Mobile.Comments = {
initialize: function() {
var self = this;
$(".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({
scrollTop: streamElement.offset().top - 54
}, 1000);
});
$(".stream").on("tap click", "a.back_to_stream_element_top", function() { $(".stream").on("tap click", "a.show_comments", function(evt){
var bottomBar = $(this).closest(".bottom_bar").first(); evt.preventDefault();
var streamElement = bottomBar.parent(); self.toggleComments($(this));
$("html, body").animate({ });
scrollTop: streamElement.offset().top - 54
}, 1000); $(".stream").on("tap click", "a.comment-action", function(evt) {
}); evt.preventDefault();
self.showCommentBox($(this));
$(".stream").on("tap click", "a.show_comments", function(evt){ var bottomBar = $(this).closest(".bottom_bar").first();
evt.preventDefault(); var commentContainer = bottomBar.find(".comment_container").first();
toggleComments($(this)); self.scrollToOffset(commentContainer);
}); });
function toggleComments(toggleReactionsLink) { $(".stream").on("submit", ".new_comment", function(evt) {
if (toggleReactionsLink.hasClass("active")) { evt.preventDefault();
hideComments(toggleReactionsLink); var form = $(this);
} else { $.post(form.attr("action")+"?format=mobile", form.serialize(), function(data) {
showComments(toggleReactionsLink); self.updateStream(form, data);
} }, "html");
} });
},
function hideComments(toggleReactionsLink) {
var bottomBar = toggleReactionsLink.closest(".bottom_bar").first(), toggleComments: function(toggleReactionsLink) {
commentsContainer = commentsContainerLazy(bottomBar), if(toggleReactionsLink.hasClass("loading")) { return; }
existingCommentsContainer = commentsContainer(); if (toggleReactionsLink.hasClass("active")) {
existingCommentsContainer.hide(); this.hideComments(toggleReactionsLink);
toggleReactionsLink.removeClass("active"); } else {
} this.showComments(toggleReactionsLink);
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();
} }
}); },
}
hideComments: function(toggleReactionsLink) {
function commentsContainerLazy(bottomBar) { var bottomBar = toggleReactionsLink.closest(".bottom_bar").first(),
return function() { commentsContainer = this.commentsContainerLazy(bottomBar),
return bottomBar.find(".comment_container").first(); existingCommentsContainer = commentsContainer();
}; existingCommentsContainer.hide();
} toggleReactionsLink.removeClass("active");
},
$(".stream").on("tap click", "a.comment-action", function(evt) {
evt.preventDefault(); showComments: function(toggleReactionsLink) {
showCommentBox(this); var bottomBar = toggleReactionsLink.closest(".bottom_bar").first(),
var bottomBar = $(this).closest(".bottom_bar").first(); commentsContainer = this.commentsContainerLazy(bottomBar),
var commentContainer = bottomBar.find(".comment_container").first(); existingCommentsContainer = commentsContainer(),
scrollToOffset(commentContainer); commentActionLink = bottomBar.find("a.comment-action");
}); if (existingCommentsContainer.length > 0) {
var scrollToOffset = function(commentsContainer){ this.showLoadedComments(toggleReactionsLink, existingCommentsContainer, commentActionLink);
var commentCount = commentsContainer.find("li.comment").length; } else {
if ( commentCount > 3 ) { this.showUnloadedComments(toggleReactionsLink, bottomBar, commentActionLink);
var lastComment = commentsContainer.find("li:nth-child("+(commentCount-3)+")"); }
$("html,body").animate({ },
scrollTop: lastComment.offset().top
}, 1000); showLoadedComments: function(toggleReactionsLink, existingCommentsContainer, commentActionLink) {
} toggleReactionsLink.addClass("active");
}; existingCommentsContainer.show();
this.showCommentBox(commentActionLink);
existingCommentsContainer.find("time.timeago").timeago();
},
showUnloadedComments: function(toggleReactionsLink, bottomBar, commentActionLink) {
toggleReactionsLink.addClass("loading");
var commentsContainer = this.commentsContainerLazy(bottomBar);
var self = this;
$.ajax({
url: toggleReactionsLink.attr("href"),
success: function (data) {
toggleReactionsLink.addClass("active").removeClass("loading");
$(data).insertAfter(bottomBar.children(".show_comments").first());
self.showCommentBox(commentActionLink);
commentsContainer().find("time.timeago").timeago();
},
error: function() {
toggleReactionsLink.removeClass("loading");
}
});
},
commentsContainerLazy: function(bottomBar) {
return function() {
return bottomBar.find(".comment_container").first();
};
},
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);
}
},
function showCommentBox(link){ showCommentBox: function(link){
var commentActionLink = $(link); if(!link.hasClass("inactive") || link.hasClass("loading")) { return; }
if(commentActionLink.hasClass("inactive")) { var self = this;
$.ajax({ $.ajax({
url: commentActionLink.attr("href"), url: link.attr("href"),
beforeSend: function(){ beforeSend: function(){
commentActionLink.addClass("loading"); link.addClass("loading");
},
context: link,
success: function(data) {
self.appendCommentBox.call(this, link, data);
}, },
context: commentActionLink, error: function() {
success: function(data){ link.removeClass("loading");
appendCommentBox.call(this, commentActionLink, data);
} }
}); });
},
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];
autosize(textArea);
},
updateStream: function(form, data) {
var bottomBar = form.closest(".bottom_bar").first();
this.addNewComments(bottomBar, data);
this.updateCommentCount(bottomBar);
this.updateReactionCount(bottomBar);
this.handleCommentShowing(form, bottomBar);
bottomBar.find("time.timeago").timeago();
},
addNewComments: function(bottomBar, data) {
var commentsContainer = bottomBar.find(".comment_container").first();
var comments = commentsContainer.find(".comments").first();
comments.append(data);
},
// Fix for no comments
updateCommentCount: function(bottomBar) {
var commentCount = bottomBar.find(".comment_count");
commentCount.text(commentCount.text().replace(/(\d+)/, function (match) {
return parseInt(match) + 1;
}));
},
// Fix for no reactions
updateReactionCount: function(bottomBar) {
var toggleReactionsLink = bottomBar.find(".show_comments").first();
toggleReactionsLink.text(toggleReactionsLink.text().replace(/(\d+)/, function (match) {
return parseInt(match) + 1;
}));
},
handleCommentShowing: function(form, bottomBar) {
var formContainer = form.parent();
formContainer.remove();
var commentActionLink = bottomBar.find("a.comment-action").first();
commentActionLink.addClass("inactive");
var toggleReactionsLink = bottomBar.find(".show_comments").first();
this.showComments(toggleReactionsLink);
} }
} };
})();
function appendCommentBox(link, data) {
link.removeClass("loading"); $(document).ready(function() {
link.removeClass("inactive"); Diaspora.Mobile.Comments.initialize();
var bottomBar = link.closest(".bottom_bar").first();
bottomBar.append(data);
var textArea = bottomBar.find("textarea.comment_box").first()[0];
autosize(textArea);
}
$(".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);
handleCommentShowing(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 handleCommentShowing(form, bottomBar) {
var formContainer = form.parent();
formContainer.remove();
var commentActionLink = bottomBar.find("a.comment-action").first();
commentActionLink.addClass("inactive");
var toggleReactionsLink = bottomBar.find(".show_comments").first();
showComments(toggleReactionsLink);
}
}); });
...@@ -58,6 +58,13 @@ describe StreamsController, :type => :controller do ...@@ -58,6 +58,13 @@ describe StreamsController, :type => :controller do
save_fixture(html_for("body"), "aspects_index_post_with_comments") save_fixture(html_for("body"), "aspects_index_post_with_comments")
end end
it "generates a mobile jasmine fixture with a post with comments", fixture: true do
message = bob.post(:status_message, text: "HALO WHIRLED", to: @bob.aspects.where(name: "generic").first.id)
5.times { bob.comment!(message, "what") }
get :aspects, format: :mobile
save_fixture(html_for("body"), "aspects_index_mobile_post_with_comments")
end
it 'generates a jasmine fixture with a followed tag', :fixture => true do it 'generates a jasmine fixture with a followed tag', :fixture => true do
@tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent") @tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent")
TagFollowing.create!(:tag => @tag, :user => alice) TagFollowing.create!(:tag => @tag, :user => alice)
......
describe("Diaspora.Mobile.Comments", function(){
describe("toggleComments", function() {
beforeEach(function() {
spec.loadFixture("aspects_index_mobile_post_with_comments");
this.link = $(".stream .show_comments").first();
spyOn(Diaspora.Mobile.Comments, "showComments");
spyOn(Diaspora.Mobile.Comments, "hideComments");
});
it("calls showComments", function() {
Diaspora.Mobile.Comments.toggleComments(this.link);
expect(Diaspora.Mobile.Comments.showComments).toHaveBeenCalled();
expect(Diaspora.Mobile.Comments.hideComments).not.toHaveBeenCalled();
});
it("calls hideComments if the link class is 'active'", function() {
this.link.addClass("active");
Diaspora.Mobile.Comments.toggleComments(this.link);
expect(Diaspora.Mobile.Comments.showComments).not.toHaveBeenCalled();
expect(Diaspora.Mobile.Comments.hideComments).toHaveBeenCalled();
});
it("doesn't call any function if the link class is 'loading'", function() {
this.link.addClass("loading");
Diaspora.Mobile.Comments.toggleComments(this.link);
expect(Diaspora.Mobile.Comments.showComments).not.toHaveBeenCalled();
expect(Diaspora.Mobile.Comments.hideComments).not.toHaveBeenCalled();
});
});
describe("showUnloadedComments", function() {
beforeEach(function() {
spec.loadFixture("aspects_index_mobile_post_with_comments");
this.link = $(".stream .show_comments").first();
this.bottomBar = this.link.closest(".bottom_bar").first();
this.commentActionLink = this.bottomBar.find("a.comment-action");
});
it("adds the 'loading' class to the link", function() {
Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
expect($(".show_comments").first()).toHaveClass("loading");
});
it("removes the 'loading' class if the request failed", function() {
Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
jasmine.Ajax.requests.mostRecent().respondWith({status: 400});
expect($(".show_comments").first()).not.toHaveClass("loading");
});
it("adds the 'active' class if the request succeeded", function() {
Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
jasmine.Ajax.requests.mostRecent().respondWith({status: 200, contentType: "text/plain", responseText: "test"});
expect($(".show_comments").first()).toHaveClass("active");
expect($(".show_comments").first()).not.toHaveClass("loading");
});
it("calls showCommentBox", function() {
spyOn(Diaspora.Mobile.Comments, "showCommentBox");
Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
jasmine.Ajax.requests.mostRecent().respondWith({status: 200, contentType: "text/plain", responseText: "test"});
expect(Diaspora.Mobile.Comments.showCommentBox).toHaveBeenCalledWith(this.commentActionLink);
});
it("adds the response text to the comments list", function() {
Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: "text/plain",
responseText: "<div class=\"commentContainerForTest\">new comments</div>"
});
expect($(".stream .stream_element").first()).toContainElement(".commentContainerForTest");
});
});
describe("showCommentBox", function() {
beforeEach(function() {
spec.loadFixture("aspects_index_mobile_post_with_comments");
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"});
expect(Diaspora.Mobile.Comments.appendCommentBox).toHaveBeenCalledWith(this.link, "test");
});
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();
});
});
});
...@@ -90,6 +90,7 @@ describe("Diaspora.I18n", function() { ...@@ -90,6 +90,7 @@ describe("Diaspora.I18n", function() {
Diaspora.I18n.load(locale, "en", locale); Diaspora.I18n.load(locale, "en", locale);
Diaspora.I18n.reset(); Diaspora.I18n.reset();
expect(Diaspora.I18n.locale.data).toEqual({}); expect(Diaspora.I18n.locale.data).toEqual({});
expect(Diaspora.I18n.locale.fallback.data).toEqual({});
}); });
it("sets the locale to only a specific value", function() { it("sets the locale to only a specific value", function() {
...@@ -97,6 +98,7 @@ describe("Diaspora.I18n", function() { ...@@ -97,6 +98,7 @@ describe("Diaspora.I18n", function() {
Diaspora.I18n.load(locale, "en", locale); Diaspora.I18n.load(locale, "en", locale);
Diaspora.I18n.reset(data); Diaspora.I18n.reset(data);
expect(Diaspora.I18n.locale.data).toEqual(data); expect(Diaspora.I18n.locale.data).toEqual(data);
expect(Diaspora.I18n.locale.fallback.data).toEqual(data);
}); });
}); });
}); });
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