diff options
Diffstat (limited to 'client/src/app/videos/video-edit/video-add.component.ts')
-rw-r--r-- | client/src/app/videos/video-edit/video-add.component.ts | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/client/src/app/videos/video-edit/video-add.component.ts b/client/src/app/videos/video-edit/video-add.component.ts new file mode 100644 index 000000000..e3cf0e9d8 --- /dev/null +++ b/client/src/app/videos/video-edit/video-add.component.ts | |||
@@ -0,0 +1,230 @@ | |||
1 | import { Component, ElementRef, OnInit } from '@angular/core'; | ||
2 | import { FormBuilder, FormGroup } from '@angular/forms'; | ||
3 | import { Router } from '@angular/router'; | ||
4 | |||
5 | import { FileUploader } from 'ng2-file-upload/ng2-file-upload'; | ||
6 | import { NotificationsService } from 'angular2-notifications'; | ||
7 | |||
8 | import { AuthService } from '../../core'; | ||
9 | import { | ||
10 | FormReactive, | ||
11 | VIDEO_NAME, | ||
12 | VIDEO_CATEGORY, | ||
13 | VIDEO_LICENCE, | ||
14 | VIDEO_LANGUAGE, | ||
15 | VIDEO_DESCRIPTION, | ||
16 | VIDEO_TAGS | ||
17 | } from '../../shared'; | ||
18 | import { VideoService } from '../shared'; | ||
19 | |||
20 | @Component({ | ||
21 | selector: 'my-videos-add', | ||
22 | styleUrls: [ './video-edit.component.scss' ], | ||
23 | templateUrl: './video-add.component.html' | ||
24 | }) | ||
25 | |||
26 | export class VideoAddComponent extends FormReactive implements OnInit { | ||
27 | tags: string[] = []; | ||
28 | uploader: FileUploader; | ||
29 | videoCategories = []; | ||
30 | videoLicences = []; | ||
31 | videoLanguages = []; | ||
32 | |||
33 | error: string = null; | ||
34 | form: FormGroup; | ||
35 | formErrors = { | ||
36 | name: '', | ||
37 | category: '', | ||
38 | licence: '', | ||
39 | language: '', | ||
40 | description: '', | ||
41 | currentTag: '' | ||
42 | }; | ||
43 | validationMessages = { | ||
44 | name: VIDEO_NAME.MESSAGES, | ||
45 | category: VIDEO_CATEGORY.MESSAGES, | ||
46 | licence: VIDEO_LICENCE.MESSAGES, | ||
47 | language: VIDEO_LANGUAGE.MESSAGES, | ||
48 | description: VIDEO_DESCRIPTION.MESSAGES, | ||
49 | currentTag: VIDEO_TAGS.MESSAGES | ||
50 | }; | ||
51 | |||
52 | // Special error messages | ||
53 | tagsError = ''; | ||
54 | fileError = ''; | ||
55 | |||
56 | constructor( | ||
57 | private authService: AuthService, | ||
58 | private elementRef: ElementRef, | ||
59 | private formBuilder: FormBuilder, | ||
60 | private router: Router, | ||
61 | private notificationsService: NotificationsService, | ||
62 | private videoService: VideoService | ||
63 | ) { | ||
64 | super(); | ||
65 | } | ||
66 | |||
67 | get filename() { | ||
68 | if (this.uploader.queue.length === 0) { | ||
69 | return null; | ||
70 | } | ||
71 | |||
72 | return this.uploader.queue[0].file.name; | ||
73 | } | ||
74 | |||
75 | buildForm() { | ||
76 | this.form = this.formBuilder.group({ | ||
77 | name: [ '', VIDEO_NAME.VALIDATORS ], | ||
78 | nsfw: [ false ], | ||
79 | category: [ '', VIDEO_CATEGORY.VALIDATORS ], | ||
80 | licence: [ '', VIDEO_LICENCE.VALIDATORS ], | ||
81 | language: [ '', VIDEO_LANGUAGE.VALIDATORS ], | ||
82 | description: [ '', VIDEO_DESCRIPTION.VALIDATORS ], | ||
83 | currentTag: [ '', VIDEO_TAGS.VALIDATORS ] | ||
84 | }); | ||
85 | |||
86 | this.form.valueChanges.subscribe(data => this.onValueChanged(data)); | ||
87 | } | ||
88 | |||
89 | ngOnInit() { | ||
90 | this.videoCategories = this.videoService.videoCategories; | ||
91 | this.videoLicences = this.videoService.videoLicences; | ||
92 | this.videoLanguages = this.videoService.videoLanguages; | ||
93 | |||
94 | this.uploader = new FileUploader({ | ||
95 | authToken: this.authService.getRequestHeaderValue(), | ||
96 | queueLimit: 1, | ||
97 | url: '/api/v1/videos', | ||
98 | removeAfterUpload: true | ||
99 | }); | ||
100 | |||
101 | this.uploader.onBuildItemForm = (item, form) => { | ||
102 | const name = this.form.value['name']; | ||
103 | const nsfw = this.form.value['nsfw']; | ||
104 | const category = this.form.value['category']; | ||
105 | const licence = this.form.value['licence']; | ||
106 | const language = this.form.value['language']; | ||
107 | const description = this.form.value['description']; | ||
108 | |||
109 | form.append('name', name); | ||
110 | form.append('category', category); | ||
111 | form.append('nsfw', nsfw); | ||
112 | form.append('licence', licence); | ||
113 | |||
114 | // Language is optional | ||
115 | if (language) { | ||
116 | form.append('language', language); | ||
117 | } | ||
118 | |||
119 | form.append('description', description); | ||
120 | |||
121 | for (let i = 0; i < this.tags.length; i++) { | ||
122 | form.append(`tags[${i}]`, this.tags[i]); | ||
123 | } | ||
124 | }; | ||
125 | |||
126 | this.buildForm(); | ||
127 | } | ||
128 | |||
129 | checkForm() { | ||
130 | this.forceCheck(); | ||
131 | |||
132 | if (this.filename === null) { | ||
133 | this.fileError = 'You did not add a file.'; | ||
134 | } | ||
135 | |||
136 | return this.form.valid === true && this.tagsError === '' && this.fileError === ''; | ||
137 | } | ||
138 | |||
139 | fileChanged() { | ||
140 | this.fileError = ''; | ||
141 | } | ||
142 | |||
143 | onTagKeyPress(event: KeyboardEvent) { | ||
144 | // Enter press | ||
145 | if (event.keyCode === 13) { | ||
146 | this.addTagIfPossible(); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | removeFile() { | ||
151 | this.uploader.clearQueue(); | ||
152 | } | ||
153 | |||
154 | removeTag(tag: string) { | ||
155 | this.tags.splice(this.tags.indexOf(tag), 1); | ||
156 | this.form.get('currentTag').enable(); | ||
157 | } | ||
158 | |||
159 | upload() { | ||
160 | // Maybe the user forgot to press "enter" when he filled the field | ||
161 | this.addTagIfPossible(); | ||
162 | |||
163 | if (this.checkForm() === false) { | ||
164 | return; | ||
165 | } | ||
166 | |||
167 | const item = this.uploader.queue[0]; | ||
168 | // TODO: wait for https://github.com/valor-software/ng2-file-upload/pull/242 | ||
169 | item.alias = 'videofile'; | ||
170 | |||
171 | // FIXME: remove | ||
172 | // Run detection change for progress bar | ||
173 | const interval = setInterval(() => { ; }, 250); | ||
174 | |||
175 | item.onSuccess = () => { | ||
176 | clearInterval(interval); | ||
177 | |||
178 | console.log('Video uploaded.'); | ||
179 | this.notificationsService.success('Success', 'Video uploaded.'); | ||
180 | |||
181 | |||
182 | // Print all the videos once it's finished | ||
183 | this.router.navigate(['/videos/list']); | ||
184 | }; | ||
185 | |||
186 | item.onError = (response: string, status: number) => { | ||
187 | clearInterval(interval); | ||
188 | |||
189 | // We need to handle manually these cases beceause we use the FileUpload component | ||
190 | if (status === 400) { | ||
191 | this.error = response; | ||
192 | } else if (status === 401) { | ||
193 | this.error = 'Access token was expired, refreshing token...'; | ||
194 | this.authService.refreshAccessToken().subscribe( | ||
195 | () => { | ||
196 | // Update the uploader request header | ||
197 | this.uploader.authToken = this.authService.getRequestHeaderValue(); | ||
198 | this.error += ' access token refreshed. Please retry your request.'; | ||
199 | } | ||
200 | ); | ||
201 | } else { | ||
202 | this.error = 'Unknow error'; | ||
203 | console.error(this.error); | ||
204 | } | ||
205 | }; | ||
206 | |||
207 | this.uploader.uploadAll(); | ||
208 | } | ||
209 | |||
210 | private addTagIfPossible() { | ||
211 | const currentTag = this.form.value['currentTag']; | ||
212 | if (currentTag === undefined) return; | ||
213 | |||
214 | // Check if the tag is valid and does not already exist | ||
215 | if ( | ||
216 | currentTag.length >= 2 && | ||
217 | this.form.controls['currentTag'].valid && | ||
218 | this.tags.indexOf(currentTag) === -1 | ||
219 | ) { | ||
220 | this.tags.push(currentTag); | ||
221 | this.form.patchValue({ currentTag: '' }); | ||
222 | |||
223 | if (this.tags.length >= 3) { | ||
224 | this.form.get('currentTag').disable(); | ||
225 | } | ||
226 | |||
227 | this.tagsError = ''; | ||
228 | } | ||
229 | } | ||
230 | } | ||