diff --git a/app/components/comment_component.rb b/app/components/comment_component.rb index 562a9b5c5..26b1afa31 100644 --- a/app/components/comment_component.rb +++ b/app/components/comment_component.rb @@ -1,14 +1,22 @@ # frozen_string_literal: true class CommentComponent < ApplicationComponent - attr_reader :comment, :context, :dtext_data, :moderation_reports, :show_deleted, :current_user + attr_reader :comment, :context, :dtext_data, :show_deleted, :current_user delegate :link_to_user, :time_ago_in_words_tagged, :format_text, :policy, to: :helpers - def initialize(comment:, context: nil, dtext_data: nil, moderation_reports: [], show_deleted: false, current_user: User.anonymous) + def self.with_collection(comments, current_user:, **options) + dtext_data = DText.preprocess(comments.map(&:body)) + # XXX + #comments = comments.includes(:moderation_reports) if Pundit.policy!([current_user, nil], ModerationReport).show? + + super(comments, current_user: current_user, dtext_data: dtext_data, **options) + end + + # XXX calls to pundit policy don't respect current_user. + def initialize(comment:, current_user:, context: nil, dtext_data: nil, show_deleted: false) @comment = comment @context = context @dtext_data = dtext_data - @moderation_reports = moderation_reports @show_deleted = show_deleted @current_user = current_user end @@ -16,4 +24,8 @@ class CommentComponent < ApplicationComponent def render? !comment.is_deleted? || show_deleted || current_user.is_moderator? end + + def has_moderation_reports? + policy(ModerationReport).show? && comment.moderation_reports.present? + end end diff --git a/app/components/comment_component/comment_component.html.erb b/app/components/comment_component/comment_component.html.erb index ebf3b7995..8f5ef5e88 100644 --- a/app/components/comment_component/comment_component.html.erb +++ b/app/components/comment_component/comment_component.html.erb @@ -8,11 +8,9 @@ data-do-not-bump-post="<%= comment.do_not_bump_post? %>" data-is-deleted="<%= comment.is_deleted? %>" data-is-sticky="<%= comment.is_sticky? %>" - data-below-threshold="<%= comment.score < CurrentUser.user.comment_threshold %>" - <% if moderation_reports.present? && policy(moderation_reports).show? %> - data-is-reported="<%= moderation_reports.pluck(:model_id).include?(comment.id) %>" - <% end %> - data-is-voted="<%= comment.voted_by?(CurrentUser.user) %>"> + data-below-threshold="<%= comment.score < current_user.comment_threshold %>" + data-is-reported="<%= has_moderation_reports? %>" + data-is-voted="<%= comment.voted_by?(current_user) %>">
<%= link_to_user comment.creator %> @@ -56,6 +54,9 @@ <% if policy(comment).reportable? %>
  • <%= link_to "Report", new_moderation_report_path(moderation_report: { model_type: "Comment", model_id: comment.id }), remote: true %>
  • <% end %> + <% if has_moderation_reports? %> +
  • This comment has been reported! (<%= link_to pluralize(comment.moderation_reports.length, "report"), moderation_reports_path(search: { model_type: "Comment", model_id: comment.id }) %>)
  • + <% end %> <% if policy(comment).update? %> <%= render "comments/form", comment: comment, hidden: true %> diff --git a/app/components/comment_component/comment_component.scss b/app/components/comment_component/comment_component.scss index a1ecd01d3..442c0f343 100644 --- a/app/components/comment_component/comment_component.scss +++ b/app/components/comment_component/comment_component.scss @@ -6,7 +6,7 @@ article.comment { } &[data-is-reported="true"] { - border: var(--moderation-report-border); + background-color: var(--moderation-report-background-color); } &[data-is-voted="true"] { @@ -28,4 +28,9 @@ article.comment { opacity: 1; } } + + .moderation-report-notice { + font-weight: bold; + color: var(--moderation-report-text-color); + } } diff --git a/app/components/forum_post_component.rb b/app/components/forum_post_component.rb index 217bdbc74..4118b6df6 100644 --- a/app/components/forum_post_component.rb +++ b/app/components/forum_post_component.rb @@ -6,15 +6,28 @@ class ForumPostComponent < ApplicationComponent with_collection_parameter :forum_post - def initialize(forum_post:, original_forum_post_id: nil, dtext_data: nil, moderation_reports: [], current_user: User.anonymous) + def self.with_collection(forum_posts, forum_topic:, current_user:) + dtext_data = DText.preprocess(forum_posts.map(&:body)) + original_forum_post_id = forum_topic.original_post&.id + + forum_posts = forum_posts.includes(:creator, :bulk_update_request) + forum_posts = forum_posts.includes(:moderation_reports) if Pundit.policy!([current_user, nil], ModerationReport).show? + + super(forum_posts, dtext_data: dtext_data, original_forum_post_id: original_forum_post_id, current_user: current_user) + end + + def initialize(forum_post:, original_forum_post_id: nil, dtext_data: nil, current_user: User.anonymous) @forum_post = forum_post @original_forum_post_id = original_forum_post_id @dtext_data = dtext_data - @moderation_reports = moderation_reports @current_user = current_user end def render? policy(forum_post).show_deleted? end + + def has_moderation_reports? + policy(ModerationReport).show? && forum_post.moderation_reports.present? + end end diff --git a/app/components/forum_post_component/forum_post_component.html.erb b/app/components/forum_post_component/forum_post_component.html.erb index ac8bcd120..46eb19f5b 100644 --- a/app/components/forum_post_component/forum_post_component.html.erb +++ b/app/components/forum_post_component/forum_post_component.html.erb @@ -1,8 +1,6 @@
    - data-is-reported="<%= moderation_reports.pluck(:model_id).include?(forum_post.id) %>" - <% end %> + data-is-reported="<%= has_moderation_reports? %>" data-creator="<%= forum_post.creator.name %>">
    @@ -42,6 +40,9 @@ <% if policy(forum_post).reportable? %>
  • <%= link_to "Report", new_moderation_report_path(moderation_report: { model_type: "ForumPost", model_id: forum_post.id }), remote: true, title: "Report this forum post to the moderators" %>
  • <% end %> + <% if has_moderation_reports? %> +
  • This post has been reported! (<%= link_to pluralize(forum_post.moderation_reports.length, "report"), moderation_reports_path(search: { model_type: "ForumPost", model_id: forum_post.id }) %>)
  • + <% end %> <% if forum_post.bulk_update_request.present? %>
      <%= render "forum_post_votes/list", votes: forum_post.votes, forum_post: forum_post %> diff --git a/app/components/forum_post_component/forum_post_component.scss b/app/components/forum_post_component/forum_post_component.scss index 3aa1e0c2e..8cc82fc4a 100644 --- a/app/components/forum_post_component/forum_post_component.scss +++ b/app/components/forum_post_component/forum_post_component.scss @@ -1,6 +1,6 @@ article.forum-post { &[data-is-reported="true"] { - border: var(--moderation-report-border); + background-color: var(--moderation-report-background-color); } a.voted { @@ -30,4 +30,9 @@ article.forum-post { } } } + + .moderation-report-notice { + font-weight: bold; + color: var(--moderation-report-text-color); + } } diff --git a/app/controllers/forum_topics_controller.rb b/app/controllers/forum_topics_controller.rb index 49e1edd73..f9a0ef00c 100644 --- a/app/controllers/forum_topics_controller.rb +++ b/app/controllers/forum_topics_controller.rb @@ -42,8 +42,6 @@ class ForumTopicsController < ApplicationController if request.format.atom? @forum_posts = @forum_posts.reverse_order.load - elsif request.format.html? - @forum_posts = @forum_posts.includes(:creator, :bulk_update_request) end respond_with(@forum_topic) diff --git a/app/helpers/comments_helper.rb b/app/helpers/comments_helper.rb index 3fb85f989..be2d52e4e 100644 --- a/app/helpers/comments_helper.rb +++ b/app/helpers/comments_helper.rb @@ -4,7 +4,6 @@ module CommentsHelper end def render_comment_list(comments, **options) - dtext_data = DText.preprocess(comments.map(&:body)) - render CommentComponent.with_collection(comments, dtext_data: dtext_data, **options) + render CommentComponent.with_collection(comments, current_user: CurrentUser.user, **options) end end diff --git a/app/javascript/src/styles/base/040_colors.css b/app/javascript/src/styles/base/040_colors.css index 472052818..3b3cb32bc 100644 --- a/app/javascript/src/styles/base/040_colors.css +++ b/app/javascript/src/styles/base/040_colors.css @@ -71,7 +71,7 @@ --forum-topic-status-rejected-color: hsla(0, 25%, 55%, 1); --moderation-report-text-color: red; - --moderation-report-border: 2px solid red; + --moderation-report-background-color: var(--error-background-color); --comment-sticky-background-color: var(--subnav-menu-background-color); @@ -349,7 +349,7 @@ body[data-current-user-theme="dark"] { --forum-topic-status-rejected-color: var(--red-3); --moderation-report-text-color: var(--red-1); - --moderation-report-border: 2px solid var(--red-1); + --moderation-report-background-color: var(--red-0); --jquery-ui-widget-content-text-color: var(--text-color); --jquery-ui-widget-content-background: var(--grey-2); diff --git a/app/javascript/src/styles/specific/forum.scss b/app/javascript/src/styles/specific/forum.scss index da7b75902..ac5f6bc9b 100644 --- a/app/javascript/src/styles/specific/forum.scss +++ b/app/javascript/src/styles/specific/forum.scss @@ -1,10 +1,3 @@ -div.list-of-forum-posts { - div.moderation-forums-notice { - font-weight: bold; - color: var(--moderation-report-text-color); - } -} - div#c-forum-topics { td.status-column { white-space: nowrap; diff --git a/app/models/forum_topic.rb b/app/models/forum_topic.rb index 0ab60d042..8edbcee0d 100644 --- a/app/models/forum_topic.rb +++ b/app/models/forum_topic.rb @@ -16,7 +16,6 @@ class ForumTopic < ApplicationRecord has_many :forum_posts, foreign_key: "topic_id", dependent: :destroy, inverse_of: :topic has_many :forum_topic_visits has_one :forum_topic_visit_by_current_user, -> { where(user_id: CurrentUser.id) }, class_name: "ForumTopicVisit" - has_many :moderation_reports, through: :forum_posts has_one :original_post, -> { order(id: :asc) }, class_name: "ForumPost", foreign_key: "topic_id", inverse_of: :topic has_many :bulk_update_requests, :foreign_key => "forum_topic_id" has_many :tag_aliases, :foreign_key => "forum_topic_id" diff --git a/app/models/post.rb b/app/models/post.rb index 8ace11420..00295b051 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -50,7 +50,6 @@ class Post < ApplicationRecord has_many :votes, :class_name => "PostVote", :dependent => :destroy has_many :notes, :dependent => :destroy has_many :comments, -> {order("comments.id")}, :dependent => :destroy - has_many :moderation_reports, through: :comments has_many :children, -> {order("posts.id")}, :class_name => "Post", :foreign_key => "parent_id" has_many :approvals, :class_name => "PostApproval", :dependent => :destroy has_many :disapprovals, :class_name => "PostDisapproval", :dependent => :destroy diff --git a/app/policies/moderation_report_policy.rb b/app/policies/moderation_report_policy.rb index 12eef8914..146335ba1 100644 --- a/app/policies/moderation_report_policy.rb +++ b/app/policies/moderation_report_policy.rb @@ -3,6 +3,10 @@ class ModerationReportPolicy < ApplicationPolicy user.is_moderator? end + def show? + user.is_moderator? + end + def create? unbanned? && policy(record.model).reportable? end diff --git a/app/views/comments/_index_by_comment.html.erb b/app/views/comments/_index_by_comment.html.erb index e44411e56..752f2c0cd 100644 --- a/app/views/comments/_index_by_comment.html.erb +++ b/app/views/comments/_index_by_comment.html.erb @@ -9,7 +9,7 @@ <%= link_to(image_tag(comment.post.preview_file_url), post_path(comment.post)) %> <% end %>
    - <%= render_comment(comment, dtext_data: dtext_data, context: :index_by_comment, show_deleted: params.dig(:search, :is_deleted).to_s.truthy?) %> + <%= 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 %> <% end %> <% end %> diff --git a/app/views/comments/index_for_post.js.erb b/app/views/comments/index_for_post.js.erb index cbefc174d..e3fbbf04b 100644 --- a/app/views/comments/index_for_post.js.erb +++ b/app/views/comments/index_for_post.js.erb @@ -1,5 +1,5 @@ $("#threshold-comments-notice-for-<%= @post.id %>").hide(); var current_comment_section = $("div.comments-for-post[data-post-id=<%= @post.id %>] div.list-of-comments"); -current_comment_section.html("<%= j render_comment_list(@comments, context: :index_by_post, moderation_reports: @post.moderation_reports.visible(CurrentUser.user).recent) %>"); +current_comment_section.html("<%= j render_comment_list(@comments, context: :index_by_post) %>"); $(window).trigger("danbooru:index_for_post", [<%= @post.id %>]); diff --git a/app/views/comments/partials/index/_list.html.erb b/app/views/comments/partials/index/_list.html.erb index 0d3d27120..8b0311e3d 100644 --- a/app/views/comments/partials/index/_list.html.erb +++ b/app/views/comments/partials/index/_list.html.erb @@ -3,13 +3,6 @@ <%= render "comments/partials/index/header", :post => post %> <% end %> - <% if post.moderation_reports.visible(CurrentUser.user).recent.present? %> -
    - - This post has comments reported for moderation! (<%= pluralize(post.moderation_reports.visible(CurrentUser.user).recent.length, "report") %>) - -
    - <% end %> <% if post.comments.hidden(CurrentUser.user).any? || (page == :comments && post.comments.size > 6) %>
    @@ -20,7 +13,7 @@
    <% if comments.present? %> - <%= render_comment_list(comments, context: :index_by_post, moderation_reports: post.moderation_reports.visible(CurrentUser.user).recent) %> + <%= render_comment_list(comments, context: :index_by_post) %> <% elsif post.last_commented_at.present? %>

    There are no visible comments.

    <% else %> diff --git a/app/views/forum_posts/_listing.html.erb b/app/views/forum_posts/_listing.html.erb deleted file mode 100644 index 86130e94f..000000000 --- a/app/views/forum_posts/_listing.html.erb +++ /dev/null @@ -1,16 +0,0 @@ -<%- # forum_post %> -<%- # original_forum_post_id %> -<%- # dtext_data %> -<%- # moderation_reports %> - -
    - <% if moderation_reports.present? %> -
    - - This topic has forum posts reported for moderation! (<%= pluralize(moderation_reports.length, "report") %>) - -
    - <% end %> - - <%= render ForumPostComponent.with_collection(forum_posts, original_forum_post_id: original_forum_post_id, dtext_data: dtext_data, moderation_reports: moderation_reports, current_user: CurrentUser.user) %> -
    diff --git a/app/views/forum_topics/show.html.erb b/app/views/forum_topics/show.html.erb index ecd4fdca0..98580574e 100644 --- a/app/views/forum_topics/show.html.erb +++ b/app/views/forum_topics/show.html.erb @@ -27,7 +27,9 @@
    <% end %> - <%= render "forum_posts/listing", forum_posts: @forum_posts, original_forum_post_id: @forum_topic.original_post&.id, dtext_data: DText.preprocess(@forum_posts.map(&:body)), moderation_reports: @forum_topic.moderation_reports.visible(CurrentUser.user).recent %> +
    + <%= render ForumPostComponent.with_collection(@forum_posts, forum_topic: @forum_topic, current_user: CurrentUser.user) %> +
    <% if policy(ForumPost.new(topic: @forum_topic)).create? %>

    <%= link_to "Post reply", new_forum_post_path(topic_id: @forum_topic.id), id: "new-response-link" %>

    diff --git a/test/components/comment_component_test.rb b/test/components/comment_component_test.rb new file mode 100644 index 000000000..bacf675f6 --- /dev/null +++ b/test/components/comment_component_test.rb @@ -0,0 +1,44 @@ +require "test_helper" + +class CommentComponentTest < ViewComponent::TestCase + def render_comment(comment, current_user: User.anonymous, **options) + as(current_user) do + render_inline(CommentComponent.new(comment: comment, current_user: current_user, **options)) + end + end + + context "The CommentComponent" do + setup do + @comment = as(create(:user)) { create(:comment) } + end + + context "for a regular comment" do + should "render for Anonymous" do + render_comment(@comment, current_user: User.anonymous) + + assert_css("article#comment_#{@comment.id}") + end + + should "render for a Member" do + render_comment(@comment, current_user: create(:user)) + + assert_css("article#comment_#{@comment.id}") + end + end + + context "for a comment with moderation reports" do + should "show the report notice to moderators" do + create(:moderation_report, model: @comment) + render_comment(@comment, current_user: create(:moderator_user)) + + assert_css(".moderation-report-notice") + end + + should "not show the report notice to regular users" do + render_comment(@comment, current_user: User.anonymous) + + assert_no_css(".moderation-report-notice") + end + end + end +end diff --git a/test/components/forum_post_component_test.rb b/test/components/forum_post_component_test.rb new file mode 100644 index 000000000..eee24ad15 --- /dev/null +++ b/test/components/forum_post_component_test.rb @@ -0,0 +1,44 @@ +require "test_helper" + +class ForumPostComponentTest < ViewComponent::TestCase + def render_forum_post(forum_post, current_user: User.anonymous, **options) + as(current_user) do + render_inline(ForumPostComponent.new(forum_post: forum_post, current_user: current_user, **options)) + end + end + + context "The ForumPostComponent" do + setup do + @forum_post = as(create(:user)) { create(:forum_post) } + end + + context "for a regular forum post" do + should "render for Anonymous" do + render_forum_post(@forum_post, current_user: User.anonymous) + + assert_css("article#forum_post_#{@forum_post.id}") + end + + should "render for a Member" do + render_forum_post(@forum_post, current_user: create(:user)) + + assert_css("article#forum_post_#{@forum_post.id}") + end + end + + context "for a forum post with moderation reports" do + should "show the report notice to moderators" do + create(:moderation_report, model: @forum_post) + render_forum_post(@forum_post, current_user: create(:moderator_user)) + + assert_css(".moderation-report-notice") + end + + should "not show the report notice to regular users" do + render_forum_post(@forum_post, current_user: User.anonymous) + + assert_no_css(".moderation-report-notice") + end + end + end +end