Fix exception when getting 404 in video watch
[oweals/peertube.git] / client / src / app / videos / video-edit / video-add.component.ts
index 0653f5ac4aff38e80470d28673f15e44b7eb870a..21311b184067add1af455b3bc7228b5f346e240d 100644 (file)
@@ -1,11 +1,9 @@
-import { Component, ElementRef, OnInit } from '@angular/core'
+import { Component, OnInit, ViewChild } from '@angular/core'
 import { FormBuilder, FormGroup } from '@angular/forms'
 import { Router } from '@angular/router'
 
-import { FileUploader } from 'ng2-file-upload/ng2-file-upload'
 import { NotificationsService } from 'angular2-notifications'
 
-import { AuthService } from '../../core'
 import {
   FormReactive,
   VIDEO_NAME,
@@ -16,6 +14,9 @@ import {
   VIDEO_TAGS
 } from '../../shared'
 import { VideoService } from '../shared'
+import { VideoCreate } from '../../../../../shared'
+import { HttpEventType, HttpResponse } from '@angular/common/http'
+import { VIDEO_FILE } from '../../shared/forms/form-validators/video'
 
 @Component({
   selector: 'my-videos-add',
@@ -24,8 +25,10 @@ import { VideoService } from '../shared'
 })
 
 export class VideoAddComponent extends FormReactive implements OnInit {
+  @ViewChild('videofileInput') videofileInput
+
+  progressPercent = 0
   tags: string[] = []
-  uploader: FileUploader
   videoCategories = []
   videoLicences = []
   videoLanguages = []
@@ -33,29 +36,26 @@ export class VideoAddComponent extends FormReactive implements OnInit {
   tagValidators = VIDEO_TAGS.VALIDATORS
   tagValidatorsMessages = VIDEO_TAGS.MESSAGES
 
-  error: string = null
+  error: string
   form: FormGroup
   formErrors = {
     name: '',
     category: '',
     licence: '',
     language: '',
-    description: ''
+    description: '',
+    videofile: ''
   }
   validationMessages = {
     name: VIDEO_NAME.MESSAGES,
     category: VIDEO_CATEGORY.MESSAGES,
     licence: VIDEO_LICENCE.MESSAGES,
     language: VIDEO_LANGUAGE.MESSAGES,
-    description: VIDEO_DESCRIPTION.MESSAGES
+    description: VIDEO_DESCRIPTION.MESSAGES,
+    videofile: VIDEO_FILE.MESSAGES
   }
 
-  // Special error messages
-  fileError = ''
-
   constructor (
-    private authService: AuthService,
-    private elementRef: ElementRef,
     private formBuilder: FormBuilder,
     private router: Router,
     private notificationsService: NotificationsService,
@@ -65,11 +65,7 @@ export class VideoAddComponent extends FormReactive implements OnInit {
   }
 
   get filename () {
-    if (this.uploader.queue.length === 0) {
-      return null
-    }
-
-    return this.uploader.queue[0].file.name
+    return this.form.value['videofile']
   }
 
   buildForm () {
@@ -80,7 +76,8 @@ export class VideoAddComponent extends FormReactive implements OnInit {
       licence: [ '', VIDEO_LICENCE.VALIDATORS ],
       language: [ '', VIDEO_LANGUAGE.VALIDATORS ],
       description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
-      tags: [ '']
+      videofile: [ '', VIDEO_FILE.VALIDATORS ],
+      tags: [ '' ]
     })
 
     this.form.valueChanges.subscribe(data => this.onValueChanged(data))
@@ -91,58 +88,24 @@ export class VideoAddComponent extends FormReactive implements OnInit {
     this.videoLicences = this.videoService.videoLicences
     this.videoLanguages = this.videoService.videoLanguages
 
-    this.uploader = new FileUploader({
-      authToken: this.authService.getRequestHeaderValue(),
-      queueLimit: 1,
-      url: API_URL + '/api/v1/videos',
-      removeAfterUpload: true
-    })
-
-    this.uploader.onBuildItemForm = (item, form) => {
-      const name = this.form.value['name']
-      const nsfw = this.form.value['nsfw']
-      const category = this.form.value['category']
-      const licence = this.form.value['licence']
-      const language = this.form.value['language']
-      const description = this.form.value['description']
-      const tags = this.form.value['tags']
-
-      form.append('name', name)
-      form.append('category', category)
-      form.append('nsfw', nsfw)
-      form.append('licence', licence)
-
-      // Language is optional
-      if (language) {
-        form.append('language', language)
-      }
-
-      form.append('description', description)
-
-      for (let i = 0; i < tags.length; i++) {
-        form.append(`tags[${i}]`, tags[i])
-      }
-    }
-
     this.buildForm()
   }
 
-  checkForm () {
-    this.forceCheck()
-
-    if (this.filename === null) {
-      this.fileError = 'You did not add a file.'
-    }
-
-    return this.form.valid === true && this.fileError === ''
+  // The goal is to keep reactive form validation (required field)
+  // https://stackoverflow.com/a/44238894
+  fileChange ($event) {
+    this.form.controls['videofile'].setValue($event.target.files[0].name)
   }
 
-  fileChanged () {
-    this.fileError = ''
+  removeFile () {
+    this.videofileInput.nativeElement.value = ''
+    this.form.controls['videofile'].setValue('')
   }
 
-  removeFile () {
-    this.uploader.clearQueue()
+  checkForm () {
+    this.forceCheck()
+
+    return this.form.valid
   }
 
   upload () {
@@ -150,37 +113,53 @@ export class VideoAddComponent extends FormReactive implements OnInit {
       return
     }
 
-    const item = this.uploader.queue[0]
-    // TODO: wait for https://github.com/valor-software/ng2-file-upload/pull/242
-    item.alias = 'videofile'
+    const formValue: VideoCreate = this.form.value
+
+    const name = formValue.name
+    const nsfw = formValue.nsfw
+    const category = formValue.category
+    const licence = formValue.licence
+    const language = formValue.language
+    const description = formValue.description
+    const tags = formValue.tags
+    const videofile = this.videofileInput.nativeElement.files[0]
+
+    const formData = new FormData()
+    formData.append('name', name)
+    formData.append('category', '' + category)
+    formData.append('nsfw', '' + nsfw)
+    formData.append('licence', '' + licence)
+    formData.append('videofile', videofile)
+
+    // Language is optional
+    if (language) {
+      formData.append('language', '' + language)
+    }
 
-    item.onSuccess = () => {
-      console.log('Video uploaded.')
-      this.notificationsService.success('Success', 'Video uploaded.')
+    formData.append('description', description)
 
-      // Print all the videos once it's finished
-      this.router.navigate(['/videos/list'])
+    for (let i = 0; i < tags.length; i++) {
+      formData.append(`tags[${i}]`, tags[i])
     }
 
-    item.onError = (response: string, status: number) => {
-      // We need to handle manually these cases beceause we use the FileUpload component
-      if (status === 400) {
-        this.error = response
-      } else if (status === 401) {
-        this.error = 'Access token was expired, refreshing token...'
-        this.authService.refreshAccessToken().subscribe(
-          () => {
-            // Update the uploader request header
-            this.uploader.authToken = this.authService.getRequestHeaderValue()
-            this.error += ' access token refreshed. Please retry your request.'
-          }
-        )
-      } else {
-        this.error = 'Unknow error'
-        console.error(this.error)
+    this.videoService.uploadVideo(formData).subscribe(
+      event => {
+        if (event.type === HttpEventType.UploadProgress) {
+          this.progressPercent = Math.round(100 * event.loaded / event.total)
+        } else if (event instanceof HttpResponse) {
+          console.log('Video uploaded.')
+          this.notificationsService.success('Success', 'Video uploaded.')
+
+          // Display all the videos once it's finished
+          this.router.navigate([ '/videos/list' ])
+        }
+      },
+
+      err => {
+        // Reset progress
+        this.progressPercent = 0
+        this.error = err.message
       }
-    }
-
-    this.uploader.uploadAll()
+    )
   }
 }