Move send video components inside a dedicated directory
authorChocobozzz <me@florianbigard.com>
Mon, 6 Aug 2018 13:30:24 +0000 (15:30 +0200)
committerChocobozzz <me@florianbigard.com>
Wed, 8 Aug 2018 07:30:31 +0000 (09:30 +0200)
16 files changed:
client/src/app/videos/+video-edit/shared/video-send.ts [deleted file]
client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html [new file with mode: 0644]
client/src/app/videos/+video-edit/video-add-components/video-import-url.component.scss [new file with mode: 0644]
client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts [new file with mode: 0644]
client/src/app/videos/+video-edit/video-add-components/video-send.ts [new file with mode: 0644]
client/src/app/videos/+video-edit/video-add-components/video-upload.component.html [new file with mode: 0644]
client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss [new file with mode: 0644]
client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts [new file with mode: 0644]
client/src/app/videos/+video-edit/video-add.component.ts
client/src/app/videos/+video-edit/video-add.module.ts
client/src/app/videos/+video-edit/video-import-url.component.html [deleted file]
client/src/app/videos/+video-edit/video-import-url.component.scss [deleted file]
client/src/app/videos/+video-edit/video-import-url.component.ts [deleted file]
client/src/app/videos/+video-edit/video-upload.component.html [deleted file]
client/src/app/videos/+video-edit/video-upload.component.scss [deleted file]
client/src/app/videos/+video-edit/video-upload.component.ts [deleted file]

diff --git a/client/src/app/videos/+video-edit/shared/video-send.ts b/client/src/app/videos/+video-edit/shared/video-send.ts
deleted file mode 100644 (file)
index bc1c7a4..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-import { FormReactive } from '@app/shared'
-import { OnInit } from '@angular/core'
-import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service'
-import { populateAsyncUserVideoChannels } from '@app/shared/misc/utils'
-import { VideoConstant, VideoPrivacy } from '../../../../../../shared/models/videos'
-import { VideoCaptionEdit } from '@app/shared/video-caption/video-caption-edit.model'
-import { LoadingBarService } from '@ngx-loading-bar/core'
-import { NotificationsService } from 'angular2-notifications'
-import { AuthService, ServerService } from '@app/core'
-import { VideoService } from '@app/shared/video/video.service'
-import { VideoCaptionService } from '@app/shared/video-caption'
-import { catchError, switchMap, tap } from 'rxjs/operators'
-import { VideoEdit } from '@app/shared/video/video-edit.model'
-
-export abstract class VideoSend extends FormReactive implements OnInit, CanComponentDeactivate {
-
-  userVideoChannels: { id: number, label: string, support: string }[] = []
-  videoPrivacies: VideoConstant<string>[] = []
-  videoCaptions: VideoCaptionEdit[] = []
-
-  firstStepPrivacyId = 0
-  firstStepChannelId = 0
-
-  protected abstract readonly DEFAULT_VIDEO_PRIVACY: VideoPrivacy
-
-  protected loadingBar: LoadingBarService
-  protected notificationsService: NotificationsService
-  protected authService: AuthService
-  protected serverService: ServerService
-  protected videoService: VideoService
-  protected videoCaptionService: VideoCaptionService
-
-  abstract canDeactivate ()
-
-  ngOnInit () {
-    this.buildForm({})
-
-    populateAsyncUserVideoChannels(this.authService, this.userVideoChannels)
-      .then(() => this.firstStepChannelId = this.userVideoChannels[ 0 ].id)
-
-    this.serverService.videoPrivaciesLoaded
-        .subscribe(
-          () => {
-            this.videoPrivacies = this.serverService.getVideoPrivacies()
-
-            this.firstStepPrivacyId = this.DEFAULT_VIDEO_PRIVACY
-          })
-  }
-
-  checkForm () {
-    this.forceCheck()
-
-    return this.form.valid
-  }
-
-  protected updateVideoAndCaptions (video: VideoEdit) {
-    this.loadingBar.start()
-
-    return this.videoService.updateVideo(video)
-        .pipe(
-          // Then update captions
-          switchMap(() => this.videoCaptionService.updateCaptions(video.id, this.videoCaptions)),
-          tap(() => this.loadingBar.complete()),
-          catchError(err => {
-            this.loadingBar.complete()
-            throw err
-          })
-        )
-  }
-}
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html
new file mode 100644 (file)
index 0000000..6b431f6
--- /dev/null
@@ -0,0 +1,60 @@
+<div *ngIf="!hasImportedVideo" class="upload-video-container">
+  <div class="import-video">
+    <div class="icon icon-upload"></div>
+
+    <div class="form-group">
+      <label i18n for="targetUrl">URL</label>
+      <my-help
+        helpType="custom" i18n-customHtml
+        customHtml="You can import any URL <a href='https://rg3.github.io/youtube-dl/supportedsites.html' target='_blank' rel='noopener noreferrer'>supported by youtube-dl</a> or URL that points to a raw MP4 file. You should make sure you have diffusion rights over the content it points to, otherwise it could cause legal trouble to yourself and your instance."
+      ></my-help>
+
+      <input type="text" id="targetUrl" [(ngModel)]="targetUrl" />
+    </div>
+
+    <div class="form-group">
+      <label i18n for="first-step-channel">Channel</label>
+      <div class="peertube-select-container">
+        <select id="first-step-channel" [(ngModel)]="firstStepChannelId">
+          <option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
+        </select>
+      </div>
+    </div>
+
+    <div class="form-group">
+      <label i18n for="first-step-privacy">Privacy</label>
+      <div class="peertube-select-container">
+        <select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId">
+          <option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
+        </select>
+      </div>
+    </div>
+
+    <input
+      type="button" i18n-value value="Import"
+      [disabled]="!isTargetUrlValid() || isImportingVideo" (click)="importVideo()"
+    />
+  </div>
+</div>
+
+<div *ngIf="hasImportedVideo" class="alert alert-info" i18n>
+  Congratulations, the video behind {{ targetUrl }} will be imported! You can already add information about this video.
+</div>
+
+<!-- Hidden because we want to load the component -->
+<form [hidden]="!hasImportedVideo" novalidate [formGroup]="form">
+  <my-video-edit
+    [form]="form" [formErrors]="formErrors" [videoCaptions]="videoCaptions" [schedulePublicationPossible]="false"
+    [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" [userVideoChannels]="userVideoChannels"
+  ></my-video-edit>
+
+  <div class="submit-container">
+    <div class="submit-button"
+       (click)="updateSecondStep()"
+       [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true }"
+    >
+      <span class="icon icon-validate"></span>
+      <input type="button" i18n-value value="Update" />
+    </div>
+  </div>
+</form>
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.scss b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.scss
new file mode 100644 (file)
index 0000000..5e713ab
--- /dev/null
@@ -0,0 +1,37 @@
+@import 'variables';
+@import 'mixins';
+
+$width-size: 190px;
+
+.peertube-select-container {
+  @include peertube-select-container($width-size);
+}
+
+.import-video {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+
+  .icon.icon-upload {
+    @include icon(90px);
+    margin-bottom: 25px;
+    cursor: default;
+
+    background-image: url('../../../../assets/images/video/upload.svg');
+  }
+
+  input[type=text] {
+    @include peertube-input-text($width-size);
+    display: block;
+  }
+
+  input[type=button] {
+    @include peertube-button;
+    @include orange-button;
+
+    width: $width-size;
+    margin-top: 30px;
+  }
+}
+
+
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts
new file mode 100644 (file)
index 0000000..dbe6940
--- /dev/null
@@ -0,0 +1,132 @@
+import { Component, EventEmitter, OnInit, Output } from '@angular/core'
+import { Router } from '@angular/router'
+import { NotificationsService } from 'angular2-notifications'
+import { VideoPrivacy, VideoUpdate } from '../../../../../../shared/models/videos'
+import { AuthService, ServerService } from '../../../core'
+import { VideoService } from '../../../shared/video/video.service'
+import { I18n } from '@ngx-translate/i18n-polyfill'
+import { LoadingBarService } from '@ngx-loading-bar/core'
+import { VideoSend } from '@app/videos/+video-edit/video-add-components/video-send'
+import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service'
+import { VideoEdit } from '@app/shared/video/video-edit.model'
+import { FormValidatorService } from '@app/shared'
+import { VideoCaptionService } from '@app/shared/video-caption'
+import { VideoImportService } from '@app/shared/video-import'
+
+@Component({
+  selector: 'my-video-import-url',
+  templateUrl: './video-import-url.component.html',
+  styleUrls: [
+    '../shared/video-edit.component.scss',
+    './video-import-url.component.scss'
+  ]
+})
+export class VideoImportUrlComponent extends VideoSend implements OnInit, CanComponentDeactivate {
+  @Output() firstStepDone = new EventEmitter<string>()
+
+  targetUrl = ''
+  videoFileName: string
+
+  isImportingVideo = false
+  hasImportedVideo = false
+  isUpdatingVideo = false
+
+  video: VideoEdit
+
+  protected readonly DEFAULT_VIDEO_PRIVACY = VideoPrivacy.PRIVATE
+
+  constructor (
+    protected formValidatorService: FormValidatorService,
+    protected loadingBar: LoadingBarService,
+    protected notificationsService: NotificationsService,
+    protected authService: AuthService,
+    protected serverService: ServerService,
+    protected videoService: VideoService,
+    protected videoCaptionService: VideoCaptionService,
+    private router: Router,
+    private videoImportService: VideoImportService,
+    private i18n: I18n
+  ) {
+    super()
+  }
+
+  ngOnInit () {
+    super.ngOnInit()
+  }
+
+  canDeactivate () {
+    return { canDeactivate: true }
+  }
+
+  isTargetUrlValid () {
+    return this.targetUrl && this.targetUrl.match(/https?:\/\//)
+  }
+
+  importVideo () {
+    this.isImportingVideo = true
+
+    const videoUpdate: VideoUpdate = {
+      privacy: this.firstStepPrivacyId,
+      waitTranscoding: false,
+      commentsEnabled: true,
+      channelId: this.firstStepChannelId
+    }
+
+    this.loadingBar.start()
+
+    this.videoImportService.importVideo(this.targetUrl, videoUpdate).subscribe(
+      res => {
+        this.loadingBar.complete()
+        this.firstStepDone.emit(res.video.name)
+        this.isImportingVideo = false
+        this.hasImportedVideo = true
+
+        this.video = new VideoEdit(Object.assign(res.video, {
+          commentsEnabled: videoUpdate.commentsEnabled,
+          support: null,
+          thumbnailUrl: null,
+          previewUrl: null
+        }))
+        this.hydrateFormFromVideo()
+      },
+
+      err => {
+        this.loadingBar.complete()
+        this.isImportingVideo = false
+        this.notificationsService.error(this.i18n('Error'), err.message)
+      }
+    )
+  }
+
+  updateSecondStep () {
+    if (this.checkForm() === false) {
+      return
+    }
+
+    this.video.patch(this.form.value)
+
+    this.isUpdatingVideo = true
+
+    // Update the video
+    this.updateVideoAndCaptions(this.video)
+        .subscribe(
+          () => {
+            this.isUpdatingVideo = false
+            this.notificationsService.success(this.i18n('Success'), this.i18n('Video to import updated.'))
+
+            this.router.navigate([ '/my-account', 'video-imports' ])
+          },
+
+          err => {
+            this.isUpdatingVideo = false
+            this.notificationsService.error(this.i18n('Error'), err.message)
+            console.error(err)
+          }
+        )
+
+  }
+
+  private hydrateFormFromVideo () {
+    this.form.patchValue(this.video.toFormPatch())
+  }
+}
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-send.ts b/client/src/app/videos/+video-edit/video-add-components/video-send.ts
new file mode 100644 (file)
index 0000000..efd1822
--- /dev/null
@@ -0,0 +1,71 @@
+import { EventEmitter, OnInit } from '@angular/core'
+import { LoadingBarService } from '@ngx-loading-bar/core'
+import { NotificationsService } from 'angular2-notifications'
+import { catchError, switchMap, tap } from 'rxjs/operators'
+import { FormReactive } from '@app/shared'
+import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service'
+import { VideoConstant, VideoPrivacy } from '../../../../../../shared'
+import { AuthService, ServerService } from '@app/core'
+import { VideoService } from '@app/shared/video/video.service'
+import { VideoCaptionEdit } from '@app/shared/video-caption/video-caption-edit.model'
+import { VideoCaptionService } from '@app/shared/video-caption'
+import { VideoEdit } from '@app/shared/video/video-edit.model'
+import { populateAsyncUserVideoChannels } from '@app/shared/misc/utils'
+
+export abstract class VideoSend extends FormReactive implements OnInit, CanComponentDeactivate {
+
+  userVideoChannels: { id: number, label: string, support: string }[] = []
+  videoPrivacies: VideoConstant<string>[] = []
+  videoCaptions: VideoCaptionEdit[] = []
+
+  firstStepPrivacyId = 0
+  firstStepChannelId = 0
+
+  abstract firstStepDone: EventEmitter<string>
+  protected abstract readonly DEFAULT_VIDEO_PRIVACY: VideoPrivacy
+
+  protected loadingBar: LoadingBarService
+  protected notificationsService: NotificationsService
+  protected authService: AuthService
+  protected serverService: ServerService
+  protected videoService: VideoService
+  protected videoCaptionService: VideoCaptionService
+
+  abstract canDeactivate ()
+
+  ngOnInit () {
+    this.buildForm({})
+
+    populateAsyncUserVideoChannels(this.authService, this.userVideoChannels)
+      .then(() => this.firstStepChannelId = this.userVideoChannels[ 0 ].id)
+
+    this.serverService.videoPrivaciesLoaded
+        .subscribe(
+          () => {
+            this.videoPrivacies = this.serverService.getVideoPrivacies()
+
+            this.firstStepPrivacyId = this.DEFAULT_VIDEO_PRIVACY
+          })
+  }
+
+  checkForm () {
+    this.forceCheck()
+
+    return this.form.valid
+  }
+
+  protected updateVideoAndCaptions (video: VideoEdit) {
+    this.loadingBar.start()
+
+    return this.videoService.updateVideo(video)
+        .pipe(
+          // Then update captions
+          switchMap(() => this.videoCaptionService.updateCaptions(video.id, this.videoCaptions)),
+          tap(() => this.loadingBar.complete()),
+          catchError(err => {
+            this.loadingBar.complete()
+            throw err
+          })
+        )
+  }
+}
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.html b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.html
new file mode 100644 (file)
index 0000000..8c07231
--- /dev/null
@@ -0,0 +1,58 @@
+<div *ngIf="!isUploadingVideo" class="upload-video-container">
+  <div class="upload-video">
+    <div class="icon icon-upload"></div>
+
+    <div class="button-file">
+      <span i18n>Select the file to upload</span>
+      <input #videofileInput type="file" name="videofile" id="videofile" [accept]="videoExtensions" (change)="fileChange()" />
+    </div>
+    <span class="button-file-extension">(.mp4, .webm, .ogv)</span>
+
+    <div class="form-group form-group-channel">
+      <label i18n for="first-step-channel">Channel</label>
+      <div class="peertube-select-container">
+        <select id="first-step-channel" [(ngModel)]="firstStepChannelId">
+          <option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
+        </select>
+      </div>
+    </div>
+
+    <div class="form-group">
+      <label i18n for="first-step-privacy">Privacy</label>
+      <div class="peertube-select-container">
+        <select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId">
+          <option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
+          <option [value]="SPECIAL_SCHEDULED_PRIVACY">Scheduled</option>
+        </select>
+      </div>
+    </div>
+  </div>
+</div>
+
+<div *ngIf="isUploadingVideo" class="upload-progress-cancel">
+  <p-progressBar
+    [value]="videoUploadPercents"
+    [ngClass]="{ processing: videoUploadPercents === 100 && videoUploaded === false }"
+  ></p-progressBar>
+  <input *ngIf="videoUploaded === false" type="button" value="Cancel" (click)="cancelUpload()" />
+</div>
+
+<!-- Hidden because we want to load the component -->
+<form [hidden]="!isUploadingVideo" novalidate [formGroup]="form">
+  <my-video-edit
+    [form]="form" [formErrors]="formErrors" [videoCaptions]="videoCaptions"
+    [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" [userVideoChannels]="userVideoChannels"
+  ></my-video-edit>
+
+  <div class="submit-container">
+    <div i18n *ngIf="videoUploaded === false" class="message-submit">Publish will be available when upload is finished</div>
+
+    <div class="submit-button"
+       (click)="updateSecondStep()"
+       [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true || videoUploaded !== true }"
+    >
+      <span class="icon icon-validate"></span>
+      <input type="button" i18n-value value="Publish" />
+    </div>
+  </div>
+</form>
\ No newline at end of file
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss
new file mode 100644 (file)
index 0000000..dbae523
--- /dev/null
@@ -0,0 +1,85 @@
+@import 'variables';
+@import 'mixins';
+
+.peertube-select-container {
+  @include peertube-select-container(190px);
+}
+
+.upload-video {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+
+  .form-group-channel {
+    margin-bottom: 20px;
+    margin-top: 35px;
+  }
+
+  .icon.icon-upload {
+    @include icon(90px);
+    margin-bottom: 25px;
+    cursor: default;
+
+    background-image: url('../../../../assets/images/video/upload.svg');
+  }
+
+  .button-file {
+    @include peertube-button-file(auto);
+
+    min-width: 190px;
+  }
+
+  .button-file-extension {
+    display: block;
+    font-size: 12px;
+    margin-top: 5px;
+  }
+}
+
+.upload-progress-cancel {
+  display: flex;
+  margin-top: 25px;
+  margin-bottom: 40px;
+
+  p-progressBar {
+    flex-grow: 1;
+
+    /deep/ .ui-progressbar {
+      font-size: 15px !important;
+      color: #fff !important;
+      height: 30px !important;
+      line-height: 30px !important;
+      border-radius: 3px !important;
+      background-color: rgba(11, 204, 41, 0.16) !important;
+
+      .ui-progressbar-value {
+        background-color: #0BCC29 !important;
+      }
+
+      .ui-progressbar-label {
+        text-align: left;
+        padding-left: 18px;
+        margin-top: 0 !important;
+      }
+    }
+
+    &.processing {
+      /deep/ .ui-progressbar-label {
+        // Same color as background to hide "100%"
+        color: rgba(11, 204, 41, 0.16) !important;
+
+        &::before {
+          content: 'Processing...';
+          color: #fff;
+        }
+      }
+    }
+  }
+
+  input {
+    @include peertube-button;
+    @include grey-button;
+
+    margin-left: 10px;
+  }
+}
\ No newline at end of file
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts
new file mode 100644 (file)
index 0000000..3ec89ff
--- /dev/null
@@ -0,0 +1,219 @@
+import { HttpEventType, HttpResponse } from '@angular/common/http'
+import { Component, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'
+import { Router } from '@angular/router'
+import { LoadingBarService } from '@ngx-loading-bar/core'
+import { NotificationsService } from 'angular2-notifications'
+import { BytesPipe } from 'ngx-pipes'
+import { Subscription } from 'rxjs'
+import { VideoPrivacy } from '../../../../../../shared/models/videos'
+import { AuthService, ServerService } from '../../../core'
+import { VideoEdit } from '../../../shared/video/video-edit.model'
+import { VideoService } from '../../../shared/video/video.service'
+import { I18n } from '@ngx-translate/i18n-polyfill'
+import { VideoSend } from '@app/videos/+video-edit/video-add-components/video-send'
+import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service'
+import { FormValidatorService, UserService } from '@app/shared'
+import { VideoCaptionService } from '@app/shared/video-caption'
+
+@Component({
+  selector: 'my-video-upload',
+  templateUrl: './video-upload.component.html',
+  styleUrls: [
+    '../shared/video-edit.component.scss',
+    './video-upload.component.scss'
+  ]
+})
+export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy, CanComponentDeactivate {
+  @Output() firstStepDone = new EventEmitter<string>()
+  @ViewChild('videofileInput') videofileInput
+
+  // So that it can be accessed in the template
+  readonly SPECIAL_SCHEDULED_PRIVACY = VideoEdit.SPECIAL_SCHEDULED_PRIVACY
+
+  userVideoQuotaUsed = 0
+
+  isUploadingVideo = false
+  isUpdatingVideo = false
+  videoUploaded = false
+  videoUploadObservable: Subscription = null
+  videoUploadPercents = 0
+  videoUploadedIds = {
+    id: 0,
+    uuid: ''
+  }
+
+  protected readonly DEFAULT_VIDEO_PRIVACY = VideoPrivacy.PUBLIC
+
+  constructor (
+    protected formValidatorService: FormValidatorService,
+    protected loadingBar: LoadingBarService,
+    protected notificationsService: NotificationsService,
+    protected authService: AuthService,
+    protected serverService: ServerService,
+    protected videoService: VideoService,
+    protected videoCaptionService: VideoCaptionService,
+    private userService: UserService,
+    private router: Router,
+    private i18n: I18n
+  ) {
+    super()
+  }
+
+  get videoExtensions () {
+    return this.serverService.getConfig().video.file.extensions.join(',')
+  }
+
+  ngOnInit () {
+    super.ngOnInit()
+
+    this.userService.getMyVideoQuotaUsed()
+      .subscribe(data => this.userVideoQuotaUsed = data.videoQuotaUsed)
+  }
+
+  ngOnDestroy () {
+    if (this.videoUploadObservable) this.videoUploadObservable.unsubscribe()
+  }
+
+  canDeactivate () {
+    let text = ''
+
+    if (this.videoUploaded === true) {
+      // FIXME: cannot concatenate strings inside i18n service :/
+      text = this.i18n('Your video was uploaded to your account and is private.') +
+        this.i18n('But associated data (tags, description...) will be lost, are you sure you want to leave this page?')
+    } else {
+      text = this.i18n('Your video is not uploaded yet, are you sure you want to leave this page?')
+    }
+
+    return {
+      canDeactivate: !this.isUploadingVideo,
+      text
+    }
+  }
+
+  fileChange () {
+    this.uploadFirstStep()
+  }
+
+  cancelUpload () {
+    if (this.videoUploadObservable !== null) {
+      this.videoUploadObservable.unsubscribe()
+      this.isUploadingVideo = false
+      this.videoUploadPercents = 0
+      this.videoUploadObservable = null
+      this.notificationsService.info(this.i18n('Info'), this.i18n('Upload cancelled'))
+    }
+  }
+
+  uploadFirstStep () {
+    const videofile = this.videofileInput.nativeElement.files[0] as File
+    if (!videofile) return
+
+    // Cannot upload videos > 8GB for now
+    if (videofile.size > 8 * 1024 * 1024 * 1024) {
+      this.notificationsService.error(this.i18n('Error'), this.i18n('We are sorry but PeerTube cannot handle videos > 8GB'))
+      return
+    }
+
+    const videoQuota = this.authService.getUser().videoQuota
+    if (videoQuota !== -1 && (this.userVideoQuotaUsed + videofile.size) > videoQuota) {
+      const bytePipes = new BytesPipe()
+
+      const msg = this.i18n(
+        'Your video quota is exceeded with this video (video size: {{ videoSize }}, used: {{ videoQuotaUsed }}, quota: {{ videoQuota }})',
+        {
+          videoSize: bytePipes.transform(videofile.size, 0),
+          videoQuotaUsed: bytePipes.transform(this.userVideoQuotaUsed, 0),
+          videoQuota: bytePipes.transform(videoQuota, 0)
+        }
+      )
+      this.notificationsService.error(this.i18n('Error'), msg)
+      return
+    }
+
+    const nameWithoutExtension = videofile.name.replace(/\.[^/.]+$/, '')
+    let name: string
+
+    // If the name of the file is very small, keep the extension
+    if (nameWithoutExtension.length < 3) name = videofile.name
+    else name = nameWithoutExtension
+
+    const privacy = this.firstStepPrivacyId.toString()
+    const nsfw = false
+    const waitTranscoding = true
+    const commentsEnabled = true
+    const channelId = this.firstStepChannelId.toString()
+
+    const formData = new FormData()
+    formData.append('name', name)
+    // Put the video "private" -> we are waiting the user validation of the second step
+    formData.append('privacy', VideoPrivacy.PRIVATE.toString())
+    formData.append('nsfw', '' + nsfw)
+    formData.append('commentsEnabled', '' + commentsEnabled)
+    formData.append('waitTranscoding', '' + waitTranscoding)
+    formData.append('channelId', '' + channelId)
+    formData.append('videofile', videofile)
+
+    this.isUploadingVideo = true
+    this.firstStepDone.emit(name)
+
+    this.form.patchValue({
+      name,
+      privacy,
+      nsfw,
+      channelId
+    })
+
+    this.videoUploadObservable = this.videoService.uploadVideo(formData).subscribe(
+      event => {
+        if (event.type === HttpEventType.UploadProgress) {
+          this.videoUploadPercents = Math.round(100 * event.loaded / event.total)
+        } else if (event instanceof HttpResponse) {
+          this.videoUploaded = true
+
+          this.videoUploadedIds = event.body.video
+
+          this.videoUploadObservable = null
+        }
+      },
+
+      err => {
+        // Reset progress
+        this.isUploadingVideo = false
+        this.videoUploadPercents = 0
+        this.videoUploadObservable = null
+        this.notificationsService.error(this.i18n('Error'), err.message)
+      }
+    )
+  }
+
+  updateSecondStep () {
+    if (this.checkForm() === false) {
+      return
+    }
+
+    const video = new VideoEdit()
+    video.patch(this.form.value)
+    video.id = this.videoUploadedIds.id
+    video.uuid = this.videoUploadedIds.uuid
+
+    this.isUpdatingVideo = true
+
+    this.updateVideoAndCaptions(video)
+        .subscribe(
+          () => {
+            this.isUpdatingVideo = false
+            this.isUploadingVideo = false
+
+            this.notificationsService.success(this.i18n('Success'), this.i18n('Video published.'))
+            this.router.navigate([ '/videos/watch', video.uuid ])
+          },
+
+          err => {
+            this.isUpdatingVideo = false
+            this.notificationsService.error(this.i18n('Error'), err.message)
+            console.error(err)
+          }
+        )
+  }
+}
index 377ea5dd217f0a3907df9969d175e5f57bd567bd..e74fa1f15c14a2b2ccf2c384c00060d315190957 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, ViewChild } from '@angular/core'
 import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service'
-import { VideoImportUrlComponent } from '@app/videos/+video-edit/video-import-url.component'
-import { VideoUploadComponent } from '@app/videos/+video-edit/video-upload.component'
+import { VideoImportUrlComponent } from '@app/videos/+video-edit/video-add-components/video-import-url.component'
+import { VideoUploadComponent } from '@app/videos/+video-edit/video-add-components/video-upload.component'
 import { ServerService } from '@app/core'
 
 @Component({
index dd1a3875dcdea511d1d8cc71df8b3946f2908d6b..a1324b3970fb84fa2a9096bd9ba81a94633665f2 100644 (file)
@@ -5,8 +5,8 @@ import { VideoEditModule } from './shared/video-edit.module'
 import { VideoAddRoutingModule } from './video-add-routing.module'
 import { VideoAddComponent } from './video-add.component'
 import { CanDeactivateGuard } from '../../shared/guards/can-deactivate-guard.service'
-import { VideoUploadComponent } from '@app/videos/+video-edit/video-upload.component'
-import { VideoImportUrlComponent } from '@app/videos/+video-edit/video-import-url.component'
+import { VideoUploadComponent } from '@app/videos/+video-edit/video-add-components/video-upload.component'
+import { VideoImportUrlComponent } from '@app/videos/+video-edit/video-add-components/video-import-url.component'
 
 @NgModule({
   imports: [
diff --git a/client/src/app/videos/+video-edit/video-import-url.component.html b/client/src/app/videos/+video-edit/video-import-url.component.html
deleted file mode 100644 (file)
index 6b431f6..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<div *ngIf="!hasImportedVideo" class="upload-video-container">
-  <div class="import-video">
-    <div class="icon icon-upload"></div>
-
-    <div class="form-group">
-      <label i18n for="targetUrl">URL</label>
-      <my-help
-        helpType="custom" i18n-customHtml
-        customHtml="You can import any URL <a href='https://rg3.github.io/youtube-dl/supportedsites.html' target='_blank' rel='noopener noreferrer'>supported by youtube-dl</a> or URL that points to a raw MP4 file. You should make sure you have diffusion rights over the content it points to, otherwise it could cause legal trouble to yourself and your instance."
-      ></my-help>
-
-      <input type="text" id="targetUrl" [(ngModel)]="targetUrl" />
-    </div>
-
-    <div class="form-group">
-      <label i18n for="first-step-channel">Channel</label>
-      <div class="peertube-select-container">
-        <select id="first-step-channel" [(ngModel)]="firstStepChannelId">
-          <option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
-        </select>
-      </div>
-    </div>
-
-    <div class="form-group">
-      <label i18n for="first-step-privacy">Privacy</label>
-      <div class="peertube-select-container">
-        <select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId">
-          <option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
-        </select>
-      </div>
-    </div>
-
-    <input
-      type="button" i18n-value value="Import"
-      [disabled]="!isTargetUrlValid() || isImportingVideo" (click)="importVideo()"
-    />
-  </div>
-</div>
-
-<div *ngIf="hasImportedVideo" class="alert alert-info" i18n>
-  Congratulations, the video behind {{ targetUrl }} will be imported! You can already add information about this video.
-</div>
-
-<!-- Hidden because we want to load the component -->
-<form [hidden]="!hasImportedVideo" novalidate [formGroup]="form">
-  <my-video-edit
-    [form]="form" [formErrors]="formErrors" [videoCaptions]="videoCaptions" [schedulePublicationPossible]="false"
-    [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" [userVideoChannels]="userVideoChannels"
-  ></my-video-edit>
-
-  <div class="submit-container">
-    <div class="submit-button"
-       (click)="updateSecondStep()"
-       [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true }"
-    >
-      <span class="icon icon-validate"></span>
-      <input type="button" i18n-value value="Update" />
-    </div>
-  </div>
-</form>
diff --git a/client/src/app/videos/+video-edit/video-import-url.component.scss b/client/src/app/videos/+video-edit/video-import-url.component.scss
deleted file mode 100644 (file)
index 9ada9db..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-@import '_variables';
-@import '_mixins';
-
-$width-size: 190px;
-
-.peertube-select-container {
-  @include peertube-select-container($width-size);
-}
-
-.import-video {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-
-  .icon.icon-upload {
-    @include icon(90px);
-    margin-bottom: 25px;
-    cursor: default;
-
-    background-image: url('../../../assets/images/video/upload.svg');
-  }
-
-  input[type=text] {
-    @include peertube-input-text($width-size);
-    display: block;
-  }
-
-  input[type=button] {
-    @include peertube-button;
-    @include orange-button;
-
-    width: $width-size;
-    margin-top: 30px;
-  }
-}
-
-
diff --git a/client/src/app/videos/+video-edit/video-import-url.component.ts b/client/src/app/videos/+video-edit/video-import-url.component.ts
deleted file mode 100644 (file)
index 99fcb6f..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-import { Component, EventEmitter, OnInit, Output } from '@angular/core'
-import { Router } from '@angular/router'
-import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service'
-import { NotificationsService } from 'angular2-notifications'
-import { VideoPrivacy, VideoUpdate } from '../../../../../shared/models/videos'
-import { AuthService, ServerService } from '../../core'
-import { VideoService } from '../../shared/video/video.service'
-import { I18n } from '@ngx-translate/i18n-polyfill'
-import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
-import { VideoImportService } from '@app/shared/video-import'
-import { VideoEdit } from '@app/shared/video/video-edit.model'
-import { LoadingBarService } from '@ngx-loading-bar/core'
-import { VideoCaptionService } from '@app/shared/video-caption'
-import { VideoSend } from '@app/videos/+video-edit/shared/video-send'
-
-@Component({
-  selector: 'my-video-import-url',
-  templateUrl: './video-import-url.component.html',
-  styleUrls: [
-    './shared/video-edit.component.scss',
-    './video-import-url.component.scss'
-  ]
-})
-export class VideoImportUrlComponent extends VideoSend implements OnInit, CanComponentDeactivate {
-  @Output() firstStepDone = new EventEmitter<string>()
-
-  targetUrl = ''
-  videoFileName: string
-
-  isImportingVideo = false
-  hasImportedVideo = false
-  isUpdatingVideo = false
-
-  video: VideoEdit
-
-  protected readonly DEFAULT_VIDEO_PRIVACY = VideoPrivacy.PRIVATE
-
-  constructor (
-    protected formValidatorService: FormValidatorService,
-    protected loadingBar: LoadingBarService,
-    protected notificationsService: NotificationsService,
-    protected authService: AuthService,
-    protected serverService: ServerService,
-    protected videoService: VideoService,
-    protected videoCaptionService: VideoCaptionService,
-    private router: Router,
-    private videoImportService: VideoImportService,
-    private i18n: I18n
-  ) {
-    super()
-  }
-
-  ngOnInit () {
-    super.ngOnInit()
-  }
-
-  canDeactivate () {
-    return { canDeactivate: true }
-  }
-
-  isTargetUrlValid () {
-    return this.targetUrl && this.targetUrl.match(/https?:\/\//)
-  }
-
-  importVideo () {
-    this.isImportingVideo = true
-
-    const videoUpdate: VideoUpdate = {
-      privacy: this.firstStepPrivacyId,
-      waitTranscoding: false,
-      commentsEnabled: true,
-      channelId: this.firstStepChannelId
-    }
-
-    this.loadingBar.start()
-
-    this.videoImportService.importVideo(this.targetUrl, videoUpdate).subscribe(
-      res => {
-        this.loadingBar.complete()
-        this.firstStepDone.emit(res.video.name)
-        this.isImportingVideo = false
-        this.hasImportedVideo = true
-
-        this.video = new VideoEdit(Object.assign(res.video, {
-          commentsEnabled: videoUpdate.commentsEnabled,
-          support: null,
-          thumbnailUrl: null,
-          previewUrl: null
-        }))
-        this.hydrateFormFromVideo()
-      },
-
-      err => {
-        this.loadingBar.complete()
-        this.isImportingVideo = false
-        this.notificationsService.error(this.i18n('Error'), err.message)
-      }
-    )
-  }
-
-  updateSecondStep () {
-    if (this.checkForm() === false) {
-      return
-    }
-
-    this.video.patch(this.form.value)
-
-    this.isUpdatingVideo = true
-
-    // Update the video
-    this.updateVideoAndCaptions(this.video)
-        .subscribe(
-          () => {
-            this.isUpdatingVideo = false
-            this.notificationsService.success(this.i18n('Success'), this.i18n('Video to import updated.'))
-
-            this.router.navigate([ '/my-account', 'video-imports' ])
-          },
-
-          err => {
-            this.isUpdatingVideo = false
-            this.notificationsService.error(this.i18n('Error'), err.message)
-            console.error(err)
-          }
-        )
-
-  }
-
-  private hydrateFormFromVideo () {
-    this.form.patchValue(this.video.toFormPatch())
-  }
-}
diff --git a/client/src/app/videos/+video-edit/video-upload.component.html b/client/src/app/videos/+video-edit/video-upload.component.html
deleted file mode 100644 (file)
index 8c07231..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<div *ngIf="!isUploadingVideo" class="upload-video-container">
-  <div class="upload-video">
-    <div class="icon icon-upload"></div>
-
-    <div class="button-file">
-      <span i18n>Select the file to upload</span>
-      <input #videofileInput type="file" name="videofile" id="videofile" [accept]="videoExtensions" (change)="fileChange()" />
-    </div>
-    <span class="button-file-extension">(.mp4, .webm, .ogv)</span>
-
-    <div class="form-group form-group-channel">
-      <label i18n for="first-step-channel">Channel</label>
-      <div class="peertube-select-container">
-        <select id="first-step-channel" [(ngModel)]="firstStepChannelId">
-          <option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
-        </select>
-      </div>
-    </div>
-
-    <div class="form-group">
-      <label i18n for="first-step-privacy">Privacy</label>
-      <div class="peertube-select-container">
-        <select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId">
-          <option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
-          <option [value]="SPECIAL_SCHEDULED_PRIVACY">Scheduled</option>
-        </select>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div *ngIf="isUploadingVideo" class="upload-progress-cancel">
-  <p-progressBar
-    [value]="videoUploadPercents"
-    [ngClass]="{ processing: videoUploadPercents === 100 && videoUploaded === false }"
-  ></p-progressBar>
-  <input *ngIf="videoUploaded === false" type="button" value="Cancel" (click)="cancelUpload()" />
-</div>
-
-<!-- Hidden because we want to load the component -->
-<form [hidden]="!isUploadingVideo" novalidate [formGroup]="form">
-  <my-video-edit
-    [form]="form" [formErrors]="formErrors" [videoCaptions]="videoCaptions"
-    [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" [userVideoChannels]="userVideoChannels"
-  ></my-video-edit>
-
-  <div class="submit-container">
-    <div i18n *ngIf="videoUploaded === false" class="message-submit">Publish will be available when upload is finished</div>
-
-    <div class="submit-button"
-       (click)="updateSecondStep()"
-       [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true || videoUploaded !== true }"
-    >
-      <span class="icon icon-validate"></span>
-      <input type="button" i18n-value value="Publish" />
-    </div>
-  </div>
-</form>
\ No newline at end of file
diff --git a/client/src/app/videos/+video-edit/video-upload.component.scss b/client/src/app/videos/+video-edit/video-upload.component.scss
deleted file mode 100644 (file)
index 0158356..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-@import '_variables';
-@import '_mixins';
-
-.peertube-select-container {
-  @include peertube-select-container(190px);
-}
-
-.upload-video {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-
-  .form-group-channel {
-    margin-bottom: 20px;
-    margin-top: 35px;
-  }
-
-  .icon.icon-upload {
-    @include icon(90px);
-    margin-bottom: 25px;
-    cursor: default;
-
-    background-image: url('../../../assets/images/video/upload.svg');
-  }
-
-  .button-file {
-    @include peertube-button-file(auto);
-
-    min-width: 190px;
-  }
-
-  .button-file-extension {
-    display: block;
-    font-size: 12px;
-    margin-top: 5px;
-  }
-}
-
-.upload-progress-cancel {
-  display: flex;
-  margin-top: 25px;
-  margin-bottom: 40px;
-
-  p-progressBar {
-    flex-grow: 1;
-
-    /deep/ .ui-progressbar {
-      font-size: 15px !important;
-      color: #fff !important;
-      height: 30px !important;
-      line-height: 30px !important;
-      border-radius: 3px !important;
-      background-color: rgba(11, 204, 41, 0.16) !important;
-
-      .ui-progressbar-value {
-        background-color: #0BCC29 !important;
-      }
-
-      .ui-progressbar-label {
-        text-align: left;
-        padding-left: 18px;
-        margin-top: 0 !important;
-      }
-    }
-
-    &.processing {
-      /deep/ .ui-progressbar-label {
-        // Same color as background to hide "100%"
-        color: rgba(11, 204, 41, 0.16) !important;
-
-        &::before {
-          content: 'Processing...';
-          color: #fff;
-        }
-      }
-    }
-  }
-
-  input {
-    @include peertube-button;
-    @include grey-button;
-
-    margin-left: 10px;
-  }
-}
\ No newline at end of file
diff --git a/client/src/app/videos/+video-edit/video-upload.component.ts b/client/src/app/videos/+video-edit/video-upload.component.ts
deleted file mode 100644 (file)
index 983af60..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-import { HttpEventType, HttpResponse } from '@angular/common/http'
-import { Component, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'
-import { Router } from '@angular/router'
-import { UserService } from '@app/shared'
-import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service'
-import { LoadingBarService } from '@ngx-loading-bar/core'
-import { NotificationsService } from 'angular2-notifications'
-import { BytesPipe } from 'ngx-pipes'
-import { Subscription } from 'rxjs'
-import { VideoPrivacy } from '../../../../../shared/models/videos'
-import { AuthService, ServerService } from '../../core'
-import { VideoEdit } from '../../shared/video/video-edit.model'
-import { VideoService } from '../../shared/video/video.service'
-import { I18n } from '@ngx-translate/i18n-polyfill'
-import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
-import { VideoCaptionService } from '@app/shared/video-caption'
-import { VideoSend } from '@app/videos/+video-edit/shared/video-send'
-
-@Component({
-  selector: 'my-video-upload',
-  templateUrl: './video-upload.component.html',
-  styleUrls: [
-    './shared/video-edit.component.scss',
-    './video-upload.component.scss'
-  ]
-})
-export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy, CanComponentDeactivate {
-  @Output() firstStepDone = new EventEmitter<string>()
-  @ViewChild('videofileInput') videofileInput
-
-  // So that it can be accessed in the template
-  readonly SPECIAL_SCHEDULED_PRIVACY = VideoEdit.SPECIAL_SCHEDULED_PRIVACY
-
-  userVideoQuotaUsed = 0
-
-  isUploadingVideo = false
-  isUpdatingVideo = false
-  videoUploaded = false
-  videoUploadObservable: Subscription = null
-  videoUploadPercents = 0
-  videoUploadedIds = {
-    id: 0,
-    uuid: ''
-  }
-
-  protected readonly DEFAULT_VIDEO_PRIVACY = VideoPrivacy.PUBLIC
-
-  constructor (
-    protected formValidatorService: FormValidatorService,
-    protected loadingBar: LoadingBarService,
-    protected notificationsService: NotificationsService,
-    protected authService: AuthService,
-    protected serverService: ServerService,
-    protected videoService: VideoService,
-    protected videoCaptionService: VideoCaptionService,
-    private userService: UserService,
-    private router: Router,
-    private i18n: I18n
-  ) {
-    super()
-  }
-
-  get videoExtensions () {
-    return this.serverService.getConfig().video.file.extensions.join(',')
-  }
-
-  ngOnInit () {
-    super.ngOnInit()
-
-    this.userService.getMyVideoQuotaUsed()
-      .subscribe(data => this.userVideoQuotaUsed = data.videoQuotaUsed)
-  }
-
-  ngOnDestroy () {
-    if (this.videoUploadObservable) this.videoUploadObservable.unsubscribe()
-  }
-
-  canDeactivate () {
-    let text = ''
-
-    if (this.videoUploaded === true) {
-      // FIXME: cannot concatenate strings inside i18n service :/
-      text = this.i18n('Your video was uploaded to your account and is private.') +
-        this.i18n('But associated data (tags, description...) will be lost, are you sure you want to leave this page?')
-    } else {
-      text = this.i18n('Your video is not uploaded yet, are you sure you want to leave this page?')
-    }
-
-    return {
-      canDeactivate: !this.isUploadingVideo,
-      text
-    }
-  }
-
-  fileChange () {
-    this.uploadFirstStep()
-  }
-
-  cancelUpload () {
-    if (this.videoUploadObservable !== null) {
-      this.videoUploadObservable.unsubscribe()
-      this.isUploadingVideo = false
-      this.videoUploadPercents = 0
-      this.videoUploadObservable = null
-      this.notificationsService.info(this.i18n('Info'), this.i18n('Upload cancelled'))
-    }
-  }
-
-  uploadFirstStep () {
-    const videofile = this.videofileInput.nativeElement.files[0] as File
-    if (!videofile) return
-
-    // Cannot upload videos > 8GB for now
-    if (videofile.size > 8 * 1024 * 1024 * 1024) {
-      this.notificationsService.error(this.i18n('Error'), this.i18n('We are sorry but PeerTube cannot handle videos > 8GB'))
-      return
-    }
-
-    const videoQuota = this.authService.getUser().videoQuota
-    if (videoQuota !== -1 && (this.userVideoQuotaUsed + videofile.size) > videoQuota) {
-      const bytePipes = new BytesPipe()
-
-      const msg = this.i18n(
-        'Your video quota is exceeded with this video (video size: {{ videoSize }}, used: {{ videoQuotaUsed }}, quota: {{ videoQuota }})',
-        {
-          videoSize: bytePipes.transform(videofile.size, 0),
-          videoQuotaUsed: bytePipes.transform(this.userVideoQuotaUsed, 0),
-          videoQuota: bytePipes.transform(videoQuota, 0)
-        }
-      )
-      this.notificationsService.error(this.i18n('Error'), msg)
-      return
-    }
-
-    const nameWithoutExtension = videofile.name.replace(/\.[^/.]+$/, '')
-    let name: string
-
-    // If the name of the file is very small, keep the extension
-    if (nameWithoutExtension.length < 3) name = videofile.name
-    else name = nameWithoutExtension
-
-    const privacy = this.firstStepPrivacyId.toString()
-    const nsfw = false
-    const waitTranscoding = true
-    const commentsEnabled = true
-    const channelId = this.firstStepChannelId.toString()
-
-    const formData = new FormData()
-    formData.append('name', name)
-    // Put the video "private" -> we are waiting the user validation of the second step
-    formData.append('privacy', VideoPrivacy.PRIVATE.toString())
-    formData.append('nsfw', '' + nsfw)
-    formData.append('commentsEnabled', '' + commentsEnabled)
-    formData.append('waitTranscoding', '' + waitTranscoding)
-    formData.append('channelId', '' + channelId)
-    formData.append('videofile', videofile)
-
-    this.isUploadingVideo = true
-    this.firstStepDone.emit(name)
-
-    this.form.patchValue({
-      name,
-      privacy,
-      nsfw,
-      channelId
-    })
-
-    this.videoUploadObservable = this.videoService.uploadVideo(formData).subscribe(
-      event => {
-        if (event.type === HttpEventType.UploadProgress) {
-          this.videoUploadPercents = Math.round(100 * event.loaded / event.total)
-        } else if (event instanceof HttpResponse) {
-          this.videoUploaded = true
-
-          this.videoUploadedIds = event.body.video
-
-          this.videoUploadObservable = null
-        }
-      },
-
-      err => {
-        // Reset progress
-        this.isUploadingVideo = false
-        this.videoUploadPercents = 0
-        this.videoUploadObservable = null
-        this.notificationsService.error(this.i18n('Error'), err.message)
-      }
-    )
-  }
-
-  updateSecondStep () {
-    if (this.checkForm() === false) {
-      return
-    }
-
-    const video = new VideoEdit()
-    video.patch(this.form.value)
-    video.id = this.videoUploadedIds.id
-    video.uuid = this.videoUploadedIds.uuid
-
-    this.isUpdatingVideo = true
-
-    this.updateVideoAndCaptions(video)
-        .subscribe(
-          () => {
-            this.isUpdatingVideo = false
-            this.isUploadingVideo = false
-
-            this.notificationsService.success(this.i18n('Success'), this.i18n('Video published.'))
-            this.router.navigate([ '/videos/watch', video.uuid ])
-          },
-
-          err => {
-            this.isUpdatingVideo = false
-            this.notificationsService.error(this.i18n('Error'), err.message)
-            console.error(err)
-          }
-        )
-  }
-}