diff --git a/app/components/comment_component.rb b/app/components/comment_component.rb new file mode 100644 index 000000000..562a9b5c5 --- /dev/null +++ b/app/components/comment_component.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class CommentComponent < ApplicationComponent + attr_reader :comment, :context, :dtext_data, :moderation_reports, :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) + @comment = comment + @context = context + @dtext_data = dtext_data + @moderation_reports = moderation_reports + @show_deleted = show_deleted + @current_user = current_user + end + + def render? + !comment.is_deleted? || show_deleted || current_user.is_moderator? + end +end diff --git a/app/components/comment_component/comment_component.html.erb b/app/components/comment_component/comment_component.html.erb new file mode 100644 index 000000000..ebf3b7995 --- /dev/null +++ b/app/components/comment_component/comment_component.html.erb @@ -0,0 +1,65 @@ + +
+ data-is-reported="<%= moderation_reports.pluck(:model_id).include?(comment.id) %>" + <% end %> + data-is-voted="<%= comment.voted_by?(CurrentUser.user) %>"> +
+
+ <%= link_to_user comment.creator %> + <% if comment.is_deleted? %> + (deleted) + <% end %> +
+ <%= link_to time_ago_in_words_tagged(comment.created_at), post_path(comment.post, anchor: "comment_#{comment.id}"), class: "message-timestamp" %> +
+
+
+ <%= format_text(comment.body, data: dtext_data) %> +
+ <%= render "application/update_notice", record: comment %> + + <% if policy(comment).create? %> + + <% if context == :index_by_comment %> +
  • <%= link_to "Reply", new_comment_path(id: comment, comment: { post_id: comment.post_id }), class: "reply-link" %>
  • + <% else %> +
  • <%= link_to "Reply", new_comment_path(id: comment, comment: { post_id: comment.post_id }), class: "reply-link", remote: true %>
  • + <% end %> + + <% if policy(comment).update? %> + <% if comment.is_deleted? %> +
  • <%= link_to "Undelete", undelete_comment_path(comment.id), method: :post, remote: true %>
  • + <% else %> +
  • <%= link_to "Delete", comment_path(comment.id), "data-confirm": "Are you sure you want to delete this comment?", method: :delete, remote: true %>
  • + <% end %> +
  • <%= link_to "Edit", edit_comment_path(comment.id), id: "edit_comment_link_#{comment.id}", class: "edit_comment_link" %>
  • + <% end %> + + + + <% if policy(comment).reportable? %> +
  • <%= link_to "Report", new_moderation_report_path(moderation_report: { model_type: "Comment", model_id: comment.id }), remote: true %>
  • + <% end %> +
    + <% if policy(comment).update? %> + <%= render "comments/form", comment: comment, hidden: true %> + <% end %> + <% end %> +
    +
    diff --git a/app/components/comment_component/comment_component.scss b/app/components/comment_component/comment_component.scss new file mode 100644 index 000000000..a1ecd01d3 --- /dev/null +++ b/app/components/comment_component/comment_component.scss @@ -0,0 +1,31 @@ +article.comment { + flex: 1; + + &[data-is-sticky="true"] { + background: var(--comment-sticky-background-color); + } + + &[data-is-reported="true"] { + border: var(--moderation-report-border); + } + + &[data-is-voted="true"] { + .comment-vote-up-link, .comment-vote-down-link { + display: none; + } + } + + &[data-is-voted="false"] { + .comment-unvote-link { + display: none; + } + } + + &[data-below-threshold="true"][data-is-sticky="false"] { + opacity: 0.3; + + &:hover { + opacity: 1; + } + } +} diff --git a/app/helpers/comments_helper.rb b/app/helpers/comments_helper.rb new file mode 100644 index 000000000..3fb85f989 --- /dev/null +++ b/app/helpers/comments_helper.rb @@ -0,0 +1,10 @@ +module CommentsHelper + def render_comment(comment, **options) + render CommentComponent.new(comment: comment, **options) + end + + def render_comment_list(comments, **options) + dtext_data = DText.preprocess(comments.map(&:body)) + render CommentComponent.with_collection(comments, dtext_data: dtext_data, **options) + end +end diff --git a/app/javascript/src/styles/specific/comments.scss b/app/javascript/src/styles/specific/comments.scss index 5bf5d95f9..47f01878f 100644 --- a/app/javascript/src/styles/specific/comments.scss +++ b/app/javascript/src/styles/specific/comments.scss @@ -10,40 +10,6 @@ div.comments-for-post { div.hidden-comments-notice { margin: 1em 0; } - - div.list-of-comments { - article.comment { - flex: 1; - - &[data-is-sticky="true"] { - background: var(--comment-sticky-background-color); - } - - &[data-is-reported="true"] { - border: var(--moderation-report-border); - } - - &[data-is-voted="true"] { - .comment-vote-up-link, .comment-vote-down-link { - display: none; - } - } - - &[data-is-voted="false"] { - .comment-unvote-link { - display: none; - } - } - - &[data-below-threshold="true"][data-is-sticky="false"] { - opacity: 0.3; - - &:hover { - opacity: 1; - } - } - } - } } div#c-comments { diff --git a/app/views/comments/_index_by_comment.html.erb b/app/views/comments/_index_by_comment.html.erb index 3a2f5cc2d..e44411e56 100644 --- a/app/views/comments/_index_by_comment.html.erb +++ b/app/views/comments/_index_by_comment.html.erb @@ -1,5 +1,6 @@
    + <% 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 %> @@ -8,7 +9,7 @@ <%= link_to(image_tag(comment.post.preview_file_url), post_path(comment.post)) %> <% end %>
    - <%= render partial: "comments/partials/show/comment", collection: [comment], locals: { context: :index_by_comment, dtext_data: DText.preprocess(@comments.map(&:body)), moderation_reports: [] } %> + <%= render_comment(comment, dtext_data: dtext_data, context: :index_by_comment, show_deleted: params.dig(:search, :is_deleted).to_s.truthy?) %> <% end %> <% end %> <% end %> diff --git a/app/views/comments/index_for_post.js.erb b/app/views/comments/index_for_post.js.erb index 3381caf97..cbefc174d 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(partial: 'comments/partials/show/comment', collection: @comments, locals: { context: :index_for_post, dtext_data: DText.preprocess(@comments.map(&:body)), moderation_reports: @post.moderation_reports.visible(CurrentUser.user).recent })) %>"); +current_comment_section.html("<%= j render_comment_list(@comments, context: :index_by_post, moderation_reports: @post.moderation_reports.visible(CurrentUser.user).recent) %>"); $(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 4b0d9935c..0d3d27120 100644 --- a/app/views/comments/partials/index/_list.html.erb +++ b/app/views/comments/partials/index/_list.html.erb @@ -20,7 +20,7 @@
    <% if comments.present? %> - <%= render partial: "comments/partials/show/comment", collection: comments, locals: { context: :index_by_post, dtext_data: DText.preprocess(comments.map(&:body)), moderation_reports: post.moderation_reports.visible(CurrentUser.user).recent } %> + <%= render_comment_list(comments, context: :index_by_post, moderation_reports: post.moderation_reports.visible(CurrentUser.user).recent) %> <% elsif post.last_commented_at.present? %>

    There are no visible comments.

    <% else %> diff --git a/app/views/comments/partials/show/_comment.html.erb b/app/views/comments/partials/show/_comment.html.erb deleted file mode 100644 index b3b52b712..000000000 --- a/app/views/comments/partials/show/_comment.html.erb +++ /dev/null @@ -1,69 +0,0 @@ -<%# locals: comment, context, dtext_data, moderation_reports %> - -<% if CurrentUser.is_moderator? || (params[:search] && params[:search][:is_deleted] =~ /t/) || !comment.is_deleted? %> - -
    - data-is-reported="<%= moderation_reports.pluck(:model_id).include?(comment.id) %>" - <% end %> - data-is-voted="<%= comment.voted_by?(CurrentUser.user) %>"> -
    -
    - <%= link_to_user comment.creator %> - <% if comment.is_deleted? %> - (deleted) - <% end %> -
    - <%= link_to time_ago_in_words_tagged(comment.created_at), post_path(comment.post, anchor: "comment_#{comment.id}"), class: "message-timestamp" %> -
    -
    -
    - <%= format_text(comment.body, data: dtext_data) %> -
    - <%= render "application/update_notice", record: comment %> - - <% if policy(comment).create? %> - - <% if context == :index_by_comment %> -
  • <%= link_to "Reply", new_comment_path(id: comment, comment: { post_id: comment.post_id }), class: "reply-link" %>
  • - <% else %> -
  • <%= link_to "Reply", new_comment_path(id: comment, comment: { post_id: comment.post_id }), class: "reply-link", remote: true %>
  • - <% end %> - - <% if policy(comment).update? %> - <% if comment.is_deleted? %> -
  • <%= link_to "Undelete", undelete_comment_path(comment.id), method: :post, remote: true %>
  • - <% else %> -
  • <%= link_to "Delete", comment_path(comment.id), "data-confirm": "Are you sure you want to delete this comment?", method: :delete, remote: true %>
  • - <% end %> -
  • <%= link_to "Edit", edit_comment_path(comment.id), id: "edit_comment_link_#{comment.id}", class: "edit_comment_link" %>
  • - <% end %> - - - - <% if policy(comment).reportable? %> -
  • <%= link_to "Report", new_moderation_report_path(moderation_report: { model_type: "Comment", model_id: comment.id }), remote: true %>
  • - <% end %> -
    - <% if policy(comment).update? %> - <%= render "comments/form", comment: comment, hidden: true %> - <% end %> - <% end %> -
    -
    -<% end %>