Merge pull request #4267 from BrokenEagle/add-report-function
Create the ability to send reports to moderators
This commit is contained in:
48
app/controllers/moderation_reports_controller.rb
Normal file
48
app/controllers/moderation_reports_controller.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
class ModerationReportsController < ApplicationController
|
||||
respond_to :html, :xml, :json, :js
|
||||
before_action :builder_only, only: [:new, :create]
|
||||
before_action :moderator_only, only: [:index]
|
||||
|
||||
def new
|
||||
check_privilege
|
||||
@moderation_report = ModerationReport.new(moderation_report_params)
|
||||
respond_with(@moderation_report)
|
||||
end
|
||||
|
||||
def index
|
||||
@moderation_reports = ModerationReport.paginated_search(params).includes(:creator, :model)
|
||||
respond_with(@moderation_reports)
|
||||
end
|
||||
|
||||
def create
|
||||
check_privilege
|
||||
@moderation_report = ModerationReport.create(moderation_report_params)
|
||||
respond_with(@moderation_report)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def model_type
|
||||
params.fetch(:moderation_report, {}).fetch(:model_type)
|
||||
end
|
||||
|
||||
def model_id
|
||||
params.fetch(:moderation_report, {}).fetch(:model_id)
|
||||
end
|
||||
|
||||
def check_privilege
|
||||
case model_type
|
||||
when "User"
|
||||
return if User.find(model_id).reportable_by?(CurrentUser.user)
|
||||
when "Comment"
|
||||
return if Comment.find(model_id).reportable_by?(CurrentUser.user)
|
||||
when "ForumPost"
|
||||
return if ForumPost.find(model_id).reportable_by?(CurrentUser.user)
|
||||
end
|
||||
raise User::PrivilegeError
|
||||
end
|
||||
|
||||
def moderation_report_params
|
||||
params.fetch(:moderation_report, {}).permit(%i[model_type model_id reason])
|
||||
end
|
||||
end
|
||||
@@ -67,6 +67,9 @@
|
||||
--forum-vote-meh-color: goldenrod;
|
||||
--forum-vote-down-color: red;
|
||||
|
||||
--moderation-report-text-color: red;
|
||||
--moderation-report-border: 2px solid red;
|
||||
|
||||
--comment-sticky-background-color: var(--subnav-menu-background-color);
|
||||
|
||||
--post-tooltip-background-color: var(--body-background-color);
|
||||
@@ -333,6 +336,9 @@ body[data-current-user-theme="dark"] {
|
||||
--forum-vote-meh-color: var(--yellow-1);
|
||||
--forum-vote-down-color: var(--red-1);
|
||||
|
||||
--moderation-report-text-color: var(--red-1);
|
||||
--moderation-report-border: 2px solid var(--red-1);
|
||||
|
||||
--jquery-ui-widget-content-text-color: var(--text-color);
|
||||
--jquery-ui-widget-content-background: var(--grey-2);
|
||||
--jquery-ui-dialog-box-shadow: 0 0 8px var(--grey-1);
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
@import "../base/000_vars.scss";
|
||||
|
||||
div.comments-for-post {
|
||||
div.moderation-comments-notice {
|
||||
margin: 1em 0;
|
||||
font-weight: bold;
|
||||
color: var(--moderation-report-text-color);
|
||||
}
|
||||
|
||||
div.hidden-comments-notice {
|
||||
margin: 1em 0;
|
||||
}
|
||||
@@ -13,6 +19,10 @@ div.comments-for-post {
|
||||
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;
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
div.list-of-forum-posts {
|
||||
div.moderation-forums-notice {
|
||||
font-weight: bold;
|
||||
color: var(--moderation-report-text-color);
|
||||
}
|
||||
|
||||
article.forum-post {
|
||||
&[data-is-reported="true"] {
|
||||
border: var(--moderation-report-border);
|
||||
}
|
||||
|
||||
a.voted {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
div#c-users {
|
||||
div#a-show {
|
||||
div.moderation-users-notice {
|
||||
margin: 1em 0;
|
||||
font-weight: bold;
|
||||
color: var(--moderation-report-text-color);
|
||||
}
|
||||
|
||||
div.box {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ class Comment < ApplicationRecord
|
||||
belongs_to :post
|
||||
belongs_to_creator
|
||||
belongs_to_updater
|
||||
has_many :moderation_reports, as: :model
|
||||
has_many :votes, :class_name => "CommentVote", :dependent => :destroy
|
||||
after_create :update_last_commented_at_on_create
|
||||
after_update(:if => ->(rec) {(!rec.is_deleted? || !rec.saved_change_to_is_deleted?) && CurrentUser.id != rec.creator_id}) do |rec|
|
||||
@@ -127,6 +128,10 @@ class Comment < ApplicationRecord
|
||||
updater_id == user.id || user.is_moderator?
|
||||
end
|
||||
|
||||
def reportable_by?(user)
|
||||
user.is_builder? && creator_id != user.id && !creator.is_moderator?
|
||||
end
|
||||
|
||||
def voted_by?(user)
|
||||
return false if user.is_anonymous?
|
||||
user.id.in?(votes.map(&:user_id))
|
||||
|
||||
@@ -6,6 +6,7 @@ class ForumPost < ApplicationRecord
|
||||
belongs_to_updater
|
||||
belongs_to :topic, :class_name => "ForumTopic"
|
||||
has_many :dtext_links, as: :model, dependent: :destroy
|
||||
has_many :moderation_reports, as: :model
|
||||
has_many :votes, class_name: "ForumPostVote"
|
||||
has_one :tag_alias
|
||||
has_one :tag_implication
|
||||
@@ -93,6 +94,10 @@ class ForumPost < ApplicationRecord
|
||||
bulk_update_request || tag_alias || tag_implication
|
||||
end
|
||||
|
||||
def reportable_by?(user)
|
||||
user.is_builder? && creator_id != user.id && !creator.is_moderator?
|
||||
end
|
||||
|
||||
def votable?
|
||||
TagAlias.where(forum_post_id: id).exists? ||
|
||||
TagImplication.where(forum_post_id: id).exists? ||
|
||||
|
||||
@@ -14,6 +14,7 @@ class ForumTopic < ApplicationRecord
|
||||
belongs_to_creator
|
||||
belongs_to_updater
|
||||
has_many :posts, -> {order("forum_posts.id asc")}, :class_name => "ForumPost", :foreign_key => "topic_id", :dependent => :destroy
|
||||
has_many :moderation_reports, through: :posts
|
||||
has_one :original_post, -> {order("forum_posts.id asc")}, class_name: "ForumPost", foreign_key: "topic_id", inverse_of: :topic
|
||||
has_many :subscriptions, :class_name => "ForumSubscription"
|
||||
before_validation :initialize_is_deleted, :on => :create
|
||||
@@ -181,4 +182,8 @@ class ForumTopic < ApplicationRecord
|
||||
def update_orignal_post
|
||||
original_post&.update_columns(:updater_id => CurrentUser.id, :updated_at => Time.now)
|
||||
end
|
||||
|
||||
def viewable_moderation_reports
|
||||
CurrentUser.is_moderator? ? moderation_reports.recent : []
|
||||
end
|
||||
end
|
||||
|
||||
61
app/models/moderation_report.rb
Normal file
61
app/models/moderation_report.rb
Normal file
@@ -0,0 +1,61 @@
|
||||
class ModerationReport < ApplicationRecord
|
||||
belongs_to :model, polymorphic: true
|
||||
belongs_to_creator
|
||||
|
||||
validates :reason, presence: true
|
||||
after_create :create_forum_post!
|
||||
|
||||
scope :user, -> { where(model_type: "User") }
|
||||
scope :comment, -> { where(model_type: "Comment") }
|
||||
scope :forum_post, -> { where(model_type: "ForumPost") }
|
||||
scope :recent, -> { where("moderation_reports.created_at >= ?", 1.week.ago) }
|
||||
|
||||
def forum_topic_title
|
||||
"Reports requiring moderation"
|
||||
end
|
||||
|
||||
def forum_topic_body
|
||||
"This topic deals with moderation events as reported by Builders. Reports can be filed against users, comments, or forum posts."
|
||||
end
|
||||
|
||||
def forum_topic
|
||||
topic = ForumTopic.find_by_title(forum_topic_title)
|
||||
if topic.nil?
|
||||
topic = CurrentUser.as_system do
|
||||
ForumTopic.create(title: forum_topic_title, category_id: 0, min_level: User::Levels::MODERATOR, original_post_attributes: {body: forum_topic_body})
|
||||
end
|
||||
end
|
||||
topic
|
||||
end
|
||||
|
||||
def forum_post_message
|
||||
messages = ["[b]Submitted by:[/b] @#{creator.name}"]
|
||||
case model_type
|
||||
when "User"
|
||||
messages << "[b]Submitted against:[/b] @#{model.name}"
|
||||
when "Comment"
|
||||
messages << "[b]Submitted against[/b]: comment ##{model_id}"
|
||||
when "ForumPost"
|
||||
messages << "[b]Submitted against[/b]: forum ##{model_id}"
|
||||
end
|
||||
messages << ""
|
||||
messages << "[quote]"
|
||||
messages << "[b]Reason:[/b]"
|
||||
messages << ""
|
||||
messages << reason
|
||||
messages << "[/quote]"
|
||||
messages.join("\n")
|
||||
end
|
||||
|
||||
def create_forum_post!
|
||||
updater = ForumUpdater.new(forum_topic)
|
||||
updater.update(forum_post_message)
|
||||
end
|
||||
|
||||
def self.search(params)
|
||||
q = super
|
||||
q = q.search_attributes(params, :model_type, :model_id, :creator_id)
|
||||
|
||||
q.apply_default_order(params)
|
||||
end
|
||||
end
|
||||
@@ -49,6 +49,7 @@ 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
|
||||
@@ -1811,4 +1812,8 @@ class Post < ApplicationRecord
|
||||
|
||||
save
|
||||
end
|
||||
|
||||
def viewable_moderation_reports
|
||||
CurrentUser.is_moderator? ? moderation_reports.recent : []
|
||||
end
|
||||
end
|
||||
|
||||
@@ -93,6 +93,7 @@ class User < ApplicationRecord
|
||||
has_many :wiki_page_versions, foreign_key: :updater_id
|
||||
has_many :feedback, :class_name => "UserFeedback", :dependent => :destroy
|
||||
has_many :forum_post_votes, dependent: :destroy, foreign_key: :creator_id
|
||||
has_many :moderation_reports, as: :model
|
||||
has_many :posts, :foreign_key => "uploader_id"
|
||||
has_many :post_appeals, foreign_key: :creator_id
|
||||
has_many :post_approvals, :dependent => :destroy
|
||||
@@ -791,6 +792,10 @@ class User < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
def reportable_by?(user)
|
||||
user.is_builder? && id != user.id && !is_moderator?
|
||||
end
|
||||
|
||||
def hide_favorites?
|
||||
!CurrentUser.is_admin? && enable_private_favorites? && CurrentUser.user.id != id
|
||||
end
|
||||
@@ -807,4 +812,8 @@ class User < ApplicationRecord
|
||||
def presenter
|
||||
@presenter ||= UserPresenter.new(self)
|
||||
end
|
||||
|
||||
def viewable_moderation_reports
|
||||
CurrentUser.is_moderator? ? moderation_reports.recent : []
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<%= link_to(image_tag(comment.post.preview_file_url), post_path(comment.post)) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= render partial: "comments/partials/show/comment", collection: [comment], locals: { context: :index_by_comment, dtext_data: DText.preprocess(@comments.map(&:body)) } %>
|
||||
<%= render partial: "comments/partials/show/comment", collection: [comment], locals: { context: :index_by_comment, dtext_data: DText.preprocess(@comments.map(&:body)), moderation_reports: [] } %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -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)) })) %>");
|
||||
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.viewable_moderation_reports })) %>");
|
||||
$(window).trigger("danbooru:index_for_post", [<%= @post.id %>]);
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
<%= render "comments/partials/index/header", :post => post %>
|
||||
<% end %>
|
||||
|
||||
<% if post.viewable_moderation_reports.present? %>
|
||||
<div class="row moderation-comments-notice">
|
||||
<span class="info" id="moderation-comments-notice-for-<%= post.id %>">
|
||||
This post has comments reported for moderation! (<%= pluralize(post.viewable_moderation_reports.length, "report") %>)
|
||||
</span>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if post.comments.hidden(CurrentUser.user).any? || (page == :comments && post.comments.size > 6) %>
|
||||
<div class="row hidden-comments-notice">
|
||||
<span class="info" id="threshold-comments-notice-for-<%= post.id %>">
|
||||
@@ -13,7 +20,7 @@
|
||||
|
||||
<div class="list-of-comments list-of-messages">
|
||||
<% if comments.present? %>
|
||||
<%= render partial: "comments/partials/show/comment", collection: comments, locals: { context: :index_by_post, dtext_data: DText.preprocess(comments.map(&:body)) } %>
|
||||
<%= render partial: "comments/partials/show/comment", collection: comments, locals: { context: :index_by_post, dtext_data: DText.preprocess(comments.map(&:body)), moderation_reports: post.viewable_moderation_reports } %>
|
||||
<% elsif post.last_commented_at.present? %>
|
||||
<p>There are no visible comments.</p>
|
||||
<% else %>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<%# locals: comment, context, dtext_data %>
|
||||
<%# locals: comment, context, dtext_data, moderation_reports %>
|
||||
|
||||
<% if CurrentUser.is_moderator? || (params[:search] && params[:search][:is_deleted] =~ /t/) || !comment.is_deleted? %>
|
||||
<a name="comment-<%= comment.id %>"></a>
|
||||
@@ -12,6 +12,9 @@
|
||||
data-is-deleted="<%= comment.is_deleted? %>"
|
||||
data-is-sticky="<%= comment.is_sticky? %>"
|
||||
data-below-threshold="<%= comment.score < CurrentUser.user.comment_threshold %>"
|
||||
<% if CurrentUser.is_moderator? %>
|
||||
data-is-reported="<%= moderation_reports.pluck(:model_id).include?(comment.id) %>"
|
||||
<% end %>
|
||||
data-is-voted="<%= comment.voted_by?(CurrentUser.user) %>">
|
||||
<div class="author">
|
||||
<h4>
|
||||
@@ -53,6 +56,9 @@
|
||||
<li class="comment-unvote-link">
|
||||
<%= link_to "Unvote", comment_comment_votes_path(comment_id: comment.id), method: :delete, remote: true %>
|
||||
</li>
|
||||
<% if comment.reportable_by?(CurrentUser.user) %>
|
||||
<li><%= link_to "Report comment", new_moderation_report_path(moderation_report: { model_type: "Comment", model_id: comment.id }), remote: true %></li>
|
||||
<% end %>
|
||||
</menu>
|
||||
<% if comment.editable_by?(CurrentUser.user) %>
|
||||
<%= render "comments/form", comment: comment, hidden: true %>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<% if forum_post.visible?(CurrentUser.user, ActiveModel::Type::Boolean.new.cast(params.dig(:search, :is_deleted))) %>
|
||||
<article class="forum-post message" id="forum_post_<%= forum_post.id %>" data-forum-post-id="<%= forum_post.id %>" data-creator="<%= forum_post.creator.name %>">
|
||||
<article class="forum-post message" id="forum_post_<%= forum_post.id %>"
|
||||
data-forum-post-id="<%= forum_post.id %>"
|
||||
<% if CurrentUser.is_moderator? %>
|
||||
data-is-reported="<%= moderation_reports.pluck(:model_id).include?(forum_post.id) %>"
|
||||
<% end %>
|
||||
data-creator="<%= forum_post.creator.name %>">
|
||||
<div class="author">
|
||||
<h4>
|
||||
<%= link_to_user forum_post.creator %>
|
||||
@@ -32,6 +37,9 @@
|
||||
<li><%= link_to "Edit", edit_forum_post_path(forum_post.id), :id => "edit_forum_post_link_#{forum_post.id}", :class => "edit_forum_post_link" %></li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if forum_post.reportable_by?(CurrentUser.user) %>
|
||||
<li><%= link_to "Report forum", new_moderation_report_path(moderation_report: { model_type: "ForumPost", model_id: forum_post.id }), remote: true %></li>
|
||||
<% end %>
|
||||
<% if forum_post.votable? %>
|
||||
<ul class="votes" id="forum-post-votes-for-<%= forum_post.id %>">
|
||||
<%= render "forum_post_votes/list", votes: forum_post.votes, forum_post: forum_post %>
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
<%- # forum_post %>
|
||||
<%- # original_forum_post_id %>
|
||||
<%- # dtext_data %>
|
||||
<%- # moderation_reports %>
|
||||
|
||||
<div class="list-of-forum-posts list-of-messages">
|
||||
<% if moderation_reports.present? %>
|
||||
<div class="row moderation-forums-notice">
|
||||
<span class="info" id="moderation-forums-notice-for-topic">
|
||||
This topic has forum posts reported for moderation! (<%= pluralize(moderation_reports.length, "report") %>)
|
||||
</span>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% forum_posts.each do |forum_post| %>
|
||||
<%= render "forum_posts/forum_post", forum_post: forum_post, original_forum_post_id: original_forum_post_id, dtext_data: dtext_data %>
|
||||
<%= render "forum_posts/forum_post", forum_post: forum_post, original_forum_post_id: original_forum_post_id, dtext_data: dtext_data, moderation_reports: moderation_reports %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</div>
|
||||
<% 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)) %>
|
||||
<%= 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.viewable_moderation_reports %>
|
||||
|
||||
<% if CurrentUser.is_member? %>
|
||||
<% if CurrentUser.is_moderator? || !@forum_topic.is_locked? %>
|
||||
|
||||
14
app/views/moderation_reports/_new.html.erb
Normal file
14
app/views/moderation_reports/_new.html.erb
Normal file
@@ -0,0 +1,14 @@
|
||||
<div class="report-dialog-body">
|
||||
<div class="prose">
|
||||
<%= format_text(WikiPage.titled(Danbooru.config.report_notice_wiki_page).first.try(&:body)) %>
|
||||
</div>
|
||||
|
||||
<%# XXX dtext_field expects there to be a `moderation_report` instance variable. %>
|
||||
<% @moderation_report = moderation_report %>
|
||||
<%= edit_form_for(@moderation_report, format: :js, remote: true) do |f| %>
|
||||
<%= f.hidden_field :model_type %>
|
||||
<%= f.hidden_field :model_id %>
|
||||
<%= dtext_field "moderation_report", "reason", preview_id: "dtext-preview-for-moderation-report", type: "string" %>
|
||||
<%= dtext_preview_button "moderation_report", "reason", preview_id: "dtext-preview-for-moderation-report" %>
|
||||
<% end %>
|
||||
</div>
|
||||
1
app/views/moderation_reports/create.js.erb
Normal file
1
app/views/moderation_reports/create.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
Danbooru.notice("Report submitted.");
|
||||
27
app/views/moderation_reports/index.html.erb
Normal file
27
app/views/moderation_reports/index.html.erb
Normal file
@@ -0,0 +1,27 @@
|
||||
<div id="c-moderation-reports">
|
||||
<div id="a-index">
|
||||
<h1>Moderation reports</h1>
|
||||
<%= table_for @moderation_reports, width: "100%" do |t| %>
|
||||
<% t.column "Reported", width: "10%" do |report| %>
|
||||
<% if report.model_type == "User" %>
|
||||
<%= link_to_user report.model %>
|
||||
<% elsif report.model_type == "Comment" %>
|
||||
<%= link_to "comment ##{report.model_id}", comment_path(report.model_id) %>
|
||||
<% elsif report.model_type == "ForumPost" %>
|
||||
<%= link_to "forum ##{report.model_id}", forum_post_path(report.model_id) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% t.column "Reason" do |report| %>
|
||||
<span class="prose">
|
||||
<%= format_text report.reason, inline: true %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% t.column "Creator", width: "10%" do |report| %>
|
||||
<%= compact_time report.created_at %>
|
||||
<br> by <%= link_to_user report.creator %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= numbered_paginator(@moderation_reports) %>
|
||||
</div>
|
||||
</div>
|
||||
5
app/views/moderation_reports/new.html.erb
Normal file
5
app/views/moderation_reports/new.html.erb
Normal file
@@ -0,0 +1,5 @@
|
||||
<div id="c-moderation-reports">
|
||||
<div id="a-new">
|
||||
<%= render "moderation_reports/new", moderation_report: @moderation_report %>
|
||||
</div>
|
||||
</div>
|
||||
1
app/views/moderation_reports/new.js.erb
Normal file
1
app/views/moderation_reports/new.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
Danbooru.Utility.dialog("Send report", "<%= j render "moderation_reports/new", moderation_report: @moderation_report %>");
|
||||
@@ -155,6 +155,7 @@
|
||||
<% end %>
|
||||
|
||||
<% if CurrentUser.is_moderator? %>
|
||||
<li><%= link_to("Moderation Reports", moderation_reports_path) %></li>
|
||||
<li><%= link_to("IP Addresses", ip_addresses_path) %></li>
|
||||
<li><%= link_to("IP Bans", ip_bans_path) %></li>
|
||||
<% end %>
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
<% if !@user.is_platinum? %>
|
||||
<%= subnav_link_to "Gift upgrade", new_user_upgrade_path(:user_id => @user.id) %>
|
||||
<% end %>
|
||||
<% if @user.reportable_by?(CurrentUser.user) %>
|
||||
<%= subnav_link_to "Report user", new_moderation_report_path(moderation_report: { model_type: "User", model_id: @user.id }), remote: true %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if CurrentUser.user.is_moderator? %>
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
<div id="a-show">
|
||||
<h1><%= link_to_user @user %></h1>
|
||||
|
||||
<% if @user.viewable_moderation_reports.present? %>
|
||||
<div class="moderation-users-notice">
|
||||
<span class="info" id="moderation-users-notice-for-<%= @user.id %>">
|
||||
This user has been reported for moderation! (<%= pluralize(@user.viewable_moderation_reports.length, "report") %>)
|
||||
</span>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render "statistics", presenter: @user.presenter, user: @user %>
|
||||
|
||||
<%= render "posts/partials/common/inline_blacklist" %>
|
||||
|
||||
@@ -305,6 +305,10 @@ module Danbooru
|
||||
"help:appeal_notice"
|
||||
end
|
||||
|
||||
def report_notice_wiki_page
|
||||
"help:report_notice"
|
||||
end
|
||||
|
||||
def replacement_notice_wiki_page
|
||||
"help:replacement_notice"
|
||||
end
|
||||
|
||||
@@ -160,6 +160,7 @@ Rails.application.routes.draw do
|
||||
end
|
||||
end
|
||||
resources :mod_actions
|
||||
resources :moderation_reports, only: [:new, :create, :index]
|
||||
resources :news_updates
|
||||
resources :notes do
|
||||
collection do
|
||||
|
||||
12
db/migrate/20200117220602_create_moderation_reports.rb
Normal file
12
db/migrate/20200117220602_create_moderation_reports.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class CreateModerationReports < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :moderation_reports do |t|
|
||||
t.timestamps
|
||||
t.references :model, polymorphic: true, null: false
|
||||
t.integer :creator_id, null: false
|
||||
t.text :reason, null: false
|
||||
end
|
||||
|
||||
add_index :moderation_reports, :creator_id
|
||||
end
|
||||
end
|
||||
@@ -2408,6 +2408,40 @@ CREATE SEQUENCE public.mod_actions_id_seq
|
||||
ALTER SEQUENCE public.mod_actions_id_seq OWNED BY public.mod_actions.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: moderation_reports; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.moderation_reports (
|
||||
id bigint NOT NULL,
|
||||
created_at timestamp(6) without time zone NOT NULL,
|
||||
updated_at timestamp(6) without time zone NOT NULL,
|
||||
model_type character varying NOT NULL,
|
||||
model_id bigint NOT NULL,
|
||||
creator_id integer NOT NULL,
|
||||
reason text NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: moderation_reports_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.moderation_reports_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: moderation_reports_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.moderation_reports_id_seq OWNED BY public.moderation_reports.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: news_updates; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -4080,6 +4114,13 @@ ALTER TABLE ONLY public.ip_bans ALTER COLUMN id SET DEFAULT nextval('public.ip_b
|
||||
ALTER TABLE ONLY public.mod_actions ALTER COLUMN id SET DEFAULT nextval('public.mod_actions_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: moderation_reports id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.moderation_reports ALTER COLUMN id SET DEFAULT nextval('public.moderation_reports_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: news_updates id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -4440,6 +4481,14 @@ ALTER TABLE ONLY public.mod_actions
|
||||
ADD CONSTRAINT mod_actions_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: moderation_reports moderation_reports_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.moderation_reports
|
||||
ADD CONSTRAINT moderation_reports_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: news_updates news_updates_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -6514,6 +6563,20 @@ CREATE INDEX index_mod_actions_on_created_at ON public.mod_actions USING btree (
|
||||
CREATE INDEX index_mod_actions_on_creator_id ON public.mod_actions USING btree (creator_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_moderation_reports_on_creator_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_moderation_reports_on_creator_id ON public.moderation_reports USING btree (creator_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_moderation_reports_on_model_type_and_model_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_moderation_reports_on_model_type_and_model_id ON public.moderation_reports USING btree (model_type, model_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_news_updates_on_created_at; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
@@ -7415,6 +7478,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20191223032633'),
|
||||
('20200114204550'),
|
||||
('20200115010442'),
|
||||
('20200117220602'),
|
||||
('20200118015014');
|
||||
|
||||
|
||||
|
||||
5
test/factories/moderation_report.rb
Normal file
5
test/factories/moderation_report.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
FactoryBot.define do
|
||||
factory(:moderation_report) do
|
||||
reason {"xxx"}
|
||||
end
|
||||
end
|
||||
66
test/functional/moderation_reports_controller_test.rb
Normal file
66
test/functional/moderation_reports_controller_test.rb
Normal file
@@ -0,0 +1,66 @@
|
||||
require 'test_helper'
|
||||
|
||||
class ModerationReportsControllerTest < ActionDispatch::IntegrationTest
|
||||
context "The moderation reports controller" do
|
||||
setup do
|
||||
travel_to(2.weeks.ago) do
|
||||
@user = create(:user)
|
||||
@builder = create(:builder_user)
|
||||
@mod = create(:moderator_user)
|
||||
end
|
||||
|
||||
@user.as_current do
|
||||
@comment = create(:comment)
|
||||
end
|
||||
end
|
||||
|
||||
context "new action" do
|
||||
should "render the access denied page" do
|
||||
get_auth new_moderation_report_path, @user
|
||||
assert_response 403
|
||||
assert_select "h1", /Access Denied/
|
||||
end
|
||||
|
||||
should "render" do
|
||||
get_auth new_moderation_report_path, @mod, params: {:moderation_report => {:model_id => @comment.id, :model_type => "Comment"}}
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
|
||||
context "index action" do
|
||||
setup do
|
||||
@builder.as_current do
|
||||
create(:moderation_report, model: @comment)
|
||||
end
|
||||
end
|
||||
|
||||
should "render the access denied page" do
|
||||
get_auth moderation_reports_path, @builder
|
||||
assert_response 403
|
||||
assert_select "h1", /Access Denied/
|
||||
end
|
||||
|
||||
should "render" do
|
||||
get_auth moderation_reports_path, @mod
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
context "with search parameters" do
|
||||
should "render" do
|
||||
get_auth moderation_reports_path, @mod, params: {:search => {:model_id => @comment.id}}
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
|
||||
context "create action" do
|
||||
should "create a new moderation report" do
|
||||
assert_difference("ModerationReport.count", 1) do
|
||||
assert_difference("ModerationReport.count") do
|
||||
post_auth moderation_reports_path, @builder, params: {:format => "js", :moderation_report => {:model_id => @comment.id, :model_type => "Comment", :reason => "xxx"}}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user