diff options
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.ts | 77 |
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' | |||
2 | import { buildVideoEmbed, buildVideoLink } from 'src/assets/player/utils' | 2 | import { buildVideoEmbed, buildVideoLink } from 'src/assets/player/utils' |
3 | import { environment } from 'src/environments/environment' | 3 | import { environment } from 'src/environments/environment' |
4 | import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core' | 4 | import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core' |
5 | import { DomSanitizer } from '@angular/platform-browser' | 5 | import { DomSanitizer, SafeHtml } from '@angular/platform-browser' |
6 | import { ActivatedRoute, Params, Router } from '@angular/router' | 6 | import { ActivatedRoute, Params, Router } from '@angular/router' |
7 | import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core' | 7 | import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core' |
8 | import { Account, Actor, DropdownAction, Video, VideoService } from '@app/shared/shared-main' | 8 | import { Account, Actor, DropdownAction, Video, VideoService } from '@app/shared/shared-main' |
@@ -10,15 +10,20 @@ import { AbuseService, BlocklistService, VideoBlockService } from '@app/shared/s | |||
10 | import { I18n } from '@ngx-translate/i18n-polyfill' | 10 | import { I18n } from '@ngx-translate/i18n-polyfill' |
11 | import { Abuse, AbuseState } from '@shared/models' | 11 | import { Abuse, AbuseState } from '@shared/models' |
12 | import { ModerationCommentModalComponent } from './moderation-comment-modal.component' | 12 | import { ModerationCommentModalComponent } from './moderation-comment-modal.component' |
13 | import truncate from 'lodash-es/truncate' | ||
13 | 14 | ||
14 | export type ProcessedAbuse = Abuse & { | 15 | export 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) |