]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/+admin/overview/videos/video-list.component.ts
Remove unnecessary onPage event on admin tables
[github/Chocobozzz/PeerTube.git] / client / src / app / +admin / overview / videos / video-list.component.ts
CommitLineData
33f6dce1 1import { SortMeta } from 'primeng/api'
61f85385 2import { finalize } from 'rxjs/operators'
3cfa8176 3import { Component, OnInit, ViewChild } from '@angular/core'
33f6dce1
C
4import { ActivatedRoute, Router } from '@angular/router'
5import { AuthService, ConfirmService, Notifier, RestPagination, RestTable } from '@app/core'
33f6dce1 6import { AdvancedInputFilter } from '@app/shared/shared-forms'
61f85385 7import { DropdownAction, Video, VideoService } from '@app/shared/shared-main'
3cfa8176 8import { VideoBlockComponent, VideoBlockService } from '@app/shared/shared-moderation'
33f6dce1 9import { VideoActionsDisplayType } from '@app/shared/shared-video-miniature'
61f85385 10import { UserRight, VideoPrivacy, VideoState, VideoStreamingPlaylistType } from '@shared/models'
05ac4ac7 11import { VideoAdminService } from './video-admin.service'
33f6dce1
C
12
13@Component({
14 selector: 'my-video-list',
15 templateUrl: './video-list.component.html',
16 styleUrls: [ './video-list.component.scss' ]
17})
18export class VideoListComponent extends RestTable implements OnInit {
3cfa8176
C
19 @ViewChild('videoBlockModal') videoBlockModal: VideoBlockComponent
20
33f6dce1
C
21 videos: Video[] = []
22
23 totalRecords = 0
7e7d8e48 24 sort: SortMeta = { field: 'publishedAt', order: -1 }
33f6dce1
C
25 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
26
27 bulkVideoActions: DropdownAction<Video[]>[][] = []
28
29 selectedVideos: Video[] = []
30
231ff4af 31 inputFilters: AdvancedInputFilter[]
33f6dce1
C
32
33 videoActionsOptions: VideoActionsDisplayType = {
34 playlist: false,
35 download: false,
36 update: true,
37 blacklist: true,
38 delete: true,
39 report: false,
40 duplicate: true,
41 mute: true,
b46cf4b9 42 liveInfo: false,
ad5db104
C
43 removeFiles: true,
44 transcoding: true
33f6dce1
C
45 }
46
231ff4af 47 loading = true
61f85385 48
33f6dce1
C
49 constructor (
50 protected route: ActivatedRoute,
51 protected router: Router,
52 private confirmService: ConfirmService,
53 private auth: AuthService,
54 private notifier: Notifier,
05ac4ac7 55 private videoService: VideoService,
3cfa8176
C
56 private videoAdminService: VideoAdminService,
57 private videoBlockService: VideoBlockService
33f6dce1
C
58 ) {
59 super()
60 }
61
62 get authUser () {
63 return this.auth.getUser()
64 }
65
66 ngOnInit () {
67 this.initialize()
68
05ac4ac7 69 this.inputFilters = this.videoAdminService.buildAdminInputFilter()
231ff4af 70
33f6dce1
C
71 this.bulkVideoActions = [
72 [
73 {
74 label: $localize`Delete`,
75 handler: videos => this.removeVideos(videos),
b46cf4b9
C
76 isDisplayed: () => this.authUser.hasRight(UserRight.REMOVE_ANY_VIDEO),
77 iconName: 'delete'
3cfa8176
C
78 },
79 {
80 label: $localize`Block`,
81 handler: videos => this.videoBlockModal.show(videos),
b46cf4b9
C
82 isDisplayed: videos => this.authUser.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) && videos.every(v => !v.blacklisted),
83 iconName: 'no'
3cfa8176
C
84 },
85 {
86 label: $localize`Unblock`,
87 handler: videos => this.unblockVideos(videos),
b46cf4b9
C
88 isDisplayed: videos => this.authUser.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) && videos.every(v => v.blacklisted),
89 iconName: 'undo'
90 }
91 ],
92 [
ad5db104
C
93 {
94 label: $localize`Run HLS transcoding`,
95 handler: videos => this.runTranscoding(videos, 'hls'),
96 isDisplayed: videos => videos.every(v => v.canRunTranscoding(this.authUser)),
97 iconName: 'cog'
98 },
99 {
100 label: $localize`Run WebTorrent transcoding`,
101 handler: videos => this.runTranscoding(videos, 'webtorrent'),
102 isDisplayed: videos => videos.every(v => v.canRunTranscoding(this.authUser)),
103 iconName: 'cog'
104 },
b46cf4b9
C
105 {
106 label: $localize`Delete HLS files`,
107 handler: videos => this.removeVideoFiles(videos, 'hls'),
ad5db104 108 isDisplayed: videos => videos.every(v => v.canRemoveFiles(this.authUser)),
b46cf4b9
C
109 iconName: 'delete'
110 },
111 {
112 label: $localize`Delete WebTorrent files`,
113 handler: videos => this.removeVideoFiles(videos, 'webtorrent'),
ad5db104 114 isDisplayed: videos => videos.every(v => v.canRemoveFiles(this.authUser)),
b46cf4b9 115 iconName: 'delete'
33f6dce1
C
116 }
117 ]
118 ]
119 }
120
121 getIdentifier () {
122 return 'VideoListComponent'
123 }
124
125 isInSelectionMode () {
126 return this.selectedVideos.length !== 0
127 }
128
d324756e 129 getPrivacyBadgeClass (video: Video) {
dd6d2a7c 130 if (video.privacy.id === VideoPrivacy.PUBLIC) return 'badge-green'
2760b454
C
131
132 return 'badge-yellow'
133 }
134
d324756e
C
135 isUnpublished (video: Video) {
136 return video.state.id !== VideoState.LIVE_ENDED && video.state.id !== VideoState.PUBLISHED
2760b454
C
137 }
138
139 isAccountBlocked (video: Video) {
140 return video.blockedOwner
141 }
142
143 isServerBlocked (video: Video) {
144 return video.blockedServer
145 }
146
147 isVideoBlocked (video: Video) {
148 return video.blacklisted
149 }
150
d324756e
C
151 isImport (video: Video) {
152 return video.state.id === VideoState.TO_IMPORT
153 }
154
3c10840f 155 isHLS (video: Video) {
d5d9c5b7
C
156 const p = video.streamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS)
157 if (!p) return false
158
159 return p.files.length !== 0
3c10840f
C
160 }
161
162 isWebTorrent (video: Video) {
163 return video.files.length !== 0
164 }
165
166 getFilesSize (video: Video) {
167 let files = video.files
168
169 if (this.isHLS(video)) {
170 files = files.concat(video.streamingPlaylists[0].files)
171 }
172
173 return files.reduce((p, f) => p += f.size, 0)
174 }
175
b46cf4b9 176 reloadData () {
33f6dce1
C
177 this.selectedVideos = []
178
61f85385
C
179 this.loading = true
180
05ac4ac7 181 this.videoAdminService.getAdminVideos({
33f6dce1
C
182 pagination: this.pagination,
183 sort: this.sort,
184 search: this.search
61f85385
C
185 }).pipe(finalize(() => this.loading = false))
186 .subscribe({
187 next: resultList => {
188 this.videos = resultList.data
189 this.totalRecords = resultList.total
190 },
191
192 error: err => this.notifier.error(err.message)
193 })
33f6dce1
C
194 }
195
196 private async removeVideos (videos: Video[]) {
197 const message = $localize`Are you sure you want to delete these ${videos.length} videos?`
198 const res = await this.confirmService.confirm(message, $localize`Delete`)
199 if (res === false) return
200
201 this.videoService.removeVideo(videos.map(v => v.id))
202 .subscribe({
203 next: () => {
3cfa8176
C
204 this.notifier.success($localize`Deleted ${videos.length} videos.`)
205 this.reloadData()
206 },
207
208 error: err => this.notifier.error(err.message)
209 })
210 }
211
212 private unblockVideos (videos: Video[]) {
213 this.videoBlockService.unblockVideo(videos.map(v => v.id))
214 .subscribe({
215 next: () => {
216 this.notifier.success($localize`Unblocked ${videos.length} videos.`)
33f6dce1
C
217 this.reloadData()
218 },
219
220 error: err => this.notifier.error(err.message)
221 })
222 }
b46cf4b9
C
223
224 private async removeVideoFiles (videos: Video[], type: 'hls' | 'webtorrent') {
225 const message = type === 'hls'
226 ? $localize`Are you sure you want to delete ${videos.length} HLS streaming playlists?`
227 : $localize`Are you sure you want to delete WebTorrent files of ${videos.length} videos?`
228
229 const res = await this.confirmService.confirm(message, $localize`Delete`)
230 if (res === false) return
231
232 this.videoService.removeVideoFiles(videos.map(v => v.id), type)
233 .subscribe({
234 next: () => {
235 this.notifier.success($localize`Files were removed.`)
236 this.reloadData()
237 },
238
239 error: err => this.notifier.error(err.message)
240 })
241 }
ad5db104
C
242
243 private runTranscoding (videos: Video[], type: 'hls' | 'webtorrent') {
244 this.videoService.runTranscoding(videos.map(v => v.id), type)
245 .subscribe({
246 next: () => {
247 this.notifier.success($localize`Transcoding jobs created.`)
248
249 this.reloadData()
250 },
251
252 error: err => this.notifier.error(err.message)
253 })
254 }
33f6dce1 255}