-import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http'
+import { Injectable } from '@angular/core'
+import 'rxjs/add/operator/do'
+import { ReplaySubject } from 'rxjs/ReplaySubject'
import { ServerConfig } from '../../../../../shared'
private static BASE_CONFIG_URL = API_URL + '/api/v1/config/'
private static BASE_VIDEO_URL = API_URL + '/api/v1/videos/'
+ videoPrivaciesLoaded = new ReplaySubject<boolean>(1)
+ videoCategoriesLoaded = new ReplaySubject<boolean>(1)
+ videoLicencesLoaded = new ReplaySubject<boolean>(1)
+ videoLanguagesLoaded = new ReplaySubject<boolean>(1)
+
private config: ServerConfig = {
signup: {
allowed: false
}
loadVideoCategories () {
- return this.loadVideoAttributeEnum('categories', this.videoCategories)
+ return this.loadVideoAttributeEnum('categories', this.videoCategories, this.videoCategoriesLoaded)
}
loadVideoLicences () {
- return this.loadVideoAttributeEnum('licences', this.videoLicences)
+ return this.loadVideoAttributeEnum('licences', this.videoLicences, this.videoLicencesLoaded)
}
loadVideoLanguages () {
- return this.loadVideoAttributeEnum('languages', this.videoLanguages)
+ return this.loadVideoAttributeEnum('languages', this.videoLanguages, this.videoLanguagesLoaded)
}
loadVideoPrivacies () {
- return this.loadVideoAttributeEnum('privacies', this.videoPrivacies)
+ return this.loadVideoAttributeEnum('privacies', this.videoPrivacies, this.videoPrivaciesLoaded)
}
getConfig () {
private loadVideoAttributeEnum (
attributeName: 'categories' | 'licences' | 'languages' | 'privacies',
- hashToPopulate: { id: number, label: string }[]
+ hashToPopulate: { id: number, label: string }[],
+ notifier: ReplaySubject<boolean>
) {
return this.http.get(ServerService.BASE_VIDEO_URL + attributeName)
- .subscribe(data => {
- Object.keys(data)
- .forEach(dataKey => {
- hashToPopulate.push({
- id: parseInt(dataKey, 10),
- label: data[dataKey]
- })
- })
+ .do(() => notifier.next(true))
+ .subscribe(data => {
+ Object.keys(data)
+ .forEach(dataKey => {
+ hashToPopulate.push({
+ id: parseInt(dataKey, 10),
+ label: data[dataKey]
+ })
})
+ })
}
}
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
- <div class="upload-video-container">
+ <div *ngIf="!isUploadingVideo" class="upload-video-container">
<div class="upload-video">
<div class="icon icon-upload"></div>
<div class="button-file">
<span>Select the file to upload</span>
- <input #videofileInput type="file" name="videofile" id="videofile" (change)="fileChange($event)" />
+ <input #videofileInput type="file" name="videofile" id="videofile" (change)="fileChange()" />
</div>
<div class="form-group">
</select>
</div>
</div>
+ </div>
-
- <form *ngIf="isUploadingVideo" novalidate [formGroup]="form">
- <my-video-edit
- [form]="form" [formErrors]="formErrors"
- [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies"
- ></my-video-edit>
-
- <div class="submit-container">
- <div class="submit-button" [ngClass]="{ disabled: !form.valid }">
- <span class="icon icon-validate"></span>
- <input type="button" value="Publish" (click)="upload()" />
- </div>
+ <!-- Hidden because we need to load the component -->
+ <form [hidden]="!isUploadingVideo" novalidate [formGroup]="form">
+ <my-video-edit
+ [form]="form" [formErrors]="formErrors"
+ [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies"
+ ></my-video-edit>
+
+ <div class="submit-container">
+ <div class="submit-button" [ngClass]="{ disabled: !form.valid }">
+ <span class="icon icon-validate"></span>
+ <input type="button" value="Publish" (click)="upload()" />
</div>
- </form>
- </div>
+ </div>
+ </form>
</div>
@ViewChild('videofileInput') videofileInput
isUploadingVideo = false
+ videoUploaded = false
progressPercent = 0
error: string = null
form: FormGroup
formErrors: { [ id: string ]: string } = {}
validationMessages: ValidatorMessage = {}
+
userVideoChannels = []
videoPrivacies = []
firstStepPrivacy = 0
ngOnInit () {
this.buildForm()
- this.videoPrivacies = this.serverService.getVideoPrivacies()
- this.firstStepPrivacy = this.videoPrivacies[0].id
+ this.serverService.videoCategoriesLoaded
+ .subscribe(
+ () => {
+ this.videoPrivacies = this.serverService.getVideoPrivacies()
+ this.firstStepPrivacy = this.videoPrivacies[0].id
+ })
this.authService.userInformationLoaded
.subscribe(
)
}
- fileChange ($event) {
- console.log('uploading file ?')
+ fileChange () {
+ this.uploadFirstStep()
}
checkForm () {
}
uploadFirstStep () {
- const formValue: VideoCreate = this.form.value
-
- const name = formValue.name
- const privacy = formValue.privacy
- const nsfw = formValue.nsfw
- const category = formValue.category
- const licence = formValue.licence
- const language = formValue.language
- const channelId = formValue.channelId
- const description = formValue.description
- const tags = formValue.tags
const videofile = this.videofileInput.nativeElement.files[0]
+ const name = videofile.name
+ const privacy = this.firstStepPrivacy.toString()
+ const nsfw = false
+ const channelId = this.firstStepChannel.toString()
const formData = new FormData()
formData.append('name', name)
formData.append('privacy', privacy.toString())
- formData.append('category', '' + category)
formData.append('nsfw', '' + nsfw)
- formData.append('licence', '' + licence)
formData.append('channelId', '' + channelId)
formData.append('videofile', videofile)
- // Language is optional
- if (language) {
- formData.append('language', '' + language)
- }
-
- formData.append('description', description)
-
- for (let i = 0; i < tags.length; i++) {
- formData.append(`tags[${i}]`, tags[i])
- }
+ this.isUploadingVideo = true
+ this.form.patchValue({
+ name,
+ privacy,
+ nsfw,
+ channelId
+ })
this.videoService.uploadVideo(formData).subscribe(
event => {
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/trending' ])
+ this.videoUploaded = true
}
},
// ---------------------------------------------------------------------------
-const LAST_MIGRATION_VERSION = 115
+const LAST_MIGRATION_VERSION = 120
// ---------------------------------------------------------------------------
import * as Sequelize from 'sequelize'
+import { CONSTRAINTS_FIELDS } from '../constants'
import { PeerTubeDatabase } from '../database'
async function up (utils: {
{
const data = {
- type: Sequelize.INTEGER,
+ type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max),
allowNull: true,
defaultValue: null
}
import { VideoPrivacy } from './video-privacy.enum'
export interface VideoCreate {
- category: number
- licence: number
- language: number
- description: string
+ category?: number
+ licence?: number
+ language?: number
+ description?: string
channelId: number
nsfw: boolean
name: string
- tags: string[]
+ tags?: string[]
privacy: VideoPrivacy
}