+import { Component, OnInit } from '@angular/core'
+import { SortMeta } from 'primeng/api'
+import { Notifier, ServerService } from '@app/core'
+import { ConfirmService } from '../../../core'
+import { RestPagination, RestTable, VideoBlockService } from '../../../shared'
+import { VideoBlocklist, VideoBlockType } from '../../../../../../shared'
+import { I18n } from '@ngx-translate/i18n-polyfill'
+import { DropdownAction } from '../../../shared/buttons/action-dropdown.component'
+import { Video } from '../../../shared/video/video.model'
+import { MarkdownService } from '@app/shared/renderer'
+import { Params, ActivatedRoute, Router } from '@angular/router'
+import { filter, switchMap } from 'rxjs/operators'
+import { VideoService } from '@app/shared/video/video.service'
+
+@Component({
+ selector: 'my-video-block-list',
+ templateUrl: './video-block-list.component.html',
+ styleUrls: [ '../moderation.component.scss', './video-block-list.component.scss' ]
+})
+export class VideoBlockListComponent extends RestTable implements OnInit {
+ blocklist: (VideoBlocklist & { reasonHtml?: string })[] = []
+ totalRecords = 0
+ sort: SortMeta = { field: 'createdAt', order: -1 }
+ pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
+ listBlockTypeFilter: VideoBlockType = undefined
+
+ videoBlocklistActions: DropdownAction<VideoBlocklist>[][] = []
+
+ constructor (
+ private notifier: Notifier,
+ private serverService: ServerService,
+ private confirmService: ConfirmService,
+ private videoBlocklistService: VideoBlockService,
+ private markdownRenderer: MarkdownService,
+ private videoService: VideoService,
+ private route: ActivatedRoute,
+ private router: Router,
+ private i18n: I18n
+ ) {
+ super()
+
+ this.videoBlocklistActions = [
+ [
+ {
+ label: this.i18n('Internal actions'),
+ isHeader: true
+ },
+ {
+ label: this.i18n('Switch video block to manual'),
+ handler: videoBlock => {
+ this.videoBlocklistService.unblockVideo(videoBlock.video.id).pipe(
+ switchMap(_ => this.videoBlocklistService.blockVideo(videoBlock.video.id, undefined, true))
+ ).subscribe(
+ () => {
+ this.notifier.success(this.i18n('Video {{name}} switched to manual block.', { name: videoBlock.video.name }))
+ this.loadData()
+ },
+
+ err => this.notifier.error(err.message)
+ )
+ }
+ }
+ ],
+ [
+ {
+ label: this.i18n('Actions for the video'),
+ isHeader: true,
+ },
+ {
+ label: this.i18n('Unblock video'),
+ handler: videoBlock => this.unblockVideo(videoBlock)
+ },
+
+ {
+ label: this.i18n('Delete video'),
+ handler: async videoBlock => {
+ const res = await this.confirmService.confirm(
+ this.i18n('Do you really want to delete this video?'),
+ this.i18n('Delete')
+ )
+ if (res === false) return
+
+ this.videoService.removeVideo(videoBlock.video.id)
+ .subscribe(
+ () => {
+ this.notifier.success(this.i18n('Video deleted.'))
+ },
+
+ err => this.notifier.error(err.message)
+ )
+ }
+ }
+ ]
+ ]
+ }
+
+ ngOnInit () {
+ this.serverService.getConfig()
+ .subscribe(config => {
+ // don't filter if auto-blacklist is not enabled as this will be the only list
+ if (config.autoBlacklist.videos.ofUsers.enabled) {
+ this.listBlockTypeFilter = VideoBlockType.MANUAL
+ }
+ })
+
+ this.initialize()
+
+ this.route.queryParams
+ .pipe(filter(params => params.search !== undefined && params.search !== null))
+ .subscribe(params => {
+ this.search = params.search
+ this.setTableFilter(params.search)
+ this.loadData()
+ })
+ }
+
+ ngAfterViewInit () {
+ if (this.search) this.setTableFilter(this.search)
+ }
+
+ /* Table filter functions */
+ onBlockSearch (event: Event) {
+ this.onSearch(event)
+ this.setQueryParams((event.target as HTMLInputElement).value)
+ }
+
+ setQueryParams (search: string) {
+ const queryParams: Params = {}
+ if (search) Object.assign(queryParams, { search })
+ this.router.navigate([ '/admin/moderation/video-blocks/list' ], { queryParams })
+ }
+
+ resetTableFilter () {
+ this.setTableFilter('')
+ this.setQueryParams('')
+ this.resetSearch()
+ }
+ /* END Table filter functions */
+
+ getIdentifier () {
+ return 'VideoBlockListComponent'
+ }
+
+ getVideoUrl (videoBlock: VideoBlocklist) {
+ return Video.buildClientUrl(videoBlock.video.uuid)
+ }
+
+ booleanToText (value: boolean) {
+ if (value === true) return this.i18n('yes')
+
+ return this.i18n('no')
+ }
+
+ toHtml (text: string) {
+ return this.markdownRenderer.textMarkdownToHTML(text)
+ }
+
+ async unblockVideo (entry: VideoBlocklist) {
+ const confirmMessage = this.i18n(
+ 'Do you really want to unblock this video? It will be available again in the videos list.'
+ )
+
+ const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblock'))
+ if (res === false) return
+
+ this.videoBlocklistService.unblockVideo(entry.video.id).subscribe(
+ () => {
+ this.notifier.success(this.i18n('Video {{name}} unblocked.', { name: entry.video.name }))
+ this.loadData()
+ },
+
+ err => this.notifier.error(err.message)
+ )
+ }
+
+ protected loadData () {
+ this.videoBlocklistService.listBlocks({
+ pagination: this.pagination,
+ sort: this.sort,
+ search: this.search,
+ })
+ .subscribe(
+ async resultList => {
+ this.totalRecords = resultList.total
+
+ this.blocklist = resultList.data
+
+ for (const element of this.blocklist) {
+ Object.assign(element, { reasonHtml: await this.toHtml(element.reason) })
+ }
+ },
+
+ err => this.notifier.error(err.message)
+ )
+ }
+}