Try to optimize frontend
[oweals/peertube.git] / client / src / app / videos / +video-edit / video-add.component.ts
1 import { Component, OnInit, ViewChild } from '@angular/core'
2 import { FormBuilder, FormGroup } from '@angular/forms'
3 import { Router } from '@angular/router'
4
5 import { NotificationsService } from 'angular2-notifications'
6
7 import {
8   FormReactive,
9   VIDEO_NAME,
10   VIDEO_CATEGORY,
11   VIDEO_LICENCE,
12   VIDEO_LANGUAGE,
13   VIDEO_DESCRIPTION,
14   VIDEO_TAGS
15 } from '../../shared'
16 import { VideoService } from '../shared'
17 import { VideoCreate } from '../../../../../shared'
18 import { HttpEventType, HttpResponse } from '@angular/common/http'
19 import { VIDEO_FILE } from '../../shared/forms/form-validators/video'
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   @ViewChild('videofileInput') videofileInput
29
30   progressPercent = 0
31   tags: string[] = []
32   videoCategories = []
33   videoLicences = []
34   videoLanguages = []
35
36   tagValidators = VIDEO_TAGS.VALIDATORS
37   tagValidatorsMessages = VIDEO_TAGS.MESSAGES
38
39   error: string
40   form: FormGroup
41   formErrors = {
42     name: '',
43     category: '',
44     licence: '',
45     language: '',
46     description: '',
47     videofile: ''
48   }
49   validationMessages = {
50     name: VIDEO_NAME.MESSAGES,
51     category: VIDEO_CATEGORY.MESSAGES,
52     licence: VIDEO_LICENCE.MESSAGES,
53     language: VIDEO_LANGUAGE.MESSAGES,
54     description: VIDEO_DESCRIPTION.MESSAGES,
55     videofile: VIDEO_FILE.MESSAGES
56   }
57
58   constructor (
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     return this.form.value['videofile']
69   }
70
71   buildForm () {
72     this.form = this.formBuilder.group({
73       name: [ '', VIDEO_NAME.VALIDATORS ],
74       nsfw: [ false ],
75       category: [ '', VIDEO_CATEGORY.VALIDATORS ],
76       licence: [ '', VIDEO_LICENCE.VALIDATORS ],
77       language: [ '', VIDEO_LANGUAGE.VALIDATORS ],
78       description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
79       videofile: [ '', VIDEO_FILE.VALIDATORS ],
80       tags: [ '' ]
81     })
82
83     this.form.valueChanges.subscribe(data => this.onValueChanged(data))
84   }
85
86   ngOnInit () {
87     this.videoCategories = this.videoService.videoCategories
88     this.videoLicences = this.videoService.videoLicences
89     this.videoLanguages = this.videoService.videoLanguages
90
91     this.buildForm()
92   }
93
94   // The goal is to keep reactive form validation (required field)
95   // https://stackoverflow.com/a/44238894
96   fileChange ($event) {
97     this.form.controls['videofile'].setValue($event.target.files[0].name)
98   }
99
100   removeFile () {
101     this.videofileInput.nativeElement.value = ''
102     this.form.controls['videofile'].setValue('')
103   }
104
105   checkForm () {
106     this.forceCheck()
107
108     return this.form.valid
109   }
110
111   upload () {
112     if (this.checkForm() === false) {
113       return
114     }
115
116     const formValue: VideoCreate = this.form.value
117
118     const name = formValue.name
119     const nsfw = formValue.nsfw
120     const category = formValue.category
121     const licence = formValue.licence
122     const language = formValue.language
123     const description = formValue.description
124     const tags = formValue.tags
125     const videofile = this.videofileInput.nativeElement.files[0]
126
127     const formData = new FormData()
128     formData.append('name', name)
129     formData.append('category', '' + category)
130     formData.append('nsfw', '' + nsfw)
131     formData.append('licence', '' + licence)
132     formData.append('videofile', videofile)
133
134     // Language is optional
135     if (language) {
136       formData.append('language', '' + language)
137     }
138
139     formData.append('description', description)
140
141     for (let i = 0; i < tags.length; i++) {
142       formData.append(`tags[${i}]`, tags[i])
143     }
144
145     this.videoService.uploadVideo(formData).subscribe(
146       event => {
147         if (event.type === HttpEventType.UploadProgress) {
148           this.progressPercent = Math.round(100 * event.loaded / event.total)
149         } else if (event instanceof HttpResponse) {
150           console.log('Video uploaded.')
151           this.notificationsService.success('Success', 'Video uploaded.')
152
153           // Display all the videos once it's finished
154           this.router.navigate([ '/videos/list' ])
155         }
156       },
157
158       err => {
159         // Reset progress
160         this.progressPercent = 0
161         this.error = err.message
162       }
163     )
164   }
165 }