aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--client/src/app/core/server/server.service.ts37
-rw-r--r--client/src/app/videos/+video-edit/video-add.component.html32
-rw-r--r--client/src/app/videos/+video-edit/video-add.component.ts52
-rw-r--r--server/initializers/constants.ts2
-rw-r--r--server/initializers/migrations/0120-video-null.ts3
-rw-r--r--shared/models/videos/video-create.model.ts10
6 files changed, 69 insertions, 67 deletions
diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts
index cbc4074c9..43a836c5a 100644
--- a/client/src/app/core/server/server.service.ts
+++ b/client/src/app/core/server/server.service.ts
@@ -1,5 +1,7 @@
1import { Injectable } from '@angular/core'
2import { HttpClient } from '@angular/common/http' 1import { HttpClient } from '@angular/common/http'
2import { Injectable } from '@angular/core'
3import 'rxjs/add/operator/do'
4import { ReplaySubject } from 'rxjs/ReplaySubject'
3 5
4import { ServerConfig } from '../../../../../shared' 6import { ServerConfig } from '../../../../../shared'
5 7
@@ -8,6 +10,11 @@ export class ServerService {
8 private static BASE_CONFIG_URL = API_URL + '/api/v1/config/' 10 private static BASE_CONFIG_URL = API_URL + '/api/v1/config/'
9 private static BASE_VIDEO_URL = API_URL + '/api/v1/videos/' 11 private static BASE_VIDEO_URL = API_URL + '/api/v1/videos/'
10 12
13 videoPrivaciesLoaded = new ReplaySubject<boolean>(1)
14 videoCategoriesLoaded = new ReplaySubject<boolean>(1)
15 videoLicencesLoaded = new ReplaySubject<boolean>(1)
16 videoLanguagesLoaded = new ReplaySubject<boolean>(1)
17
11 private config: ServerConfig = { 18 private config: ServerConfig = {
12 signup: { 19 signup: {
13 allowed: false 20 allowed: false
@@ -29,19 +36,19 @@ export class ServerService {
29 } 36 }
30 37
31 loadVideoCategories () { 38 loadVideoCategories () {
32 return this.loadVideoAttributeEnum('categories', this.videoCategories) 39 return this.loadVideoAttributeEnum('categories', this.videoCategories, this.videoCategoriesLoaded)
33 } 40 }
34 41
35 loadVideoLicences () { 42 loadVideoLicences () {
36 return this.loadVideoAttributeEnum('licences', this.videoLicences) 43 return this.loadVideoAttributeEnum('licences', this.videoLicences, this.videoLicencesLoaded)
37 } 44 }
38 45
39 loadVideoLanguages () { 46 loadVideoLanguages () {
40 return this.loadVideoAttributeEnum('languages', this.videoLanguages) 47 return this.loadVideoAttributeEnum('languages', this.videoLanguages, this.videoLanguagesLoaded)
41 } 48 }
42 49
43 loadVideoPrivacies () { 50 loadVideoPrivacies () {
44 return this.loadVideoAttributeEnum('privacies', this.videoPrivacies) 51 return this.loadVideoAttributeEnum('privacies', this.videoPrivacies, this.videoPrivaciesLoaded)
45 } 52 }
46 53
47 getConfig () { 54 getConfig () {
@@ -66,17 +73,19 @@ export class ServerService {
66 73
67 private loadVideoAttributeEnum ( 74 private loadVideoAttributeEnum (
68 attributeName: 'categories' | 'licences' | 'languages' | 'privacies', 75 attributeName: 'categories' | 'licences' | 'languages' | 'privacies',
69 hashToPopulate: { id: number, label: string }[] 76 hashToPopulate: { id: number, label: string }[],
77 notifier: ReplaySubject<boolean>
70 ) { 78 ) {
71 return this.http.get(ServerService.BASE_VIDEO_URL + attributeName) 79 return this.http.get(ServerService.BASE_VIDEO_URL + attributeName)
72 .subscribe(data => { 80 .do(() => notifier.next(true))
73 Object.keys(data) 81 .subscribe(data => {
74 .forEach(dataKey => { 82 Object.keys(data)
75 hashToPopulate.push({ 83 .forEach(dataKey => {
76 id: parseInt(dataKey, 10), 84 hashToPopulate.push({
77 label: data[dataKey] 85 id: parseInt(dataKey, 10),
78 }) 86 label: data[dataKey]
79 }) 87 })
80 }) 88 })
89 })
81 } 90 }
82} 91}
diff --git a/client/src/app/videos/+video-edit/video-add.component.html b/client/src/app/videos/+video-edit/video-add.component.html
index f8355f3db..78e5bb70e 100644
--- a/client/src/app/videos/+video-edit/video-add.component.html
+++ b/client/src/app/videos/+video-edit/video-add.component.html
@@ -5,13 +5,13 @@
5 5
6 <div *ngIf="error" class="alert alert-danger">{{ error }}</div> 6 <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
7 7
8 <div class="upload-video-container"> 8 <div *ngIf="!isUploadingVideo" class="upload-video-container">
9 <div class="upload-video"> 9 <div class="upload-video">
10 <div class="icon icon-upload"></div> 10 <div class="icon icon-upload"></div>
11 11
12 <div class="button-file"> 12 <div class="button-file">
13 <span>Select the file to upload</span> 13 <span>Select the file to upload</span>
14 <input #videofileInput type="file" name="videofile" id="videofile" (change)="fileChange($event)" /> 14 <input #videofileInput type="file" name="videofile" id="videofile" (change)="fileChange()" />
15 </div> 15 </div>
16 16
17 <div class="form-group"> 17 <div class="form-group">
@@ -26,20 +26,20 @@
26 </select> 26 </select>
27 </div> 27 </div>
28 </div> 28 </div>
29 </div>
29 30
30 31 <!-- Hidden because we need to load the component -->
31 <form *ngIf="isUploadingVideo" novalidate [formGroup]="form"> 32 <form [hidden]="!isUploadingVideo" novalidate [formGroup]="form">
32 <my-video-edit 33 <my-video-edit
33 [form]="form" [formErrors]="formErrors" 34 [form]="form" [formErrors]="formErrors"
34 [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" 35 [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies"
35 ></my-video-edit> 36 ></my-video-edit>
36 37
37 <div class="submit-container"> 38 <div class="submit-container">
38 <div class="submit-button" [ngClass]="{ disabled: !form.valid }"> 39 <div class="submit-button" [ngClass]="{ disabled: !form.valid }">
39 <span class="icon icon-validate"></span> 40 <span class="icon icon-validate"></span>
40 <input type="button" value="Publish" (click)="upload()" /> 41 <input type="button" value="Publish" (click)="upload()" />
41 </div>
42 </div> 42 </div>
43 </form> 43 </div>
44 </div> 44 </form>
45</div> 45</div>
diff --git a/client/src/app/videos/+video-edit/video-add.component.ts b/client/src/app/videos/+video-edit/video-add.component.ts
index 071f9a28b..c2ee4ae2e 100644
--- a/client/src/app/videos/+video-edit/video-add.component.ts
+++ b/client/src/app/videos/+video-edit/video-add.component.ts
@@ -23,12 +23,14 @@ export class VideoAddComponent extends FormReactive implements OnInit {
23 @ViewChild('videofileInput') videofileInput 23 @ViewChild('videofileInput') videofileInput
24 24
25 isUploadingVideo = false 25 isUploadingVideo = false
26 videoUploaded = false
26 progressPercent = 0 27 progressPercent = 0
27 28
28 error: string = null 29 error: string = null
29 form: FormGroup 30 form: FormGroup
30 formErrors: { [ id: string ]: string } = {} 31 formErrors: { [ id: string ]: string } = {}
31 validationMessages: ValidatorMessage = {} 32 validationMessages: ValidatorMessage = {}
33
32 userVideoChannels = [] 34 userVideoChannels = []
33 videoPrivacies = [] 35 videoPrivacies = []
34 firstStepPrivacy = 0 36 firstStepPrivacy = 0
@@ -53,8 +55,12 @@ export class VideoAddComponent extends FormReactive implements OnInit {
53 ngOnInit () { 55 ngOnInit () {
54 this.buildForm() 56 this.buildForm()
55 57
56 this.videoPrivacies = this.serverService.getVideoPrivacies() 58 this.serverService.videoCategoriesLoaded
57 this.firstStepPrivacy = this.videoPrivacies[0].id 59 .subscribe(
60 () => {
61 this.videoPrivacies = this.serverService.getVideoPrivacies()
62 this.firstStepPrivacy = this.videoPrivacies[0].id
63 })
58 64
59 this.authService.userInformationLoaded 65 this.authService.userInformationLoaded
60 .subscribe( 66 .subscribe(
@@ -71,8 +77,8 @@ export class VideoAddComponent extends FormReactive implements OnInit {
71 ) 77 )
72 } 78 }
73 79
74 fileChange ($event) { 80 fileChange () {
75 console.log('uploading file ?') 81 this.uploadFirstStep()
76 } 82 }
77 83
78 checkForm () { 84 checkForm () {
@@ -82,38 +88,26 @@ export class VideoAddComponent extends FormReactive implements OnInit {
82 } 88 }
83 89
84 uploadFirstStep () { 90 uploadFirstStep () {
85 const formValue: VideoCreate = this.form.value
86
87 const name = formValue.name
88 const privacy = formValue.privacy
89 const nsfw = formValue.nsfw
90 const category = formValue.category
91 const licence = formValue.licence
92 const language = formValue.language
93 const channelId = formValue.channelId
94 const description = formValue.description
95 const tags = formValue.tags
96 const videofile = this.videofileInput.nativeElement.files[0] 91 const videofile = this.videofileInput.nativeElement.files[0]
92 const name = videofile.name
93 const privacy = this.firstStepPrivacy.toString()
94 const nsfw = false
95 const channelId = this.firstStepChannel.toString()
97 96
98 const formData = new FormData() 97 const formData = new FormData()
99 formData.append('name', name) 98 formData.append('name', name)
100 formData.append('privacy', privacy.toString()) 99 formData.append('privacy', privacy.toString())
101 formData.append('category', '' + category)
102 formData.append('nsfw', '' + nsfw) 100 formData.append('nsfw', '' + nsfw)
103 formData.append('licence', '' + licence)
104 formData.append('channelId', '' + channelId) 101 formData.append('channelId', '' + channelId)
105 formData.append('videofile', videofile) 102 formData.append('videofile', videofile)
106 103
107 // Language is optional 104 this.isUploadingVideo = true
108 if (language) { 105 this.form.patchValue({
109 formData.append('language', '' + language) 106 name,
110 } 107 privacy,
111 108 nsfw,
112 formData.append('description', description) 109 channelId
113 110 })
114 for (let i = 0; i < tags.length; i++) {
115 formData.append(`tags[${i}]`, tags[i])
116 }
117 111
118 this.videoService.uploadVideo(formData).subscribe( 112 this.videoService.uploadVideo(formData).subscribe(
119 event => { 113 event => {
@@ -121,10 +115,8 @@ export class VideoAddComponent extends FormReactive implements OnInit {
121 this.progressPercent = Math.round(100 * event.loaded / event.total) 115 this.progressPercent = Math.round(100 * event.loaded / event.total)
122 } else if (event instanceof HttpResponse) { 116 } else if (event instanceof HttpResponse) {
123 console.log('Video uploaded.') 117 console.log('Video uploaded.')
124 this.notificationsService.success('Success', 'Video uploaded.')
125 118
126 // Display all the videos once it's finished 119 this.videoUploaded = true
127 this.router.navigate([ '/videos/trending' ])
128 } 120 }
129 }, 121 },
130 122
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index 3e083fd92..7be7a5f95 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -14,7 +14,7 @@ import { FollowState } from '../../shared/models/accounts/follow.model'
14 14
15// --------------------------------------------------------------------------- 15// ---------------------------------------------------------------------------
16 16
17const LAST_MIGRATION_VERSION = 115 17const LAST_MIGRATION_VERSION = 120
18 18
19// --------------------------------------------------------------------------- 19// ---------------------------------------------------------------------------
20 20
diff --git a/server/initializers/migrations/0120-video-null.ts b/server/initializers/migrations/0120-video-null.ts
index 3506a5046..9130d10ee 100644
--- a/server/initializers/migrations/0120-video-null.ts
+++ b/server/initializers/migrations/0120-video-null.ts
@@ -1,4 +1,5 @@
1import * as Sequelize from 'sequelize' 1import * as Sequelize from 'sequelize'
2import { CONSTRAINTS_FIELDS } from '../constants'
2import { PeerTubeDatabase } from '../database' 3import { PeerTubeDatabase } from '../database'
3 4
4async function up (utils: { 5async function up (utils: {
@@ -28,7 +29,7 @@ async function up (utils: {
28 29
29 { 30 {
30 const data = { 31 const data = {
31 type: Sequelize.INTEGER, 32 type: Sequelize.STRING(CONSTRAINTS_FIELDS.VIDEOS.DESCRIPTION.max),
32 allowNull: true, 33 allowNull: true,
33 defaultValue: null 34 defaultValue: null
34 } 35 }
diff --git a/shared/models/videos/video-create.model.ts b/shared/models/videos/video-create.model.ts
index e537c38a8..8bc6a6639 100644
--- a/shared/models/videos/video-create.model.ts
+++ b/shared/models/videos/video-create.model.ts
@@ -1,13 +1,13 @@
1import { VideoPrivacy } from './video-privacy.enum' 1import { VideoPrivacy } from './video-privacy.enum'
2 2
3export interface VideoCreate { 3export interface VideoCreate {
4 category: number 4 category?: number
5 licence: number 5 licence?: number
6 language: number 6 language?: number
7 description: string 7 description?: string
8 channelId: number 8 channelId: number
9 nsfw: boolean 9 nsfw: boolean
10 name: string 10 name: string
11 tags: string[] 11 tags?: string[]
12 privacy: VideoPrivacy 12 privacy: VideoPrivacy
13} 13}