]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/+video-studio/edit/video-studio-edit.component.ts
Prevent edition with 0 task
[github/Chocobozzz/PeerTube.git] / client / src / app / +video-studio / edit / video-studio-edit.component.ts
CommitLineData
c729caf6
C
1import { Component, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { ConfirmService, Notifier, ServerService } from '@app/core'
5c5bcea2 4import { FormReactive, FormReactiveService } from '@app/shared/shared-forms'
92e66e04 5import { VideoDetails } from '@app/shared/shared-main'
c729caf6 6import { LoadingBarService } from '@ngx-loading-bar/core'
42b40636 7import { logger } from '@root-helpers/logger'
c729caf6 8import { secondsToTime } from '@shared/core-utils'
92e66e04
C
9import { VideoStudioTask, VideoStudioTaskCut } from '@shared/models'
10import { VideoStudioService } from '../shared'
c729caf6
C
11
12@Component({
92e66e04
C
13 selector: 'my-video-studio-edit',
14 templateUrl: './video-studio-edit.component.html',
15 styleUrls: [ './video-studio-edit.component.scss' ]
c729caf6 16})
92e66e04 17export class VideoStudioEditComponent extends FormReactive implements OnInit {
c729caf6
C
18 isRunningEdition = false
19
20 video: VideoDetails
21
22 constructor (
5c5bcea2 23 protected formReactiveService: FormReactiveService,
c729caf6
C
24 private serverService: ServerService,
25 private notifier: Notifier,
26 private router: Router,
27 private route: ActivatedRoute,
92e66e04 28 private videoStudioService: VideoStudioService,
c729caf6
C
29 private loadingBar: LoadingBarService,
30 private confirmService: ConfirmService
31 ) {
32 super()
33 }
34
35 ngOnInit () {
36 this.video = this.route.snapshot.data.video
37
38 const defaultValues = {
39 cut: {
40 start: 0,
41 end: this.video.duration
42 }
43 }
44
45 this.buildForm({
46 cut: {
47 start: null,
48 end: null
49 },
50 'add-intro': {
51 file: null
52 },
53 'add-outro': {
54 file: null
55 },
56 'add-watermark': {
57 file: null
58 }
59 }, defaultValues)
60 }
61
62 get videoExtensions () {
63 return this.serverService.getHTMLConfig().video.file.extensions
64 }
65
66 get imageExtensions () {
67 return this.serverService.getHTMLConfig().video.image.extensions
68 }
69
70 async runEdition () {
71 if (this.isRunningEdition) return
366d5aea
C
72 if (!this.form.valid) return
73 if (this.noEdition()) return
c729caf6
C
74
75 const title = $localize`Are you sure you want to edit "${this.video.name}"?`
76 const listHTML = this.getTasksSummary().map(t => `<li>${t}</li>`).join('')
77
78 // eslint-disable-next-line max-len
79 const confirmHTML = $localize`The current video will be overwritten by this edited video and <strong>you won't be able to recover it</strong>.<br /><br />` +
80 $localize`As a reminder, the following tasks will be executed: <ol>${listHTML}</ol>`
81
82 if (await this.confirmService.confirm(confirmHTML, title) !== true) return
83
84 this.isRunningEdition = true
85
86 const tasks = this.buildTasks()
87
88 this.loadingBar.useRef().start()
89
92e66e04 90 return this.videoStudioService.editVideo(this.video.uuid, tasks)
c729caf6
C
91 .subscribe({
92 next: () => {
92e66e04
C
93 this.notifier.success($localize`Edition tasks created.`)
94
95 // Don't redirect to old video version watch page that could be confusing for users
96 this.router.navigateByUrl('/my-library/videos')
c729caf6
C
97 },
98
99 error: err => {
100 this.loadingBar.useRef().complete()
101 this.isRunningEdition = false
102 this.notifier.error(err.message)
42b40636 103 logger.error(err)
c729caf6
C
104 }
105 })
106 }
107
108 getIntroOutroTooltip () {
109 return $localize`(extensions: ${this.videoExtensions.join(', ')})`
110 }
111
112 getWatermarkTooltip () {
113 return $localize`(extensions: ${this.imageExtensions.join(', ')})`
114 }
115
116 noEdition () {
117 return this.buildTasks().length === 0
118 }
119
120 getTasksSummary () {
121 const tasks = this.buildTasks()
122
123 return tasks.map(t => {
124 if (t.name === 'add-intro') {
052bdb7c 125 return $localize`"${this.getFilename(t.options.file)}" will be added at the beginning of the video`
c729caf6
C
126 }
127
128 if (t.name === 'add-outro') {
129 return $localize`"${this.getFilename(t.options.file)}" will be added at the end of the video`
130 }
131
132 if (t.name === 'add-watermark') {
133 return $localize`"${this.getFilename(t.options.file)}" image watermark will be added to the video`
134 }
135
136 if (t.name === 'cut') {
137 const { start, end } = t.options
138
139 if (start !== undefined && end !== undefined) {
140 return $localize`Video will begin at ${secondsToTime(start)} and stop at ${secondsToTime(end)}`
141 }
142
143 if (start !== undefined) {
144 return $localize`Video will begin at ${secondsToTime(start)}`
145 }
146
147 if (end !== undefined) {
148 return $localize`Video will stop at ${secondsToTime(end)}`
149 }
150 }
151
152 return ''
153 })
154 }
155
156 private getFilename (obj: any) {
157 return obj.name
158 }
159
160 private buildTasks () {
92e66e04 161 const tasks: VideoStudioTask[] = []
c729caf6
C
162 const value = this.form.value
163
164 const cut = value['cut']
165 if (cut['start'] !== 0 || cut['end'] !== this.video.duration) {
166
92e66e04 167 const options: VideoStudioTaskCut['options'] = {}
c729caf6
C
168 if (cut['start'] !== 0) options.start = cut['start']
169 if (cut['end'] !== this.video.duration) options.end = cut['end']
170
171 tasks.push({
172 name: 'cut',
173 options
174 })
175 }
176
177 if (value['add-intro']?.['file']) {
178 tasks.push({
179 name: 'add-intro',
180 options: {
181 file: value['add-intro']['file']
182 }
183 })
184 }
185
186 if (value['add-outro']?.['file']) {
187 tasks.push({
188 name: 'add-outro',
189 options: {
190 file: value['add-outro']['file']
191 }
192 })
193 }
194
195 if (value['add-watermark']?.['file']) {
196 tasks.push({
197 name: 'add-watermark',
198 options: {
199 file: value['add-watermark']['file']
200 }
201 })
202 }
203
204 return tasks
205 }
206
207}