Skip to content

Commit 1184468

Browse files
committed
Start adding reporting form
1 parent aba3317 commit 1184468

14 files changed

Lines changed: 380 additions & 1 deletion
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
window.addEventListener('DOMContentLoaded', () => {
2+
QPixel.DOM.addSelectorListener('change', 'input[name="report_type"]', ev => {
3+
const value = document.querySelector('input[name="report_type"]:checked').value;
4+
document.querySelectorAll(`[data-report-type="${value}"]`).forEach(el => {
5+
el.classList.remove('hidden');
6+
el.removeAttribute('disabled');
7+
});
8+
document.querySelectorAll(`[data-report-type]:not([data-report-type="${value}"])`).forEach(el => {
9+
el.classList.add('hidden');
10+
el.disabled = true;
11+
});
12+
});
13+
});
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
@import 'variables';
2+
3+
.complaint-form {
4+
label {
5+
display: block;
6+
margin-bottom: 1rem;
7+
font-weight: bold;
8+
font-size: 1.2rem;
9+
color: #222;
10+
11+
&.inline {
12+
display: inline-block;
13+
font-weight: normal;
14+
font-size: 1rem;
15+
}
16+
}
17+
18+
.form-radio-group {
19+
display: flex;
20+
margin: 0.75rem 0;
21+
justify-content: flex-start;
22+
align-items: center;
23+
24+
:first-child {
25+
margin-right: 0.5rem;
26+
}
27+
28+
label {
29+
display: block;
30+
margin: 0;
31+
font-weight: normal;
32+
font-size: 1rem;
33+
}
34+
35+
.form-caption {
36+
margin: 0;
37+
}
38+
}
39+
40+
.form-group {
41+
margin-bottom: 2rem;
42+
}
43+
44+
.hidden {
45+
display: none;
46+
}
47+
48+
[disabled] {
49+
border: 1px solid $muted-text;
50+
background: $muted-graphic;
51+
}
52+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class ComplaintsController < ApplicationController
2+
def index
3+
render layout: 'without_sidebar'
4+
end
5+
6+
def report
7+
@report_types = AppConfig.safety_center['report_types'].select { |_k, t| t['enabled'] }
8+
@content_types = AppConfig.safety_center['content_types']
9+
render layout: 'without_sidebar'
10+
end
11+
12+
def create; end
13+
end

app/helpers/complaints_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module ComplaintsHelper
2+
end
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<h1>Safety Center</h1>
2+
<p>
3+
We are committed to protecting your privacy and safety online, and to protecting our communities from harmful or
4+
abusive content. If you see something that has no place in our communities, please report it to us here.
5+
</p>
6+
7+
<div class="grid">
8+
<div class="grid--cell is-12 is-6-md is-6-lg">
9+
<div class="widget">
10+
<div class="widget--body">
11+
<h2 class="has-font-size-larger h-m-t-0">
12+
<%= link_to new_complaint_path do %>
13+
Make a report or complaint &raquo;
14+
<% end %>
15+
</h2>
16+
<p class="has-font-size-caption">
17+
Report seeing abusive, harmful, or illegal content, or make a complaint about how we've handled your content.
18+
</p>
19+
</div>
20+
</div>
21+
</div>
22+
</div>
23+
24+
<% if user_signed_in? && current_user.staff? %>
25+
<div class="grid">
26+
<div class="grid--cell is-12 is-6-md is-6-lg">
27+
<div class="widget">
28+
<div class="widget--body">
29+
<h2 class="has-font-size-larger h-m-t-0">
30+
<%= link_to '#' do %>
31+
Reports &raquo;
32+
<% end %>
33+
</h2>
34+
<p class="has-font-size-caption">
35+
View and handle content reports and complaints from users.
36+
</p>
37+
</div>
38+
</div>
39+
</div>
40+
</div>
41+
<% end %>
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<%= link_to safety_center_path do %>
2+
&laquo; Back to Safety Center
3+
<% end %>
4+
5+
<h1>Make a report or complaint</h1>
6+
<p>
7+
Thank you for taking the time to make a report. If you've seen harmful, abusive, or illegal content on our
8+
communities, you can report this to us here. You can also use this page if you've received a message saying we've
9+
classified your content as harmful, abusive, or illegal and you wish to contest it.
10+
</p>
11+
12+
<div class="notice is-warning has-color-yellow-900 flex-row-always ai-c has-font-size-caption h-m-b-4">
13+
<i class="fas fa-exclamation-triangle"></i>
14+
<p>
15+
Please don't use this tool to complain about moderator actions, including deletion of posts. Raise these in the
16+
appropriate Meta category instead.
17+
</p>
18+
</div>
19+
20+
<div class="widget">
21+
<%= form_tag create_complaint_path, class: 'widget--body complaint-form' do %>
22+
<div class="form-group">
23+
<%= label_tag :report_type, 'What are you reporting?' %>
24+
<% @report_types.each do |key, type| %>
25+
<div class="form-radio-group">
26+
<%= radio_button_tag :report_type, key, id: "report_type_#{key}", class: 'form-radio-element' %>
27+
<%= label_tag "report_type_#{key}", type['description'] %>
28+
</div>
29+
<% end %>
30+
</div>
31+
32+
<div class="form-group">
33+
<%= label_tag :reported_url, 'Where is this content?' %>
34+
<div class="form-caption">
35+
Enter a URL or link to where we can find this content on our network. You can use the Copy Link button under
36+
posts to get a direct link to a post.
37+
</div>
38+
<%= text_field_tag :reported_url, nil, class: 'form-element' %>
39+
</div>
40+
41+
<div class="form-group hidden js-content-type" data-report-type="illegal">
42+
<%= label_tag :content_type, 'Does this content fall into any of these types of illegal content?' %>
43+
<div class="form-caption">
44+
This question helps us to classify reports and ensure harmful content is reported to the right channels.
45+
</div>
46+
<% @content_types.each do |key, type| %>
47+
<div class="form-radio-group">
48+
<%= radio_button_tag :content_type, key, id: "content_type_#{key}", class: 'form-radio-element',
49+
data: { report_type: 'illegal' } %>
50+
<div>
51+
<%= label_tag "content_type_#{key}", type['name'] %>
52+
<div class="form-caption">
53+
<%= type['description'] %>
54+
</div>
55+
</div>
56+
</div>
57+
<% end %>
58+
<div class="form-radio-group">
59+
<%= radio_button_tag :content_type, 'none', id: 'content_type_none', class: 'form-radio-element',
60+
data: { report_type: 'illegal' } %>
61+
<%= label_tag 'content_type_none', 'None of the above' %>
62+
</div>
63+
</div>
64+
65+
<div class="form-group">
66+
<%= label_tag :comment, 'Tell us more' %>
67+
<div class="form-caption" data-report-type="none">
68+
Tell us any additional information you have about this report.
69+
</div>
70+
<div class="form-caption hidden" data-report-type="illegal">
71+
Tell us any additional information you have about this report. For example, why do you think this content is
72+
harmful or illegal? How did you come across it? Has the user posted any other content you wish to report?
73+
</div>
74+
<div class="form-caption hidden" data-report-type="abusive">
75+
Tell us any additional information you have about this report. For example, why do you think this content is
76+
abusive, or in what way is it harmful? Has the user posted any other content you wish to report?
77+
</div>
78+
<div class="form-caption hidden" data-report-type="copyright">
79+
Tell us any additional information you have about this report. Do you own the copyright? What part of the
80+
content is infringing?
81+
</div>
82+
<div class="form-caption hidden" data-report-type="appeal">
83+
Tell us any additional information you have about this report. Is there any additional content we removed that
84+
you would like to include? Provide detailed reasoning explaining why you disagree with our classification.
85+
</div>
86+
<%= text_area_tag :comment, nil, class: 'form-element', rows: 10 %>
87+
</div>
88+
89+
<div class="form-group">
90+
<%= label_tag :user_email, 'Your email address' %>
91+
<div class="form-caption">
92+
This is used for abuse prevention purposes, and to contact you if we need additional information or to update
93+
you on the status of your report. If you do not wish to receive further updates about your report, please
94+
opt out below.
95+
</div>
96+
<%= text_field_tag :user_email, user_signed_in? ? current_user.email : nil, class: 'form-element',
97+
disabled: user_signed_in? %>
98+
</div>
99+
100+
<div class="form-group">
101+
<%= label_tag :updates, 'Do you wish to receive updates about this report?' %>
102+
<div class="form-caption">
103+
We will let you know once we have investigated your report, and once we've taken any necessary action and closed
104+
your report. If you do not wish to receive these updates, please untick the box.
105+
</div>
106+
<div class="form-radio-group">
107+
<%= check_box_tag :user_wants_updates, 'true', true, class: 'form-radio-element' %>
108+
<%= label_tag :user_wants_updates, 'Receive updates?' %>
109+
</div>
110+
</div>
111+
112+
<%= submit_tag 'Submit report', class: 'button is-primary is-filled' %>
113+
<% end %>
114+
</div>

app/views/layouts/_footer.html.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
<ul>
66
<li><%= link_to 'Our Communities', '/dashboard' %></li>
77
<li><%= link_to 'About Us', '/policy/network-faq' %></li>
8+
<li><%= link_to 'Privacy & Safety Center', safety_center_url %></li>
9+
<li><%= link_to 'Report harmful content', new_complaint_path %></li>
810
</ul>
911
</div>
1012
<div class="grid--cell is-6 is-12-md is-12-sm">

config/config/safety_center.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
report_types:
2+
illegal:
3+
enabled: true
4+
description: illegal harmful content
5+
abusive:
6+
enabled: true
7+
description: abusive or otherwise harmful content
8+
copyright:
9+
enabled: true
10+
description: copyright infringement
11+
appeal:
12+
enabled: true
13+
description: an appeal regarding how we've handled your content
14+
15+
content_types:
16+
terrorism:
17+
name: Terrorism
18+
description: Content promoting, glorifying, or encouraging terrorism.
19+
grooming:
20+
name: Grooming
21+
description: Content which appears to be for the purpose of grooming a child for the purposes of sexual exploitation
22+
or abuse.
23+
image_csam:
24+
name: Image-based child sexual abuse material
25+
description: Images which depict or encourage child sexual exploitation or abuse.
26+
csam_urls:
27+
name: Child sexual abuse material URLs
28+
description: Content which links to child sexual abuse material.
29+
hate:
30+
name: Hate
31+
description: Content which appears to amount to hate speech - abuse relating to a protected characteristic like
32+
race or sexual orientation.
33+
harassment:
34+
name: Harassment, stalking, threats, or abuse
35+
description: Content which appears to be harassing or threatening another user, or which appears to be part of a
36+
course of action in stalking another user.
37+
ccb:
38+
name: Controlling or coercive behaviour
39+
description: Content posted for the purpose of controlling another user or which may an attempt to coerce another
40+
user.
41+
intimate_images:
42+
name: Intimate image abuse
43+
description: Intimate images which appear to have been posted without the consent of their subject. Commonly known
44+
as "revenge porn".
45+
extreme_pornography:
46+
name: Extreme pornography
47+
description: Content, including images, which is pornographic in nature and which may depict an illegal sexual act.
48+
sea:
49+
name: Sexual exploitation of adults
50+
description: Content offering or promoting sexual services involving adult participants who are non-consenting or
51+
being controlled by someone else.
52+
human_trafficking:
53+
name: Human trafficking
54+
description: Content which promotes or offers services related to human trafficking.
55+
unlawful_immigration:
56+
name: Unlawful immigration
57+
description: Content which promotes or offers services related to unlawful immigration.
58+
fraud:
59+
name: Fraud & illegal financial services
60+
description: Content which appears to be fraudulent in nature, or which offers or promotes illegal financial
61+
services.
62+
proceeds_crime:
63+
name: Proceeds of crime
64+
description: Content which relates to the posession or concealment of the proceeds of criminal activity.
65+
drugs:
66+
name: Drugs & psychoactive substances
67+
description: Content which relates to the possession or use of illegal drugs or psychoactive substances.
68+
weapons:
69+
name: Firearms, knives, & other weapons
70+
description: Content which relates to the possession or use of illegal firearms, knives, or other weapons.
71+
suicide:
72+
name: Encouraging or assisting suicide
73+
description: Content which glorifies or promotes suicide or attempted suicide, or which appears to be an attempt to
74+
encourage another user to commit or attempt suicide.
75+
foreign_interference:
76+
name: Foreign interference
77+
description: Content which appears to be posted on behalf of a hostile foreign power with the intent to disrupt or
78+
interfere with society.
79+
animal_cruelty:
80+
name: Animal cruelty
81+
description: Content which glorifies or promotes animal cruelty, or which depicts acts of animal cruelty.

config/routes.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,12 @@
374374
post 'log', to: 'email_logs#log', as: :create_email_log
375375
end
376376

377+
scope 'safety' do
378+
root to: 'complaints#index', as: :safety_center
379+
get 'report', to: 'complaints#report', as: :new_complaint
380+
post 'report', to: 'complaints#create', as: :create_complaint
381+
end
382+
377383
get '403', to: 'errors#forbidden'
378384
get '404', to: 'errors#not_found'
379385
get '409', to: 'errors#conflict'
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddContentTypeToComplaints < ActiveRecord::Migration[7.2]
2+
def change
3+
add_column :complaints, :content_type, :string
4+
end
5+
end

0 commit comments

Comments
 (0)