]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame_incremental - 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
1import { SortMeta } from 'primeng/api'
2import { finalize } from 'rxjs/operators'
3import { Component, OnInit, ViewChild } from '@angular/core'
4import { ActivatedRoute, Router } from '@angular/router'
5import { AuthService, ConfirmService, Notifier, RestPagination, RestTable } from '@app/core'
6import { AdvancedInputFilter } from '@app/shared/shared-forms'
7import { DropdownAction, Video, VideoService } from '@app/shared/shared-main'
8import { VideoBlockComponent, VideoBlockService } from '@app/shared/shared-moderation'
9import { VideoActionsDisplayType } from '@app/shared/shared-video-miniature'
10import { UserRight, VideoPrivacy, VideoState, VideoStreamingPlaylistType } from '@shared/models'
11import { VideoAdminService } from './video-admin.service'
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 {
19 @ViewChild('videoBlockModal') videoBlockModal: VideoBlockComponent
20
21 videos: Video[] = []
22
23 totalRecords = 0
24 sort: SortMeta = { field: 'publishedAt', order: -1 }
25 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
26
27 bulkVideoActions: DropdownAction<Video[]>[][] = []
28
29 selectedVideos: Video[] = []
30
31 inputFilters: AdvancedInputFilter[]
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,
42 liveInfo: false,
43 removeFiles: true,
44 transcoding: true
45 }
46
47 loading = true
48
49 constructor (
50 protected route: ActivatedRoute,
51 protected router: Router,
52 private confirmService: ConfirmService,
53 private auth: AuthService,
54 private notifier: Notifier,
55 private videoService: VideoService,
56 private videoAdminService: VideoAdminService,
57 private videoBlockService: VideoBlockService
58 ) {
59 super()
60 }
61
62 get authUser () {
63 return this.auth.getUser()
64 }
65
66 ngOnInit () {
67 this.initialize()
68
69 this.inputFilters = this.videoAdminService.buildAdminInputFilter()
70
71 this.bulkVideoActions = [
72 [
73 {
74 label: $localize`Delete`,
75 handler: videos => this.removeVideos(videos),
76 isDisplayed: () => this.authUser.hasRight(UserRight.REMOVE_ANY_VIDEO),
77 iconName: 'delete'
78 },
79 {
80 label: $localize`Block`,
81 handler: videos => this.videoBlockModal.show(videos),
82 isDisplayed: videos => this.authUser.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) && videos.every(v => !v.blacklisted),
83 iconName: 'no'
84 },
85 {
86 label: $localize`Unblock`,
87 handler: videos => this.unblockVideos(videos),
88 isDisplayed: videos => this.authUser.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) && videos.every(v => v.blacklisted),
89 iconName: 'undo'
90 }
91 ],
92 [
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 },
105 {
106 label: $localize`Delete HLS files`,
107 handler: videos => this.removeVideoFiles(videos, 'hls'),
108 isDisplayed: videos => videos.every(v => v.canRemoveFiles(this.authUser)),
109 iconName: 'delete'
110 },
111 {
112 label: $localize`Delete WebTorrent files`,
113 handler: videos => this.removeVideoFiles(videos, 'webtorrent'),
114 isDisplayed: videos => videos.every(v => v.canRemoveFiles(this.authUser)),
115 iconName: 'delete'
116 }
117 ]
118 ]
119 }
120
121 getIdentifier () {
122 return 'VideoListComponent'
123 }
124
125 isInSelectionMode () {
126 return this.selectedVideos.length !== 0
127 }
128
129 getPrivacyBadgeClass (video: Video) {
130 if (video.privacy.id === VideoPrivacy.PUBLIC) return 'badge-green'
131
132 return 'badge-yellow'
133 }
134
135 isUnpublished (video: Video) {
136 return video.state.id !== VideoState.LIVE_ENDED && video.state.id !== VideoState.PUBLISHED
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
151 isImport (video: Video) {
152 return video.state.id === VideoState.TO_IMPORT
153 }
154
155 isHLS (video: Video) {
156 const p = video.streamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS)
157 if (!p) return false
158
159 return p.files.length !== 0
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
176 reloadData () {
177 this.selectedVideos = []
178
179 this.loading = true
180
181 this.videoAdminService.getAdminVideos({
182 pagination: this.pagination,
183 sort: this.sort,
184 search: this.search
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 })
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: () => {
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.`)
217 this.reloadData()
218 },
219
220 error: err => this.notifier.error(err.message)
221 })
222 }
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 }
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 }
255}