fix DOM structure when replying to or updating comments

This commit is contained in:
Serge Paquet 2014-01-15 21:21:05 -05:00
parent 02a30c66b1
commit 41c9dfad5d
10 changed files with 113 additions and 102 deletions

View file

@ -141,14 +141,18 @@ var _Lobsters = Class.extend({
},
postComment: function(form) {
$(form).parent().load($(form).attr("action"), $(form).serializeArray());
$.post($(form).attr("action"), $(form).serializeArray(), function(data) {
$(form).closest('.comment').replaceWith($.parseHTML(data));
});
},
previewComment: function(form) {
$(form).parent().load($(form).attr("action").replace(/(post|update)/,
"preview"), $(form).serializeArray());
var action = $(form).attr("action").replace(/(post|update)/, "preview");
$.post(action, $(form).serializeArray(), function(data) {
$(form).closest('.comment').replaceWith($.parseHTML(data));
});
},
previewStory: function(form) {
$("#inside").load("/stories/preview", $(form).serializeArray());
},
@ -249,33 +253,28 @@ $(document).ready(function() {
return false;
}
var box = $(this).parents("li.comment").first().find("div.comment_reply").
first();
box.html($("#comment_form").clone());
box.find("ol").remove();
box.find("button.comment-preview").after("&nbsp;\n&nbsp;<button class=\"comment-cancel\" name=\"button\" type=\"button\">Cancel</button>");
box.find("textarea").focus();
var el = $("<input type=\"hidden\" " +
"name=\"parent_comment_short_id\" value=\"" +
$(this).parents("li.comment").first().attr("data-shortid") + "\">");
box.find("form").append(el);
var comment = $(this).closest(".comment");
var replies = comment.nextAll(".comments").first();
$.get("/comments/" + comment.attr("data-shortid") + "/reply",
function(data) {
var reply = $($.parseHTML(data));
replies.prepend(reply);
reply.find("textarea").focus();
});
return false;
});
$(document).on("click", "button.comment-cancel", function() {
$(this).parents("div.comment_reply form").remove();
$(this).closest(".comment").remove();
});
$(document).on("click", "a.comment_editor", function() {
var li = $(this).parents("li.comment").first();
li.load("/comments/" + $(li).attr("data-shortid") + "/edit",
{ "edit": 1 });
var comment = $(this).closest(".comment");
$.get("/comments/" + comment.attr("data-shortid") + "/edit",
function(data) {
comment.replaceWith($.parseHTML(data));
});
});
$(document).on("click", "a.comment_deletor", function() {

View file

@ -358,10 +358,6 @@ ol.comments.comments1 {
border-left-color: transparent;
}
ol.comments.preview {
margin: 1em 0 0 -15px;
padding: 0;
}
ol.comments.collapsed ol,
ol.comments.collapsed li {
display: none;
@ -532,7 +528,7 @@ div.story_content {
}
div.story_content {
margin-bottom: 3em;
margin-bottom: 1em;
}
div.morelink {
@ -618,14 +614,6 @@ div.comment_actions a {
text-decoration: none;
}
div.comment_reply form {
padding-top: 1em;
}
div.comment_reply button.comment-post {
font-weight: bold;
}
a.pagelink {
border: 1px solid #ddd;
background-color: #fbfbfb;
@ -717,10 +705,14 @@ div#story_box div.markdown_help_toggler {
width: 610px;
}
div.comment_form_container, div.comment_reply {
div.comment_form_container {
max-width: 700px;
}
div.comment_form_container form {
margin-left: 15px;
}
ul.root {
list-style-type: none;
margin: 0;

View file

@ -20,9 +20,7 @@ class CommentsController < ApplicationController
if params[:parent_comment_short_id].present?
if pc = Comment.where(:story_id => story.id, :short_id =>
params[:parent_comment_short_id]).first
comment.parent_comment_id = pc.id
# needed for carryng along in comment preview form
comment.parent_comment_short_id = params[:parent_comment_short_id]
comment.parent_comment = pc
else
return render :json => { :error => "invalid parent comment",
:status => 400 }
@ -45,14 +43,8 @@ class CommentsController < ApplicationController
if comment.valid? && !params[:preview].present? && comment.save
comment.current_vote = { :vote => 1 }
if comment.parent_comment_id
render :partial => "postedreply", :layout => false,
:content_type => "text/html", :locals => { :comment => comment }
else
render :partial => "commentbox", :layout => false,
:content_type => "text/html", :locals => {
:comment => story.comments.build, :show_comment => comment }
end
render :partial => "comments/postedreply", :layout => false,
:content_type => "text/html", :locals => { :comment => comment }
else
comment.previewing = true
comment.upvotes = 1
@ -78,6 +70,20 @@ class CommentsController < ApplicationController
:content_type => "text/html", :locals => { :comment => comment }
end
def reply
if !(parent_comment = find_comment)
return render :text => "can't find comment", :status => 400
end
comment = Comment.new
comment.story = parent_comment.story
comment.parent_comment = parent_comment
render :partial => "commentbox", :layout => false,
:content_type => "text/html", :locals => { :comment => comment,
:cancellable => true }
end
def delete
if !((comment = find_comment) && comment.is_deletable_by_user?(@user))
return render :text => "can't find comment", :status => 400
@ -108,9 +114,11 @@ class CommentsController < ApplicationController
comment.comment = params[:comment]
if comment.save
# TODO: render the comment again properly, it's indented wrong
votes = Vote.comment_votes_by_user_for_comment_ids_hash(@user.id,
[comment.id])
comment.current_vote = votes[comment.id]
render :partial => "postedreply", :layout => false,
render :partial => "comments/comment", :layout => false,
:content_type => "text/html", :locals => { :comment => comment }
else
comment.previewing = true
@ -269,6 +277,6 @@ class CommentsController < ApplicationController
private
def find_comment
Comment.where(:short_id => params[:comment_id]).first
Comment.where(:short_id => params[:id]).first
end
end

View file

@ -11,8 +11,7 @@ class Comment < ActiveRecord::Base
attr_accessible :comment, :moderation_reason
attr_accessor :parent_comment_short_id, :current_vote, :previewing,
:indent_level, :highlighted
attr_accessor :current_vote, :previewing, :indent_level, :highlighted
before_validation :on => :create do
self.assign_short_id_and_upvote

View file

@ -91,8 +91,6 @@ class="comment <%= comment.current_vote ? (comment.current_vote[:vote] == 1 ?
<%= raw comment.markeddown_comment %>
<% end %>
</div>
<div class="comment_reply"></div>
</div>
</li>

View file

@ -1,14 +1,15 @@
<li class="comment">
<div class="comment_form_container">
<%= form_tag comment.new_record? ?
"/comments/post_to/#{comment.story.short_id}" :
"/comments/#{comment.short_id}/update", :id => "comment_form" do |f| %>
"/comments/#{comment.short_id}/update" do |f| %>
<% if comment.errors.any? %>
<%= errors_for comment %>
<% end %>
<% if comment.parent_comment_short_id.present? %>
<% if comment.parent_comment %>
<%= hidden_field_tag "parent_comment_short_id",
comment.parent_comment_short_id %>
comment.parent_comment.short_id %>
<% end %>
<div style="width: 100%;">
@ -27,6 +28,12 @@
&nbsp;
<%= button_tag "Preview Comment", :class => "comment-preview",
:type => "button" %>
<% if local_assigns[:cancellable] %>
&nbsp;
<%= button_tag "Cancel", :class => "comment-cancel",
:type => "button" %>
<% end %>
<div style="clear: both;"></div>
@ -42,3 +49,4 @@
</ol>
<% end %>
</div>
</li>

View file

@ -1,3 +1,2 @@
<ol class="comments comments1 preview">
<%= render "comments/comment", :comment => comment %>
</ol>
<%= render "comments/comment", :comment => comment %>
<ol class="comments"></ol>

View file

@ -1,20 +1,25 @@
<% @threads.each do |thread| %>
<% indent_level = -1 %>
<% thread.each do |comment| %>
<% if comment.indent_level > indent_level %>
<ol class="comments comments<%= comment.indent_level %>">
<% elsif comment.indent_level < indent_level %>
<% (indent_level - comment.indent_level).times do %>
<ol class="comments comments1">
<% comments_by_parent = thread.group_by(&:parent_comment_id) %>
<% subtree = comments_by_parent[nil] %>
<% ancestors = [] %>
<% while subtree %>
<% if (comment = subtree.shift) %>
<%= render "comments/comment", :comment => comment,
:show_story => ancestors.empty? %>
<% if (children = comments_by_parent[comment.id]) %>
<% ancestors << subtree %>
<% subtree = children %>
<ol class="comments">
<% else %>
<ol class="comments"></ol>
<% end %>
<% elsif (subtree = ancestors.pop) %>
</ol>
<% end %>
<% end %>
<%= render :partial => "comments/comment", :locals => {
:comment => comment, :show_story => (comment.indent_level == 1) } %>
<% indent_level = comment.indent_level %>
<% end %>
<% indent_level.times do %>
</ol>
<% end %>
</ol>
<% end %>

View file

@ -9,29 +9,30 @@
<%= raw @story.markeddown_description %>
</div>
<% end %>
</div>
<p></p>
<ol class="comments comments1">
<% if @user && !@story.is_gone? && !@story.previewing %>
<%= render "comments/commentbox", :comment => @comment %>
<% end %>
</div>
<% if @comments %>
<% indent_level = -1 %>
<% @comments.each_with_index do |comment,x| %>
<% if comment.indent_level > indent_level %>
<ol class="comments comments<%= comment.indent_level %>">
<% elsif comment.indent_level < indent_level %>
<% (indent_level - comment.indent_level).times do %>
</ol>
<% comments_by_parent = @comments.group_by(&:parent_comment_id) %>
<% subtree = comments_by_parent[nil] %>
<% ancestors = [] %>
<% while subtree %>
<% if (comment = subtree.shift) %>
<%= render "comments/comment", :comment => comment %>
<% if (children = comments_by_parent[comment.id]) %>
<% ancestors << subtree %>
<% subtree = children %>
<ol class="comments">
<% else %>
<ol class="comments"></ol>
<% end %>
<% elsif (subtree = ancestors.pop) %>
</ol>
<% end %>
<%= render "comments/comment", :comment => comment %>
<% indent_level = comment.indent_level %>
<% end %>
<% indent_level.times do %>
</ol>
<% end %>
<% end %>
</ol>

View file

@ -45,15 +45,17 @@ Lobsters::Application.routes.draw do
post "/stories/preview" => "stories#preview"
resources :comments do
post "upvote"
post "downvote"
post "unvote"
member do
get "reply"
post "upvote"
post "downvote"
post "unvote"
post "edit"
post "preview"
post "update"
post "delete"
post "undelete"
post "preview"
post "update"
post "delete"
post "undelete"
end
end
get "/comments/page/:page" => "comments#index"
post "/comments/post_to/:story_id" => "comments#create"