aboutsummaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-04-16 14:06:48 +0200
committerChocobozzz <florian.bigard@gmail.com>2017-04-16 14:06:48 +0200
commit3758da9489b636997a3a4fad7fc1a6081737bbe0 (patch)
tree7c335e1466887af1437c4701c859a72e58c93678 /client
parentad42bea3a55ca7937f082cc641764de70ce34bd1 (diff)
downloadPeerTube-3758da9489b636997a3a4fad7fc1a6081737bbe0.tar.gz
PeerTube-3758da9489b636997a3a4fad7fc1a6081737bbe0.tar.zst
PeerTube-3758da9489b636997a3a4fad7fc1a6081737bbe0.zip
Client: use ng2-tag-input for forms with video tags
Diffstat (limited to 'client')
-rw-r--r--client/package.json2
-rw-r--r--client/src/app/shared/forms/form-validators/video.ts3
-rw-r--r--client/src/app/videos/video-edit/video-add.component.html24
-rw-r--r--client/src/app/videos/video-edit/video-add.component.ts55
-rw-r--r--client/src/app/videos/video-edit/video-edit.component.scss4
-rw-r--r--client/src/app/videos/video-edit/video-update.component.html24
-rw-r--r--client/src/app/videos/video-edit/video-update.component.ts60
-rw-r--r--client/src/app/videos/videos.module.ts4
8 files changed, 35 insertions, 141 deletions
diff --git a/client/package.json b/client/package.json
index e8b2a1c35..00eb0e272 100644
--- a/client/package.json
+++ b/client/package.json
@@ -58,7 +58,7 @@
58 "ng-router-loader": "^1.0.2", 58 "ng-router-loader": "^1.0.2",
59 "ng2-file-upload": "^1.1.4-2", 59 "ng2-file-upload": "^1.1.4-2",
60 "ng2-smart-table": "1.0.3", 60 "ng2-smart-table": "1.0.3",
61 "ng2-tag-input": "1.0.1", 61 "ng2-tag-input": "^1.0.5",
62 "ngc-webpack": "1.1.0", 62 "ngc-webpack": "1.1.0",
63 "ngx-bootstrap": "1.6.6", 63 "ngx-bootstrap": "1.6.6",
64 "node-sass": "^4.1.1", 64 "node-sass": "^4.1.1",
diff --git a/client/src/app/shared/forms/form-validators/video.ts b/client/src/app/shared/forms/form-validators/video.ts
index 293fd805f..f7e4e5e4b 100644
--- a/client/src/app/shared/forms/form-validators/video.ts
+++ b/client/src/app/shared/forms/form-validators/video.ts
@@ -38,8 +38,9 @@ export const VIDEO_DESCRIPTION = {
38}; 38};
39 39
40export const VIDEO_TAGS = { 40export const VIDEO_TAGS = {
41 VALIDATORS: [ Validators.maxLength(10) ], 41 VALIDATORS: [ Validators.minLength(2), Validators.maxLength(10) ],
42 MESSAGES: { 42 MESSAGES: {
43 'minlength': 'A tag should be more than 2 characters long.',
43 'maxlength': 'A tag should be less than 10 characters long.' 44 'maxlength': 'A tag should be less than 10 characters long.'
44 } 45 }
45}; 46};
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 104747a8c..04f4f85b0 100644
--- a/client/src/app/videos/video-edit/video-add.component.html
+++ b/client/src/app/videos/video-edit/video-add.component.html
@@ -59,25 +59,11 @@
59 </div> 59 </div>
60 60
61 <div class="form-group"> 61 <div class="form-group">
62 <label for="tags">Tags</label> <span class="little-information">(press enter to add the tag)</span> 62 <label for="tags" class="label-tags">Tags</label> <span class="little-information">(press enter to add the tag)</span>
63 <input 63 <tag-input
64 type="text" class="form-control" id="currentTag" 64 [ngModel]="tags" [validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
65 formControlName="currentTag" (keyup)="onTagKeyPress($event)" 65 formControlName="tags" maxItems="3" modelAsStrings="true"
66 > 66 ></tag-input>
67 <div *ngIf="formErrors.currentTag" class="alert alert-danger">
68 {{ formErrors.currentTag }}
69 </div>
70 </div>
71
72 <div class="tags">
73 <div class="label label-primary tag" *ngFor="let tag of tags">
74 {{ tag }}
75 <span class="remove" (click)="removeTag(tag)">x</span>
76 </div>
77 </div>
78
79 <div *ngIf="tagsError" class="alert alert-danger">
80 {{ tagsError }}
81 </div> 67 </div>
82 68
83 <div class="form-group"> 69 <div class="form-group">
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 e3cf0e9d8..21343880d 100644
--- a/client/src/app/videos/video-edit/video-add.component.ts
+++ b/client/src/app/videos/video-edit/video-add.component.ts
@@ -30,6 +30,9 @@ export class VideoAddComponent extends FormReactive implements OnInit {
30 videoLicences = []; 30 videoLicences = [];
31 videoLanguages = []; 31 videoLanguages = [];
32 32
33 tagValidators = VIDEO_TAGS.VALIDATORS;
34 tagValidatorsMessages = VIDEO_TAGS.MESSAGES;
35
33 error: string = null; 36 error: string = null;
34 form: FormGroup; 37 form: FormGroup;
35 formErrors = { 38 formErrors = {
@@ -37,20 +40,17 @@ export class VideoAddComponent extends FormReactive implements OnInit {
37 category: '', 40 category: '',
38 licence: '', 41 licence: '',
39 language: '', 42 language: '',
40 description: '', 43 description: ''
41 currentTag: ''
42 }; 44 };
43 validationMessages = { 45 validationMessages = {
44 name: VIDEO_NAME.MESSAGES, 46 name: VIDEO_NAME.MESSAGES,
45 category: VIDEO_CATEGORY.MESSAGES, 47 category: VIDEO_CATEGORY.MESSAGES,
46 licence: VIDEO_LICENCE.MESSAGES, 48 licence: VIDEO_LICENCE.MESSAGES,
47 language: VIDEO_LANGUAGE.MESSAGES, 49 language: VIDEO_LANGUAGE.MESSAGES,
48 description: VIDEO_DESCRIPTION.MESSAGES, 50 description: VIDEO_DESCRIPTION.MESSAGES
49 currentTag: VIDEO_TAGS.MESSAGES
50 }; 51 };
51 52
52 // Special error messages 53 // Special error messages
53 tagsError = '';
54 fileError = ''; 54 fileError = '';
55 55
56 constructor( 56 constructor(
@@ -80,7 +80,7 @@ export class VideoAddComponent extends FormReactive implements OnInit {
80 licence: [ '', VIDEO_LICENCE.VALIDATORS ], 80 licence: [ '', VIDEO_LICENCE.VALIDATORS ],
81 language: [ '', VIDEO_LANGUAGE.VALIDATORS ], 81 language: [ '', VIDEO_LANGUAGE.VALIDATORS ],
82 description: [ '', VIDEO_DESCRIPTION.VALIDATORS ], 82 description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
83 currentTag: [ '', VIDEO_TAGS.VALIDATORS ] 83 tags: [ '']
84 }); 84 });
85 85
86 this.form.valueChanges.subscribe(data => this.onValueChanged(data)); 86 this.form.valueChanges.subscribe(data => this.onValueChanged(data));
@@ -105,6 +105,7 @@ export class VideoAddComponent extends FormReactive implements OnInit {
105 const licence = this.form.value['licence']; 105 const licence = this.form.value['licence'];
106 const language = this.form.value['language']; 106 const language = this.form.value['language'];
107 const description = this.form.value['description']; 107 const description = this.form.value['description'];
108 const tags = this.form.value['tags'];
108 109
109 form.append('name', name); 110 form.append('name', name);
110 form.append('category', category); 111 form.append('category', category);
@@ -118,8 +119,8 @@ export class VideoAddComponent extends FormReactive implements OnInit {
118 119
119 form.append('description', description); 120 form.append('description', description);
120 121
121 for (let i = 0; i < this.tags.length; i++) { 122 for (let i = 0; i < tags.length; i++) {
122 form.append(`tags[${i}]`, this.tags[i]); 123 form.append(`tags[${i}]`, tags[i]);
123 } 124 }
124 }; 125 };
125 126
@@ -133,33 +134,18 @@ export class VideoAddComponent extends FormReactive implements OnInit {
133 this.fileError = 'You did not add a file.'; 134 this.fileError = 'You did not add a file.';
134 } 135 }
135 136
136 return this.form.valid === true && this.tagsError === '' && this.fileError === ''; 137 return this.form.valid === true && this.fileError === '';
137 } 138 }
138 139
139 fileChanged() { 140 fileChanged() {
140 this.fileError = ''; 141 this.fileError = '';
141 } 142 }
142 143
143 onTagKeyPress(event: KeyboardEvent) {
144 // Enter press
145 if (event.keyCode === 13) {
146 this.addTagIfPossible();
147 }
148 }
149
150 removeFile() { 144 removeFile() {
151 this.uploader.clearQueue(); 145 this.uploader.clearQueue();
152 } 146 }
153 147
154 removeTag(tag: string) {
155 this.tags.splice(this.tags.indexOf(tag), 1);
156 this.form.get('currentTag').enable();
157 }
158
159 upload() { 148 upload() {
160 // Maybe the user forgot to press "enter" when he filled the field
161 this.addTagIfPossible();
162
163 if (this.checkForm() === false) { 149 if (this.checkForm() === false) {
164 return; 150 return;
165 } 151 }
@@ -206,25 +192,4 @@ export class VideoAddComponent extends FormReactive implements OnInit {
206 192
207 this.uploader.uploadAll(); 193 this.uploader.uploadAll();
208 } 194 }
209
210 private addTagIfPossible() {
211 const currentTag = this.form.value['currentTag'];
212 if (currentTag === undefined) return;
213
214 // Check if the tag is valid and does not already exist
215 if (
216 currentTag.length >= 2 &&
217 this.form.controls['currentTag'].valid &&
218 this.tags.indexOf(currentTag) === -1
219 ) {
220 this.tags.push(currentTag);
221 this.form.patchValue({ currentTag: '' });
222
223 if (this.tags.length >= 3) {
224 this.form.get('currentTag').disable();
225 }
226
227 this.tagsError = '';
228 }
229 }
230} 195}
diff --git a/client/src/app/videos/video-edit/video-edit.component.scss b/client/src/app/videos/video-edit/video-edit.component.scss
index 92b731191..9ee0c520c 100644
--- a/client/src/app/videos/video-edit/video-edit.component.scss
+++ b/client/src/app/videos/video-edit/video-edit.component.scss
@@ -50,3 +50,7 @@ div.file-to-upload {
50 font-size: 0.8em; 50 font-size: 0.8em;
51 font-style: italic; 51 font-style: italic;
52} 52}
53
54.label-tags {
55 margin-bottom: 0;
56}
diff --git a/client/src/app/videos/video-edit/video-update.component.html b/client/src/app/videos/video-edit/video-update.component.html
index 2e10d5bf7..bedbc91b8 100644
--- a/client/src/app/videos/video-edit/video-update.component.html
+++ b/client/src/app/videos/video-edit/video-update.component.html
@@ -59,25 +59,11 @@
59 </div> 59 </div>
60 60
61 <div class="form-group"> 61 <div class="form-group">
62 <label for="tags">Tags</label> <span class="little-information">(press enter to add the tag)</span> 62 <label for="tags" class="label-tags">Tags</label> <span class="little-information">(press enter to add the tag)</span>
63 <input 63 <tag-input
64 type="text" class="form-control" id="currentTag" 64 [ngModel]="tags" [validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
65 formControlName="currentTag" (keyup)="onTagKeyPress($event)" 65 formControlName="tags" maxItems="3" modelAsStrings="true"
66 > 66 ></tag-input>
67 <div *ngIf="formErrors.currentTag" class="alert alert-danger">
68 {{ formErrors.currentTag }}
69 </div>
70 </div>
71
72 <div class="tags">
73 <div class="label label-primary tag" *ngFor="let tag of tags">
74 {{ tag }}
75 <span class="remove" (click)="removeTag(tag)">x</span>
76 </div>
77 </div>
78
79 <div *ngIf="tagsError" class="alert alert-danger">
80 {{ tagsError }}
81 </div> 67 </div>
82 68
83 <div class="form-group"> 69 <div class="form-group">
diff --git a/client/src/app/videos/video-edit/video-update.component.ts b/client/src/app/videos/video-edit/video-update.component.ts
index b45780a41..adb3d295c 100644
--- a/client/src/app/videos/video-edit/video-update.component.ts
+++ b/client/src/app/videos/video-edit/video-update.component.ts
@@ -30,6 +30,9 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
30 videoLanguages = []; 30 videoLanguages = [];
31 video: Video; 31 video: Video;
32 32
33 tagValidators = VIDEO_TAGS.VALIDATORS;
34 tagValidatorsMessages = VIDEO_TAGS.MESSAGES;
35
33 error: string = null; 36 error: string = null;
34 form: FormGroup; 37 form: FormGroup;
35 formErrors = { 38 formErrors = {
@@ -37,20 +40,16 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
37 category: '', 40 category: '',
38 licence: '', 41 licence: '',
39 language: '', 42 language: '',
40 description: '', 43 description: ''
41 currentTag: ''
42 }; 44 };
43 validationMessages = { 45 validationMessages = {
44 name: VIDEO_NAME.MESSAGES, 46 name: VIDEO_NAME.MESSAGES,
45 category: VIDEO_CATEGORY.MESSAGES, 47 category: VIDEO_CATEGORY.MESSAGES,
46 licence: VIDEO_LICENCE.MESSAGES, 48 licence: VIDEO_LICENCE.MESSAGES,
47 language: VIDEO_LANGUAGE.MESSAGES, 49 language: VIDEO_LANGUAGE.MESSAGES,
48 description: VIDEO_DESCRIPTION.MESSAGES, 50 description: VIDEO_DESCRIPTION.MESSAGES
49 currentTag: VIDEO_TAGS.MESSAGES
50 }; 51 };
51 52
52 // Special error messages
53 tagsError = '';
54 fileError = ''; 53 fileError = '';
55 54
56 constructor( 55 constructor(
@@ -73,7 +72,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
73 licence: [ '', VIDEO_LICENCE.VALIDATORS ], 72 licence: [ '', VIDEO_LICENCE.VALIDATORS ],
74 language: [ '', VIDEO_LANGUAGE.VALIDATORS ], 73 language: [ '', VIDEO_LANGUAGE.VALIDATORS ],
75 description: [ '', VIDEO_DESCRIPTION.VALIDATORS ], 74 description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
76 currentTag: [ '', VIDEO_TAGS.VALIDATORS ] 75 tags: [ '' ]
77 }); 76 });
78 77
79 this.form.valueChanges.subscribe(data => this.onValueChanged(data)); 78 this.form.valueChanges.subscribe(data => this.onValueChanged(data));
@@ -99,33 +98,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
99 ); 98 );
100 } 99 }
101 100
102 checkForm() {
103 this.forceCheck();
104
105 return this.form.valid === true && this.tagsError === '' && this.fileError === '';
106 }
107
108
109 onTagKeyPress(event: KeyboardEvent) {
110 // Enter press
111 if (event.keyCode === 13) {
112 this.addTagIfPossible();
113 }
114 }
115
116 removeTag(tag: string) {
117 this.tags.splice(this.tags.indexOf(tag), 1);
118 this.form.get('currentTag').enable();
119 }
120
121 update() { 101 update() {
122 // Maybe the user forgot to press "enter" when he filled the field
123 this.addTagIfPossible();
124
125 if (this.checkForm() === false) {
126 return;
127 }
128
129 this.video.patch(this.form.value); 102 this.video.patch(this.form.value);
130 103
131 this.videoService.updateVideo(this.video) 104 this.videoService.updateVideo(this.video)
@@ -143,27 +116,6 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
143 116
144 } 117 }
145 118
146 private addTagIfPossible() {
147 const currentTag = this.form.value['currentTag'];
148 if (currentTag === undefined) return;
149
150 // Check if the tag is valid and does not already exist
151 if (
152 currentTag.length >= 2 &&
153 this.form.controls['currentTag'].valid &&
154 this.tags.indexOf(currentTag) === -1
155 ) {
156 this.tags.push(currentTag);
157 this.form.patchValue({ currentTag: '' });
158
159 if (this.tags.length >= 3) {
160 this.form.get('currentTag').disable();
161 }
162
163 this.tagsError = '';
164 }
165 }
166
167 private hydrateFormFromVideo() { 119 private hydrateFormFromVideo() {
168 this.form.patchValue(this.video.toJSON()); 120 this.form.patchValue(this.video.toJSON());
169 } 121 }
diff --git a/client/src/app/videos/videos.module.ts b/client/src/app/videos/videos.module.ts
index 4f2839c85..04a06e0a3 100644
--- a/client/src/app/videos/videos.module.ts
+++ b/client/src/app/videos/videos.module.ts
@@ -1,6 +1,6 @@
1import { NgModule } from '@angular/core'; 1import { NgModule } from '@angular/core';
2 2
3// import { TagInputModule } from 'ng2-tag-input'; 3import { TagInputModule } from 'ng2-tag-input';
4 4
5import { VideosRoutingModule } from './videos-routing.module'; 5import { VideosRoutingModule } from './videos-routing.module';
6import { VideosComponent } from './videos.component'; 6import { VideosComponent } from './videos.component';
@@ -18,7 +18,7 @@ import { SharedModule } from '../shared';
18 18
19@NgModule({ 19@NgModule({
20 imports: [ 20 imports: [
21 // TagInputModule, 21 TagInputModule,
22 22
23 VideosRoutingModule, 23 VideosRoutingModule,
24 SharedModule 24 SharedModule