Skip to content

Commit

Permalink
Add report
Browse files Browse the repository at this point in the history
  • Loading branch information
Flowtter committed Oct 11, 2022
1 parent 19a80c8 commit 5bdc97f
Show file tree
Hide file tree
Showing 11 changed files with 238 additions and 60 deletions.
2 changes: 2 additions & 0 deletions core/client/ui/radial-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const otherUserMenuItems = [
{ id: 'send-love', icon: '❤️', order: 1, shortcut: 50, label: 'Send love' },
{ id: 'show-profile', icon: '👤', order: 2, label: 'Profile', shortcut: 51 },
{ id: 'send-vocal', icon: '🎙️', order: 3, label: 'Send vocal', shortcut: 52 },
{ id: 'report', icon: '🚨️', order: 4, label: 'Report', shortcut: 53 },
];

const menuOptions = new ReactiveVar(mainMenuItems);
Expand All @@ -75,6 +76,7 @@ const onMenuOptionSelected = e => {
else if (option.id === 'send-love' && user) setReaction(Random.choice(lovePhrases(user.profile.name)));
else if (option.id === 'follow' && user) userManager.follow(user);
else if (option.id === 'show-profile') Session.set('modal', { template: 'userProfile', userId: Session.get('menu')?.userId });
else if (option.id === 'report') Session.set('modal', { template: 'report', userId: Session.get('menu')?.userId });
else if (option.id === 'go-back') buildMenuFromOptions([...mainMenuItems, ...additionalOptions('me')]);
else if (option.id === 'custom-reaction') setReaction(Meteor.user().profile.defaultReaction || Meteor.settings.public.defaultReaction);
else if (option.id === 'emoji') setReaction(option.icon);
Expand Down
23 changes: 23 additions & 0 deletions core/client/ui/report.hbs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<template name="report">
{{#modal title=title }}
<div class="header">
<h2 class="h2">{{ title }}</h2>
<hr class="separator" />
</div>
<div class="report">
<select name="reason-select"
id="reason-select"
class="js-report-reason-select select">
{{#each reportAllReasons }}
<option value="{{ this }}">
{{ this }}
</option>
{{/each }}
</select>
<form class="js-console-form">
<textarea class="textarea js-command-input" name="js-command-input" placeholder="Explain here" autocomplete="off"></textarea>
<button type="button" class="button js-button-submit">Send</button>
</form>
</div>
{{/modal }}
</template>
115 changes: 115 additions & 0 deletions core/client/ui/report.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
const inputSelector = '.js-command-input';


const getUser = id => Meteor.users.findOne(id);

const getMessage = id => Messages.findOne(id);

const getAllAdmins = () => Meteor.users.find({ roles: { admin: true } }).fetch();

function buildMessage(text, level, reason, reported, messageId) {
let messageText = '';
if (messageId) {
const message = getMessage(messageId);
messageText = `Message: ${messageId} - ${message.text}\nChannel: ${message.channel}\n`;
}

return `REPORT LOG - ${Date()}\n\n\nLevel: ${level}\n\nJustification:\n${text}\n\nReason:\n${reason}\n\n${messageText}Reported:\n${reported._id} - ${reported.profile.name}`;
}

const sendReport = (channel, text) => {
let messageId;

try {
messageId = messagesModule.sendMessage(channel, text);
lp.notif.success('Report sent');
} catch (e) { lp.notif.error(e); }

return messageId;
};

const closeConsole = () => { closeModal('report'); };

const onSubmit = (reason, reported, messageId) => {
if (reported._id === Meteor.userId()) {
lp.notif.error('You can\'t report yourself');
return;
}
const isAdmin = getUser(Meteor.userId()).roles?.admin;

const text = document.querySelector(inputSelector).value;
const currentLevel = Meteor.user().profile.levelId;
if (!text) {
lp.notif.error('Please enter a message');
return;
}
if (text.length > 1024) {
lp.notif.error('Message is too long');
return;
}
let admins = getAllAdmins();
if (isAdmin) {
admins = admins.filter(admin => admin._id !== Meteor.userId());
}
if (!admins.length) {
// Quiting even if the user is an admin because we don't want to create a conversation with himself
lp.notif.error('No admins found');
return;
}
const adminsLevel = admins.filter(admin => admin.profile.levelId === currentLevel);
if (adminsLevel.length) {
admins = adminsLevel;
}
const level = Levels.findOne(currentLevel).name;
const message = buildMessage(text, level, reason, reported, messageId);
const channel = [...admins.map(admin => admin._id), Meteor.userId()].sort().join(';');

sendReport(channel, message);

closeConsole();
};

Template.report.onCreated(function () {
this.reason = new ReactiveVar('Non-specified');
});

Template.report.helpers({
title() {
const template = Template.instance();
return `Report user - ${getUser(template.data.userId)?.profile.name}`;
},
reportAllReasons() {
const reportAllReasons = ['Non-specified', 'Spam', 'Abusive chat', 'Cheating', 'Offensive name', 'Other'];
return reportAllReasons;
},
explanation() {
switch (Template.instance().reason.get()) {
case 'Non-specified':
return '';
case 'Spam':
return 'Spam is the use of the messages to send too many messages in a short period of time, to send the same message multiple times, or to repeatedly connect and disconnect with an user';
case 'Abusive chat':
return 'Abusive chat is the use of the messages to harass, insult, or threaten another user';
case 'Cheating':
return 'Cheating is the use of any third-party software or any other method to gain an unfair advantage in the game';
case 'Offensive name':
return 'Offensive name is the use of a name that is offensive, vulgar, or inappropriate';
case 'Other':
return 'Other behavior that is not listed above, please specify';
default:
return '';
}
},
});

Template.report.events({
'change .js-report-reason-select'(event) {
Template.instance().reason.set(event.target.value);
},
'click .js-button-submit'(event) {
event.preventDefault();
event.stopPropagation();
const template = Template.instance();
lp.notif.confirm('Report user', `Do you really want to report this message?`, () => onSubmit(template.reason.get(), getUser(template.data.userId), template.data.messageId));
},
});
17 changes: 17 additions & 0 deletions core/client/ui/report.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.report {
width: 90%;
height: 80%;
margin: auto;

form {
height: 100%;
textarea {
margin-top: 25px;
width: 100%;
height: 80%;
}
button {
margin-bottom: 0px;
}
}
}
10 changes: 9 additions & 1 deletion core/client/ui/user-profile.hbs.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
<template name="userProfile">
{{#modal title=title}}
<div class="header">
<h2 class="h2">{{title}}</h2>
<h2 class="h2">
<span class="js-title">{{title}}</span>
{{#unless myProfile}}
<div class="tooltip">
<button type="button" class="emoji-before-tooltip js-report">🚨</button>
<span class="tooltiptext">Report</span>
</div>
{{/unless}}
</h2>
<hr class="separator">
</div>
<div class="user-profile">
Expand Down
7 changes: 6 additions & 1 deletion core/client/ui/user-profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Template.userProfile.helpers({
const template = Template.instance();
return getUser(template).profile.name;
},
myProfile() { return Meteor.userId() === Template.instance().data.userId; },
age() { return moment().diff(getUser(Template.instance()).createdAt, 'days'); },
website() {
const { website } = getUser(Template.instance()).profile;
Expand All @@ -43,7 +44,11 @@ Template.userProfile.helpers({
});

Template.userProfile.events({
'click .header'(event, templateInstance) {
'click .js-title'(event, templateInstance) {
navigator.clipboard.writeText(getUser(templateInstance)._id).then(() => lp.notif.success('✂️ Identifier copied to your clipboard'));
},
'click .js-report'(event, templateInstance) {
const { userId } = templateInstance.data;
Session.set('modal', { template: 'report', userId });
},
});
19 changes: 14 additions & 5 deletions core/modules/messages/client/messages-list.hbs.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,20 @@
{{/each}}
</ul>
</div>
<div class="actions show">
<button type="button" class="button js-message-open-reactions-box" tabindex="-1">👍</button>
</div>
<div class="owner-actions {{#if showActions}}show{{/if}}">
<button type="button" class="button js-message-remove" tabindex="-1">x</button>
<div class="actions-container">
<div class="action show">
<button type="button" class="button js-message-open-reactions-box" tabindex="-1">👍</button>
</div>
{{#if showActions}}
<div class="action show">
<button type="button" class="button js-message-remove" tabindex="-1">x</button>
</div>
{{/if}}
{{#unless isOwner}}
<div class="action show">
<button type="button" class="button js-message-report" tabindex="-1">🚨</button>
</div>
{{/unless}}
</div>
{{/if}}
</div>
Expand Down
6 changes: 6 additions & 0 deletions core/modules/messages/client/messages-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Template.messagesListMessage.helpers({
date() { return this.message.createdAt.toDateString(); },
time() { return this.message.createdAt.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); },
showActions() { return Template.instance().moderationAllowed; },
isOwner() { return this.message.createdBy === Meteor.userId(); },
reactions() {
const userId = Meteor.userId();
return Object.entries(this.message.reactions || []).map(reaction => ({ reaction: reaction[0], amount: reaction[1].length, owner: reaction[1].indexOf(userId) > -1 }));
Expand All @@ -77,6 +78,11 @@ Template.messagesListMessage.events({
const messageId = templateInstance.data.message._id;
lp.notif.confirm('Delete message', `Do you really want to delete this message?`, () => Messages.remove(messageId));
},
'click .js-message-report'(event, templateInstance) {
const messageId = templateInstance.data.message._id;
const userId = templateInstance.data.message.createdBy;
Session.set('modal', { template: 'report', userId, messageId });
},
'click .js-message-open-reactions-box'(event, templateInstance) {
event.preventDefault();
event.stopPropagation();
Expand Down
91 changes: 41 additions & 50 deletions core/modules/messages/client/messages-list.scss
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,7 @@
}
}

&:hover .owner-actions.show {
opacity: 1;
pointer-events: all;
}

&:hover .actions.show {
&:hover .action.show {
opacity: 1;
pointer-events: all;
}
Expand All @@ -194,52 +189,48 @@
margin-right: 10px;
}

.owner-actions {
position: absolute;
right: 35px;
top: 8px;
pointer-events: none;
opacity: 0;
transition: opacity 0.25s;

.js-message-remove {
background-color: $light-red;
color: white;
width: 30px;
height: 30px;
padding: 0;
margin: 0;
border: 0;
font-size: 0.9rem;
font-weight: bold;
.actions-container {
.action {
position: absolute;
right: 0px;
top: 8px;
pointer-events: none;
opacity: 0;
transition: opacity 0.25s;

>button {
background-color: $light-blue;
color: white;
width: 30px;
height: 30px;
padding: 0;
margin: 0;
border: 0;
font-size: 0.9rem;
font-weight: bold;

&:hover {
background-color: darken($light-red, 10%);
&:hover {
background-color: darken($light-blue, 10%);
}
}
}
}

.actions {
position: absolute;
right: 0px;
top: 8px;
pointer-events: none;
opacity: 0;
transition: opacity 0.25s;

.js-message-open-reactions-box {
background-color: $light-blue;
color: white;
width: 30px;
height: 30px;
padding: 0;
margin: 0;
border: 0;
font-size: 0.9rem;
font-weight: bold;

&:hover {
background-color: darken($light-blue, 10%);
&:nth-child(2) {
right: 40px;
>button {
background-color: $light-red;

&:hover {
background-color: darken($light-red, 20%);
}
}
}
&:nth-child(3) {
right: 80px;
>button {
background-color: darken($light-red, 15%);
&:hover {
background-color: darken($light-red, 20%);
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/modules/notifications/client/notifications.hbs.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<h2 class="h2">
<span>Notifications</span>
<div class="tooltip">
<button type="button" class="mark-as-read js-notification-mark-all-as-read">📨</button>
<button type="button" class="emoji-before-tooltip js-notification-mark-all-as-read">📨</button>
<span class="tooltiptext">Mark all as read</span>
</div>
</h2>
Expand Down
6 changes: 4 additions & 2 deletions core/modules/notifications/client/notifications.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import "../../../client/variables";

button.mark-as-read {
button.emoji-before-tooltip {
background: none;
color: inherit;
border: none;
Expand All @@ -22,7 +22,7 @@ button.mark-as-read {
border-radius: 50%;
}

.mark-as-read:hover {
.emoji-before-tooltip:hover {
background-color: darken($light-blue, 15%);
border-radius: 35%;
transition: all 0.2s ease-in-out;
Expand Down Expand Up @@ -54,6 +54,8 @@ button.mark-as-read {
visibility: visible;
}



.h4 {
margin-top: -16px;
margin-bottom: 20px;
Expand Down

0 comments on commit 5bdc97f

Please sign in to comment.