diff options
Diffstat (limited to 'client/src/app/+videos/+video-edit/video-update.component.ts')
-rw-r--r-- | client/src/app/+videos/+video-edit/video-update.component.ts | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/client/src/app/+videos/+video-edit/video-update.component.ts b/client/src/app/+videos/+video-edit/video-update.component.ts new file mode 100644 index 000000000..7bd6eb553 --- /dev/null +++ b/client/src/app/+videos/+video-edit/video-update.component.ts | |||
@@ -0,0 +1,155 @@ | |||
1 | import { map, switchMap } from 'rxjs/operators' | ||
2 | import { Component, HostListener, OnInit } from '@angular/core' | ||
3 | import { ActivatedRoute, Router } from '@angular/router' | ||
4 | import { Notifier } from '@app/core' | ||
5 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' | ||
6 | import { VideoCaptionEdit, VideoCaptionService, VideoDetails, VideoEdit, VideoService } from '@app/shared/shared-main' | ||
7 | import { LoadingBarService } from '@ngx-loading-bar/core' | ||
8 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
9 | import { VideoPrivacy } from '@shared/models' | ||
10 | |||
11 | @Component({ | ||
12 | selector: 'my-videos-update', | ||
13 | styleUrls: [ './shared/video-edit.component.scss' ], | ||
14 | templateUrl: './video-update.component.html' | ||
15 | }) | ||
16 | export class VideoUpdateComponent extends FormReactive implements OnInit { | ||
17 | video: VideoEdit | ||
18 | |||
19 | isUpdatingVideo = false | ||
20 | userVideoChannels: { id: number, label: string, support: string }[] = [] | ||
21 | schedulePublicationPossible = false | ||
22 | videoCaptions: VideoCaptionEdit[] = [] | ||
23 | waitTranscodingEnabled = true | ||
24 | |||
25 | private updateDone = false | ||
26 | |||
27 | constructor ( | ||
28 | protected formValidatorService: FormValidatorService, | ||
29 | private route: ActivatedRoute, | ||
30 | private router: Router, | ||
31 | private notifier: Notifier, | ||
32 | private videoService: VideoService, | ||
33 | private loadingBar: LoadingBarService, | ||
34 | private videoCaptionService: VideoCaptionService, | ||
35 | private i18n: I18n | ||
36 | ) { | ||
37 | super() | ||
38 | } | ||
39 | |||
40 | ngOnInit () { | ||
41 | this.buildForm({}) | ||
42 | |||
43 | this.route.data | ||
44 | .pipe(map(data => data.videoData)) | ||
45 | .subscribe(({ video, videoChannels, videoCaptions }) => { | ||
46 | this.video = new VideoEdit(video) | ||
47 | this.userVideoChannels = videoChannels | ||
48 | this.videoCaptions = videoCaptions | ||
49 | |||
50 | this.schedulePublicationPossible = this.video.privacy === VideoPrivacy.PRIVATE | ||
51 | |||
52 | const videoFiles = (video as VideoDetails).getFiles() | ||
53 | if (videoFiles.length > 1) { // Already transcoded | ||
54 | this.waitTranscodingEnabled = false | ||
55 | } | ||
56 | |||
57 | // FIXME: Angular does not detect the change inside this subscription, so use the patched setTimeout | ||
58 | setTimeout(() => this.hydrateFormFromVideo()) | ||
59 | }, | ||
60 | |||
61 | err => { | ||
62 | console.error(err) | ||
63 | this.notifier.error(err.message) | ||
64 | } | ||
65 | ) | ||
66 | } | ||
67 | |||
68 | @HostListener('window:beforeunload', [ '$event' ]) | ||
69 | onUnload (event: any) { | ||
70 | const { text, canDeactivate } = this.canDeactivate() | ||
71 | |||
72 | if (canDeactivate) return | ||
73 | |||
74 | event.returnValue = text | ||
75 | return text | ||
76 | } | ||
77 | |||
78 | canDeactivate (): { canDeactivate: boolean, text?: string } { | ||
79 | if (this.updateDone === true) return { canDeactivate: true } | ||
80 | |||
81 | const text = this.i18n('You have unsaved changes! If you leave, your changes will be lost.') | ||
82 | |||
83 | for (const caption of this.videoCaptions) { | ||
84 | if (caption.action) return { canDeactivate: false, text } | ||
85 | } | ||
86 | |||
87 | return { canDeactivate: this.formChanged === false, text } | ||
88 | } | ||
89 | |||
90 | checkForm () { | ||
91 | this.forceCheck() | ||
92 | |||
93 | return this.form.valid | ||
94 | } | ||
95 | |||
96 | update () { | ||
97 | if (this.checkForm() === false | ||
98 | || this.isUpdatingVideo === true) { | ||
99 | return | ||
100 | } | ||
101 | |||
102 | this.video.patch(this.form.value) | ||
103 | |||
104 | this.loadingBar.start() | ||
105 | this.isUpdatingVideo = true | ||
106 | |||
107 | // Update the video | ||
108 | this.videoService.updateVideo(this.video) | ||
109 | .pipe( | ||
110 | // Then update captions | ||
111 | switchMap(() => this.videoCaptionService.updateCaptions(this.video.id, this.videoCaptions)) | ||
112 | ) | ||
113 | .subscribe( | ||
114 | () => { | ||
115 | this.updateDone = true | ||
116 | this.isUpdatingVideo = false | ||
117 | this.loadingBar.complete() | ||
118 | this.notifier.success(this.i18n('Video updated.')) | ||
119 | this.router.navigate([ '/videos/watch', this.video.uuid ]) | ||
120 | }, | ||
121 | |||
122 | err => { | ||
123 | this.loadingBar.complete() | ||
124 | this.isUpdatingVideo = false | ||
125 | this.notifier.error(err.message) | ||
126 | console.error(err) | ||
127 | } | ||
128 | ) | ||
129 | } | ||
130 | |||
131 | private hydrateFormFromVideo () { | ||
132 | this.form.patchValue(this.video.toFormPatch()) | ||
133 | |||
134 | const objects = [ | ||
135 | { | ||
136 | url: 'thumbnailUrl', | ||
137 | name: 'thumbnailfile' | ||
138 | }, | ||
139 | { | ||
140 | url: 'previewUrl', | ||
141 | name: 'previewfile' | ||
142 | } | ||
143 | ] | ||
144 | |||
145 | for (const obj of objects) { | ||
146 | fetch(this.video[obj.url]) | ||
147 | .then(response => response.blob()) | ||
148 | .then(data => { | ||
149 | this.form.patchValue({ | ||
150 | [ obj.name ]: data | ||
151 | }) | ||
152 | }) | ||
153 | } | ||
154 | } | ||
155 | } | ||