aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/shared')
-rw-r--r--client/src/app/shared/shared-main/video/video.model.ts11
-rw-r--r--client/src/app/shared/shared-main/video/video.service.ts9
-rw-r--r--client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts39
3 files changed, 57 insertions, 2 deletions
diff --git a/client/src/app/shared/shared-main/video/video.model.ts b/client/src/app/shared/shared-main/video/video.model.ts
index 472a8c810..4203ff1c0 100644
--- a/client/src/app/shared/shared-main/video/video.model.ts
+++ b/client/src/app/shared/shared-main/video/video.model.ts
@@ -14,7 +14,8 @@ import {
14 VideoPrivacy, 14 VideoPrivacy,
15 VideoScheduleUpdate, 15 VideoScheduleUpdate,
16 VideoState, 16 VideoState,
17 VideoStreamingPlaylist 17 VideoStreamingPlaylist,
18 VideoStreamingPlaylistType
18} from '@shared/models' 19} from '@shared/models'
19 20
20export class Video implements VideoServerModel { 21export class Video implements VideoServerModel {
@@ -219,6 +220,14 @@ export class Video implements VideoServerModel {
219 return user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.UPDATE_ANY_VIDEO)) 220 return user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.UPDATE_ANY_VIDEO))
220 } 221 }
221 222
223 hasHLS () {
224 return this.streamingPlaylists?.some(p => p.type === VideoStreamingPlaylistType.HLS)
225 }
226
227 hasWebTorrent () {
228 return this.files && this.files.length !== 0
229 }
230
222 isLiveInfoAvailableBy (user: AuthUser) { 231 isLiveInfoAvailableBy (user: AuthUser) {
223 return this.isLive && 232 return this.isLive &&
224 user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.GET_ANY_LIVE)) 233 user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.GET_ANY_LIVE))
diff --git a/client/src/app/shared/shared-main/video/video.service.ts b/client/src/app/shared/shared-main/video/video.service.ts
index 570e8e3be..d135a27dc 100644
--- a/client/src/app/shared/shared-main/video/video.service.ts
+++ b/client/src/app/shared/shared-main/video/video.service.ts
@@ -299,6 +299,15 @@ export class VideoService {
299 ) 299 )
300 } 300 }
301 301
302 removeVideoFiles (videoIds: (number | string)[], type: 'hls' | 'webtorrent') {
303 return from(videoIds)
304 .pipe(
305 concatMap(id => this.authHttp.delete(VideoService.BASE_VIDEO_URL + '/' + id + '/' + type)),
306 toArray(),
307 catchError(err => this.restExtractor.handleError(err))
308 )
309 }
310
302 loadCompleteDescription (descriptionPath: string) { 311 loadCompleteDescription (descriptionPath: string) {
303 return this.authHttp 312 return this.authHttp
304 .get<{ description: string }>(environment.apiUrl + descriptionPath) 313 .get<{ description: string }>(environment.apiUrl + descriptionPath)
diff --git a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts
index eff56b40e..82c084791 100644
--- a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts
+++ b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts
@@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, OnChanges, Output, ViewChild } from '@a
2import { AuthService, ConfirmService, Notifier, ScreenService } from '@app/core' 2import { AuthService, ConfirmService, Notifier, ScreenService } from '@app/core'
3import { BlocklistService, VideoBlockComponent, VideoBlockService, VideoReportComponent } from '@app/shared/shared-moderation' 3import { BlocklistService, VideoBlockComponent, VideoBlockService, VideoReportComponent } from '@app/shared/shared-moderation'
4import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' 4import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'
5import { VideoCaption } from '@shared/models' 5import { UserRight, VideoCaption } from '@shared/models'
6import { 6import {
7 Actor, 7 Actor,
8 DropdownAction, 8 DropdownAction,
@@ -27,6 +27,7 @@ export type VideoActionsDisplayType = {
27 duplicate?: boolean 27 duplicate?: boolean
28 mute?: boolean 28 mute?: boolean
29 liveInfo?: boolean 29 liveInfo?: boolean
30 removeFiles?: boolean
30} 31}
31 32
32@Component({ 33@Component({
@@ -65,6 +66,7 @@ export class VideoActionsDropdownComponent implements OnChanges {
65 @Input() buttonSize: DropdownButtonSize = 'normal' 66 @Input() buttonSize: DropdownButtonSize = 'normal'
66 @Input() buttonDirection: DropdownDirection = 'vertical' 67 @Input() buttonDirection: DropdownDirection = 'vertical'
67 68
69 @Output() videoFilesRemoved = new EventEmitter()
68 @Output() videoRemoved = new EventEmitter() 70 @Output() videoRemoved = new EventEmitter()
69 @Output() videoUnblocked = new EventEmitter() 71 @Output() videoUnblocked = new EventEmitter()
70 @Output() videoBlocked = new EventEmitter() 72 @Output() videoBlocked = new EventEmitter()
@@ -174,6 +176,10 @@ export class VideoActionsDropdownComponent implements OnChanges {
174 return this.video.account.id !== this.user.account.id 176 return this.video.account.id !== this.user.account.id
175 } 177 }
176 178
179 canRemoveVideoFiles () {
180 return this.user.hasRight(UserRight.MANAGE_VIDEO_FILES) && this.video.hasHLS() && this.video.hasWebTorrent()
181 }
182
177 /* Action handlers */ 183 /* Action handlers */
178 184
179 async unblockVideo () { 185 async unblockVideo () {
@@ -245,6 +251,23 @@ export class VideoActionsDropdownComponent implements OnChanges {
245 }) 251 })
246 } 252 }
247 253
254 async removeVideoFiles (video: Video, type: 'hls' | 'webtorrent') {
255 const confirmMessage = $localize`Do you really want to remove "${this.video.name}" files?`
256
257 const res = await this.confirmService.confirm(confirmMessage, $localize`Remove "${this.video.name}" files`)
258 if (res === false) return
259
260 this.videoService.removeVideoFiles([ video.id ], type)
261 .subscribe({
262 next: () => {
263 this.notifier.success($localize`Removed files of ${video.name}.`)
264 this.videoFilesRemoved.emit()
265 },
266
267 error: err => this.notifier.error(err.message)
268 })
269 }
270
248 onVideoBlocked () { 271 onVideoBlocked () {
249 this.videoBlocked.emit() 272 this.videoBlocked.emit()
250 } 273 }
@@ -317,6 +340,20 @@ export class VideoActionsDropdownComponent implements OnChanges {
317 iconName: 'flag' 340 iconName: 'flag'
318 } 341 }
319 ], 342 ],
343 [
344 {
345 label: $localize`Delete HLS files`,
346 handler: ({ video }) => this.removeVideoFiles(video, 'hls'),
347 isDisplayed: () => this.displayOptions.removeFiles && this.canRemoveVideoFiles(),
348 iconName: 'delete'
349 },
350 {
351 label: $localize`Delete WebTorrent files`,
352 handler: ({ video }) => this.removeVideoFiles(video, 'webtorrent'),
353 isDisplayed: () => this.displayOptions.removeFiles && this.canRemoveVideoFiles(),
354 iconName: 'delete'
355 }
356 ],
320 [ // actions regarding the account/its server 357 [ // actions regarding the account/its server
321 { 358 {
322 label: $localize`Mute account`, 359 label: $localize`Mute account`,