aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+admin/moderation/abuse-list/abuse-list.component.ts
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/+admin/moderation/abuse-list/abuse-list.component.ts')
-rw-r--r--client/src/app/+admin/moderation/abuse-list/abuse-list.component.ts77
1 files changed, 55 insertions, 22 deletions
diff --git a/client/src/app/+admin/moderation/abuse-list/abuse-list.component.ts b/client/src/app/+admin/moderation/abuse-list/abuse-list.component.ts
index 427ec4d5d..1ea61ed37 100644
--- a/client/src/app/+admin/moderation/abuse-list/abuse-list.component.ts
+++ b/client/src/app/+admin/moderation/abuse-list/abuse-list.component.ts
@@ -2,7 +2,7 @@ import { SortMeta } from 'primeng/api'
2import { buildVideoEmbed, buildVideoLink } from 'src/assets/player/utils' 2import { buildVideoEmbed, buildVideoLink } from 'src/assets/player/utils'
3import { environment } from 'src/environments/environment' 3import { environment } from 'src/environments/environment'
4import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core' 4import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'
5import { DomSanitizer } from '@angular/platform-browser' 5import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
6import { ActivatedRoute, Params, Router } from '@angular/router' 6import { ActivatedRoute, Params, Router } from '@angular/router'
7import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core' 7import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core'
8import { Account, Actor, DropdownAction, Video, VideoService } from '@app/shared/shared-main' 8import { Account, Actor, DropdownAction, Video, VideoService } from '@app/shared/shared-main'
@@ -10,15 +10,20 @@ import { AbuseService, BlocklistService, VideoBlockService } from '@app/shared/s
10import { I18n } from '@ngx-translate/i18n-polyfill' 10import { I18n } from '@ngx-translate/i18n-polyfill'
11import { Abuse, AbuseState } from '@shared/models' 11import { Abuse, AbuseState } from '@shared/models'
12import { ModerationCommentModalComponent } from './moderation-comment-modal.component' 12import { ModerationCommentModalComponent } from './moderation-comment-modal.component'
13import truncate from 'lodash-es/truncate'
13 14
14export type ProcessedAbuse = Abuse & { 15export type ProcessedAbuse = Abuse & {
15 moderationCommentHtml?: string, 16 moderationCommentHtml?: string,
16 reasonHtml?: string 17 reasonHtml?: string
17 embedHtml?: string 18 embedHtml?: SafeHtml
18 updatedAt?: Date 19 updatedAt?: Date
19 20
20 // override bare server-side definitions with rich client-side definitions 21 // override bare server-side definitions with rich client-side definitions
21 reporterAccount: Account 22 reporterAccount?: Account
23 flaggedAccount?: Account
24
25 truncatedCommentHtml?: string
26 commentHtml?: string
22 27
23 video: Abuse['video'] & { 28 video: Abuse['video'] & {
24 channel: Abuse['video']['channel'] & { 29 channel: Abuse['video']['channel'] & {
@@ -92,11 +97,11 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn
92 { 97 {
93 label: this.i18n('Actions for the video'), 98 label: this.i18n('Actions for the video'),
94 isHeader: true, 99 isHeader: true,
95 isDisplayed: abuse => !abuse.video.deleted 100 isDisplayed: abuse => abuse.video && !abuse.video.deleted
96 }, 101 },
97 { 102 {
98 label: this.i18n('Block video'), 103 label: this.i18n('Block video'),
99 isDisplayed: abuse => !abuse.video.deleted && !abuse.video.blacklisted, 104 isDisplayed: abuse => abuse.video && !abuse.video.deleted && !abuse.video.blacklisted,
100 handler: abuse => { 105 handler: abuse => {
101 this.videoBlocklistService.blockVideo(abuse.video.id, undefined, true) 106 this.videoBlocklistService.blockVideo(abuse.video.id, undefined, true)
102 .subscribe( 107 .subscribe(
@@ -112,7 +117,7 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn
112 }, 117 },
113 { 118 {
114 label: this.i18n('Unblock video'), 119 label: this.i18n('Unblock video'),
115 isDisplayed: abuse => !abuse.video.deleted && abuse.video.blacklisted, 120 isDisplayed: abuse => abuse.video && !abuse.video.deleted && abuse.video.blacklisted,
116 handler: abuse => { 121 handler: abuse => {
117 this.videoBlocklistService.unblockVideo(abuse.video.id) 122 this.videoBlocklistService.unblockVideo(abuse.video.id)
118 .subscribe( 123 .subscribe(
@@ -128,7 +133,7 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn
128 }, 133 },
129 { 134 {
130 label: this.i18n('Delete video'), 135 label: this.i18n('Delete video'),
131 isDisplayed: abuse => !abuse.video.deleted, 136 isDisplayed: abuse => abuse.video && !abuse.video.deleted,
132 handler: async abuse => { 137 handler: async abuse => {
133 const res = await this.confirmService.confirm( 138 const res = await this.confirmService.confirm(
134 this.i18n('Do you really want to delete this video?'), 139 this.i18n('Do you really want to delete this video?'),
@@ -152,10 +157,12 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn
152 [ 157 [
153 { 158 {
154 label: this.i18n('Actions for the reporter'), 159 label: this.i18n('Actions for the reporter'),
155 isHeader: true 160 isHeader: true,
161 isDisplayed: abuse => !!abuse.reporterAccount
156 }, 162 },
157 { 163 {
158 label: this.i18n('Mute reporter'), 164 label: this.i18n('Mute reporter'),
165 isDisplayed: abuse => !!abuse.reporterAccount,
159 handler: async abuse => { 166 handler: async abuse => {
160 const account = abuse.reporterAccount as Account 167 const account = abuse.reporterAccount as Account
161 168
@@ -175,7 +182,7 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn
175 }, 182 },
176 { 183 {
177 label: this.i18n('Mute server'), 184 label: this.i18n('Mute server'),
178 isDisplayed: abuse => !abuse.reporterAccount.userId, 185 isDisplayed: abuse => abuse.reporterAccount && !abuse.reporterAccount.userId,
179 handler: async abuse => { 186 handler: async abuse => {
180 this.blocklistService.blockServerByInstance(abuse.reporterAccount.host) 187 this.blocklistService.blockServerByInstance(abuse.reporterAccount.host)
181 .subscribe( 188 .subscribe(
@@ -231,7 +238,7 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn
231 const queryParams: Params = {} 238 const queryParams: Params = {}
232 if (search) Object.assign(queryParams, { search }) 239 if (search) Object.assign(queryParams, { search })
233 240
234 this.router.navigate([ '/admin/moderation/video-abuses/list' ], { queryParams }) 241 this.router.navigate([ '/admin/moderation/abuses/list' ], { queryParams })
235 } 242 }
236 243
237 resetTableFilter () { 244 resetTableFilter () {
@@ -253,6 +260,10 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn
253 return Video.buildClientUrl(abuse.video.uuid) 260 return Video.buildClientUrl(abuse.video.uuid)
254 } 261 }
255 262
263 getCommentUrl (abuse: Abuse) {
264 return Video.buildClientUrl(abuse.comment.video.uuid) + ';threadId=' + abuse.comment.threadId
265 }
266
256 getVideoEmbed (abuse: Abuse) { 267 getVideoEmbed (abuse: Abuse) {
257 return buildVideoEmbed( 268 return buildVideoEmbed(
258 buildVideoLink({ 269 buildVideoLink({
@@ -300,23 +311,45 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn
300 }).subscribe( 311 }).subscribe(
301 async resultList => { 312 async resultList => {
302 this.totalRecords = resultList.total 313 this.totalRecords = resultList.total
303 const abuses = []
304 314
305 for (const abuse of resultList.data) { 315 this.abuses = []
306 Object.assign(abuse, { 316
307 reasonHtml: await this.toHtml(abuse.reason), 317 for (const a of resultList.data) {
308 moderationCommentHtml: await this.toHtml(abuse.moderationComment), 318 const abuse = a as ProcessedAbuse
309 embedHtml: this.sanitizer.bypassSecurityTrustHtml(this.getVideoEmbed(abuse)), 319
310 reporterAccount: new Account(abuse.reporterAccount) 320 abuse.reasonHtml = await this.toHtml(abuse.reason)
311 }) 321 abuse.moderationCommentHtml = await this.toHtml(abuse.moderationComment)
322
323 if (abuse.video) {
324 abuse.embedHtml = this.sanitizer.bypassSecurityTrustHtml(this.getVideoEmbed(abuse))
325
326 if (abuse.video.channel?.ownerAccount) {
327 abuse.video.channel.ownerAccount = new Account(abuse.video.channel.ownerAccount)
328 }
329 }
330
331 if (abuse.comment) {
332 if (abuse.comment.deleted) {
333 abuse.truncatedCommentHtml = abuse.commentHtml = this.i18n('Deleted comment')
334 } else {
335 const truncated = truncate(abuse.comment.text, { length: 100 })
336 abuse.truncatedCommentHtml = await this.markdownRenderer.textMarkdownToHTML(truncated, true)
337 abuse.commentHtml = await this.markdownRenderer.textMarkdownToHTML(abuse.comment.text, true)
338 }
339 }
340
341 if (abuse.reporterAccount) {
342 abuse.reporterAccount = new Account(abuse.reporterAccount)
343 }
344
345 if (abuse.flaggedAccount) {
346 abuse.flaggedAccount = new Account(abuse.flaggedAccount)
347 }
312 348
313 if (abuse.video.channel?.ownerAccount) abuse.video.channel.ownerAccount = new Account(abuse.video.channel.ownerAccount)
314 if (abuse.updatedAt === abuse.createdAt) delete abuse.updatedAt 349 if (abuse.updatedAt === abuse.createdAt) delete abuse.updatedAt
315 350
316 abuses.push(abuse as ProcessedAbuse) 351 this.abuses.push(abuse)
317 } 352 }
318
319 this.abuses = abuses
320 }, 353 },
321 354
322 err => this.notifier.error(err.message) 355 err => this.notifier.error(err.message)