]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts
Bumped to version v5.2.1
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-abuse-list / abuse-list-table.component.ts
index eeb9f128b623e744a1212cba87900f4e0116994f..d8470e927768e9054099987b18287c1a42ffee54 100644 (file)
@@ -1,30 +1,28 @@
 import * as debug from 'debug'
 import truncate from 'lodash-es/truncate'
 import { SortMeta } from 'primeng/api'
-import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils'
-import { environment } from 'src/environments/environment'
-import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core'
-import { DomSanitizer } from '@angular/platform-browser'
+import { Component, Input, OnInit, ViewChild } from '@angular/core'
 import { ActivatedRoute, Router } from '@angular/router'
 import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core'
 import { Account, Actor, DropdownAction, Video, VideoService } from '@app/shared/shared-main'
 import { AbuseService, BlocklistService, VideoBlockService } from '@app/shared/shared-moderation'
 import { VideoCommentService } from '@app/shared/shared-video-comment'
+import { logger } from '@root-helpers/logger'
 import { AbuseState, AdminAbuse } from '@shared/models'
+import { AdvancedInputFilter } from '../shared-forms'
 import { AbuseMessageModalComponent } from './abuse-message-modal.component'
 import { ModerationCommentModalComponent } from './moderation-comment-modal.component'
 import { ProcessedAbuse } from './processed-abuse.model'
 
-const logger = debug('peertube:moderation:AbuseListTableComponent')
+const debugLogger = debug('peertube:moderation:AbuseListTableComponent')
 
 @Component({
   selector: 'my-abuse-list-table',
   templateUrl: './abuse-list-table.component.html',
   styleUrls: [ '../shared-moderation/moderation.scss', './abuse-list-table.component.scss' ]
 })
-export class AbuseListTableComponent extends RestTable implements OnInit, AfterViewInit {
+export class AbuseListTableComponent extends RestTable implements OnInit {
   @Input() viewType: 'admin' | 'user'
-  @Input() baseRoute: string
 
   @ViewChild('abuseMessagesModal', { static: true }) abuseMessagesModal: AbuseMessageModalComponent
   @ViewChild('moderationCommentModal', { static: true }) moderationCommentModal: ModerationCommentModalComponent
@@ -36,6 +34,34 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
 
   abuseActions: DropdownAction<ProcessedAbuse>[][] = []
 
+  inputFilters: AdvancedInputFilter[] = [
+    {
+      title: $localize`Advanced filters`,
+      children: [
+        {
+          value: 'state:pending',
+          label: $localize`Unsolved reports`
+        },
+        {
+          value: 'state:accepted',
+          label: $localize`Accepted reports`
+        },
+        {
+          value: 'state:rejected',
+          label: $localize`Refused reports`
+        },
+        {
+          value: 'videoIs:blacklisted',
+          label: $localize`Reports with blocked videos`
+        },
+        {
+          value: 'videoIs:deleted',
+          label: $localize`Reports with deleted videos`
+        }
+      ]
+    }
+  ]
+
   constructor (
     protected route: ActivatedRoute,
     protected router: Router,
@@ -46,8 +72,7 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
     private videoService: VideoService,
     private videoBlocklistService: VideoBlockService,
     private confirmService: ConfirmService,
-    private markdownRenderer: MarkdownService,
-    private sanitizer: DomSanitizer
+    private markdownRenderer: MarkdownService
   ) {
     super()
   }
@@ -66,11 +91,6 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
     ]
 
     this.initialize()
-    this.listenToSearchChange()
-  }
-
-  ngAfterViewInit () {
-    if (this.search) this.setTableFilter(this.search, false)
   }
 
   isAdminView () {
@@ -86,7 +106,7 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
   }
 
   onModerationCommentUpdated () {
-    this.loadData()
+    this.reloadData()
   }
 
   isAbuseAccepted (abuse: AdminAbuse) {
@@ -98,62 +118,46 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
   }
 
   getVideoUrl (abuse: AdminAbuse) {
-    return Video.buildClientUrl(abuse.video.uuid)
+    return Video.buildWatchUrl(abuse.video)
   }
 
   getCommentUrl (abuse: AdminAbuse) {
-    return Video.buildClientUrl(abuse.comment.video.uuid) + ';threadId=' + abuse.comment.threadId
+    return Video.buildWatchUrl(abuse.comment.video) + ';threadId=' + abuse.comment.threadId
   }
 
   getAccountUrl (abuse: ProcessedAbuse) {
-    return '/accounts/' + abuse.flaggedAccount.nameWithHost
-  }
-
-  getVideoEmbed (abuse: AdminAbuse) {
-    return buildVideoOrPlaylistEmbed(
-      buildVideoLink({
-        baseUrl: `${environment.originServerUrl}/videos/embed/${abuse.video.uuid}`,
-        title: false,
-        warningTitle: false,
-        startTime: abuse.video.startAt,
-        stopTime: abuse.video.endAt
-      }),
-      abuse.video.name
-    )
-  }
-
-  switchToDefaultAvatar ($event: Event) {
-    ($event.target as HTMLImageElement).src = Account.GET_DEFAULT_AVATAR_URL()
+    return '/a/' + abuse.flaggedAccount.nameWithHost
   }
 
   async removeAbuse (abuse: AdminAbuse) {
     const res = await this.confirmService.confirm($localize`Do you really want to delete this abuse report?`, $localize`Delete`)
     if (res === false) return
 
-    this.abuseService.removeAbuse(abuse).subscribe(
-      () => {
-        this.notifier.success($localize`Abuse deleted.`)
-        this.loadData()
-      },
+    this.abuseService.removeAbuse(abuse)
+      .subscribe({
+        next: () => {
+          this.notifier.success($localize`Abuse deleted.`)
+          this.reloadData()
+        },
 
-      err => this.notifier.error(err.message)
-    )
+        error: err => this.notifier.error(err.message)
+      })
   }
 
   updateAbuseState (abuse: AdminAbuse, state: AbuseState) {
     this.abuseService.updateAbuse(abuse, { state })
-      .subscribe(
-        () => this.loadData(),
+      .subscribe({
+        next: () => this.reloadData(),
 
-        err => this.notifier.error(err.message)
-      )
+        error: err => this.notifier.error(err.message)
+      })
   }
 
   onCountMessagesUpdated (event: { abuseId: number, countMessages: number }) {
     const abuse = this.abuses.find(a => a.id === event.abuseId)
 
     if (!abuse) {
-      console.error('Cannot find abuse %d.', event.abuseId)
+      logger.error(`Cannot find abuse ${event.abuseId}`)
       return
     }
 
@@ -166,12 +170,13 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
 
   isLocalAbuse (abuse: AdminAbuse) {
     if (this.viewType === 'user') return true
+    if (!abuse.reporterAccount) return false
 
     return Actor.IS_LOCAL(abuse.reporterAccount.host)
   }
 
-  protected loadData () {
-    logger('Loading data.')
+  protected reloadDataInternal () {
+    debugLogger('Loading data.')
 
     const options = {
       pagination: this.pagination,
@@ -183,55 +188,53 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
       ? this.abuseService.getAdminAbuses(options)
       : this.abuseService.getUserAbuses(options)
 
-    return observable.subscribe(
-        async resultList => {
-          this.totalRecords = resultList.total
-
-          this.abuses = []
+    return observable.subscribe({
+      next: async resultList => {
+        this.totalRecords = resultList.total
 
-          for (const a of resultList.data) {
-            const abuse = a as ProcessedAbuse
+        this.abuses = []
 
-            abuse.reasonHtml = await this.toHtml(abuse.reason)
+        for (const a of resultList.data) {
+          const abuse = a as ProcessedAbuse
 
-            if (abuse.moderationComment) {
-              abuse.moderationCommentHtml = await this.toHtml(abuse.moderationComment)
-            }
+          abuse.reasonHtml = await this.toHtml(abuse.reason)
 
-            if (abuse.video) {
-              abuse.embedHtml = this.sanitizer.bypassSecurityTrustHtml(this.getVideoEmbed(abuse))
+          if (abuse.moderationComment) {
+            abuse.moderationCommentHtml = await this.toHtml(abuse.moderationComment)
+          }
 
-              if (abuse.video.channel?.ownerAccount) {
-                abuse.video.channel.ownerAccount = new Account(abuse.video.channel.ownerAccount)
-              }
+          if (abuse.video) {
+            if (abuse.video.channel?.ownerAccount) {
+              abuse.video.channel.ownerAccount = new Account(abuse.video.channel.ownerAccount)
             }
+          }
 
-            if (abuse.comment) {
-              if (abuse.comment.deleted) {
-                abuse.truncatedCommentHtml = abuse.commentHtml = $localize`Deleted comment`
-              } else {
-                const truncated = truncate(abuse.comment.text, { length: 100 })
-                abuse.truncatedCommentHtml = await this.markdownRenderer.textMarkdownToHTML(truncated, true)
-                abuse.commentHtml = await this.markdownRenderer.textMarkdownToHTML(abuse.comment.text, true)
-              }
+          if (abuse.comment) {
+            if (abuse.comment.deleted) {
+              abuse.truncatedCommentHtml = abuse.commentHtml = $localize`Deleted comment`
+            } else {
+              const truncated = truncate(abuse.comment.text, { length: 100 })
+              abuse.truncatedCommentHtml = await this.markdownRenderer.textMarkdownToHTML({ markdown: truncated, withHtml: true })
+              abuse.commentHtml = await this.markdownRenderer.textMarkdownToHTML({ markdown: abuse.comment.text, withHtml: true })
             }
+          }
 
-            if (abuse.reporterAccount) {
-              abuse.reporterAccount = new Account(abuse.reporterAccount)
-            }
+          if (abuse.reporterAccount) {
+            abuse.reporterAccount = new Account(abuse.reporterAccount)
+          }
 
-            if (abuse.flaggedAccount) {
-              abuse.flaggedAccount = new Account(abuse.flaggedAccount)
-            }
+          if (abuse.flaggedAccount) {
+            abuse.flaggedAccount = new Account(abuse.flaggedAccount)
+          }
 
-            if (abuse.updatedAt === abuse.createdAt) delete abuse.updatedAt
+          if (abuse.updatedAt === abuse.createdAt) delete abuse.updatedAt
 
-            this.abuses.push(abuse)
-          }
-        },
+          this.abuses.push(abuse)
+        }
+      },
 
-        err => this.notifier.error(err.message)
-      )
+      error: err => this.notifier.error(err.message)
+    })
   }
 
   private buildInternalActions (): DropdownAction<ProcessedAbuse>[] {
@@ -269,7 +272,8 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
       },
       {
         label: $localize`Delete report`,
-        handler: abuse => this.isAdminView() && this.removeAbuse(abuse)
+        handler: abuse => this.removeAbuse(abuse),
+        isDisplayed: () => this.isAdminView()
       }
     ]
   }
@@ -335,16 +339,16 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
         label: $localize`Block video`,
         isDisplayed: abuse => abuse.video && !abuse.video.deleted && !abuse.video.blacklisted,
         handler: abuse => {
-          this.videoBlocklistService.blockVideo(abuse.video.id, undefined, abuse.video.channel.isLocal)
-            .subscribe(
-              () => {
+          this.videoBlocklistService.blockVideo([ { videoId: abuse.video.id, unfederate: abuse.video.channel.isLocal } ])
+            .subscribe({
+              next: () => {
                 this.notifier.success($localize`Video blocked.`)
 
                 this.updateAbuseState(abuse, AbuseState.ACCEPTED)
               },
 
-              err => this.notifier.error(err.message)
-            )
+              error: err => this.notifier.error(err.message)
+            })
         }
       },
       {
@@ -352,15 +356,15 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
         isDisplayed: abuse => abuse.video && !abuse.video.deleted && abuse.video.blacklisted,
         handler: abuse => {
           this.videoBlocklistService.unblockVideo(abuse.video.id)
-            .subscribe(
-              () => {
+            .subscribe({
+              next: () => {
                 this.notifier.success($localize`Video unblocked.`)
 
                 this.updateAbuseState(abuse, AbuseState.ACCEPTED)
               },
 
-              err => this.notifier.error(err.message)
-            )
+              error: err => this.notifier.error(err.message)
+            })
         }
       },
       {
@@ -374,15 +378,15 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
           if (res === false) return
 
           this.videoService.removeVideo(abuse.video.id)
-            .subscribe(
-              () => {
+            .subscribe({
+              next: () => {
                 this.notifier.success($localize`Video deleted.`)
 
                 this.updateAbuseState(abuse, AbuseState.ACCEPTED)
               },
 
-              err => this.notifier.error(err.message)
-            )
+              error: err => this.notifier.error(err.message)
+            })
         }
       }
     ]
@@ -409,15 +413,15 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
           if (res === false) return
 
           this.commentService.deleteVideoComment(abuse.comment.video.id, abuse.comment.id)
-            .subscribe(
-              () => {
+            .subscribe({
+              next: () => {
                 this.notifier.success($localize`Comment deleted.`)
 
                 this.updateAbuseState(abuse, AbuseState.ACCEPTED)
               },
 
-              err => this.notifier.error(err.message)
-            )
+              error: err => this.notifier.error(err.message)
+            })
         }
       }
     ]
@@ -425,28 +429,28 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
 
   private muteAccountHelper (account: Account) {
     this.blocklistService.blockAccountByInstance(account)
-      .subscribe(
-        () => {
+      .subscribe({
+        next: () => {
           this.notifier.success($localize`Account ${account.nameWithHost} muted by the instance.`)
           account.mutedByInstance = true
         },
 
-        err => this.notifier.error(err.message)
-      )
+        error: err => this.notifier.error(err.message)
+      })
   }
 
   private muteServerHelper (host: string) {
     this.blocklistService.blockServerByInstance(host)
-      .subscribe(
-        () => {
+      .subscribe({
+        next: () => {
           this.notifier.success($localize`Server ${host} muted by the instance.`)
         },
 
-        err => this.notifier.error(err.message)
-      )
+        error: err => this.notifier.error(err.message)
+      })
   }
 
   private toHtml (text: string) {
-    return this.markdownRenderer.textMarkdownToHTML(text)
+    return this.markdownRenderer.textMarkdownToHTML({ markdown: text })
   }
 }