feat(community): basic "report profile"

This commit is contained in:
SabreCat
2023-08-31 17:02:07 -05:00
parent ce7d51a20c
commit a8f5e25d38
7 changed files with 199 additions and 6 deletions
@@ -3,6 +3,7 @@
<creator-intro />
<profileModal />
<report-flag-modal />
<report-member-modal />
<send-gift-modal />
<select-user-modal />
<b-navbar
@@ -732,6 +733,7 @@ import creatorIntro from '../creatorIntro';
import notificationMenu from './notificationsDropdown';
import profileModal from '../userMenu/profileModal';
import reportFlagModal from '../chat/reportFlagModal';
import reportMemberModal from '../members/reportMemberModal';
import sendGiftModal from '@/components/payments/sendGiftModal';
import selectUserModal from '@/components/payments/selectUserModal';
import sync from '@/mixins/sync';
@@ -744,6 +746,7 @@ export default {
notificationMenu,
profileModal,
reportFlagModal,
reportMemberModal,
sendGiftModal,
selectUserModal,
userDropdown,
@@ -0,0 +1,149 @@
<template>
<b-modal
id="report-profile"
:title="$t('reportPlayer')"
size="md"
:hide-footer="true"
>
<div slot="modal-header">
<h2 class="mt-2 mb-0"> {{ $t('reportPlayer') }} </h2>
<close-x
@close="close()"
/>
</div>
<div>
<blockquote>
<strong> {{ displayName }} </strong>
<p class="mb-0"> {{ username }} </p>
</blockquote>
<div>
<strong>{{ $t('whyReportingPlayer') }}</strong>
<textarea
v-model="reportComment"
class="form-control"
:placeholder="$t('whyReportingPlayerPlaceholder')"
></textarea>
</div>
<p
class="mb-2"
v-html="$t('playerReportModalBody', abuseFlagModalBody)">
</p>
</div>
<div class="footer text-center d-flex flex-column">
<button
class="btn btn-danger mx-auto px-3 mb-4"
@click="reportAbuse()"
>
{{ $t('report') }}
</button>
<a
class="cancel-link"
@click.prevent="close()"
>{{ $t('cancel') }}</a>
</div>
</b-modal>
</template>
<style lang="scss">
#report-profile {
.modal-header {
padding: 24px;
border-bottom: none;
}
.modal-body {
padding: 0px 24px 24px 24px;
}
}
</style>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
strong, p {
line-height: 1.71;
}
h2 {
color: $maroon-100;
}
blockquote {
border-radius: 2px;
background-color: $gray-700;
padding: .5rem 1rem;
}
textarea {
margin-top: 1em;
margin-bottom: 1em;
border-radius: 2px;
border: solid 1px $gray-400;
min-height: 106px;
}
.footer {
padding: 1rem 1rem 0rem 1rem;
}
</style>
<script>
import closeX from '@/components/ui/closeX';
import notifications from '@/mixins/notifications';
import markdownDirective from '@/directives/markdown';
import { userStateMixin } from '../../mixins/userState';
export default {
components: {
closeX,
},
directives: {
markdown: markdownDirective,
},
mixins: [notifications, userStateMixin],
data () {
const abuseFlagModalBody = {
firstLinkStart: '<a href="/static/community-guidelines" target="_blank">',
secondLinkStart: '<a href="/static/terms" target="_blank">',
linkEnd: '</a>',
};
return {
abuseFlagModalBody,
displayName: '',
username: '',
reportComment: '',
};
},
mounted () {
this.$root.$on('habitica::report-profile', this.handleReport);
},
beforeDestroy () {
this.$root.$off('habitica::report-profile', this.handleReport);
},
methods: {
close () {
this.$root.$emit('bv::hide::modal', 'report-profile');
},
async reportAbuse () {
this.text(this.$t('abuseReported'));
const result = await this.$store.dispatch('members:reportMember', {
memberId: this.memberId,
source: this.$route.fullPath,
comment: this.reportComment,
});
this.$root.$emit('habitica:report-profile-result', result);
this.close();
},
handleReport (data) {
if (!data.memberId) return;
this.displayName = data.displayName;
this.username = `@${data.username}`;
this.memberId = data.memberId;
this.reportComment = '';
this.$root.$emit('bv::show::modal', 'report-profile');
},
},
};
</script>
@@ -58,6 +58,18 @@
v-html="icons.positive"
></div>
</button>
<button
v-if="user._id !== userLoggedIn._id"
v-b-tooltip.hover.right="$t('reportPlayer')"
class="btn d-flex justify-content-center align-items-center"
@click="reportUser()"
>
<div
v-once
class="svg-icon block-icon color"
v-html="icons.report"
></div>
</button>
<button
v-if="hasPermission(userLoggedIn, 'moderator')"
v-b-tooltip.hover.right="'Admin - Toggle Tools'"
@@ -523,6 +535,11 @@
color: $gray-100;
}
.report-icon {
width: 16px;
color: $gray-100;
}
.photo img {
max-width: 100%;
}
@@ -697,7 +714,6 @@
}
.info-item-value {
display: inline-block;
float: right;
}
}
@@ -758,6 +774,7 @@ import lock from '@/assets/svg/lock.svg';
import challenge from '@/assets/svg/challenge.svg';
import member from '@/assets/svg/member-icon.svg';
import staff from '@/assets/svg/tier-staff.svg';
import report from '@/assets/svg/report.svg';
import error404 from '../404';
import externalLinks from '../../mixins/externalLinks';
import { userCustomStateMixin } from '../../mixins/userState';
@@ -788,6 +805,7 @@ export default {
lock,
member,
staff,
report,
}),
adminToolsLoaded: false,
userIdToMessage: '',
@@ -1071,6 +1089,13 @@ export default {
const status = this.achievementsCategories[categoryKey].open;
this.achievementsCategories[categoryKey].open = !status;
},
reportUser () {
this.$root.$emit('habitica::report-profile', {
memberId: this.user._id,
displayName: this.user.profile.name,
username: this.user.auth.local.username,
});
},
},
};
</script>
@@ -114,3 +114,13 @@ export async function getPurchaseHistory (store, payload) {
const response = await axios.get(`${apiv4Prefix}/members/${payload.memberId}/purchase-history`);
return response.data.data;
}
export async function reportMember (store, payload) {
const url = `${apiv4Prefix}/members/${payload.memberId}/flag`;
const data = {
comment: payload.comment,
source: payload.source,
};
const response = await axios.post(url, data);
return response.data.data;
}
+5 -1
View File
@@ -222,5 +222,9 @@
"question": "Question",
"questionDescriptionText": "It's okay to ask your questions in your primary language if you aren't comfortable speaking in English.",
"questionPlaceholder": "Ask your question here",
"submitQuestion": "Submit Question"
"submitQuestion": "Submit Question",
"reportPlayer": "Report Player",
"whyReportingPlayer": "Why are you reporting this player?",
"whyReportingPlayerPlaceholder": "Reason for report",
"playerReportModalBody": "You should only report a player who violates the <%= firstLinkStart %>Community Guidelines<%= linkEnd %> and/or <%= secondLinkStart %>Terms of Service<%= linkEnd %>. Submitting a false report is a violation of Habiticas Community Guidelines."
}
@@ -82,7 +82,7 @@ export default class ProfileReporter extends ChatReporter {
return timestamp;
}
notify (flaggedUser, comment) {
notify (flaggedUser, comment, source) {
let emailVariables = this.getEmailVariables(flaggedUser);
emailVariables = emailVariables.concat([
{ name: 'REPORTER_COMMENT', content: comment || '' },
@@ -93,7 +93,8 @@ export default class ProfileReporter extends ChatReporter {
slack.sendProfileFlagNotification({
reporter: this.user,
flaggedUser,
comment,
userComment: comment,
source,
});
}
+3 -2
View File
@@ -180,10 +180,11 @@ function sendProfileFlagNotification ({
reporter,
flaggedUser,
userComment,
source,
}) {
const title = 'User Profile Report';
const titleLink = `${BASE_URL}/static/front/#?memberId=${flaggedUser._id}`;
let text = `@${reporter.auth.local.username} (${reporter._id}; language: ${reporter.preferences.language}) flagged @${flaggedUser.auth.local.username}'s profile`;
const titleLink = `${BASE_URL}/profile/${flaggedUser._id}`;
let text = `@${reporter.auth.local.username} (${reporter._id}; language: ${reporter.preferences.language}) flagged @${flaggedUser.auth.local.username}'s profile from ${source}`;
if (userComment) {
text += ` and commented: ${userComment}`;
}