Better typescript typing for a better world
[oweals/peertube.git] / client / src / app / videos / video-edit / video-add.component.ts
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 import { VideoCreate } from '../../../../../shared'
20
21 @Component({
22   selector: 'my-videos-add',
23   styleUrls: [ './video-edit.component.scss' ],
24   templateUrl: './video-add.component.html'
25 })
26
27 export class VideoAddComponent extends FormReactive implements OnInit {
28   tags: string[] = []
29   uploader: FileUploader
30   videoCategories = []
31   videoLicences = []
32   videoLanguages = []
33
34   tagValidators = VIDEO_TAGS.VALIDATORS
35   tagValidatorsMessages = VIDEO_TAGS.MESSAGES
36
37   error: string = null
38   form: FormGroup
39   formErrors = {
40     name: '',
41     category: '',
42     licence: '',
43     language: '',
44     description: ''
45   }
46   validationMessages = {
47     name: VIDEO_NAME.MESSAGES,
48     category: VIDEO_CATEGORY.MESSAGES,
49     licence: VIDEO_LICENCE.MESSAGES,
50     language: VIDEO_LANGUAGE.MESSAGES,
51     description: VIDEO_DESCRIPTION.MESSAGES
52   }
53
54   // Special error messages
55   fileError = ''
56
57   constructor (
58     private authService: AuthService,
59     private elementRef: ElementRef,
60     private formBuilder: FormBuilder,
61     private router: Router,
62     private notificationsService: NotificationsService,
63     private videoService: VideoService
64   ) {
65     super()
66   }
67
68   get filename () {
69     if (this.uploader.queue.length === 0) {
70       return null
71     }
72
73     return this.uploader.queue[0].file.name
74   }
75
76   buildForm () {
77     this.form = this.formBuilder.group({
78       name: [ '', VIDEO_NAME.VALIDATORS ],
79       nsfw: [ false ],
80       category: [ '', VIDEO_CATEGORY.VALIDATORS ],
81       licence: [ '', VIDEO_LICENCE.VALIDATORS ],
82       language: [ '', VIDEO_LANGUAGE.VALIDATORS ],
83       description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
84       tags: [ '']
85     })
86
87     this.form.valueChanges.subscribe(data => this.onValueChanged(data))
88   }
89
90   ngOnInit () {
91     this.videoCategories = this.videoService.videoCategories
92     this.videoLicences = this.videoService.videoLicences
93     this.videoLanguages = this.videoService.videoLanguages
94
95     this.uploader = new FileUploader({
96       authToken: this.authService.getRequestHeaderValue(),
97       queueLimit: 1,
98       url: API_URL + '/api/v1/videos',
99       removeAfterUpload: true
100     })
101
102     this.uploader.onBuildItemForm = (item, form: FormData) => {
103       const formValue: VideoCreate = this.form.value
104
105       const name = formValue.name
106       const nsfw = formValue.nsfw
107       const category = formValue.category
108       const licence = formValue.licence
109       const language = formValue.language
110       const description = formValue.description
111       const tags = formValue.tags
112
113       form.append('name', name)
114       form.append('category', '' + category)
115       form.append('nsfw', '' + nsfw)
116       form.append('licence', '' + licence)
117
118       // Language is optional
119       if (language) {
120         form.append('language', '' + language)
121       }
122
123       form.append('description', description)
124
125       for (let i = 0; i < tags.length; i++) {
126         form.append(`tags[${i}]`, tags[i])
127       }
128     }
129
130     this.buildForm()
131   }
132
133   checkForm () {
134     this.forceCheck()
135
136     if (this.filename === null) {
137       this.fileError = 'You did not add a file.'
138     }
139
140     return this.form.valid === true && this.fileError === ''
141   }
142
143   fileChanged () {
144     this.fileError = ''
145   }
146
147   removeFile () {
148     this.uploader.clearQueue()
149   }
150
151   upload () {
152     if (this.checkForm() === false) {
153       return
154     }
155
156     const item = this.uploader.queue[0]
157     // TODO: wait for https://github.com/valor-software/ng2-file-upload/pull/242
158     item.alias = 'videofile'
159
160     item.onSuccess = () => {
161       console.log('Video uploaded.')
162       this.notificationsService.success('Success', 'Video uploaded.')
163
164       // Print all the videos once it's finished
165       this.router.navigate(['/videos/list'])
166     }
167
168     item.onError = (response: string, status: number) => {
169       // We need to handle manually these cases beceause we use the FileUpload component
170       if (status === 400) {
171         this.error = response
172       } else if (status === 401) {
173         this.error = 'Access token was expired, refreshing token...'
174         this.authService.refreshAccessToken().subscribe(
175           () => {
176             // Update the uploader request header
177             this.uploader.authToken = this.authService.getRequestHeaderValue()
178             this.error += ' access token refreshed. Please retry your request.'
179           }
180         )
181       } else {
182         this.error = 'Unknow error'
183         console.error(this.error)
184       }
185     }
186
187     this.uploader.uploadAll()
188   }
189 }