diff options
Diffstat (limited to 'client/src/app/videos/video-add/video-add.component.ts')
-rw-r--r-- | client/src/app/videos/video-add/video-add.component.ts | 162 |
1 files changed, 110 insertions, 52 deletions
diff --git a/client/src/app/videos/video-add/video-add.component.ts b/client/src/app/videos/video-add/video-add.component.ts index 144879a54..2b45ea125 100644 --- a/client/src/app/videos/video-add/video-add.component.ts +++ b/client/src/app/videos/video-add/video-add.component.ts | |||
@@ -1,29 +1,31 @@ | |||
1 | /// <reference path="../../../../typings/globals/jquery/index.d.ts" /> | 1 | import { Control, ControlGroup, Validators } from '@angular/common'; |
2 | /// <reference path="../../../../typings/globals/jquery.fileupload/index.d.ts" /> | ||
3 | |||
4 | import { Component, ElementRef, OnInit } from '@angular/core'; | 2 | import { Component, ElementRef, OnInit } from '@angular/core'; |
5 | import { Router } from '@angular/router-deprecated'; | 3 | import { Router } from '@angular/router-deprecated'; |
6 | 4 | ||
7 | import { BytesPipe } from 'angular-pipes/src/math/bytes.pipe'; | 5 | import { BytesPipe } from 'angular-pipes/src/math/bytes.pipe'; |
8 | import { PROGRESSBAR_DIRECTIVES } from 'ng2-bootstrap/components/progressbar'; | 6 | import { PROGRESSBAR_DIRECTIVES } from 'ng2-bootstrap/components/progressbar'; |
7 | import { FileSelectDirective, FileUploader } from 'ng2-file-upload/ng2-file-upload'; | ||
9 | 8 | ||
10 | import { AuthService, User } from '../../shared'; | 9 | import { AuthService } from '../../shared'; |
11 | 10 | ||
12 | @Component({ | 11 | @Component({ |
13 | selector: 'my-videos-add', | 12 | selector: 'my-videos-add', |
14 | styles: [ require('./video-add.component.scss') ], | 13 | styles: [ require('./video-add.component.scss') ], |
15 | template: require('./video-add.component.html'), | 14 | template: require('./video-add.component.html'), |
16 | directives: [ PROGRESSBAR_DIRECTIVES ], | 15 | directives: [ FileSelectDirective, PROGRESSBAR_DIRECTIVES ], |
17 | pipes: [ BytesPipe ] | 16 | pipes: [ BytesPipe ] |
18 | }) | 17 | }) |
19 | 18 | ||
20 | export class VideoAddComponent implements OnInit { | 19 | export class VideoAddComponent implements OnInit { |
20 | currentTag: string; // Tag the user is writing in the input | ||
21 | error: string = null; | 21 | error: string = null; |
22 | fileToUpload: any; | 22 | videoForm: ControlGroup; |
23 | progressBar: { value: number; max: number; } = { value: 0, max: 0 }; | 23 | uploader: FileUploader; |
24 | user: User; | 24 | video = { |
25 | 25 | name: '', | |
26 | private form: any; | 26 | tags: [], |
27 | description: '' | ||
28 | }; | ||
27 | 29 | ||
28 | constructor( | 30 | constructor( |
29 | private authService: AuthService, | 31 | private authService: AuthService, |
@@ -31,52 +33,108 @@ export class VideoAddComponent implements OnInit { | |||
31 | private router: Router | 33 | private router: Router |
32 | ) {} | 34 | ) {} |
33 | 35 | ||
36 | get filename() { | ||
37 | if (this.uploader.queue.length === 0) { | ||
38 | return null; | ||
39 | } | ||
40 | |||
41 | return this.uploader.queue[0].file.name; | ||
42 | } | ||
43 | |||
44 | get isTagsInputDisabled () { | ||
45 | return this.video.tags.length >= 3; | ||
46 | } | ||
47 | |||
48 | getInvalidFieldsTitle() { | ||
49 | let title = ''; | ||
50 | const nameControl = this.videoForm.controls['name']; | ||
51 | const descriptionControl = this.videoForm.controls['description']; | ||
52 | |||
53 | if (!nameControl.valid) { | ||
54 | title += 'A name is required\n'; | ||
55 | } | ||
56 | |||
57 | if (this.video.tags.length === 0) { | ||
58 | title += 'At least one tag is required\n'; | ||
59 | } | ||
60 | |||
61 | if (this.filename === null) { | ||
62 | title += 'A file is required\n'; | ||
63 | } | ||
64 | |||
65 | if (!descriptionControl.valid) { | ||
66 | title += 'A description is required\n'; | ||
67 | } | ||
68 | |||
69 | return title; | ||
70 | } | ||
71 | |||
34 | ngOnInit() { | 72 | ngOnInit() { |
35 | this.user = User.load(); | 73 | this.videoForm = new ControlGroup({ |
36 | jQuery(this.elementRef.nativeElement).find('#videofile').fileupload({ | 74 | name: new Control('', Validators.compose([ Validators.required, Validators.minLength(3), Validators.maxLength(50) ])), |
75 | description: new Control('', Validators.compose([ Validators.required, Validators.minLength(3), Validators.maxLength(250) ])), | ||
76 | tags: new Control('', Validators.pattern('^[a-zA-Z0-9]{2,10}$')) | ||
77 | }); | ||
78 | |||
79 | |||
80 | this.uploader = new FileUploader({ | ||
81 | authToken: this.authService.getRequestHeaderValue(), | ||
82 | queueLimit: 1, | ||
37 | url: '/api/v1/videos', | 83 | url: '/api/v1/videos', |
38 | dataType: 'json', | 84 | removeAfterUpload: true |
39 | singleFileUploads: true, | ||
40 | multipart: true, | ||
41 | autoUpload: false, | ||
42 | |||
43 | add: (e, data) => { | ||
44 | this.form = data; | ||
45 | this.fileToUpload = data['files'][0]; | ||
46 | }, | ||
47 | |||
48 | progressall: (e, data) => { | ||
49 | this.progressBar.value = data.loaded; | ||
50 | // The server is a little bit slow to answer (has to seed the video) | ||
51 | // So we add more time to the progress bar (+10%) | ||
52 | this.progressBar.max = data.total + (0.1 * data.total); | ||
53 | }, | ||
54 | |||
55 | done: (e, data) => { | ||
56 | this.progressBar.value = this.progressBar.max; | ||
57 | console.log('Video uploaded.'); | ||
58 | |||
59 | // Print all the videos once it's finished | ||
60 | this.router.navigate(['VideosList']); | ||
61 | }, | ||
62 | |||
63 | fail: (e, data) => { | ||
64 | const xhr = data.jqXHR; | ||
65 | if (xhr.status === 400) { | ||
66 | this.error = xhr.responseText; | ||
67 | } else { | ||
68 | this.error = 'Unknow error'; | ||
69 | } | ||
70 | |||
71 | console.error(data); | ||
72 | } | ||
73 | }); | 85 | }); |
86 | |||
87 | this.uploader.onBuildItemForm = (item, form) => { | ||
88 | form.append('name', this.video.name); | ||
89 | form.append('description', this.video.description); | ||
90 | |||
91 | for (let i = 0; i < this.video.tags.length; i++) { | ||
92 | form.append(`tags[${i}]`, this.video.tags[i]); | ||
93 | } | ||
94 | }; | ||
95 | } | ||
96 | |||
97 | onTagKeyPress(event: KeyboardEvent) { | ||
98 | // Enter press | ||
99 | if (event.keyCode === 13) { | ||
100 | // Check if the tag is valid and does not already exist | ||
101 | if ( | ||
102 | this.currentTag !== '' && | ||
103 | this.videoForm.controls['tags'].valid && | ||
104 | this.video.tags.indexOf(this.currentTag) === -1 | ||
105 | ) { | ||
106 | this.video.tags.push(this.currentTag); | ||
107 | this.currentTag = ''; | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | |||
112 | removeFile() { | ||
113 | this.uploader.clearQueue(); | ||
114 | } | ||
115 | |||
116 | removeTag(tag: string) { | ||
117 | this.video.tags.splice(this.video.tags.indexOf(tag), 1); | ||
74 | } | 118 | } |
75 | 119 | ||
76 | uploadFile() { | 120 | upload() { |
77 | this.error = null; | 121 | const item = this.uploader.queue[0]; |
78 | this.form.formData = jQuery(this.elementRef.nativeElement).find('form').serializeArray(); | 122 | // TODO: wait for https://github.com/valor-software/ng2-file-upload/pull/242 |
79 | this.form.headers = this.authService.getRequestHeader().toJSON(); | 123 | item.alias = 'videofile'; |
80 | this.form.submit(); | 124 | |
125 | item.onSuccess = () => { | ||
126 | console.log('Video uploaded.'); | ||
127 | |||
128 | // Print all the videos once it's finished | ||
129 | this.router.navigate(['VideosList']); | ||
130 | }; | ||
131 | |||
132 | item.onError = (response: string, status: number) => { | ||
133 | this.error = (status === 400) ? response : 'Unknow error'; | ||
134 | console.error(this.error); | ||
135 | }; | ||
136 | |||
137 | |||
138 | this.uploader.uploadAll(); | ||
81 | } | 139 | } |
82 | } | 140 | } |