From b46cf4b920984492df598c1b61179acfc7f6f22e Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 17 Nov 2021 16:04:53 +0100 Subject: Add ability to remove hls/webtorrent files --- .../app/shared/shared-main/video/video.model.ts | 11 +++++- .../app/shared/shared-main/video/video.service.ts | 9 +++++ .../video-actions-dropdown.component.ts | 39 +++++++++++++++++++++- 3 files changed, 57 insertions(+), 2 deletions(-) (limited to 'client/src/app/shared') 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 { VideoPrivacy, VideoScheduleUpdate, VideoState, - VideoStreamingPlaylist + VideoStreamingPlaylist, + VideoStreamingPlaylistType } from '@shared/models' export class Video implements VideoServerModel { @@ -219,6 +220,14 @@ export class Video implements VideoServerModel { return user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.UPDATE_ANY_VIDEO)) } + hasHLS () { + return this.streamingPlaylists?.some(p => p.type === VideoStreamingPlaylistType.HLS) + } + + hasWebTorrent () { + return this.files && this.files.length !== 0 + } + isLiveInfoAvailableBy (user: AuthUser) { return this.isLive && 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 { ) } + removeVideoFiles (videoIds: (number | string)[], type: 'hls' | 'webtorrent') { + return from(videoIds) + .pipe( + concatMap(id => this.authHttp.delete(VideoService.BASE_VIDEO_URL + '/' + id + '/' + type)), + toArray(), + catchError(err => this.restExtractor.handleError(err)) + ) + } + loadCompleteDescription (descriptionPath: string) { return this.authHttp .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 import { AuthService, ConfirmService, Notifier, ScreenService } from '@app/core' import { BlocklistService, VideoBlockComponent, VideoBlockService, VideoReportComponent } from '@app/shared/shared-moderation' import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' -import { VideoCaption } from '@shared/models' +import { UserRight, VideoCaption } from '@shared/models' import { Actor, DropdownAction, @@ -27,6 +27,7 @@ export type VideoActionsDisplayType = { duplicate?: boolean mute?: boolean liveInfo?: boolean + removeFiles?: boolean } @Component({ @@ -65,6 +66,7 @@ export class VideoActionsDropdownComponent implements OnChanges { @Input() buttonSize: DropdownButtonSize = 'normal' @Input() buttonDirection: DropdownDirection = 'vertical' + @Output() videoFilesRemoved = new EventEmitter() @Output() videoRemoved = new EventEmitter() @Output() videoUnblocked = new EventEmitter() @Output() videoBlocked = new EventEmitter() @@ -174,6 +176,10 @@ export class VideoActionsDropdownComponent implements OnChanges { return this.video.account.id !== this.user.account.id } + canRemoveVideoFiles () { + return this.user.hasRight(UserRight.MANAGE_VIDEO_FILES) && this.video.hasHLS() && this.video.hasWebTorrent() + } + /* Action handlers */ async unblockVideo () { @@ -245,6 +251,23 @@ export class VideoActionsDropdownComponent implements OnChanges { }) } + async removeVideoFiles (video: Video, type: 'hls' | 'webtorrent') { + const confirmMessage = $localize`Do you really want to remove "${this.video.name}" files?` + + const res = await this.confirmService.confirm(confirmMessage, $localize`Remove "${this.video.name}" files`) + if (res === false) return + + this.videoService.removeVideoFiles([ video.id ], type) + .subscribe({ + next: () => { + this.notifier.success($localize`Removed files of ${video.name}.`) + this.videoFilesRemoved.emit() + }, + + error: err => this.notifier.error(err.message) + }) + } + onVideoBlocked () { this.videoBlocked.emit() } @@ -317,6 +340,20 @@ export class VideoActionsDropdownComponent implements OnChanges { iconName: 'flag' } ], + [ + { + label: $localize`Delete HLS files`, + handler: ({ video }) => this.removeVideoFiles(video, 'hls'), + isDisplayed: () => this.displayOptions.removeFiles && this.canRemoveVideoFiles(), + iconName: 'delete' + }, + { + label: $localize`Delete WebTorrent files`, + handler: ({ video }) => this.removeVideoFiles(video, 'webtorrent'), + isDisplayed: () => this.displayOptions.removeFiles && this.canRemoveVideoFiles(), + iconName: 'delete' + } + ], [ // actions regarding the account/its server { label: $localize`Mute account`, -- cgit v1.2.3