PronounsPage/components/AbuseReports.vue

132 lines
5.1 KiB
Vue

<template>
<Table :data="abuseReports" :columns="abuseReports.length && abuseReports[0].snapshot ? 5 : 4">
<template #header>
<div class="bold text-nowrap">
Suspicious account
</div>
<div class="bold text-nowrap">
Reported by
</div>
<div class="bold text-nowrap">
Comment
</div>
<div class="bold text-nowrap">
Action
</div>
<div v-if="abuseReports.length && abuseReports[0].snapshot" class="bold text-nowrap">
Snapshot
</div>
</template>
<template #row="s">
<template v-if="s && s.el.susUsername">
<div>
<a :href="`https://pronouns.page/@${s.el.susUsername}`" target="_blank" rel="noopener">@{{ s.el.susUsername }}</a>
<ul v-if="s.el.profiles" class="small list-inline">
<li v-for="locale in s.el.profiles.split(',')" class="list-inline-item mt-2">
<LocaleLink :locale="locale" :link="`/@${s.el.susUsername}`">
{{ $locales[locale]?.name || locale }}
</LocaleLink>
</li>
</ul>
</div>
<div>
<span v-if="s.el.isAutomatic" class="badge bg-info">
Keyword found
</span>
<a v-else :href="`https://pronouns.page/@${s.el.reporterUsername}`" target="_blank" rel="noopener">@{{ s.el.reporterUsername }}</a>
<small>({{ $datetime($ulidTime(s.el.id)) }})</small>
</div>
<div class="small" v-html="s.el.isAutomatic ? formatComment(s.el.comment) : s.el.comment"></div>
<div>
<span v-if="s.el.isHandled" class="badge bg-success">
Case closed
</span>
<template v-else>
<a
v-if="allowQueue && canBeInQueue(s.el)"
href="#"
class="badge bg-light text-primary border border-primary m-1"
@click.prevent="startQueue(s.el)"
>
<Icon v="play" />
Start a moderation queue here
</a>
<a
v-if="allowResolving"
href="#"
class="badge bg-light text-success border border-success m-1"
@click.prevent="handleReport(s.el.id)"
>
<Icon v="thumbs-up" />
I checked the profile, it's OK.
</a>
</template>
</div>
<div v-if="s.el.snapshot">
<a
href="#"
class="badge bg-info"
@click.prevent="dialogue.alertRaw(s.el.snapshot)"
>
<Icon v="camera-polaroid" />
Snapshot
</a>
</div>
</template>
</template>
</Table>
</template>
<script>
import useConfig from '../composables/useConfig.ts';
import useDialogue from '../composables/useDialogue.ts';
export default {
props: {
abuseReports: { required: true },
allowResolving: { type: Boolean },
allowQueue: { type: Boolean },
},
setup() {
return {
config: useConfig(),
dialogue: useDialogue(),
};
},
methods: {
formatComment(comment) {
return comment
.split(', ')
.map((x) => x.replace(/^(.*) \((.*)\)$/, '<dfn title="$2">$1</dfn>'))
.join(', ');
},
async handleReport(id) {
// await this.dialogue.confirm('Are you sure you want to mark this report as handled?', 'success');
await this.dialogue.postWithAlertOnError(`/api/admin/reports/handle/${id}`);
this.abuseReports = this.abuseReports.map((r) => {
if (r.id === id) {
r.isHandled = true;
}
return r;
});
},
canBeInQueue(report) {
return report.profiles && report.profiles.split(',').includes(this.config.locale);
},
startQueue(report) {
localStorage.setItem('moderationQueue', [...new Set(this.abuseReports.filter((r) => this.canBeInQueue(r)).map((r) => r.susUsername))]);
localStorage.setItem('moderationQueueCaret', report.susUsername);
this.$router.push(`/@${report.susUsername}`);
},
},
};
</script>
<style scoped lang="scss">
:deep(.row-header), :deep(.row-content) {
grid-template-columns: 10em 10em 1fr 13.5em 5.5em;
word-wrap: break-word;
}
</style>