preserve original variable names server-side
[oweals/peertube.git] / client / src / app / +admin / moderation / video-block-list / video-block-list.component.ts
1 import { Component, OnInit } from '@angular/core'
2 import { SortMeta } from 'primeng/api'
3 import { Notifier, ServerService } from '@app/core'
4 import { ConfirmService } from '../../../core'
5 import { RestPagination, RestTable, VideoBlockService } from '../../../shared'
6 import { VideoBlacklist, VideoBlacklistType } from '../../../../../../shared'
7 import { I18n } from '@ngx-translate/i18n-polyfill'
8 import { DropdownAction } from '../../../shared/buttons/action-dropdown.component'
9 import { Video } from '../../../shared/video/video.model'
10 import { MarkdownService } from '@app/shared/renderer'
11 import { Params, ActivatedRoute, Router } from '@angular/router'
12 import { filter, switchMap } from 'rxjs/operators'
13 import { VideoService } from '@app/shared/video/video.service'
14
15 @Component({
16   selector: 'my-video-block-list',
17   templateUrl: './video-block-list.component.html',
18   styleUrls: [ '../moderation.component.scss', './video-block-list.component.scss' ]
19 })
20 export class VideoBlockListComponent extends RestTable implements OnInit {
21   blocklist: (VideoBlacklist & { reasonHtml?: string })[] = []
22   totalRecords = 0
23   sort: SortMeta = { field: 'createdAt', order: -1 }
24   pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
25   blocklistTypeFilter: VideoBlacklistType = undefined
26
27   videoBlocklistActions: DropdownAction<VideoBlacklist>[][] = []
28
29   constructor (
30     private notifier: Notifier,
31     private serverService: ServerService,
32     private confirmService: ConfirmService,
33     private videoBlocklistService: VideoBlockService,
34     private markdownRenderer: MarkdownService,
35     private videoService: VideoService,
36     private route: ActivatedRoute,
37     private router: Router,
38     private i18n: I18n
39   ) {
40     super()
41
42     this.videoBlocklistActions = [
43       [
44         {
45           label: this.i18n('Internal actions'),
46           isHeader: true
47         },
48         {
49           label: this.i18n('Switch video block to manual'),
50           handler: videoBlock => {
51             this.videoBlocklistService.unblockVideo(videoBlock.video.id).pipe(
52               switchMap(_ => this.videoBlocklistService.blockVideo(videoBlock.video.id, undefined, true))
53             ).subscribe(
54               () => {
55                 this.notifier.success(this.i18n('Video {{name}} switched to manual block.', { name: videoBlock.video.name }))
56                 this.loadData()
57               },
58         
59               err => this.notifier.error(err.message)
60             )
61           }
62         }
63       ],
64       [
65         {
66           label: this.i18n('Actions for the video'),
67           isHeader: true,
68         },
69         {
70           label: this.i18n('Unblock video'),
71           handler: videoBlock => this.unblockVideo(videoBlock)
72         },
73
74         {
75           label: this.i18n('Delete video'),
76           handler: async videoBlock => {
77             const res = await this.confirmService.confirm(
78               this.i18n('Do you really want to delete this video?'),
79               this.i18n('Delete')
80             )
81             if (res === false) return
82
83             this.videoService.removeVideo(videoBlock.video.id)
84               .subscribe(
85                 () => {
86                   this.notifier.success(this.i18n('Video deleted.'))
87                 },
88
89                 err => this.notifier.error(err.message)
90               )
91           }
92         }
93       ]
94     ]
95   }
96
97   ngOnInit () {
98     this.serverService.getConfig()
99         .subscribe(config => {
100           // don't filter if auto-blacklist is not enabled as this will be the only list
101           if (config.autoBlacklist.videos.ofUsers.enabled) {
102             this.blocklistTypeFilter = VideoBlacklistType.MANUAL
103           }
104         })
105
106     this.initialize()
107
108     this.route.queryParams
109       .pipe(filter(params => params.search !== undefined && params.search !== null))
110       .subscribe(params => {
111         this.search = params.search
112         this.setTableFilter(params.search)
113         this.loadData()
114       })
115   }
116
117   ngAfterViewInit () {
118     if (this.search) this.setTableFilter(this.search)
119   }
120
121   /* Table filter functions */
122   onBlockSearch (event: Event) {
123     this.onSearch(event)
124     this.setQueryParams((event.target as HTMLInputElement).value)
125   }
126
127   setQueryParams (search: string) {
128     const queryParams: Params = {}
129     if (search) Object.assign(queryParams, { search })
130     this.router.navigate([ '/admin/moderation/video-blocks/list' ], { queryParams })
131   }
132
133   resetTableFilter () {
134     this.setTableFilter('')
135     this.setQueryParams('')
136     this.resetSearch()
137   }
138   /* END Table filter functions */
139
140   getIdentifier () {
141     return 'VideoBlockListComponent'
142   }
143
144   getVideoUrl (videoBlock: VideoBlacklist) {
145     return Video.buildClientUrl(videoBlock.video.uuid)
146   }
147
148   booleanToText (value: boolean) {
149     if (value === true) return this.i18n('yes')
150
151     return this.i18n('no')
152   }
153
154   toHtml (text: string) {
155     return this.markdownRenderer.textMarkdownToHTML(text)
156   }
157
158   async unblockVideo (entry: VideoBlacklist) {
159     const confirmMessage = this.i18n(
160       'Do you really want to unblock this video? It will be available again in the videos list.'
161     )
162
163     const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblock'))
164     if (res === false) return
165
166     this.videoBlocklistService.unblockVideo(entry.video.id).subscribe(
167       () => {
168         this.notifier.success(this.i18n('Video {{name}} unblocked.', { name: entry.video.name }))
169         this.loadData()
170       },
171
172       err => this.notifier.error(err.message)
173     )
174   }
175
176   protected loadData () {
177     this.videoBlocklistService.listBlocks({
178       pagination: this.pagination,
179       sort: this.sort,
180       search: this.search,
181     })
182       .subscribe(
183         async resultList => {
184           this.totalRecords = resultList.total
185
186           this.blocklist = resultList.data
187
188           for (const element of this.blocklist) {
189             Object.assign(element, { reasonHtml: await this.toHtml(element.reason) })
190           }
191         },
192
193         err => this.notifier.error(err.message)
194       )
195   }
196 }