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