comments: rework deleted comments.
Let users see when a post has deleted comments. Show normal users a '[deleted]' placeholder when a comment is deleted. Show the full comment to moderators. Also fix it so that the comment creator can't edit or undelete deleted comments, and users can't vote on or report deleted comments. Finally, hide the creator_id, updater_id, and body of deleted comments in the API.
This commit is contained in:
@@ -1,27 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CommentComponent < ApplicationComponent
|
||||
attr_reader :comment, :context, :dtext_data, :show_deleted, :current_user
|
||||
attr_reader :comment, :context, :dtext_data, :current_user
|
||||
delegate :link_to_user, :time_ago_in_words_tagged, :format_text, to: :helpers
|
||||
|
||||
def initialize(comment:, current_user:, context: nil, dtext_data: nil, show_deleted: false)
|
||||
def initialize(comment:, current_user:, context: nil, dtext_data: nil)
|
||||
@comment = comment
|
||||
@context = context
|
||||
@dtext_data = dtext_data
|
||||
@show_deleted = show_deleted
|
||||
@current_user = current_user
|
||||
end
|
||||
|
||||
def render?
|
||||
!comment.is_deleted? || show_deleted || current_user.is_moderator?
|
||||
end
|
||||
|
||||
def dimmed?
|
||||
!comment.is_sticky? && comment.score < current_user.comment_threshold/2.0
|
||||
comment.is_deleted? || (!comment.is_sticky? && comment.score < current_user.comment_threshold/2.0)
|
||||
end
|
||||
|
||||
def thresholded?
|
||||
!comment.is_sticky? && comment.score < current_user.comment_threshold
|
||||
!comment.is_deleted? && !comment.is_sticky? && comment.score < current_user.comment_threshold
|
||||
end
|
||||
|
||||
def redact_deleted?
|
||||
comment.is_deleted? && !policy(comment).can_see_deleted?
|
||||
end
|
||||
|
||||
def has_moderation_reports?
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<article id="comment_<%= comment.id %>" class="comment message"
|
||||
data-id="<%= comment.id %>"
|
||||
data-post-id="<%= comment.post_id %>"
|
||||
data-creator-id="<%= comment.creator_id %>"
|
||||
data-updater-id="<%= comment.updater_id %>"
|
||||
data-creator-id="<%= comment.creator_id unless redact_deleted? %>"
|
||||
data-updater-id="<%= comment.updater_id unless redact_deleted? %>"
|
||||
data-score="<%= comment.score %>"
|
||||
data-do-not-bump-post="<%= comment.do_not_bump_post? %>"
|
||||
data-is-deleted="<%= comment.is_deleted? %>"
|
||||
@@ -14,9 +14,13 @@
|
||||
data-is-voted="<%= comment.voted_by?(current_user) %>">
|
||||
<div class="author">
|
||||
<div class="author-name">
|
||||
<%= link_to_user comment.creator %>
|
||||
<% if comment.is_deleted? %>
|
||||
(deleted)
|
||||
<% if redact_deleted? %>
|
||||
[deleted]
|
||||
<% else %>
|
||||
<%= link_to_user comment.creator %>
|
||||
<% if comment.is_deleted? %>
|
||||
(deleted)
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= link_to time_ago_in_words_tagged(comment.created_at), post_path(comment.post, anchor: "comment_#{comment.id}"), class: "message-timestamp" %>
|
||||
@@ -27,26 +31,34 @@
|
||||
<% end %>
|
||||
|
||||
<%= tag.div class: "body prose", style: ("display: none;" if thresholded?) do %>
|
||||
<%= format_text(comment.body, data: dtext_data) %>
|
||||
<% if redact_deleted? %>
|
||||
<p>[deleted]</p>
|
||||
<% else %>
|
||||
<%= format_text(comment.body, data: dtext_data) %>
|
||||
<% end %>
|
||||
|
||||
<%= render "application/update_notice", record: comment %>
|
||||
<% end %>
|
||||
|
||||
<% if policy(comment).create? %>
|
||||
<menu>
|
||||
<menu>
|
||||
<% if policy(comment).reply? %>
|
||||
<% if context == :index_by_comment %>
|
||||
<li><%= link_to "Reply", new_comment_path(id: comment, comment: { post_id: comment.post_id }), class: "reply-link" %></li>
|
||||
<% else %>
|
||||
<li><%= link_to "Reply", new_comment_path(id: comment, comment: { post_id: comment.post_id }), class: "reply-link", remote: true %></li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if policy(comment).update? %>
|
||||
<% if comment.is_deleted? %>
|
||||
<li><%= link_to "Undelete", undelete_comment_path(comment.id), method: :post, remote: true %></li>
|
||||
<% else %>
|
||||
<li><%= link_to "Delete", comment_path(comment.id), "data-confirm": "Are you sure you want to delete this comment?", method: :delete, remote: true %></li>
|
||||
<% end %>
|
||||
<li><%= link_to "Edit", edit_comment_path(comment.id), id: "edit_comment_link_#{comment.id}", class: "edit_comment_link" %></li>
|
||||
<% if policy(comment).update? %>
|
||||
<% if comment.is_deleted? %>
|
||||
<li><%= link_to "Undelete", undelete_comment_path(comment.id), method: :post, remote: true %></li>
|
||||
<% else %>
|
||||
<li><%= link_to "Delete", comment_path(comment.id), "data-confirm": "Are you sure you want to delete this comment?", method: :delete, remote: true %></li>
|
||||
<% end %>
|
||||
<li><%= link_to "Edit", edit_comment_path(comment.id), id: "edit_comment_link_#{comment.id}", class: "edit_comment_link" %></li>
|
||||
<% end %>
|
||||
|
||||
<% if policy(comment).vote? %>
|
||||
<li class="comment-vote-up-link">
|
||||
<%= link_to "Vote up", comment_comment_votes_path(comment_id: comment.id, score: "up"), method: :post, remote: true %>
|
||||
</li>
|
||||
@@ -56,16 +68,19 @@
|
||||
<li class="comment-unvote-link">
|
||||
<%= link_to "Unvote", comment_comment_votes_path(comment_id: comment.id), method: :delete, remote: true %>
|
||||
</li>
|
||||
<% if policy(comment).reportable? %>
|
||||
<li><%= link_to "Report", new_moderation_report_path(moderation_report: { model_type: "Comment", model_id: comment.id }), remote: true %></li>
|
||||
<% end %>
|
||||
<% if has_moderation_reports? %>
|
||||
<li class="moderation-report-notice">This comment has been reported! (<%= link_to pluralize(comment.moderation_reports.length, "report"), moderation_reports_path(search: { model_type: "Comment", model_id: comment.id }) %>)</li>
|
||||
<% end %>
|
||||
</menu>
|
||||
<% if policy(comment).update? %>
|
||||
<%= render "comments/form", comment: comment, hidden: true %>
|
||||
<% end %>
|
||||
|
||||
<% if policy(comment).reportable? %>
|
||||
<li><%= link_to "Report", new_moderation_report_path(moderation_report: { model_type: "Comment", model_id: comment.id }), remote: true %></li>
|
||||
<% end %>
|
||||
|
||||
<% if has_moderation_reports? %>
|
||||
<li class="moderation-report-notice">This comment has been reported! (<%= link_to pluralize(comment.moderation_reports.length, "report"), moderation_reports_path(search: { model_type: "Comment", model_id: comment.id }) %>)</li>
|
||||
<% end %>
|
||||
</menu>
|
||||
|
||||
<% if policy(comment).update? %>
|
||||
<%= render "comments/form", comment: comment, hidden: true %>
|
||||
<% end %>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
@@ -1,16 +1,33 @@
|
||||
class CommentPolicy < ApplicationPolicy
|
||||
def create?
|
||||
unbanned?
|
||||
end
|
||||
|
||||
def update?
|
||||
unbanned? && (user.is_moderator? || record.updater_id == user.id)
|
||||
unbanned? && (user.is_moderator? || (record.updater_id == user.id && !record.is_deleted?))
|
||||
end
|
||||
|
||||
def reportable?
|
||||
unbanned? && record.creator_id != user.id && !record.creator.is_moderator?
|
||||
unbanned? && record.creator_id != user.id && !record.creator.is_moderator? && !record.is_deleted?
|
||||
end
|
||||
|
||||
def can_sticky_comment?
|
||||
user.is_moderator?
|
||||
end
|
||||
|
||||
def can_see_deleted?
|
||||
user.is_moderator?
|
||||
end
|
||||
|
||||
def reply?
|
||||
create? && !record.is_deleted?
|
||||
end
|
||||
|
||||
def vote?
|
||||
# XXX should use CommentVotePolicy
|
||||
unbanned? && !record.is_deleted?
|
||||
end
|
||||
|
||||
def permitted_attributes_for_create
|
||||
[:body, :post_id, :do_not_bump_post, (:is_sticky if can_sticky_comment?)].compact
|
||||
end
|
||||
@@ -19,5 +36,11 @@ class CommentPolicy < ApplicationPolicy
|
||||
[:body, :is_deleted, (:is_sticky if can_sticky_comment?)].compact
|
||||
end
|
||||
|
||||
def api_attributes
|
||||
attributes = super
|
||||
attributes -= [:creator_id, :updater_id, :body] if record.is_deleted? && !can_see_deleted?
|
||||
attributes
|
||||
end
|
||||
|
||||
alias_method :undelete?, :update?
|
||||
end
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<div id="p-index-by-comment" class="comments-for-post">
|
||||
<div class="list-of-comments list-of-messages">
|
||||
<% dtext_data = DText.preprocess(@comments.map(&:body)) %>
|
||||
|
||||
<% @comments.each do |comment| %>
|
||||
<% if CurrentUser.is_moderator? || (params[:search] && params[:search][:is_deleted] =~ /t/) || !comment.is_deleted? %>
|
||||
<%= tag.div id: "post_#{comment.post.id}", **PostPreviewComponent.new(post: comment.post).article_attrs("post") do %>
|
||||
<div class="preview">
|
||||
<% if policy(comment.post).visible? %>
|
||||
<%= link_to(image_tag(comment.post.preview_file_url), post_path(comment.post)) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= render_comment(comment, dtext_data: dtext_data, context: :index_by_comment, show_deleted: params.dig(:search, :is_deleted).to_s.truthy?, current_user: CurrentUser.user) %>
|
||||
<% end %>
|
||||
<%= tag.div id: "post_#{comment.post.id}", **PostPreviewComponent.new(post: comment.post).article_attrs("post") do %>
|
||||
<div class="preview">
|
||||
<% if policy(comment.post).visible? %>
|
||||
<%= link_to(image_tag(comment.post.preview_file_url), post_path(comment.post)) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= render_comment(comment, dtext_data: dtext_data, context: :index_by_comment, current_user: CurrentUser.user) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user