aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-06-05 15:01:45 +0200
committerChocobozzz <me@florianbigard.com>2018-06-05 15:02:27 +0200
commite309822b93d9b69f30cbe830ef3d09dfdb2c13b2 (patch)
tree41dbc3b3108ced7fdba4062974e568695c30e486
parentd4d5853e65e584ca51c718f8df590b987f981047 (diff)
downloadPeerTube-e309822b93d9b69f30cbe830ef3d09dfdb2c13b2.tar.gz
PeerTube-e309822b93d9b69f30cbe830ef3d09dfdb2c13b2.tar.zst
PeerTube-e309822b93d9b69f30cbe830ef3d09dfdb2c13b2.zip
Add form validator translations
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html2
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts38
-rw-r--r--client/src/app/+admin/users/user-edit/user-create.component.ts13
-rw-r--r--client/src/app/+admin/users/user-edit/user-update.component.ts10
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts8
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.html32
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.scss5
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts8
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts13
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts13
-rw-r--r--client/src/app/app.module.ts6
-rw-r--r--client/src/app/login/login.component.ts7
-rw-r--r--client/src/app/reset-password/reset-password.component.ts10
-rw-r--r--client/src/app/shared/forms/form-validators/custom-config-validators.service.ts72
-rw-r--r--client/src/app/shared/forms/form-validators/custom-config.ts56
-rw-r--r--client/src/app/shared/forms/form-validators/form-validator.service.ts9
-rw-r--r--client/src/app/shared/forms/form-validators/index.ts11
-rw-r--r--client/src/app/shared/forms/form-validators/login-validators.service.ts30
-rw-r--r--client/src/app/shared/forms/form-validators/login.ts18
-rw-r--r--client/src/app/shared/forms/form-validators/reset-password-validators.service.ts20
-rw-r--r--client/src/app/shared/forms/form-validators/reset-password.ts10
-rw-r--r--client/src/app/shared/forms/form-validators/user-validators.service.ts93
-rw-r--r--client/src/app/shared/forms/form-validators/user.ts70
-rw-r--r--client/src/app/shared/forms/form-validators/validator-message.ts5
-rw-r--r--client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts20
-rw-r--r--client/src/app/shared/forms/form-validators/video-abuse.ts10
-rw-r--r--client/src/app/shared/forms/form-validators/video-channel-validators.service.ts48
-rw-r--r--client/src/app/shared/forms/form-validators/video-channel.ts34
-rw-r--r--client/src/app/shared/forms/form-validators/video-comment-validators.service.ts20
-rw-r--r--client/src/app/shared/forms/form-validators/video-comment.ts10
-rw-r--r--client/src/app/shared/forms/form-validators/video-validators.service.ts88
-rw-r--r--client/src/app/shared/forms/form-validators/video.ts68
-rw-r--r--client/src/app/shared/shared.module.ts16
-rw-r--r--client/src/app/signup/signup.component.ts10
-rw-r--r--client/src/app/videos/+video-edit/shared/video-edit.component.ts43
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment-add.component.ts5
-rw-r--r--client/src/app/videos/+video-watch/modal/video-report.component.ts8
-rw-r--r--client/src/locale/source/messages_en_US.xml535
-rw-r--r--client/src/locale/target/messages_fr.xml583
-rw-r--r--client/src/main.ts14
40 files changed, 1476 insertions, 595 deletions
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
index 4263b7b5f..a0bd01e5e 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
@@ -207,7 +207,7 @@ Check this checkbox, save the configuration and test with a video URL of your in
207 <div i18n class="inner-form-title">Cache</div> 207 <div i18n class="inner-form-title">Cache</div>
208 208
209 <div class="form-group"> 209 <div class="form-group">
210 <label i18n for="cachePreviewsSize">Preview cache size</label> 210 <label i18n for="cachePreviewsSize">Previews cache size</label>
211 <my-help 211 <my-help
212 helpType="custom" i18n-customHtml 212 helpType="custom" i18n-customHtml
213 customHtml="Previews are not federated. We fetch them directly from the origin instance and cache them." 213 customHtml="Previews are not federated. We fetch them directly from the origin instance and cache them."
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
index f2a3464cb..7b3e72803 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
@@ -1,19 +1,9 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { FormBuilder, FormGroup } from '@angular/forms'
3import { Router } from '@angular/router' 2import { Router } from '@angular/router'
4import { ConfigService } from '@app/+admin/config/shared/config.service' 3import { ConfigService } from '@app/+admin/config/shared/config.service'
5import { ConfirmService } from '@app/core' 4import { ConfirmService } from '@app/core'
6import { ServerService } from '@app/core/server/server.service' 5import { ServerService } from '@app/core/server/server.service'
7import { FormReactive, USER_VIDEO_QUOTA } from '@app/shared' 6import { CustomConfigValidatorsService, FormReactive, UserValidatorsService } from '@app/shared'
8import {
9 ADMIN_EMAIL,
10 CACHE_PREVIEWS_SIZE,
11 INSTANCE_NAME,
12 INSTANCE_SHORT_DESCRIPTION,
13 SERVICES_TWITTER_USERNAME,
14 SIGNUP_LIMIT,
15 TRANSCODING_THREADS
16} from '@app/shared/forms/form-validators/custom-config'
17import { NotificationsService } from 'angular2-notifications' 7import { NotificationsService } from 'angular2-notifications'
18import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model' 8import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model'
19import { I18n } from '@ngx-translate/i18n-polyfill' 9import { I18n } from '@ngx-translate/i18n-polyfill'
@@ -50,6 +40,8 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
50 40
51 constructor ( 41 constructor (
52 protected formValidatorService: FormValidatorService, 42 protected formValidatorService: FormValidatorService,
43 private customConfigValidatorsService: CustomConfigValidatorsService,
44 private userValidatorsService: UserValidatorsService,
53 private router: Router, 45 private router: Router,
54 private notificationsService: NotificationsService, 46 private notificationsService: NotificationsService,
55 private configService: ConfigService, 47 private configService: ConfigService,
@@ -66,20 +58,20 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
66 58
67 ngOnInit () { 59 ngOnInit () {
68 const formGroupData = { 60 const formGroupData = {
69 instanceName: INSTANCE_NAME, 61 instanceName: this.customConfigValidatorsService.INSTANCE_NAME,
70 instanceShortDescription: INSTANCE_SHORT_DESCRIPTION, 62 instanceShortDescription: this.customConfigValidatorsService.INSTANCE_SHORT_DESCRIPTION,
71 instanceDescription: null, 63 instanceDescription: null,
72 instanceTerms: null, 64 instanceTerms: null,
73 instanceDefaultClientRoute: null, 65 instanceDefaultClientRoute: null,
74 instanceDefaultNSFWPolicy: null, 66 instanceDefaultNSFWPolicy: null,
75 servicesTwitterUsername: SERVICES_TWITTER_USERNAME, 67 servicesTwitterUsername: this.customConfigValidatorsService.SERVICES_TWITTER_USERNAME,
76 servicesTwitterWhitelisted: null, 68 servicesTwitterWhitelisted: null,
77 cachePreviewsSize: CACHE_PREVIEWS_SIZE, 69 cachePreviewsSize: this.customConfigValidatorsService.CACHE_PREVIEWS_SIZE,
78 signupEnabled: null, 70 signupEnabled: null,
79 signupLimit: SIGNUP_LIMIT, 71 signupLimit: this.customConfigValidatorsService.SIGNUP_LIMIT,
80 adminEmail: ADMIN_EMAIL, 72 adminEmail: this.customConfigValidatorsService.ADMIN_EMAIL,
81 userVideoQuota: USER_VIDEO_QUOTA, 73 userVideoQuota: this.userValidatorsService.USER_VIDEO_QUOTA,
82 transcodingThreads: TRANSCODING_THREADS, 74 transcodingThreads: this.customConfigValidatorsService.TRANSCODING_THREADS,
83 transcodingEnabled: null, 75 transcodingEnabled: null,
84 customizationJavascript: null, 76 customizationJavascript: null,
85 customizationCSS: null 77 customizationCSS: null
@@ -134,11 +126,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
134 const message = this.i18n('You set custom {{customizationsText}}. ', { customizationsText }) + 126 const message = this.i18n('You set custom {{customizationsText}}. ', { customizationsText }) +
135 this.i18n('This could lead to security issues or bugs if you do not understand it. ') + 127 this.i18n('This could lead to security issues or bugs if you do not understand it. ') +
136 this.i18n('Are you sure you want to update the configuration?') 128 this.i18n('Are you sure you want to update the configuration?')
137 const label = this.i18n( 129
138 'Please type "I understand the {{customizationsText}} I set" to confirm.', 130 const label = this.i18n('Please type') + ` "I understand the ${customizationsText} I set" ` + this.i18n('to confirm.')
139 { customizationsText } 131 const expectedInputValue = `I understand the ${customizationsText} I set`
140 )
141 const expectedInputValue = this.i18n('I understand the {{customizationsText}} I set', { customizationsText })
142 132
143 const confirmRes = await this.confirmService.confirmWithInput(message, label, expectedInputValue) 133 const confirmRes = await this.confirmService.confirmWithInput(message, label, expectedInputValue)
144 if (confirmRes === false) return 134 if (confirmRes === false) return
diff --git a/client/src/app/+admin/users/user-edit/user-create.component.ts b/client/src/app/+admin/users/user-edit/user-create.component.ts
index e5f0903b6..c15cfb267 100644
--- a/client/src/app/+admin/users/user-edit/user-create.component.ts
+++ b/client/src/app/+admin/users/user-edit/user-create.component.ts
@@ -2,12 +2,12 @@ import { Component, OnInit } from '@angular/core'
2import { Router } from '@angular/router' 2import { Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications' 3import { NotificationsService } from 'angular2-notifications'
4import { UserService } from '../shared' 4import { UserService } from '../shared'
5import { USER_EMAIL, USER_PASSWORD, USER_ROLE, USER_USERNAME, USER_VIDEO_QUOTA } from '../../../shared'
6import { ServerService } from '../../../core' 5import { ServerService } from '../../../core'
7import { UserCreate, UserRole } from '../../../../../../shared' 6import { UserCreate, UserRole } from '../../../../../../shared'
8import { UserEdit } from './user-edit' 7import { UserEdit } from './user-edit'
9import { I18n } from '@ngx-translate/i18n-polyfill' 8import { I18n } from '@ngx-translate/i18n-polyfill'
10import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
10import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service'
11 11
12@Component({ 12@Component({
13 selector: 'my-user-create', 13 selector: 'my-user-create',
@@ -20,6 +20,7 @@ export class UserCreateComponent extends UserEdit implements OnInit {
20 constructor ( 20 constructor (
21 protected serverService: ServerService, 21 protected serverService: ServerService,
22 protected formValidatorService: FormValidatorService, 22 protected formValidatorService: FormValidatorService,
23 private userValidatorsService: UserValidatorsService,
23 private router: Router, 24 private router: Router,
24 private notificationsService: NotificationsService, 25 private notificationsService: NotificationsService,
25 private userService: UserService, 26 private userService: UserService,
@@ -35,11 +36,11 @@ export class UserCreateComponent extends UserEdit implements OnInit {
35 } 36 }
36 37
37 this.buildForm({ 38 this.buildForm({
38 username: USER_USERNAME, 39 username: this.userValidatorsService.USER_USERNAME,
39 email: USER_EMAIL, 40 email: this.userValidatorsService.USER_EMAIL,
40 password: USER_PASSWORD, 41 password: this.userValidatorsService.USER_PASSWORD,
41 role: USER_ROLE, 42 role: this.userValidatorsService.USER_ROLE,
42 videoQuota: USER_VIDEO_QUOTA 43 videoQuota: this.userValidatorsService.USER_VIDEO_QUOTA
43 }, defaultValues) 44 }, defaultValues)
44 } 45 }
45 46
diff --git a/client/src/app/+admin/users/user-edit/user-update.component.ts b/client/src/app/+admin/users/user-edit/user-update.component.ts
index f8073c928..3e60991d2 100644
--- a/client/src/app/+admin/users/user-edit/user-update.component.ts
+++ b/client/src/app/+admin/users/user-edit/user-update.component.ts
@@ -3,12 +3,13 @@ import { ActivatedRoute, Router } from '@angular/router'
3import { Subscription } from 'rxjs' 3import { Subscription } from 'rxjs'
4import { NotificationsService } from 'angular2-notifications' 4import { NotificationsService } from 'angular2-notifications'
5import { UserService } from '../shared' 5import { UserService } from '../shared'
6import { User, USER_EMAIL, USER_ROLE, USER_VIDEO_QUOTA } from '../../../shared' 6import { User } from '../../../shared'
7import { ServerService } from '../../../core' 7import { ServerService } from '../../../core'
8import { UserEdit } from './user-edit' 8import { UserEdit } from './user-edit'
9import { UserUpdate } from '../../../../../../shared' 9import { UserUpdate } from '../../../../../../shared'
10import { I18n } from '@ngx-translate/i18n-polyfill' 10import { I18n } from '@ngx-translate/i18n-polyfill'
11import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 11import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
12import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service'
12 13
13@Component({ 14@Component({
14 selector: 'my-user-update', 15 selector: 'my-user-update',
@@ -25,6 +26,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
25 constructor ( 26 constructor (
26 protected formValidatorService: FormValidatorService, 27 protected formValidatorService: FormValidatorService,
27 protected serverService: ServerService, 28 protected serverService: ServerService,
29 private userValidatorsService: UserValidatorsService,
28 private route: ActivatedRoute, 30 private route: ActivatedRoute,
29 private router: Router, 31 private router: Router,
30 private notificationsService: NotificationsService, 32 private notificationsService: NotificationsService,
@@ -37,9 +39,9 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
37 ngOnInit () { 39 ngOnInit () {
38 const defaultValues = { videoQuota: '-1' } 40 const defaultValues = { videoQuota: '-1' }
39 this.buildForm({ 41 this.buildForm({
40 email: USER_EMAIL, 42 email: this.userValidatorsService.USER_EMAIL,
41 role: USER_ROLE, 43 role: this.userValidatorsService.USER_ROLE,
42 videoQuota: USER_VIDEO_QUOTA 44 videoQuota: this.userValidatorsService.USER_VIDEO_QUOTA
43 }, defaultValues) 45 }, defaultValues)
44 46
45 this.paramsSub = this.route.params.subscribe(routeParams => { 47 this.paramsSub = this.route.params.subscribe(routeParams => {
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
index 56e644f39..7be7aabc2 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
@@ -1,8 +1,9 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { NotificationsService } from 'angular2-notifications'
3import { FormReactive, USER_PASSWORD, UserService } from '../../../shared' 3import { FormReactive, UserService } from '../../../shared'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 5import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
6import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service'
6 7
7@Component({ 8@Component({
8 selector: 'my-account-change-password', 9 selector: 'my-account-change-password',
@@ -14,6 +15,7 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On
14 15
15 constructor ( 16 constructor (
16 protected formValidatorService: FormValidatorService, 17 protected formValidatorService: FormValidatorService,
18 private userValidatorsService: UserValidatorsService,
17 private notificationsService: NotificationsService, 19 private notificationsService: NotificationsService,
18 private userService: UserService, 20 private userService: UserService,
19 private i18n: I18n 21 private i18n: I18n
@@ -23,8 +25,8 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On
23 25
24 ngOnInit () { 26 ngOnInit () {
25 this.buildForm({ 27 this.buildForm({
26 'new-password': USER_PASSWORD, 28 'new-password': this.userValidatorsService.USER_PASSWORD,
27 'new-confirmed-password': USER_PASSWORD 29 'new-confirmed-password': this.userValidatorsService.USER_PASSWORD
28 }) 30 })
29 } 31 }
30 32
diff --git a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.html b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.html
index bbdce5b02..05c0b5ddc 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.html
+++ b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.html
@@ -2,22 +2,26 @@
2 2
3<form role="form" (ngSubmit)="updateMyProfile()" [formGroup]="form"> 3<form role="form" (ngSubmit)="updateMyProfile()" [formGroup]="form">
4 4
5 <label i18n for="display-name">Display name</label> 5 <div class="form-group">
6 <input 6 <label i18n for="display-name">Display name</label>
7 type="text" id="display-name" 7 <input
8 formControlName="display-name" [ngClass]="{ 'input-error': formErrors['display-name'] }" 8 type="text" id="display-name"
9 > 9 formControlName="display-name" [ngClass]="{ 'input-error': formErrors['display-name'] }"
10 <div *ngIf="formErrors['display-name']" class="form-error"> 10 >
11 {{ formErrors['display-name'] }} 11 <div *ngIf="formErrors['display-name']" class="form-error">
12 {{ formErrors['display-name'] }}
13 </div>
12 </div> 14 </div>
13 15
14 <label i18n for="description">Description</label> 16 <div class="form-group">
15 <textarea 17 <label i18n for="description">Description</label>
16 id="description" formControlName="description" 18 <textarea
17 [ngClass]="{ 'input-error': formErrors['description'] }" 19 id="description" formControlName="description"
18 ></textarea> 20 [ngClass]="{ 'input-error': formErrors['description'] }"
19 <div *ngIf="formErrors.description" class="form-error"> 21 ></textarea>
20 {{ formErrors.description }} 22 <div *ngIf="formErrors.description" class="form-error">
23 {{ formErrors.description }}
24 </div>
21 </div> 25 </div>
22 26
23 <input type="submit" i18n-value value="Update my profile" [disabled]="!form.valid"> 27 <input type="submit" i18n-value value="Update my profile" [disabled]="!form.valid">
diff --git a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.scss b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.scss
index fc2b92c89..6aabb60f4 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.scss
+++ b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.scss
@@ -1,11 +1,14 @@
1@import '_variables'; 1@import '_variables';
2@import '_mixins'; 2@import '_mixins';
3 3
4.form-group:first-child {
5 margin-bottom: 15px;
6}
7
4input[type=text] { 8input[type=text] {
5 @include peertube-input-text(340px); 9 @include peertube-input-text(340px);
6 10
7 display: block; 11 display: block;
8 margin-bottom: 15px;
9} 12}
10 13
11textarea { 14textarea {
diff --git a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
index 1fe337da0..400c3b889 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
@@ -1,10 +1,11 @@
1import { Component, Input, OnInit } from '@angular/core' 1import { Component, Input, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { NotificationsService } from 'angular2-notifications'
3import { FormReactive, USER_DESCRIPTION, USER_DISPLAY_NAME, UserService } from '../../../shared' 3import { FormReactive, UserService } from '../../../shared'
4import { User } from '@app/shared' 4import { User } from '@app/shared'
5import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
7import { Subject } from 'rxjs/Subject' 7import { Subject } from 'rxjs/Subject'
8import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service'
8 9
9@Component({ 10@Component({
10 selector: 'my-account-profile', 11 selector: 'my-account-profile',
@@ -19,6 +20,7 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit {
19 20
20 constructor ( 21 constructor (
21 protected formValidatorService: FormValidatorService, 22 protected formValidatorService: FormValidatorService,
23 private userValidatorsService: UserValidatorsService,
22 private notificationsService: NotificationsService, 24 private notificationsService: NotificationsService,
23 private userService: UserService, 25 private userService: UserService,
24 private i18n: I18n 26 private i18n: I18n
@@ -28,8 +30,8 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit {
28 30
29 ngOnInit () { 31 ngOnInit () {
30 this.buildForm({ 32 this.buildForm({
31 'display-name': USER_DISPLAY_NAME, 33 'display-name': this.userValidatorsService.USER_DISPLAY_NAME,
32 description: USER_DESCRIPTION 34 description: this.userValidatorsService.USER_DESCRIPTION
33 }) 35 })
34 36
35 this.userInformationLoaded.subscribe(() => { 37 this.userInformationLoaded.subscribe(() => {
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
index e38eaae9c..c0eaa4763 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
@@ -3,15 +3,11 @@ import { Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications' 3import { NotificationsService } from 'angular2-notifications'
4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' 4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit'
5import { VideoChannelCreate } from '../../../../../shared/models/videos' 5import { VideoChannelCreate } from '../../../../../shared/models/videos'
6import {
7 VIDEO_CHANNEL_DESCRIPTION,
8 VIDEO_CHANNEL_DISPLAY_NAME,
9 VIDEO_CHANNEL_SUPPORT
10} from '@app/shared/forms/form-validators/video-channel'
11import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 6import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
12import { AuthService } from '@app/core' 7import { AuthService } from '@app/core'
13import { I18n } from '@ngx-translate/i18n-polyfill' 8import { I18n } from '@ngx-translate/i18n-polyfill'
14import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
10import { VideoChannelValidatorsService } from '@app/shared/forms/form-validators/video-channel-validators.service'
15 11
16@Component({ 12@Component({
17 selector: 'my-account-video-channel-create', 13 selector: 'my-account-video-channel-create',
@@ -24,6 +20,7 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE
24 constructor ( 20 constructor (
25 protected formValidatorService: FormValidatorService, 21 protected formValidatorService: FormValidatorService,
26 private authService: AuthService, 22 private authService: AuthService,
23 private videoChannelValidatorsService: VideoChannelValidatorsService,
27 private notificationsService: NotificationsService, 24 private notificationsService: NotificationsService,
28 private router: Router, 25 private router: Router,
29 private videoChannelService: VideoChannelService, 26 private videoChannelService: VideoChannelService,
@@ -34,9 +31,9 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE
34 31
35 ngOnInit () { 32 ngOnInit () {
36 this.buildForm({ 33 this.buildForm({
37 'display-name': VIDEO_CHANNEL_DISPLAY_NAME, 34 'display-name': this.videoChannelValidatorsService.VIDEO_CHANNEL_DISPLAY_NAME,
38 description: VIDEO_CHANNEL_DESCRIPTION, 35 description: this.videoChannelValidatorsService.VIDEO_CHANNEL_DESCRIPTION,
39 support: VIDEO_CHANNEL_SUPPORT 36 support: this.videoChannelValidatorsService.VIDEO_CHANNEL_SUPPORT
40 }) 37 })
41 } 38 }
42 39
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
index eda03374a..1510c5015 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
@@ -3,17 +3,13 @@ import { ActivatedRoute, Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications' 3import { NotificationsService } from 'angular2-notifications'
4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' 4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit'
5import { VideoChannelUpdate } from '../../../../../shared/models/videos' 5import { VideoChannelUpdate } from '../../../../../shared/models/videos'
6import {
7 VIDEO_CHANNEL_DESCRIPTION,
8 VIDEO_CHANNEL_DISPLAY_NAME,
9 VIDEO_CHANNEL_SUPPORT
10} from '@app/shared/forms/form-validators/video-channel'
11import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 6import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
12import { Subscription } from 'rxjs' 7import { Subscription } from 'rxjs'
13import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 8import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
14import { AuthService } from '@app/core' 9import { AuthService } from '@app/core'
15import { I18n } from '@ngx-translate/i18n-polyfill' 10import { I18n } from '@ngx-translate/i18n-polyfill'
16import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 11import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
12import { VideoChannelValidatorsService } from '@app/shared/forms/form-validators/video-channel-validators.service'
17 13
18@Component({ 14@Component({
19 selector: 'my-account-video-channel-update', 15 selector: 'my-account-video-channel-update',
@@ -29,6 +25,7 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
29 constructor ( 25 constructor (
30 protected formValidatorService: FormValidatorService, 26 protected formValidatorService: FormValidatorService,
31 private authService: AuthService, 27 private authService: AuthService,
28 private videoChannelValidatorsService: VideoChannelValidatorsService,
32 private notificationsService: NotificationsService, 29 private notificationsService: NotificationsService,
33 private router: Router, 30 private router: Router,
34 private route: ActivatedRoute, 31 private route: ActivatedRoute,
@@ -40,9 +37,9 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
40 37
41 ngOnInit () { 38 ngOnInit () {
42 this.buildForm({ 39 this.buildForm({
43 'display-name': VIDEO_CHANNEL_DISPLAY_NAME, 40 'display-name': this.videoChannelValidatorsService.VIDEO_CHANNEL_DISPLAY_NAME,
44 description: VIDEO_CHANNEL_DESCRIPTION, 41 description: this.videoChannelValidatorsService.VIDEO_CHANNEL_DESCRIPTION,
45 support: VIDEO_CHANNEL_SUPPORT 42 support: this.videoChannelValidatorsService.VIDEO_CHANNEL_SUPPORT
46 }) 43 })
47 44
48 this.paramsSub = this.route.params.subscribe(routeParams => { 45 this.paramsSub = this.route.params.subscribe(routeParams => {
diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts
index 44552021f..9992b9c44 100644
--- a/client/src/app/app.module.ts
+++ b/client/src/app/app.module.ts
@@ -17,6 +17,7 @@ import { SharedModule } from './shared'
17import { SignupModule } from './signup' 17import { SignupModule } from './signup'
18import { VideosModule } from './videos' 18import { VideosModule } from './videos'
19import { buildFileLocale, getDefaultLocale } from '../../../shared/models/i18n' 19import { buildFileLocale, getDefaultLocale } from '../../../shared/models/i18n'
20import { environment } from '../environments/environment'
20 21
21export function metaFactory (serverService: ServerService): MetaLoader { 22export function metaFactory (serverService: ServerService): MetaLoader {
22 return new MetaStaticLoader({ 23 return new MetaStaticLoader({
@@ -66,6 +67,11 @@ export function metaFactory (serverService: ServerService): MetaLoader {
66 { 67 {
67 provide: TRANSLATIONS, 68 provide: TRANSLATIONS,
68 useFactory: (locale) => { 69 useFactory: (locale) => {
70 // On dev mode, test locales
71 if (environment.production === false && window.location.search === '?lang=fr') {
72 return require(`raw-loader!../locale/target/messages_fr.xml`)
73 }
74
69 const fileLocale = buildFileLocale(locale) 75 const fileLocale = buildFileLocale(locale)
70 76
71 // Default locale, nothing to translate 77 // Default locale, nothing to translate
diff --git a/client/src/app/login/login.component.ts b/client/src/app/login/login.component.ts
index f7aad06e8..a91522db3 100644
--- a/client/src/app/login/login.component.ts
+++ b/client/src/app/login/login.component.ts
@@ -7,7 +7,7 @@ import { AuthService } from '../core'
7import { FormReactive } from '../shared' 7import { FormReactive } from '../shared'
8import { I18n } from '@ngx-translate/i18n-polyfill' 8import { I18n } from '@ngx-translate/i18n-polyfill'
9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
10import { LOGIN_PASSWORD, LOGIN_USERNAME } from '@app/shared/forms/form-validators/login' 10import { LoginValidatorsService } from '@app/shared/forms/form-validators/login-validators.service'
11 11
12@Component({ 12@Component({
13 selector: 'my-login', 13 selector: 'my-login',
@@ -24,6 +24,7 @@ export class LoginComponent extends FormReactive implements OnInit {
24 24
25 constructor ( 25 constructor (
26 protected formValidatorService: FormValidatorService, 26 protected formValidatorService: FormValidatorService,
27 private loginValidatorsService: LoginValidatorsService,
27 private authService: AuthService, 28 private authService: AuthService,
28 private userService: UserService, 29 private userService: UserService,
29 private serverService: ServerService, 30 private serverService: ServerService,
@@ -40,8 +41,8 @@ export class LoginComponent extends FormReactive implements OnInit {
40 41
41 ngOnInit () { 42 ngOnInit () {
42 this.buildForm({ 43 this.buildForm({
43 username: LOGIN_USERNAME, 44 username: this.loginValidatorsService.LOGIN_USERNAME,
44 password: LOGIN_PASSWORD 45 password: this.loginValidatorsService.LOGIN_PASSWORD
45 }) 46 })
46 } 47 }
47 48
diff --git a/client/src/app/reset-password/reset-password.component.ts b/client/src/app/reset-password/reset-password.component.ts
index 58e086f45..cb4a634f1 100644
--- a/client/src/app/reset-password/reset-password.component.ts
+++ b/client/src/app/reset-password/reset-password.component.ts
@@ -1,12 +1,12 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { USER_PASSWORD, UserService } from '@app/shared' 3import { UserService, UserValidatorsService } from '@app/shared'
4import { NotificationsService } from 'angular2-notifications' 4import { NotificationsService } from 'angular2-notifications'
5import { AuthService } from '../core' 5import { AuthService } from '../core'
6import { FormReactive } from '../shared' 6import { FormReactive } from '../shared'
7import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { RESET_PASSWORD_CONFIRM } from '@app/shared/forms/form-validators/reset-password'
9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 8import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
9import { ResetPasswordValidatorsService } from '@app/shared/forms/form-validators/reset-password-validators.service'
10 10
11@Component({ 11@Component({
12 selector: 'my-login', 12 selector: 'my-login',
@@ -20,6 +20,8 @@ export class ResetPasswordComponent extends FormReactive implements OnInit {
20 20
21 constructor ( 21 constructor (
22 protected formValidatorService: FormValidatorService, 22 protected formValidatorService: FormValidatorService,
23 private resetPasswordValidatorsService: ResetPasswordValidatorsService,
24 private userValidatorsService: UserValidatorsService,
23 private authService: AuthService, 25 private authService: AuthService,
24 private userService: UserService, 26 private userService: UserService,
25 private notificationsService: NotificationsService, 27 private notificationsService: NotificationsService,
@@ -32,8 +34,8 @@ export class ResetPasswordComponent extends FormReactive implements OnInit {
32 34
33 ngOnInit () { 35 ngOnInit () {
34 this.buildForm({ 36 this.buildForm({
35 password: USER_PASSWORD, 37 password: this.userValidatorsService.USER_PASSWORD,
36 'password-confirm': RESET_PASSWORD_CONFIRM 38 'password-confirm': this.resetPasswordValidatorsService.RESET_PASSWORD_CONFIRM
37 }) 39 })
38 40
39 this.userId = this.route.snapshot.queryParams['userId'] 41 this.userId = this.route.snapshot.queryParams['userId']
diff --git a/client/src/app/shared/forms/form-validators/custom-config-validators.service.ts b/client/src/app/shared/forms/form-validators/custom-config-validators.service.ts
new file mode 100644
index 000000000..1b36bbc6b
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/custom-config-validators.service.ts
@@ -0,0 +1,72 @@
1import { Validators } from '@angular/forms'
2import { I18n } from '@ngx-translate/i18n-polyfill'
3import { BuildFormValidator } from '@app/shared'
4import { Injectable } from '@angular/core'
5
6@Injectable()
7export class CustomConfigValidatorsService {
8 readonly INSTANCE_NAME: BuildFormValidator
9 readonly INSTANCE_SHORT_DESCRIPTION: BuildFormValidator
10 readonly SERVICES_TWITTER_USERNAME: BuildFormValidator
11 readonly CACHE_PREVIEWS_SIZE: BuildFormValidator
12 readonly SIGNUP_LIMIT: BuildFormValidator
13 readonly ADMIN_EMAIL: BuildFormValidator
14 readonly TRANSCODING_THREADS: BuildFormValidator
15
16 constructor (private i18n: I18n) {
17 this.INSTANCE_NAME = {
18 VALIDATORS: [ Validators.required ],
19 MESSAGES: {
20 'required': this.i18n('Instance name is required.')
21 }
22 }
23
24 this.INSTANCE_SHORT_DESCRIPTION = {
25 VALIDATORS: [ Validators.max(250) ],
26 MESSAGES: {
27 'max': this.i18n('Short description should not be longer than 250 characters.')
28 }
29 }
30
31 this.SERVICES_TWITTER_USERNAME = {
32 VALIDATORS: [ Validators.required ],
33 MESSAGES: {
34 'required': this.i18n('Twitter username is required.')
35 }
36 }
37
38 this.CACHE_PREVIEWS_SIZE = {
39 VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ],
40 MESSAGES: {
41 'required': this.i18n('Previews cache size is required.'),
42 'min': this.i18n('Previews cache size must be greater than 1.'),
43 'pattern': this.i18n('Previews cache size must be a number.')
44 }
45 }
46
47 this.SIGNUP_LIMIT = {
48 VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ],
49 MESSAGES: {
50 'required': this.i18n('Signup limit is required.'),
51 'min': this.i18n('Signup limit must be greater than 1.'),
52 'pattern': this.i18n('Signup limit must be a number.')
53 }
54 }
55
56 this.ADMIN_EMAIL = {
57 VALIDATORS: [ Validators.required, Validators.email ],
58 MESSAGES: {
59 'required': this.i18n('Admin email is required.'),
60 'email': this.i18n('Admin email must be valid.')
61 }
62 }
63
64 this.TRANSCODING_THREADS = {
65 VALIDATORS: [ Validators.required, Validators.min(1) ],
66 MESSAGES: {
67 'required': this.i18n('Transcoding threads is required.'),
68 'min': this.i18n('Transcoding threads must be greater than 1.')
69 }
70 }
71 }
72}
diff --git a/client/src/app/shared/forms/form-validators/custom-config.ts b/client/src/app/shared/forms/form-validators/custom-config.ts
deleted file mode 100644
index e3d9a4c7b..000000000
--- a/client/src/app/shared/forms/form-validators/custom-config.ts
+++ /dev/null
@@ -1,56 +0,0 @@
1import { Validators } from '@angular/forms'
2
3export const INSTANCE_NAME = {
4 VALIDATORS: [ Validators.required ],
5 MESSAGES: {
6 'required': 'Instance name is required.'
7 }
8}
9
10export const INSTANCE_SHORT_DESCRIPTION = {
11 VALIDATORS: [ Validators.max(250) ],
12 MESSAGES: {
13 'max': 'Short description should not be longer than 250 characters.'
14 }
15}
16
17export const SERVICES_TWITTER_USERNAME = {
18 VALIDATORS: [ Validators.required ],
19 MESSAGES: {
20 'required': 'Twitter username is required.'
21 }
22}
23
24export const CACHE_PREVIEWS_SIZE = {
25 VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ],
26 MESSAGES: {
27 'required': 'Preview cache size is required.',
28 'min': 'Preview cache size must be greater than 1.',
29 'pattern': 'Preview cache size must be a number.'
30 }
31}
32
33export const SIGNUP_LIMIT = {
34 VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ],
35 MESSAGES: {
36 'required': 'Signup limit is required.',
37 'min': 'Signup limit must be greater than 1.',
38 'pattern': 'Preview cache size must be a number.'
39 }
40}
41
42export const ADMIN_EMAIL = {
43 VALIDATORS: [ Validators.required, Validators.email ],
44 MESSAGES: {
45 'required': 'Admin email is required.',
46 'email': 'Admin email must be valid.'
47 }
48}
49
50export const TRANSCODING_THREADS = {
51 VALIDATORS: [ Validators.required, Validators.min(1) ],
52 MESSAGES: {
53 'required': 'Transcoding threads is required.',
54 'min': 'Transcoding threads must be greater than 1.'
55 }
56}
diff --git a/client/src/app/shared/forms/form-validators/form-validator.service.ts b/client/src/app/shared/forms/form-validators/form-validator.service.ts
index 5c3d3e4bd..d10e17ca7 100644
--- a/client/src/app/shared/forms/form-validators/form-validator.service.ts
+++ b/client/src/app/shared/forms/form-validators/form-validator.service.ts
@@ -3,11 +3,12 @@ import { Injectable } from '@angular/core'
3import { FormReactiveErrors, FormReactiveValidationMessages } from '@app/shared/forms/form-reactive' 3import { FormReactiveErrors, FormReactiveValidationMessages } from '@app/shared/forms/form-reactive'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5 5
6export type BuildFormValidator = {
7 VALIDATORS: ValidatorFn[],
8 MESSAGES: { [ name: string ]: string }
9}
6export type BuildFormArgument = { 10export type BuildFormArgument = {
7 [ id: string ]: { 11 [ id: string ]: BuildFormValidator
8 VALIDATORS: ValidatorFn[],
9 MESSAGES: { [ name: string ]: string }
10 }
11} 12}
12export type BuildFormDefaultValues = { 13export type BuildFormDefaultValues = {
13 [ name: string ]: string | string[] 14 [ name: string ]: string | string[]
diff --git a/client/src/app/shared/forms/form-validators/index.ts b/client/src/app/shared/forms/form-validators/index.ts
index cf544b2a9..487683088 100644
--- a/client/src/app/shared/forms/form-validators/index.ts
+++ b/client/src/app/shared/forms/form-validators/index.ts
@@ -1,5 +1,10 @@
1export * from './custom-config-validators.service'
1export * from './form-validator.service' 2export * from './form-validator.service'
2export * from './host' 3export * from './host'
3export * from './user' 4export * from './login-validators.service'
4export * from './video-abuse' 5export * from './reset-password-validators.service'
5export * from './video' 6export * from './user-validators.service'
7export * from './video-abuse-validators.service'
8export * from './video-channel-validators.service'
9export * from './video-comment-validators.service'
10export * from './video-validators.service'
diff --git a/client/src/app/shared/forms/form-validators/login-validators.service.ts b/client/src/app/shared/forms/form-validators/login-validators.service.ts
new file mode 100644
index 000000000..9d68f830c
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/login-validators.service.ts
@@ -0,0 +1,30 @@
1import { I18n } from '@ngx-translate/i18n-polyfill'
2import { Validators } from '@angular/forms'
3import { Injectable } from '@angular/core'
4import { BuildFormValidator } from '@app/shared'
5
6@Injectable()
7export class LoginValidatorsService {
8 readonly LOGIN_USERNAME: BuildFormValidator
9 readonly LOGIN_PASSWORD: BuildFormValidator
10
11 constructor (private i18n: I18n) {
12 this.LOGIN_USERNAME = {
13 VALIDATORS: [
14 Validators.required
15 ],
16 MESSAGES: {
17 'required': this.i18n('Username is required.')
18 }
19 }
20
21 this.LOGIN_PASSWORD = {
22 VALIDATORS: [
23 Validators.required
24 ],
25 MESSAGES: {
26 'required': this.i18n('Password is required.')
27 }
28 }
29 }
30}
diff --git a/client/src/app/shared/forms/form-validators/login.ts b/client/src/app/shared/forms/form-validators/login.ts
deleted file mode 100644
index f37f8d285..000000000
--- a/client/src/app/shared/forms/form-validators/login.ts
+++ /dev/null
@@ -1,18 +0,0 @@
1import { Validators } from '@angular/forms'
2
3export const LOGIN_USERNAME = {
4 VALIDATORS: [
5 Validators.required
6 ],
7 MESSAGES: {
8 'required': 'Username is required.'
9 }
10}
11export const LOGIN_PASSWORD = {
12 VALIDATORS: [
13 Validators.required
14 ],
15 MESSAGES: {
16 'required': 'Password is required.'
17 }
18}
diff --git a/client/src/app/shared/forms/form-validators/reset-password-validators.service.ts b/client/src/app/shared/forms/form-validators/reset-password-validators.service.ts
new file mode 100644
index 000000000..df206254d
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/reset-password-validators.service.ts
@@ -0,0 +1,20 @@
1import { I18n } from '@ngx-translate/i18n-polyfill'
2import { Validators } from '@angular/forms'
3import { Injectable } from '@angular/core'
4import { BuildFormValidator } from '@app/shared'
5
6@Injectable()
7export class ResetPasswordValidatorsService {
8 readonly RESET_PASSWORD_CONFIRM: BuildFormValidator
9
10 constructor (private i18n: I18n) {
11 this.RESET_PASSWORD_CONFIRM = {
12 VALIDATORS: [
13 Validators.required
14 ],
15 MESSAGES: {
16 'required': this.i18n('Confirmation of the password is required.')
17 }
18 }
19 }
20}
diff --git a/client/src/app/shared/forms/form-validators/reset-password.ts b/client/src/app/shared/forms/form-validators/reset-password.ts
deleted file mode 100644
index 7dafdef9a..000000000
--- a/client/src/app/shared/forms/form-validators/reset-password.ts
+++ /dev/null
@@ -1,10 +0,0 @@
1import { Validators } from '@angular/forms'
2
3export const RESET_PASSWORD_CONFIRM = {
4 VALIDATORS: [
5 Validators.required
6 ],
7 MESSAGES: {
8 'required': 'Confirmation of the password is required.'
9 }
10}
diff --git a/client/src/app/shared/forms/form-validators/user-validators.service.ts b/client/src/app/shared/forms/form-validators/user-validators.service.ts
new file mode 100644
index 000000000..bb6ff2068
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/user-validators.service.ts
@@ -0,0 +1,93 @@
1import { I18n } from '@ngx-translate/i18n-polyfill'
2import { Validators } from '@angular/forms'
3import { BuildFormValidator } from '@app/shared'
4import { Injectable } from '@angular/core'
5
6@Injectable()
7export class UserValidatorsService {
8 readonly USER_USERNAME: BuildFormValidator
9 readonly USER_EMAIL: BuildFormValidator
10 readonly USER_PASSWORD: BuildFormValidator
11 readonly USER_VIDEO_QUOTA: BuildFormValidator
12 readonly USER_ROLE: BuildFormValidator
13 readonly USER_DISPLAY_NAME: BuildFormValidator
14 readonly USER_DESCRIPTION: BuildFormValidator
15
16 constructor (private i18n: I18n) {
17
18 this.USER_USERNAME = {
19 VALIDATORS: [
20 Validators.required,
21 Validators.minLength(3),
22 Validators.maxLength(20),
23 Validators.pattern(/^[a-z0-9._]+$/)
24 ],
25 MESSAGES: {
26 'required': this.i18n('Username is required.'),
27 'minlength': this.i18n('Username must be at least 3 characters long.'),
28 'maxlength': this.i18n('Username cannot be more than 20 characters long.'),
29 'pattern': this.i18n('Username should be only lowercase alphanumeric characters.')
30 }
31 }
32
33 this.USER_EMAIL = {
34 VALIDATORS: [ Validators.required, Validators.email ],
35 MESSAGES: {
36 'required': this.i18n('Email is required.'),
37 'email': this.i18n('Email must be valid.')
38 }
39 }
40
41 this.USER_PASSWORD = {
42 VALIDATORS: [
43 Validators.required,
44 Validators.minLength(6),
45 Validators.maxLength(255)
46 ],
47 MESSAGES: {
48 'required': this.i18n('Password is required.'),
49 'minlength': this.i18n('Password must be at least 6 characters long.'),
50 'maxlength': this.i18n('Password cannot be more than 255 characters long.')
51 }
52 }
53
54 this.USER_VIDEO_QUOTA = {
55 VALIDATORS: [ Validators.required, Validators.min(-1) ],
56 MESSAGES: {
57 'required': this.i18n('Video quota is required.'),
58 'min': this.i18n('Quota must be greater than -1.')
59 }
60 }
61
62 this.USER_ROLE = {
63 VALIDATORS: [ Validators.required ],
64 MESSAGES: {
65 'required': this.i18n('User role is required.')
66 }
67 }
68
69 this.USER_DISPLAY_NAME = {
70 VALIDATORS: [
71 Validators.required,
72 Validators.minLength(3),
73 Validators.maxLength(120)
74 ],
75 MESSAGES: {
76 'required': this.i18n('Display name is required.'),
77 'minlength': this.i18n('Display name must be at least 3 characters long.'),
78 'maxlength': this.i18n('Display name cannot be more than 120 characters long.')
79 }
80 }
81
82 this.USER_DESCRIPTION = {
83 VALIDATORS: [
84 Validators.minLength(3),
85 Validators.maxLength(250)
86 ],
87 MESSAGES: {
88 'minlength': this.i18n('Description must be at least 3 characters long.'),
89 'maxlength': this.i18n('Description cannot be more than 250 characters long.')
90 }
91 }
92 }
93}
diff --git a/client/src/app/shared/forms/form-validators/user.ts b/client/src/app/shared/forms/form-validators/user.ts
deleted file mode 100644
index 0973f1b00..000000000
--- a/client/src/app/shared/forms/form-validators/user.ts
+++ /dev/null
@@ -1,70 +0,0 @@
1import { Validators } from '@angular/forms'
2
3export const USER_USERNAME = {
4 VALIDATORS: [
5 Validators.required,
6 Validators.minLength(3),
7 Validators.maxLength(20),
8 Validators.pattern(/^[a-z0-9._]+$/)
9 ],
10 MESSAGES: {
11 'required': 'Username is required.',
12 'minlength': 'Username must be at least 3 characters long.',
13 'maxlength': 'Username cannot be more than 20 characters long.',
14 'pattern': 'Username should be only lowercase alphanumeric characters.'
15 }
16}
17export const USER_EMAIL = {
18 VALIDATORS: [ Validators.required, Validators.email ],
19 MESSAGES: {
20 'required': 'Email is required.',
21 'email': 'Email must be valid.'
22 }
23}
24export const USER_PASSWORD = {
25 VALIDATORS: [
26 Validators.required,
27 Validators.minLength(6),
28 Validators.maxLength(255)
29 ],
30 MESSAGES: {
31 'required': 'Password is required.',
32 'minlength': 'Password must be at least 6 characters long.',
33 'maxlength': 'Password cannot be more than 255 characters long.'
34 }
35}
36export const USER_VIDEO_QUOTA = {
37 VALIDATORS: [ Validators.required, Validators.min(-1) ],
38 MESSAGES: {
39 'required': 'Video quota is required.',
40 'min': 'Quota must be greater than -1.'
41 }
42}
43export const USER_ROLE = {
44 VALIDATORS: [ Validators.required ],
45 MESSAGES: {
46 'required': 'User role is required.'
47 }
48}
49export const USER_DISPLAY_NAME = {
50 VALIDATORS: [
51 Validators.required,
52 Validators.minLength(3),
53 Validators.maxLength(120)
54 ],
55 MESSAGES: {
56 'required': 'Display name is required.',
57 'minlength': 'Display name must be at least 3 characters long.',
58 'maxlength': 'Display name cannot be more than 120 characters long.'
59 }
60}
61export const USER_DESCRIPTION = {
62 VALIDATORS: [
63 Validators.minLength(3),
64 Validators.maxLength(250)
65 ],
66 MESSAGES: {
67 'minlength': 'Description must be at least 3 characters long.',
68 'maxlength': 'Description cannot be more than 250 characters long.'
69 }
70}
diff --git a/client/src/app/shared/forms/form-validators/validator-message.ts b/client/src/app/shared/forms/form-validators/validator-message.ts
deleted file mode 100644
index 5ce45833b..000000000
--- a/client/src/app/shared/forms/form-validators/validator-message.ts
+++ /dev/null
@@ -1,5 +0,0 @@
1export type ValidatorMessage = {
2 [ id: string ]: {
3 [ error: string ]: string
4 }
5}
diff --git a/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts b/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts
new file mode 100644
index 000000000..774e6a488
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts
@@ -0,0 +1,20 @@
1import { I18n } from '@ngx-translate/i18n-polyfill'
2import { Validators } from '@angular/forms'
3import { Injectable } from '@angular/core'
4import { BuildFormValidator } from '@app/shared'
5
6@Injectable()
7export class VideoAbuseValidatorsService {
8 readonly VIDEO_ABUSE_REASON: BuildFormValidator
9
10 constructor (private i18n: I18n) {
11 this.VIDEO_ABUSE_REASON = {
12 VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(300) ],
13 MESSAGES: {
14 'required': this.i18n('Report reason is required.'),
15 'minlength': this.i18n('Report reason must be at least 2 characters long.'),
16 'maxlength': this.i18n('Report reason cannot be more than 300 characters long.')
17 }
18 }
19 }
20}
diff --git a/client/src/app/shared/forms/form-validators/video-abuse.ts b/client/src/app/shared/forms/form-validators/video-abuse.ts
deleted file mode 100644
index 4b2a2b789..000000000
--- a/client/src/app/shared/forms/form-validators/video-abuse.ts
+++ /dev/null
@@ -1,10 +0,0 @@
1import { Validators } from '@angular/forms'
2
3export const VIDEO_ABUSE_REASON = {
4 VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(300) ],
5 MESSAGES: {
6 'required': 'Report reason is required.',
7 'minlength': 'Report reason must be at least 2 characters long.',
8 'maxlength': 'Report reason cannot be more than 300 characters long.'
9 }
10}
diff --git a/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts b/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts
new file mode 100644
index 000000000..28b063f89
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts
@@ -0,0 +1,48 @@
1import { I18n } from '@ngx-translate/i18n-polyfill'
2import { Validators } from '@angular/forms'
3import { Injectable } from '@angular/core'
4import { BuildFormValidator } from '@app/shared'
5
6@Injectable()
7export class VideoChannelValidatorsService {
8 readonly VIDEO_CHANNEL_DISPLAY_NAME: BuildFormValidator
9 readonly VIDEO_CHANNEL_DESCRIPTION: BuildFormValidator
10 readonly VIDEO_CHANNEL_SUPPORT: BuildFormValidator
11
12 constructor (private i18n: I18n) {
13 this.VIDEO_CHANNEL_DISPLAY_NAME = {
14 VALIDATORS: [
15 Validators.required,
16 Validators.minLength(3),
17 Validators.maxLength(120)
18 ],
19 MESSAGES: {
20 'required': i18n('Display name is required.'),
21 'minlength': i18n('Display name must be at least 3 characters long.'),
22 'maxlength': i18n('Display name cannot be more than 120 characters long.')
23 }
24 }
25
26 this.VIDEO_CHANNEL_DESCRIPTION = {
27 VALIDATORS: [
28 Validators.minLength(3),
29 Validators.maxLength(500)
30 ],
31 MESSAGES: {
32 'minlength': i18n('Description must be at least 3 characters long.'),
33 'maxlength': i18n('Description cannot be more than 500 characters long.')
34 }
35 }
36
37 this.VIDEO_CHANNEL_SUPPORT = {
38 VALIDATORS: [
39 Validators.minLength(3),
40 Validators.maxLength(500)
41 ],
42 MESSAGES: {
43 'minlength': i18n('Support text must be at least 3 characters long.'),
44 'maxlength': i18n('Support text cannot be more than 500 characters long.')
45 }
46 }
47 }
48}
diff --git a/client/src/app/shared/forms/form-validators/video-channel.ts b/client/src/app/shared/forms/form-validators/video-channel.ts
deleted file mode 100644
index 2185cdaa9..000000000
--- a/client/src/app/shared/forms/form-validators/video-channel.ts
+++ /dev/null
@@ -1,34 +0,0 @@
1import { Validators } from '@angular/forms'
2
3export const VIDEO_CHANNEL_DISPLAY_NAME = {
4 VALIDATORS: [
5 Validators.required,
6 Validators.minLength(3),
7 Validators.maxLength(120)
8 ],
9 MESSAGES: {
10 'required': 'Display name is required.',
11 'minlength': 'Display name must be at least 3 characters long.',
12 'maxlength': 'Display name cannot be more than 120 characters long.'
13 }
14}
15export const VIDEO_CHANNEL_DESCRIPTION = {
16 VALIDATORS: [
17 Validators.minLength(3),
18 Validators.maxLength(500)
19 ],
20 MESSAGES: {
21 'minlength': 'Description must be at least 3 characters long.',
22 'maxlength': 'Description cannot be more than 500 characters long.'
23 }
24}
25export const VIDEO_CHANNEL_SUPPORT = {
26 VALIDATORS: [
27 Validators.minLength(3),
28 Validators.maxLength(500)
29 ],
30 MESSAGES: {
31 'minlength': 'Support text must be at least 3 characters long.',
32 'maxlength': 'Support text cannot be more than 500 characters long.'
33 }
34}
diff --git a/client/src/app/shared/forms/form-validators/video-comment-validators.service.ts b/client/src/app/shared/forms/form-validators/video-comment-validators.service.ts
new file mode 100644
index 000000000..45c7081ef
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/video-comment-validators.service.ts
@@ -0,0 +1,20 @@
1import { I18n } from '@ngx-translate/i18n-polyfill'
2import { Validators } from '@angular/forms'
3import { Injectable } from '@angular/core'
4import { BuildFormValidator } from '@app/shared'
5
6@Injectable()
7export class VideoCommentValidatorsService {
8 readonly VIDEO_COMMENT_TEXT: BuildFormValidator
9
10 constructor (private i18n: I18n) {
11 this.VIDEO_COMMENT_TEXT = {
12 VALIDATORS: [ Validators.required, Validators.minLength(1), Validators.maxLength(3000) ],
13 MESSAGES: {
14 'required': this.i18n('Comment is required.'),
15 'minlength': this.i18n('Comment must be at least 2 characters long.'),
16 'maxlength': this.i18n('Comment cannot be more than 3000 characters long.')
17 }
18 }
19 }
20}
diff --git a/client/src/app/shared/forms/form-validators/video-comment.ts b/client/src/app/shared/forms/form-validators/video-comment.ts
deleted file mode 100644
index 290d83195..000000000
--- a/client/src/app/shared/forms/form-validators/video-comment.ts
+++ /dev/null
@@ -1,10 +0,0 @@
1import { Validators } from '@angular/forms'
2
3export const VIDEO_COMMENT_TEXT = {
4 VALIDATORS: [ Validators.required, Validators.minLength(1), Validators.maxLength(3000) ],
5 MESSAGES: {
6 'required': 'Comment is required.',
7 'minlength': 'Comment must be at least 2 characters long.',
8 'maxlength': 'Comment cannot be more than 3000 characters long.'
9 }
10}
diff --git a/client/src/app/shared/forms/form-validators/video-validators.service.ts b/client/src/app/shared/forms/form-validators/video-validators.service.ts
new file mode 100644
index 000000000..76fc5cf04
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/video-validators.service.ts
@@ -0,0 +1,88 @@
1import { I18n } from '@ngx-translate/i18n-polyfill'
2import { Validators } from '@angular/forms'
3import { Injectable } from '@angular/core'
4import { BuildFormValidator } from '@app/shared'
5
6@Injectable()
7export class VideoValidatorsService {
8 readonly VIDEO_NAME: BuildFormValidator
9 readonly VIDEO_PRIVACY: BuildFormValidator
10 readonly VIDEO_CATEGORY: BuildFormValidator
11 readonly VIDEO_LICENCE: BuildFormValidator
12 readonly VIDEO_LANGUAGE: BuildFormValidator
13 readonly VIDEO_IMAGE: BuildFormValidator
14 readonly VIDEO_CHANNEL: BuildFormValidator
15 readonly VIDEO_DESCRIPTION: BuildFormValidator
16 readonly VIDEO_TAGS: BuildFormValidator
17 readonly VIDEO_SUPPORT: BuildFormValidator
18
19 constructor (private i18n: I18n) {
20
21 this.VIDEO_NAME = {
22 VALIDATORS: [ Validators.required, Validators.minLength(3), Validators.maxLength(120) ],
23 MESSAGES: {
24 'required': this.i18n('Video name is required.'),
25 'minlength': this.i18n('Video name must be at least 3 characters long.'),
26 'maxlength': this.i18n('Video name cannot be more than 120 characters long.')
27 }
28 }
29
30 this.VIDEO_PRIVACY = {
31 VALIDATORS: [ Validators.required ],
32 MESSAGES: {
33 'required': this.i18n('Video privacy is required.')
34 }
35 }
36
37 this.VIDEO_CATEGORY = {
38 VALIDATORS: [ ],
39 MESSAGES: {}
40 }
41
42 this.VIDEO_LICENCE = {
43 VALIDATORS: [ ],
44 MESSAGES: {}
45 }
46
47 this.VIDEO_LANGUAGE = {
48 VALIDATORS: [ ],
49 MESSAGES: {}
50 }
51
52 this.VIDEO_IMAGE = {
53 VALIDATORS: [ ],
54 MESSAGES: {}
55 }
56
57 this.VIDEO_CHANNEL = {
58 VALIDATORS: [ Validators.required ],
59 MESSAGES: {
60 'required': this.i18n('Video channel is required.')
61 }
62 }
63
64 this.VIDEO_DESCRIPTION = {
65 VALIDATORS: [ Validators.minLength(3), Validators.maxLength(10000) ],
66 MESSAGES: {
67 'minlength': this.i18n('Video description must be at least 3 characters long.'),
68 'maxlength': this.i18n('Video description cannot be more than 10000 characters long.')
69 }
70 }
71
72 this.VIDEO_TAGS = {
73 VALIDATORS: [ Validators.minLength(2), Validators.maxLength(30) ],
74 MESSAGES: {
75 'minlength': this.i18n('A tag should be more than 2 characters long.'),
76 'maxlength': this.i18n('A tag should be less than 30 characters long.')
77 }
78 }
79
80 this.VIDEO_SUPPORT = {
81 VALIDATORS: [ Validators.minLength(3), Validators.maxLength(500) ],
82 MESSAGES: {
83 'minlength': this.i18n('Video support must be at least 3 characters long.'),
84 'maxlength': this.i18n('Video support cannot be more than 500 characters long.')
85 }
86 }
87 }
88}
diff --git a/client/src/app/shared/forms/form-validators/video.ts b/client/src/app/shared/forms/form-validators/video.ts
deleted file mode 100644
index a986243df..000000000
--- a/client/src/app/shared/forms/form-validators/video.ts
+++ /dev/null
@@ -1,68 +0,0 @@
1import { Validators } from '@angular/forms'
2
3export const VIDEO_NAME = {
4 VALIDATORS: [ Validators.required, Validators.minLength(3), Validators.maxLength(120) ],
5 MESSAGES: {
6 'required': 'Video name is required.',
7 'minlength': 'Video name must be at least 3 characters long.',
8 'maxlength': 'Video name cannot be more than 120 characters long.'
9 }
10}
11
12export const VIDEO_PRIVACY = {
13 VALIDATORS: [ Validators.required ],
14 MESSAGES: {
15 'required': 'Video privacy is required.'
16 }
17}
18
19export const VIDEO_CATEGORY = {
20 VALIDATORS: [ ],
21 MESSAGES: {}
22}
23
24export const VIDEO_LICENCE = {
25 VALIDATORS: [ ],
26 MESSAGES: {}
27}
28
29export const VIDEO_LANGUAGE = {
30 VALIDATORS: [ ],
31 MESSAGES: {}
32}
33
34export const VIDEO_IMAGE = {
35 VALIDATORS: [ ],
36 MESSAGES: {}
37}
38
39export const VIDEO_CHANNEL = {
40 VALIDATORS: [ Validators.required ],
41 MESSAGES: {
42 'required': 'Video channel is required.'
43 }
44}
45
46export const VIDEO_DESCRIPTION = {
47 VALIDATORS: [ Validators.minLength(3), Validators.maxLength(10000) ],
48 MESSAGES: {
49 'minlength': 'Video description must be at least 3 characters long.',
50 'maxlength': 'Video description cannot be more than 10000 characters long.'
51 }
52}
53
54export const VIDEO_TAGS = {
55 VALIDATORS: [ Validators.minLength(2), Validators.maxLength(30) ],
56 MESSAGES: {
57 'minlength': 'A tag should be more than 2 characters long.',
58 'maxlength': 'A tag should be less than 30 characters long.'
59 }
60}
61
62export const VIDEO_SUPPORT = {
63 VALIDATORS: [ Validators.minLength(3), Validators.maxLength(500) ],
64 MESSAGES: {
65 'minlength': 'Video support must be at least 3 characters long.',
66 'maxlength': 'Video support cannot be more than 500 characters long.'
67 }
68}
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts
index 91d905ec7..b85445ef5 100644
--- a/client/src/app/shared/shared.module.ts
+++ b/client/src/app/shared/shared.module.ts
@@ -35,6 +35,12 @@ import { AccountService } from '@app/shared/account/account.service'
35import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 35import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
36import { I18n } from '@ngx-translate/i18n-polyfill' 36import { I18n } from '@ngx-translate/i18n-polyfill'
37import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 37import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
38import {
39 CustomConfigValidatorsService,
40 LoginValidatorsService,
41 ResetPasswordValidatorsService,
42 UserValidatorsService, VideoAbuseValidatorsService, VideoChannelValidatorsService, VideoCommentValidatorsService, VideoValidatorsService
43} from '@app/shared/forms'
38 44
39@NgModule({ 45@NgModule({
40 imports: [ 46 imports: [
@@ -111,7 +117,17 @@ import { FormValidatorService } from '@app/shared/forms/form-validators/form-val
111 AccountService, 117 AccountService,
112 MarkdownService, 118 MarkdownService,
113 VideoChannelService, 119 VideoChannelService,
120
114 FormValidatorService, 121 FormValidatorService,
122 CustomConfigValidatorsService,
123 LoginValidatorsService,
124 ResetPasswordValidatorsService,
125 UserValidatorsService,
126 VideoAbuseValidatorsService,
127 VideoChannelValidatorsService,
128 VideoCommentValidatorsService,
129 VideoValidatorsService,
130
115 I18n 131 I18n
116 ] 132 ]
117}) 133})
diff --git a/client/src/app/signup/signup.component.ts b/client/src/app/signup/signup.component.ts
index 682e592c7..a40f42cb1 100644
--- a/client/src/app/signup/signup.component.ts
+++ b/client/src/app/signup/signup.component.ts
@@ -1,10 +1,9 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { Router } from '@angular/router' 2import { Router } from '@angular/router'
3import { ServerService } from '@app/core/server' 3import { ServerService } from '@app/core/server'
4
5import { NotificationsService } from 'angular2-notifications' 4import { NotificationsService } from 'angular2-notifications'
6import { UserCreate } from '../../../../shared' 5import { UserCreate } from '../../../../shared'
7import { FormReactive, USER_EMAIL, USER_PASSWORD, USER_USERNAME, UserService } from '../shared' 6import { FormReactive, UserService, UserValidatorsService } from '../shared'
8import { RedirectService } from '@app/core' 7import { RedirectService } from '@app/core'
9import { I18n } from '@ngx-translate/i18n-polyfill' 8import { I18n } from '@ngx-translate/i18n-polyfill'
10import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
@@ -32,6 +31,7 @@ export class SignupComponent extends FormReactive implements OnInit {
32 31
33 constructor ( 32 constructor (
34 protected formValidatorService: FormValidatorService, 33 protected formValidatorService: FormValidatorService,
34 private userValidatorsService: UserValidatorsService,
35 private router: Router, 35 private router: Router,
36 private notificationsService: NotificationsService, 36 private notificationsService: NotificationsService,
37 private userService: UserService, 37 private userService: UserService,
@@ -48,9 +48,9 @@ export class SignupComponent extends FormReactive implements OnInit {
48 48
49 ngOnInit () { 49 ngOnInit () {
50 this.buildForm({ 50 this.buildForm({
51 username: USER_USERNAME, 51 username: this.userValidatorsService.USER_USERNAME,
52 password: USER_PASSWORD, 52 password: this.userValidatorsService.USER_PASSWORD,
53 email: USER_EMAIL 53 email: this.userValidatorsService.USER_EMAIL
54 }) 54 })
55 55
56 this.serverService.configLoaded 56 this.serverService.configLoaded
diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.ts b/client/src/app/videos/+video-edit/shared/video-edit.component.ts
index cd2a26ae3..61515c0b0 100644
--- a/client/src/app/videos/+video-edit/shared/video-edit.component.ts
+++ b/client/src/app/videos/+video-edit/shared/video-edit.component.ts
@@ -1,20 +1,9 @@
1import { Component, Input, OnInit } from '@angular/core' 1import { Component, Input, OnInit } from '@angular/core'
2import { FormGroup } from '@angular/forms' 2import { FormGroup, ValidatorFn } from '@angular/forms'
3import { ActivatedRoute, Router } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
4import { VIDEO_SUPPORT } from '@app/shared' 4import { FormReactiveValidationMessages, VideoValidatorsService } from '@app/shared'
5import { NotificationsService } from 'angular2-notifications' 5import { NotificationsService } from 'angular2-notifications'
6import { ServerService } from '../../../core/server' 6import { ServerService } from '../../../core/server'
7import { VIDEO_CHANNEL } from '../../../shared/forms/form-validators'
8import { ValidatorMessage } from '../../../shared/forms/form-validators/validator-message'
9import {
10 VIDEO_CATEGORY,
11 VIDEO_DESCRIPTION,
12 VIDEO_LANGUAGE,
13 VIDEO_LICENCE,
14 VIDEO_NAME,
15 VIDEO_PRIVACY,
16 VIDEO_TAGS
17} from '../../../shared/forms/form-validators/video'
18import { VideoEdit } from '../../../shared/video/video-edit.model' 7import { VideoEdit } from '../../../shared/video/video-edit.model'
19import { map } from 'rxjs/operators' 8import { map } from 'rxjs/operators'
20import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
@@ -28,7 +17,7 @@ import { FormValidatorService } from '@app/shared/forms/form-validators/form-val
28export class VideoEditComponent implements OnInit { 17export class VideoEditComponent implements OnInit {
29 @Input() form: FormGroup 18 @Input() form: FormGroup
30 @Input() formErrors: { [ id: string ]: string } = {} 19 @Input() formErrors: { [ id: string ]: string } = {}
31 @Input() validationMessages: ValidatorMessage = {} 20 @Input() validationMessages: FormReactiveValidationMessages = {}
32 @Input() videoPrivacies = [] 21 @Input() videoPrivacies = []
33 @Input() userVideoChannels: { id: number, label: string, support: string }[] = [] 22 @Input() userVideoChannels: { id: number, label: string, support: string }[] = []
34 23
@@ -37,18 +26,22 @@ export class VideoEditComponent implements OnInit {
37 videoLanguages = [] 26 videoLanguages = []
38 video: VideoEdit 27 video: VideoEdit
39 28
40 tagValidators = VIDEO_TAGS.VALIDATORS 29 tagValidators: ValidatorFn[]
41 tagValidatorsMessages = VIDEO_TAGS.MESSAGES 30 tagValidatorsMessages: { [ name: string ]: string }
42 31
43 error: string = null 32 error: string = null
44 33
45 constructor ( 34 constructor (
46 private formValidatorService: FormValidatorService, 35 private formValidatorService: FormValidatorService,
36 private videoValidatorsService: VideoValidatorsService,
47 private route: ActivatedRoute, 37 private route: ActivatedRoute,
48 private router: Router, 38 private router: Router,
49 private notificationsService: NotificationsService, 39 private notificationsService: NotificationsService,
50 private serverService: ServerService 40 private serverService: ServerService
51 ) { } 41 ) {
42 this.tagValidators = this.videoValidatorsService.VIDEO_TAGS.VALIDATORS
43 this.tagValidatorsMessages = this.videoValidatorsService.VIDEO_TAGS.MESSAGES
44 }
52 45
53 updateForm () { 46 updateForm () {
54 const defaultValues = { 47 const defaultValues = {
@@ -57,19 +50,19 @@ export class VideoEditComponent implements OnInit {
57 tags: [] 50 tags: []
58 } 51 }
59 const obj = { 52 const obj = {
60 name: VIDEO_NAME, 53 name: this.videoValidatorsService.VIDEO_NAME,
61 privacy: VIDEO_PRIVACY, 54 privacy: this.videoValidatorsService.VIDEO_PRIVACY,
62 channelId: VIDEO_CHANNEL, 55 channelId: this.videoValidatorsService.VIDEO_CHANNEL,
63 nsfw: null, 56 nsfw: null,
64 commentsEnabled: null, 57 commentsEnabled: null,
65 category: VIDEO_CATEGORY, 58 category: this.videoValidatorsService.VIDEO_CATEGORY,
66 licence: VIDEO_LICENCE, 59 licence: this.videoValidatorsService.VIDEO_LICENCE,
67 language: VIDEO_LANGUAGE, 60 language: this.videoValidatorsService.VIDEO_LANGUAGE,
68 description: VIDEO_DESCRIPTION, 61 description: this.videoValidatorsService.VIDEO_DESCRIPTION,
69 tags: null, 62 tags: null,
70 thumbnailfile: null, 63 thumbnailfile: null,
71 previewfile: null, 64 previewfile: null,
72 support: VIDEO_SUPPORT 65 support: this.videoValidatorsService.VIDEO_SUPPORT
73 } 66 }
74 67
75 this.formValidatorService.updateForm( 68 this.formValidatorService.updateForm(
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
index c70e544a3..46d7a4e9e 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
@@ -3,13 +3,13 @@ import { NotificationsService } from 'angular2-notifications'
3import { Observable } from 'rxjs' 3import { Observable } from 'rxjs'
4import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model' 4import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model'
5import { FormReactive } from '../../../shared' 5import { FormReactive } from '../../../shared'
6import { VIDEO_COMMENT_TEXT } from '../../../shared/forms/form-validators/video-comment'
7import { User } from '../../../shared/users' 6import { User } from '../../../shared/users'
8import { Video } from '../../../shared/video/video.model' 7import { Video } from '../../../shared/video/video.model'
9import { VideoComment } from './video-comment.model' 8import { VideoComment } from './video-comment.model'
10import { VideoCommentService } from './video-comment.service' 9import { VideoCommentService } from './video-comment.service'
11import { I18n } from '@ngx-translate/i18n-polyfill' 10import { I18n } from '@ngx-translate/i18n-polyfill'
12import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 11import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
12import { VideoCommentValidatorsService } from '@app/shared/forms/form-validators/video-comment-validators.service'
13 13
14@Component({ 14@Component({
15 selector: 'my-video-comment-add', 15 selector: 'my-video-comment-add',
@@ -29,6 +29,7 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
29 29
30 constructor ( 30 constructor (
31 protected formValidatorService: FormValidatorService, 31 protected formValidatorService: FormValidatorService,
32 private videoCommentValidatorsService: VideoCommentValidatorsService,
32 private notificationsService: NotificationsService, 33 private notificationsService: NotificationsService,
33 private videoCommentService: VideoCommentService, 34 private videoCommentService: VideoCommentService,
34 private i18n: I18n 35 private i18n: I18n
@@ -38,7 +39,7 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
38 39
39 ngOnInit () { 40 ngOnInit () {
40 this.buildForm({ 41 this.buildForm({
41 text: VIDEO_COMMENT_TEXT 42 text: this.videoCommentValidatorsService.VIDEO_COMMENT_TEXT
42 }) 43 })
43 44
44 if (this.focusOnInit === true) { 45 if (this.focusOnInit === true) {
diff --git a/client/src/app/videos/+video-watch/modal/video-report.component.ts b/client/src/app/videos/+video-watch/modal/video-report.component.ts
index 8641e8dfb..d9768fdac 100644
--- a/client/src/app/videos/+video-watch/modal/video-report.component.ts
+++ b/client/src/app/videos/+video-watch/modal/video-report.component.ts
@@ -1,12 +1,11 @@
1import { Component, Input, OnInit, ViewChild } from '@angular/core' 1import { Component, Input, OnInit, ViewChild } from '@angular/core'
2import { FormBuilder, FormGroup } from '@angular/forms'
3import { NotificationsService } from 'angular2-notifications' 2import { NotificationsService } from 'angular2-notifications'
4import { ModalDirective } from 'ngx-bootstrap/modal' 3import { ModalDirective } from 'ngx-bootstrap/modal'
5import { FormReactive, VIDEO_ABUSE_REASON, VideoAbuseService } from '../../../shared/index' 4import { FormReactive, VideoAbuseService } from '../../../shared/index'
6import { VideoDetails } from '../../../shared/video/video-details.model' 5import { VideoDetails } from '../../../shared/video/video-details.model'
7import { I18n } from '@ngx-translate/i18n-polyfill' 6import { I18n } from '@ngx-translate/i18n-polyfill'
8import { FormReactiveErrors, FormReactiveValidationMessages } from '@app/shared'
9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 7import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
8import { VideoAbuseValidatorsService } from '@app/shared/forms/form-validators/video-abuse-validators.service'
10 9
11@Component({ 10@Component({
12 selector: 'my-video-report', 11 selector: 'my-video-report',
@@ -22,6 +21,7 @@ export class VideoReportComponent extends FormReactive implements OnInit {
22 21
23 constructor ( 22 constructor (
24 protected formValidatorService: FormValidatorService, 23 protected formValidatorService: FormValidatorService,
24 private videoAbuseValidatorsService: VideoAbuseValidatorsService,
25 private videoAbuseService: VideoAbuseService, 25 private videoAbuseService: VideoAbuseService,
26 private notificationsService: NotificationsService, 26 private notificationsService: NotificationsService,
27 private i18n: I18n 27 private i18n: I18n
@@ -31,7 +31,7 @@ export class VideoReportComponent extends FormReactive implements OnInit {
31 31
32 ngOnInit () { 32 ngOnInit () {
33 this.buildForm({ 33 this.buildForm({
34 reason: VIDEO_ABUSE_REASON 34 reason: this.videoAbuseValidatorsService.VIDEO_ABUSE_REASON
35 }) 35 })
36 } 36 }
37 37
diff --git a/client/src/locale/source/messages_en_US.xml b/client/src/locale/source/messages_en_US.xml
index 9ac231954..08949c564 100644
--- a/client/src/locale/source/messages_en_US.xml
+++ b/client/src/locale/source/messages_en_US.xml
@@ -306,7 +306,7 @@
306 </context-group> 306 </context-group>
307 <context-group purpose="location"> 307 <context-group purpose="location">
308 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts</context> 308 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts</context>
309 <context context-type="linenumber">14</context> 309 <context context-type="linenumber">17</context>
310 </context-group> 310 </context-group>
311 <context-group purpose="location"> 311 <context-group purpose="location">
312 <context context-type="sourcefile">app/+video-channels/video-channel-about/video-channel-about.component.ts</context> 312 <context context-type="sourcefile">app/+video-channels/video-channel-about/video-channel-about.component.ts</context>
@@ -739,8 +739,8 @@ Check this checkbox, save the configuration and test with a video URL of your in
739 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context> 739 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context>
740 <context context-type="linenumber">207</context> 740 <context context-type="linenumber">207</context>
741 </context-group> 741 </context-group>
742 </trans-unit><trans-unit id="48c189b718ed2d091e5c515bfc14b03e5ceb4f93" datatype="html"> 742 </trans-unit><trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7" datatype="html">
743 <source>Preview cache size</source> 743 <source>Previews cache size</source>
744 <context-group purpose="location"> 744 <context-group purpose="location">
745 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context> 745 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context>
746 <context context-type="linenumber">210</context> 746 <context context-type="linenumber">210</context>
@@ -1239,7 +1239,7 @@ Check this checkbox, save the configuration and test with a video URL of your in
1239 </context-group> 1239 </context-group>
1240 <context-group purpose="location"> 1240 <context-group purpose="location">
1241 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts</context> 1241 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts</context>
1242 <context context-type="linenumber">5</context> 1242 <context context-type="linenumber">6</context>
1243 </context-group> 1243 </context-group>
1244 </trans-unit><trans-unit id="74728de5289ea2ff3f553bc2b48f1811680b931a" datatype="html"> 1244 </trans-unit><trans-unit id="74728de5289ea2ff3f553bc2b48f1811680b931a" datatype="html">
1245 <source>Short text to tell people how they can support your channel (membership platform...).&lt;br /&gt;&lt;br /&gt; 1245 <source>Short text to tell people how they can support your channel (membership platform...).&lt;br /&gt;&lt;br /&gt;
@@ -1296,7 +1296,7 @@ When you will upload a video in this channel, the video support field will be au
1296 <source>Update my profile</source> 1296 <source>Update my profile</source>
1297 <context-group purpose="location"> 1297 <context-group purpose="location">
1298 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts</context> 1298 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts</context>
1299 <context context-type="linenumber">23</context> 1299 <context context-type="linenumber">27</context>
1300 </context-group> 1300 </context-group>
1301 </trans-unit><trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd" datatype="html"> 1301 </trans-unit><trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd" datatype="html">
1302 <source> 1302 <source>
@@ -1851,8 +1851,8 @@ When you will upload a video in this channel, the video support field will be au
1851 <context context-type="linenumber">1</context> 1851 <context context-type="linenumber">1</context>
1852 </context-group> 1852 </context-group>
1853 </trans-unit> 1853 </trans-unit>
1854 <trans-unit id="b0ea97653991a80d6324423949d37b8f165a4505" datatype="html"> 1854 <trans-unit id="369ef5e9c0dd1251abdbf699a5db408bca10777f" datatype="html">
1855 <source>Published &lt;x id="INTERPOLATION" equiv-text="{{ totalVideos }}"/&gt; videos</source> 1855 <source>Published &lt;x id="INTERPOLATION" equiv-text="{{totalVideos}}"/&gt; videos</source>
1856 <context-group purpose="location"> 1856 <context-group purpose="location">
1857 <context context-type="sourcefile">src/app/+accounts/account-videos/account-videos.component.ts</context> 1857 <context context-type="sourcefile">src/app/+accounts/account-videos/account-videos.component.ts</context>
1858 <context context-type="linenumber">1</context> 1858 <context context-type="linenumber">1</context>
@@ -2009,8 +2009,8 @@ When you will upload a video in this channel, the video support field will be au
2009 <context context-type="linenumber">1</context> 2009 <context context-type="linenumber">1</context>
2010 </context-group> 2010 </context-group>
2011 </trans-unit> 2011 </trans-unit>
2012 <trans-unit id="6b988bab9e171f65ed3510e8a66b9c5f7fcc5209" datatype="html"> 2012 <trans-unit id="27a71a0aee65258179e90ecf0841c0a68f95beed" datatype="html">
2013 <source>You set custom &lt;x id="INTERPOLATION" equiv-text="{{ customizationsText }}"/&gt;. </source> 2013 <source>You set custom &lt;x id="INTERPOLATION" equiv-text="{{customizationsText}}"/&gt;. </source>
2014 <context-group purpose="location"> 2014 <context-group purpose="location">
2015 <context context-type="sourcefile">src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context> 2015 <context context-type="sourcefile">src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context>
2016 <context context-type="linenumber">1</context> 2016 <context context-type="linenumber">1</context>
@@ -2030,15 +2030,15 @@ When you will upload a video in this channel, the video support field will be au
2030 <context context-type="linenumber">1</context> 2030 <context context-type="linenumber">1</context>
2031 </context-group> 2031 </context-group>
2032 </trans-unit> 2032 </trans-unit>
2033 <trans-unit id="03b6bae23e3f895ed8f53e3b29fad0cafc7dd002" datatype="html"> 2033 <trans-unit id="1ae0ab69f5c19d179282c8d882fd2f3c00e29119" datatype="html">
2034 <source>Please type &quot;I understand the &lt;x id="INTERPOLATION" equiv-text="{{ customizationsText }}"/&gt; I set&quot; to confirm.</source> 2034 <source>Please type</source>
2035 <context-group purpose="location"> 2035 <context-group purpose="location">
2036 <context context-type="sourcefile">src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context> 2036 <context context-type="sourcefile">src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context>
2037 <context context-type="linenumber">1</context> 2037 <context context-type="linenumber">1</context>
2038 </context-group> 2038 </context-group>
2039 </trans-unit> 2039 </trans-unit>
2040 <trans-unit id="892eb3bbce40125f9ed1dc13078d2938b921ff53" datatype="html"> 2040 <trans-unit id="75f4bb68ee4c6b282abfd9d8d32be22c6202794d" datatype="html">
2041 <source>I understand the &lt;x id="INTERPOLATION" equiv-text="{{ customizationsText }}"/&gt; I set</source> 2041 <source>to confirm.</source>
2042 <context-group purpose="location"> 2042 <context-group purpose="location">
2043 <context context-type="sourcefile">src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context> 2043 <context context-type="sourcefile">src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context>
2044 <context context-type="linenumber">1</context> 2044 <context context-type="linenumber">1</context>
@@ -2146,8 +2146,8 @@ When you will upload a video in this channel, the video support field will be au
2146 <context context-type="linenumber">1</context> 2146 <context context-type="linenumber">1</context>
2147 </context-group> 2147 </context-group>
2148 </trans-unit> 2148 </trans-unit>
2149 <trans-unit id="511be2e1ddb087fe7a0d95654f5f72b446d3da87" datatype="html"> 2149 <trans-unit id="fc5731a28a99b25c62d43333ceebb250d60aff84" datatype="html">
2150 <source>&lt;x id="INTERPOLATION" equiv-text="{{ host }}"/&gt; is not valid</source> 2150 <source>&lt;x id="INTERPOLATION" equiv-text="{{host}}"/&gt; is not valid</source>
2151 <context-group purpose="location"> 2151 <context-group purpose="location">
2152 <context context-type="sourcefile">src/app/+admin/follows/following-add/following-add.component.ts</context> 2152 <context context-type="sourcefile">src/app/+admin/follows/following-add/following-add.component.ts</context>
2153 <context context-type="linenumber">1</context> 2153 <context context-type="linenumber">1</context>
@@ -2188,8 +2188,8 @@ When you will upload a video in this channel, the video support field will be au
2188 <context context-type="linenumber">1</context> 2188 <context context-type="linenumber">1</context>
2189 </context-group> 2189 </context-group>
2190 </trans-unit> 2190 </trans-unit>
2191 <trans-unit id="b1f6b95a2d83bc589955f2679de00ce70fa03594" datatype="html"> 2191 <trans-unit id="5729c34a858c78daa1aa606f62a3665527cf97e6" datatype="html">
2192 <source>Do you really want to unfollow &lt;x id="INTERPOLATION" equiv-text="{{ host }}"/&gt;?</source> 2192 <source>Do you really want to unfollow &lt;x id="INTERPOLATION" equiv-text="{{host}}"/&gt;?</source>
2193 <context-group purpose="location"> 2193 <context-group purpose="location">
2194 <context context-type="sourcefile">src/app/+admin/follows/following-list/following-list.component.ts</context> 2194 <context context-type="sourcefile">src/app/+admin/follows/following-list/following-list.component.ts</context>
2195 <context context-type="linenumber">1</context> 2195 <context context-type="linenumber">1</context>
@@ -2202,22 +2202,22 @@ When you will upload a video in this channel, the video support field will be au
2202 <context context-type="linenumber">1</context> 2202 <context context-type="linenumber">1</context>
2203 </context-group> 2203 </context-group>
2204 </trans-unit> 2204 </trans-unit>
2205 <trans-unit id="c02051988cf0b04bc8bea7602c909c4835ed770f" datatype="html"> 2205 <trans-unit id="fb4e35e2b0ea2abc1f71295a4b34830e57c07bd0" datatype="html">
2206 <source>You are not following &lt;x id="INTERPOLATION" equiv-text="{{ host }}"/&gt; anymore.</source> 2206 <source>You are not following &lt;x id="INTERPOLATION" equiv-text="{{host}}"/&gt; anymore.</source>
2207 <context-group purpose="location"> 2207 <context-group purpose="location">
2208 <context context-type="sourcefile">src/app/+admin/follows/following-list/following-list.component.ts</context> 2208 <context context-type="sourcefile">src/app/+admin/follows/following-list/following-list.component.ts</context>
2209 <context context-type="linenumber">1</context> 2209 <context context-type="linenumber">1</context>
2210 </context-group> 2210 </context-group>
2211 </trans-unit> 2211 </trans-unit>
2212 <trans-unit id="fed7ccf455d8457dfe6b8650161b2ba991fc3162" datatype="html"> 2212 <trans-unit id="364463fab6c5714118d6449561a0f8de1cc10bfa" datatype="html">
2213 <source>User &lt;x id="INTERPOLATION" equiv-text="{{ username }}"/&gt; created.</source> 2213 <source>User &lt;x id="INTERPOLATION" equiv-text="{{username}}"/&gt; created.</source>
2214 <context-group purpose="location"> 2214 <context-group purpose="location">
2215 <context context-type="sourcefile">src/app/+admin/users/user-edit/user-create.component.ts</context> 2215 <context context-type="sourcefile">src/app/+admin/users/user-edit/user-create.component.ts</context>
2216 <context context-type="linenumber">1</context> 2216 <context context-type="linenumber">1</context>
2217 </context-group> 2217 </context-group>
2218 </trans-unit> 2218 </trans-unit>
2219 <trans-unit id="047fa00d26afadba9a3c82453e653ba863ed048b" datatype="html"> 2219 <trans-unit id="964865a3cd90b4af99902f071644a4b2aede4c32" datatype="html">
2220 <source>User &lt;x id="INTERPOLATION" equiv-text="{{ username }}"/&gt; updated.</source> 2220 <source>User &lt;x id="INTERPOLATION" equiv-text="{{username}}"/&gt; updated.</source>
2221 <context-group purpose="location"> 2221 <context-group purpose="location">
2222 <context context-type="sourcefile">src/app/+admin/users/user-edit/user-update.component.ts</context> 2222 <context context-type="sourcefile">src/app/+admin/users/user-edit/user-update.component.ts</context>
2223 <context context-type="linenumber">1</context> 2223 <context context-type="linenumber">1</context>
@@ -2244,8 +2244,8 @@ When you will upload a video in this channel, the video support field will be au
2244 <context context-type="linenumber">1</context> 2244 <context context-type="linenumber">1</context>
2245 </context-group> 2245 </context-group>
2246 </trans-unit> 2246 </trans-unit>
2247 <trans-unit id="383611faadd7b4cf0bbc124d2e42b535fa6c2eb0" datatype="html"> 2247 <trans-unit id="28220fae6799ab98ef6b41af449aa9680082357a" datatype="html">
2248 <source>User &lt;x id="INTERPOLATION" equiv-text="{{ username }}"/&gt; deleted.</source> 2248 <source>User &lt;x id="INTERPOLATION" equiv-text="{{username}}"/&gt; deleted.</source>
2249 <context-group purpose="location"> 2249 <context-group purpose="location">
2250 <context context-type="sourcefile">src/app/+admin/users/user-list/user-list.component.ts</context> 2250 <context context-type="sourcefile">src/app/+admin/users/user-list/user-list.component.ts</context>
2251 <context context-type="linenumber">1</context> 2251 <context context-type="linenumber">1</context>
@@ -2258,8 +2258,8 @@ When you will upload a video in this channel, the video support field will be au
2258 <context context-type="linenumber">1</context> 2258 <context context-type="linenumber">1</context>
2259 </context-group> 2259 </context-group>
2260 </trans-unit> 2260 </trans-unit>
2261 <trans-unit id="4255d5c12ab55f41866ad22453d4b70e0deab89f" datatype="html"> 2261 <trans-unit id="1585babc36806e20e225ac27dbba0e7c7cd09e0f" datatype="html">
2262 <source>Video &lt;x id="INTERPOLATION" equiv-text="{{ name }}"/&gt; removed from the blacklist.</source> 2262 <source>Video &lt;x id="INTERPOLATION" equiv-text="{{name}}"/&gt; removed from the blacklist.</source>
2263 <context-group purpose="location"> 2263 <context-group purpose="location">
2264 <context context-type="sourcefile">src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts</context> 2264 <context context-type="sourcefile">src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts</context>
2265 <context context-type="linenumber">1</context> 2265 <context context-type="linenumber">1</context>
@@ -2307,8 +2307,8 @@ When you will upload a video in this channel, the video support field will be au
2307 <context context-type="linenumber">1</context> 2307 <context context-type="linenumber">1</context>
2308 </context-group> 2308 </context-group>
2309 </trans-unit> 2309 </trans-unit>
2310 <trans-unit id="206542c1b57ce583f3cfe68b8609a0c4f791ae0c" datatype="html"> 2310 <trans-unit id="3ef8bf973a9a481a08c6f0aaa875f0259b3ea645" datatype="html">
2311 <source>Video channel &lt;x id="INTERPOLATION" equiv-text="{{ videoChannelName }}"/&gt; created.</source> 2311 <source>Video channel &lt;x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/&gt; created.</source>
2312 <context-group purpose="location"> 2312 <context-group purpose="location">
2313 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts</context> 2313 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts</context>
2314 <context context-type="linenumber">1</context> 2314 <context context-type="linenumber">1</context>
@@ -2321,15 +2321,15 @@ When you will upload a video in this channel, the video support field will be au
2321 <context context-type="linenumber">1</context> 2321 <context context-type="linenumber">1</context>
2322 </context-group> 2322 </context-group>
2323 </trans-unit> 2323 </trans-unit>
2324 <trans-unit id="8ad57f6504ec3c791c2fc07523053ae4bf12e63e" datatype="html"> 2324 <trans-unit id="98ab64f0af924a60a48b40835c1b655bd17c6559" datatype="html">
2325 <source>Video channel &lt;x id="INTERPOLATION" equiv-text="{{ videoChannelName }}"/&gt; updated.</source> 2325 <source>Video channel &lt;x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/&gt; updated.</source>
2326 <context-group purpose="location"> 2326 <context-group purpose="location">
2327 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts</context> 2327 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts</context>
2328 <context context-type="linenumber">1</context> 2328 <context context-type="linenumber">1</context>
2329 </context-group> 2329 </context-group>
2330 </trans-unit> 2330 </trans-unit>
2331 <trans-unit id="cb033ad5876fce7072bceb4eeba7d2154748153f" datatype="html"> 2331 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814" datatype="html">
2332 <source>Do you really want to delete &lt;x id="INTERPOLATION" equiv-text="{{ videoChannelName }}"/&gt;? It will delete all videos uploaded in this channel too.</source> 2332 <source>Do you really want to delete &lt;x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/&gt;? It will delete all videos uploaded in this channel too.</source>
2333 <context-group purpose="location"> 2333 <context-group purpose="location">
2334 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts</context> 2334 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts</context>
2335 <context context-type="linenumber">1</context> 2335 <context context-type="linenumber">1</context>
@@ -2342,8 +2342,8 @@ When you will upload a video in this channel, the video support field will be au
2342 <context context-type="linenumber">1</context> 2342 <context context-type="linenumber">1</context>
2343 </context-group> 2343 </context-group>
2344 </trans-unit> 2344 </trans-unit>
2345 <trans-unit id="504b4bf7053bc5ac9853d4fd7aaa6b38703dcbd2" datatype="html"> 2345 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2" datatype="html">
2346 <source>Video channel {{ videoChannelName } deleted.</source> 2346 <source>Video channel &lt;x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/&gt; deleted.</source>
2347 <context-group purpose="location"> 2347 <context-group purpose="location">
2348 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts</context> 2348 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts</context>
2349 <context context-type="linenumber">1</context> 2349 <context context-type="linenumber">1</context>
@@ -2356,8 +2356,8 @@ When you will upload a video in this channel, the video support field will be au
2356 <context context-type="linenumber">1</context> 2356 <context context-type="linenumber">1</context>
2357 </context-group> 2357 </context-group>
2358 </trans-unit> 2358 </trans-unit>
2359 <trans-unit id="070558f351471e268ae7a690ba31ac0c1ead6d8f" datatype="html"> 2359 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7" datatype="html">
2360 <source>Cannot retrieve OAuth Client credentials: &lt;x id="INTERPOLATION" equiv-text="{{ errorText }}"/&gt;. 2360 <source>Cannot retrieve OAuth Client credentials: &lt;x id="INTERPOLATION" equiv-text="{{errorText}}"/&gt;.
2361</source> 2361</source>
2362 <context-group purpose="location"> 2362 <context-group purpose="location">
2363 <context context-type="sourcefile">src/app/core/auth/auth.service.ts</context> 2363 <context context-type="sourcefile">src/app/core/auth/auth.service.ts</context>
@@ -2406,6 +2406,387 @@ When you will upload a video in this channel, the video support field will be au
2406 <context context-type="linenumber">1</context> 2406 <context context-type="linenumber">1</context>
2407 </context-group> 2407 </context-group>
2408 </trans-unit> 2408 </trans-unit>
2409 <trans-unit id="b67c8e57904c67c4566610363b7f82c748d04323" datatype="html">
2410 <source>Instance name is required.</source>
2411 <context-group purpose="location">
2412 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2413 <context context-type="linenumber">1</context>
2414 </context-group>
2415 </trans-unit>
2416 <trans-unit id="10a248adb1ee12830355a04ac3cde2bad2d41d7d" datatype="html">
2417 <source>Short description should not be longer than 250 characters.</source>
2418 <context-group purpose="location">
2419 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2420 <context context-type="linenumber">1</context>
2421 </context-group>
2422 </trans-unit>
2423 <trans-unit id="356e63270712273da168072ec0fc78a969919bf1" datatype="html">
2424 <source>Twitter username is required.</source>
2425 <context-group purpose="location">
2426 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2427 <context context-type="linenumber">1</context>
2428 </context-group>
2429 </trans-unit>
2430 <trans-unit id="dbb2ef02020afc05e146855f2e1dd7c9522d49b6" datatype="html">
2431 <source>Previews cache size is required.</source>
2432 <context-group purpose="location">
2433 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2434 <context context-type="linenumber">1</context>
2435 </context-group>
2436 </trans-unit>
2437 <trans-unit id="97836c6e698185b4ce357de9d4b2ab3e838f2459" datatype="html">
2438 <source>Previews cache size must be greater than 1.</source>
2439 <context-group purpose="location">
2440 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2441 <context context-type="linenumber">1</context>
2442 </context-group>
2443 </trans-unit>
2444 <trans-unit id="e7393dc4a4aa12d005582eb9e1ddc7e5ca5bebd3" datatype="html">
2445 <source>Previews cache size must be a number.</source>
2446 <context-group purpose="location">
2447 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2448 <context context-type="linenumber">1</context>
2449 </context-group>
2450 </trans-unit>
2451 <trans-unit id="2cdd5a8c604ef16c2f9a17ed81d73f4f9509e828" datatype="html">
2452 <source>Signup limit is required.</source>
2453 <context-group purpose="location">
2454 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2455 <context context-type="linenumber">1</context>
2456 </context-group>
2457 </trans-unit>
2458 <trans-unit id="0ca9f7ec55c9896add6e82d2b52e9217e1140cf7" datatype="html">
2459 <source>Signup limit must be greater than 1.</source>
2460 <context-group purpose="location">
2461 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2462 <context context-type="linenumber">1</context>
2463 </context-group>
2464 </trans-unit>
2465 <trans-unit id="58c2f66ba74f1400914031ef4ed635938e9e8ced" datatype="html">
2466 <source>Signup limit must be a number.</source>
2467 <context-group purpose="location">
2468 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2469 <context context-type="linenumber">1</context>
2470 </context-group>
2471 </trans-unit>
2472 <trans-unit id="1245841647f9b42d3e7554903c1c50bdd80ab021" datatype="html">
2473 <source>Admin email is required.</source>
2474 <context-group purpose="location">
2475 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2476 <context context-type="linenumber">1</context>
2477 </context-group>
2478 </trans-unit>
2479 <trans-unit id="3fd2feb77dfe57fe82573e3cdf996105e2fafc66" datatype="html">
2480 <source>Admin email must be valid.</source>
2481 <context-group purpose="location">
2482 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2483 <context context-type="linenumber">1</context>
2484 </context-group>
2485 </trans-unit>
2486 <trans-unit id="f15f2e02b1f6a96553e98ea4a969045d17ec1400" datatype="html">
2487 <source>Transcoding threads is required.</source>
2488 <context-group purpose="location">
2489 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2490 <context context-type="linenumber">1</context>
2491 </context-group>
2492 </trans-unit>
2493 <trans-unit id="ba88636d27c1a6a7e1f75ff57ec182b30b851c2e" datatype="html">
2494 <source>Transcoding threads must be greater than 1.</source>
2495 <context-group purpose="location">
2496 <context context-type="sourcefile">src/app/shared/forms/form-validators/custom-config-validators.service.ts</context>
2497 <context context-type="linenumber">1</context>
2498 </context-group>
2499 </trans-unit>
2500 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149" datatype="html">
2501 <source>Username is required.</source>
2502 <context-group purpose="location">
2503 <context context-type="sourcefile">src/app/shared/forms/form-validators/login-validators.service.ts</context>
2504 <context context-type="linenumber">1</context>
2505 </context-group>
2506 <context-group purpose="location">
2507 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2508 <context context-type="linenumber">1</context>
2509 </context-group>
2510 </trans-unit>
2511 <trans-unit id="4eb39d69b74d7a56652ec84fa6826994ee26c0e5" datatype="html">
2512 <source>Password is required.</source>
2513 <context-group purpose="location">
2514 <context context-type="sourcefile">src/app/shared/forms/form-validators/login-validators.service.ts</context>
2515 <context context-type="linenumber">1</context>
2516 </context-group>
2517 <context-group purpose="location">
2518 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2519 <context context-type="linenumber">1</context>
2520 </context-group>
2521 </trans-unit>
2522 <trans-unit id="c90872a06666a51c2957c4b29724e68df5c67154" datatype="html">
2523 <source>Confirmation of the password is required.</source>
2524 <context-group purpose="location">
2525 <context context-type="sourcefile">src/app/shared/forms/form-validators/reset-password-validators.service.ts</context>
2526 <context context-type="linenumber">1</context>
2527 </context-group>
2528 </trans-unit>
2529 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea" datatype="html">
2530 <source>Username must be at least 3 characters long.</source>
2531 <context-group purpose="location">
2532 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2533 <context context-type="linenumber">1</context>
2534 </context-group>
2535 </trans-unit>
2536 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef" datatype="html">
2537 <source>Username cannot be more than 20 characters long.</source>
2538 <context-group purpose="location">
2539 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2540 <context context-type="linenumber">1</context>
2541 </context-group>
2542 </trans-unit>
2543 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9" datatype="html">
2544 <source>Username should be only lowercase alphanumeric characters.</source>
2545 <context-group purpose="location">
2546 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2547 <context context-type="linenumber">1</context>
2548 </context-group>
2549 </trans-unit>
2550 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0" datatype="html">
2551 <source>Email is required.</source>
2552 <context-group purpose="location">
2553 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2554 <context context-type="linenumber">1</context>
2555 </context-group>
2556 </trans-unit>
2557 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1" datatype="html">
2558 <source>Email must be valid.</source>
2559 <context-group purpose="location">
2560 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2561 <context context-type="linenumber">1</context>
2562 </context-group>
2563 </trans-unit>
2564 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0" datatype="html">
2565 <source>Password must be at least 6 characters long.</source>
2566 <context-group purpose="location">
2567 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2568 <context context-type="linenumber">1</context>
2569 </context-group>
2570 </trans-unit>
2571 <trans-unit id="0a154031f3e66985af96d5f903441cf84f0dc75e" datatype="html">
2572 <source>Password cannot be more than 255 characters long.</source>
2573 <context-group purpose="location">
2574 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2575 <context context-type="linenumber">1</context>
2576 </context-group>
2577 </trans-unit>
2578 <trans-unit id="abede840116d58f04a55d99a6cbd68da8a3e1bbf" datatype="html">
2579 <source>Video quota is required.</source>
2580 <context-group purpose="location">
2581 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2582 <context context-type="linenumber">1</context>
2583 </context-group>
2584 </trans-unit>
2585 <trans-unit id="93a6dc1d3aa0d3201c86ef1ec8adf5cf0ada3c80" datatype="html">
2586 <source>Quota must be greater than -1.</source>
2587 <context-group purpose="location">
2588 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2589 <context context-type="linenumber">1</context>
2590 </context-group>
2591 </trans-unit>
2592 <trans-unit id="545e77fd5d9526228a2133109447c23225ed9c85" datatype="html">
2593 <source>User role is required.</source>
2594 <context-group purpose="location">
2595 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2596 <context context-type="linenumber">1</context>
2597 </context-group>
2598 </trans-unit>
2599 <trans-unit id="1c417b7aef730d6ef5d62fa8a0a7e25e3a2393e4" datatype="html">
2600 <source>Display name is required.</source>
2601 <context-group purpose="location">
2602 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2603 <context context-type="linenumber">1</context>
2604 </context-group>
2605 <context-group purpose="location">
2606 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context>
2607 <context context-type="linenumber">1</context>
2608 </context-group>
2609 </trans-unit>
2610 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674" datatype="html">
2611 <source>Display name must be at least 3 characters long.</source>
2612 <context-group purpose="location">
2613 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2614 <context context-type="linenumber">1</context>
2615 </context-group>
2616 <context-group purpose="location">
2617 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context>
2618 <context context-type="linenumber">1</context>
2619 </context-group>
2620 </trans-unit>
2621 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9" datatype="html">
2622 <source>Display name cannot be more than 120 characters long.</source>
2623 <context-group purpose="location">
2624 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2625 <context context-type="linenumber">1</context>
2626 </context-group>
2627 <context-group purpose="location">
2628 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context>
2629 <context context-type="linenumber">1</context>
2630 </context-group>
2631 </trans-unit>
2632 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae" datatype="html">
2633 <source>Description must be at least 3 characters long.</source>
2634 <context-group purpose="location">
2635 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2636 <context context-type="linenumber">1</context>
2637 </context-group>
2638 <context-group purpose="location">
2639 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context>
2640 <context context-type="linenumber">1</context>
2641 </context-group>
2642 </trans-unit>
2643 <trans-unit id="916a6e4fd83ece1dc54c6135eb3b8cd064b4bac3" datatype="html">
2644 <source>Description cannot be more than 250 characters long.</source>
2645 <context-group purpose="location">
2646 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
2647 <context context-type="linenumber">1</context>
2648 </context-group>
2649 </trans-unit>
2650 <trans-unit id="b3cf1889d2fdd6b15e697c270c9b80772fe2cae6" datatype="html">
2651 <source>Report reason is required.</source>
2652 <context-group purpose="location">
2653 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-abuse-validators.service.ts</context>
2654 <context context-type="linenumber">1</context>
2655 </context-group>
2656 </trans-unit>
2657 <trans-unit id="993f9f5703d449a1d467243db75253d288a2947e" datatype="html">
2658 <source>Report reason must be at least 2 characters long.</source>
2659 <context-group purpose="location">
2660 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-abuse-validators.service.ts</context>
2661 <context context-type="linenumber">1</context>
2662 </context-group>
2663 </trans-unit>
2664 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9" datatype="html">
2665 <source>Report reason cannot be more than 300 characters long.</source>
2666 <context-group purpose="location">
2667 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-abuse-validators.service.ts</context>
2668 <context context-type="linenumber">1</context>
2669 </context-group>
2670 </trans-unit>
2671 <trans-unit id="fac936be125163a8494f3d7e7f21d65c7e4f1ff6" datatype="html">
2672 <source>Description cannot be more than 500 characters long.</source>
2673 <context-group purpose="location">
2674 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context>
2675 <context context-type="linenumber">1</context>
2676 </context-group>
2677 </trans-unit>
2678 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b" datatype="html">
2679 <source>Support text must be at least 3 characters long.</source>
2680 <context-group purpose="location">
2681 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context>
2682 <context context-type="linenumber">1</context>
2683 </context-group>
2684 </trans-unit>
2685 <trans-unit id="3fe80c71378e127dda2dda9dbcd66b059d362813" datatype="html">
2686 <source>Support text cannot be more than 500 characters long.</source>
2687 <context-group purpose="location">
2688 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context>
2689 <context context-type="linenumber">1</context>
2690 </context-group>
2691 </trans-unit>
2692 <trans-unit id="6ca60e0f6dfbc0073b0514bce7d273150b0b9e79" datatype="html">
2693 <source>Comment is required.</source>
2694 <context-group purpose="location">
2695 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-comment-validators.service.ts</context>
2696 <context context-type="linenumber">1</context>
2697 </context-group>
2698 </trans-unit>
2699 <trans-unit id="f5a94cae76685e72f33541b977efdd7845cb0ed6" datatype="html">
2700 <source>Comment must be at least 2 characters long.</source>
2701 <context-group purpose="location">
2702 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-comment-validators.service.ts</context>
2703 <context context-type="linenumber">1</context>
2704 </context-group>
2705 </trans-unit>
2706 <trans-unit id="7c194080446ee6901fd17a8b8648534ffe98b123" datatype="html">
2707 <source>Comment cannot be more than 3000 characters long.</source>
2708 <context-group purpose="location">
2709 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-comment-validators.service.ts</context>
2710 <context context-type="linenumber">1</context>
2711 </context-group>
2712 </trans-unit>
2713 <trans-unit id="cdc51eaeab88683610a28af8645cf91d136b39e1" datatype="html">
2714 <source>Video name is required.</source>
2715 <context-group purpose="location">
2716 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-validators.service.ts</context>
2717 <context context-type="linenumber">1</context>
2718 </context-group>
2719 </trans-unit>
2720 <trans-unit id="c27cc734f76efd221663921dd0898ea7c8bcbb5c" datatype="html">
2721 <source>Video name must be at least 3 characters long.</source>
2722 <context-group purpose="location">
2723 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-validators.service.ts</context>
2724 <context context-type="linenumber">1</context>
2725 </context-group>
2726 </trans-unit>
2727 <trans-unit id="0320d0f7f8eec2341e27ca53d7875217a3d99695" datatype="html">
2728 <source>Video name cannot be more than 120 characters long.</source>
2729 <context-group purpose="location">
2730 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-validators.service.ts</context>
2731 <context context-type="linenumber">1</context>
2732 </context-group>
2733 </trans-unit>
2734 <trans-unit id="a627c58cf1849d7d838696e7f36c1bae1a8b31a4" datatype="html">
2735 <source>Video privacy is required.</source>
2736 <context-group purpose="location">
2737 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-validators.service.ts</context>
2738 <context context-type="linenumber">1</context>
2739 </context-group>
2740 </trans-unit>
2741 <trans-unit id="97afb789c1ab09074495d49aaadb92a1c3e71a16" datatype="html">
2742 <source>Video channel is required.</source>
2743 <context-group purpose="location">
2744 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-validators.service.ts</context>
2745 <context context-type="linenumber">1</context>
2746 </context-group>
2747 </trans-unit>
2748 <trans-unit id="af5e2d5f3ac817c735fb7ff9ca16322789f66fef" datatype="html">
2749 <source>Video description must be at least 3 characters long.</source>
2750 <context-group purpose="location">
2751 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-validators.service.ts</context>
2752 <context context-type="linenumber">1</context>
2753 </context-group>
2754 </trans-unit>
2755 <trans-unit id="ce28a9403c2d7e5da2e59af27118f8b6d109e906" datatype="html">
2756 <source>Video description cannot be more than 10000 characters long.</source>
2757 <context-group purpose="location">
2758 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-validators.service.ts</context>
2759 <context context-type="linenumber">1</context>
2760 </context-group>
2761 </trans-unit>
2762 <trans-unit id="f1cffdc2e156716cd9880201d65ba457d11464f8" datatype="html">
2763 <source>A tag should be more than 2 characters long.</source>
2764 <context-group purpose="location">
2765 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-validators.service.ts</context>
2766 <context context-type="linenumber">1</context>
2767 </context-group>
2768 </trans-unit>
2769 <trans-unit id="34a0811f9a2a7366cc9efcdad52ea59b105326ea" datatype="html">
2770 <source>A tag should be less than 30 characters long.</source>
2771 <context-group purpose="location">
2772 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-validators.service.ts</context>
2773 <context context-type="linenumber">1</context>
2774 </context-group>
2775 </trans-unit>
2776 <trans-unit id="665092574f9af9fec262f8349b67b14192391ae6" datatype="html">
2777 <source>Video support must be at least 3 characters long.</source>
2778 <context-group purpose="location">
2779 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-validators.service.ts</context>
2780 <context context-type="linenumber">1</context>
2781 </context-group>
2782 </trans-unit>
2783 <trans-unit id="e61f1c05121fa5effa6ccddf5be6dcf1c822ff4b" datatype="html">
2784 <source>Video support cannot be more than 500 characters long.</source>
2785 <context-group purpose="location">
2786 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-validators.service.ts</context>
2787 <context context-type="linenumber">1</context>
2788 </context-group>
2789 </trans-unit>
2409 <trans-unit id="0bf41abaa85526711f7952b4600e4044bc7f04a4" datatype="html"> 2790 <trans-unit id="0bf41abaa85526711f7952b4600e4044bc7f04a4" datatype="html">
2410 <source>All unsaved data will be lost, are you sure you want to leave this page?</source> 2791 <source>All unsaved data will be lost, are you sure you want to leave this page?</source>
2411 <context-group purpose="location"> 2792 <context-group purpose="location">
@@ -2420,78 +2801,78 @@ When you will upload a video in this channel, the video support field will be au
2420 <context context-type="linenumber">1</context> 2801 <context context-type="linenumber">1</context>
2421 </context-group> 2802 </context-group>
2422 </trans-unit> 2803 </trans-unit>
2423 <trans-unit id="4ae5829f2615ca2343280765e6b6adfb5cc41128" datatype="html"> 2804 <trans-unit id="0b2054a863319d2cf59867addd125b6717cae41d" datatype="html">
2424 <source>&lt;x id="INTERPOLATION" equiv-text="{{ interval }}"/&gt; years ago</source> 2805 <source>&lt;x id="INTERPOLATION" equiv-text="{{interval}}"/&gt; years ago</source>
2425 <context-group purpose="location"> 2806 <context-group purpose="location">
2426 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context> 2807 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context>
2427 <context context-type="linenumber">1</context> 2808 <context context-type="linenumber">1</context>
2428 </context-group> 2809 </context-group>
2429 </trans-unit> 2810 </trans-unit>
2430 <trans-unit id="a2bada0a7274e74d4318cc86d413e3ae32f57bdd" datatype="html"> 2811 <trans-unit id="e622d3813449fe36371ea258281059306819199d" datatype="html">
2431 <source>&lt;x id="INTERPOLATION" equiv-text="{{ interval }}"/&gt; months ago</source> 2812 <source>&lt;x id="INTERPOLATION" equiv-text="{{interval}}"/&gt; months ago</source>
2432 <context-group purpose="location"> 2813 <context-group purpose="location">
2433 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context> 2814 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context>
2434 <context context-type="linenumber">1</context> 2815 <context context-type="linenumber">1</context>
2435 </context-group> 2816 </context-group>
2436 </trans-unit> 2817 </trans-unit>
2437 <trans-unit id="550f8907c0a4a636d494ed945f3c10dd3a58113a" datatype="html"> 2818 <trans-unit id="2f8a5a5f7efb521d7d89dc659ff65dd13cb7b17b" datatype="html">
2438 <source>&lt;x id="INTERPOLATION" equiv-text="{{ interval }}"/&gt; month ago</source> 2819 <source>&lt;x id="INTERPOLATION" equiv-text="{{interval}}"/&gt; month ago</source>
2439 <context-group purpose="location"> 2820 <context-group purpose="location">
2440 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context> 2821 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context>
2441 <context context-type="linenumber">1</context> 2822 <context context-type="linenumber">1</context>
2442 </context-group> 2823 </context-group>
2443 </trans-unit> 2824 </trans-unit>
2444 <trans-unit id="bcc068f243c2f21112b7559f88d1d599b94e2a46" datatype="html"> 2825 <trans-unit id="1d1a46543a29096d3c6676be2d561380a0bc94e1" datatype="html">
2445 <source>&lt;x id="INTERPOLATION" equiv-text="{{ interval }}"/&gt; weeks ago</source> 2826 <source>&lt;x id="INTERPOLATION" equiv-text="{{interval}}"/&gt; weeks ago</source>
2446 <context-group purpose="location"> 2827 <context-group purpose="location">
2447 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context> 2828 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context>
2448 <context context-type="linenumber">1</context> 2829 <context context-type="linenumber">1</context>
2449 </context-group> 2830 </context-group>
2450 </trans-unit> 2831 </trans-unit>
2451 <trans-unit id="a8ab22b7de1e4a70285fe7d06962a2140d5a5252" datatype="html"> 2832 <trans-unit id="e1db0b98b6cdf817508195f3649c48475c32ae7e" datatype="html">
2452 <source>&lt;x id="INTERPOLATION" equiv-text="{{ interval }}"/&gt; week ago</source> 2833 <source>&lt;x id="INTERPOLATION" equiv-text="{{interval}}"/&gt; week ago</source>
2453 <context-group purpose="location"> 2834 <context-group purpose="location">
2454 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context> 2835 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context>
2455 <context context-type="linenumber">1</context> 2836 <context context-type="linenumber">1</context>
2456 </context-group> 2837 </context-group>
2457 </trans-unit> 2838 </trans-unit>
2458 <trans-unit id="ca8bfebe411d4b56e2cfea8bd47346a7a51dea66" datatype="html"> 2839 <trans-unit id="a7654c3ece96e777527606f1c2870d6ee0b180f7" datatype="html">
2459 <source>&lt;x id="INTERPOLATION" equiv-text="{{ interval }}"/&gt; days ago</source> 2840 <source>&lt;x id="INTERPOLATION" equiv-text="{{interval}}"/&gt; days ago</source>
2460 <context-group purpose="location"> 2841 <context-group purpose="location">
2461 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context> 2842 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context>
2462 <context context-type="linenumber">1</context> 2843 <context context-type="linenumber">1</context>
2463 </context-group> 2844 </context-group>
2464 </trans-unit> 2845 </trans-unit>
2465 <trans-unit id="853e61e6ba27292056e756194829c5498387b381" datatype="html"> 2846 <trans-unit id="5b465235ae55091d32535e23dd180c407f1352d1" datatype="html">
2466 <source>&lt;x id="INTERPOLATION" equiv-text="{{ interval }}"/&gt; day ago</source> 2847 <source>&lt;x id="INTERPOLATION" equiv-text="{{interval}}"/&gt; day ago</source>
2467 <context-group purpose="location"> 2848 <context-group purpose="location">
2468 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context> 2849 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context>
2469 <context context-type="linenumber">1</context> 2850 <context context-type="linenumber">1</context>
2470 </context-group> 2851 </context-group>
2471 </trans-unit> 2852 </trans-unit>
2472 <trans-unit id="41d5a34bc1c27138d8ffbeecd7499f7854025f11" datatype="html"> 2853 <trans-unit id="dc7addf53bd6405a9c746db6dfca665c33679a84" datatype="html">
2473 <source>&lt;x id="INTERPOLATION" equiv-text="{{ interval }}"/&gt; hours ago</source> 2854 <source>&lt;x id="INTERPOLATION" equiv-text="{{interval}}"/&gt; hours ago</source>
2474 <context-group purpose="location"> 2855 <context-group purpose="location">
2475 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context> 2856 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context>
2476 <context context-type="linenumber">1</context> 2857 <context context-type="linenumber">1</context>
2477 </context-group> 2858 </context-group>
2478 </trans-unit> 2859 </trans-unit>
2479 <trans-unit id="551090bafad6b52d4677e7d65fb10692b813945b" datatype="html"> 2860 <trans-unit id="d54a610250ed38efccf0e3afdd0004f6ad83ea8d" datatype="html">
2480 <source>&lt;x id="INTERPOLATION" equiv-text="{{ interval }}"/&gt; hour ago</source> 2861 <source>&lt;x id="INTERPOLATION" equiv-text="{{interval}}"/&gt; hour ago</source>
2481 <context-group purpose="location"> 2862 <context-group purpose="location">
2482 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context> 2863 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context>
2483 <context context-type="linenumber">1</context> 2864 <context context-type="linenumber">1</context>
2484 </context-group> 2865 </context-group>
2485 </trans-unit> 2866 </trans-unit>
2486 <trans-unit id="5f751a2e17480da31cd12f8cac3e85a9a5ea9439" datatype="html"> 2867 <trans-unit id="9704e5e3adce178c127ead05f7057d3fb827308a" datatype="html">
2487 <source>&lt;x id="INTERPOLATION" equiv-text="{{ interval }}"/&gt; min ago</source> 2868 <source>&lt;x id="INTERPOLATION" equiv-text="{{interval}}"/&gt; min ago</source>
2488 <context-group purpose="location"> 2869 <context-group purpose="location">
2489 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context> 2870 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context>
2490 <context context-type="linenumber">1</context> 2871 <context context-type="linenumber">1</context>
2491 </context-group> 2872 </context-group>
2492 </trans-unit> 2873 </trans-unit>
2493 <trans-unit id="a3ac5cb5be93ff145b3bf0139fe20da052060c4c" datatype="html"> 2874 <trans-unit id="7a158a7555a44ea7eff9fa4988df9aa24d262ceb" datatype="html">
2494 <source>&lt;x id="INTERPOLATION" equiv-text="{{ interval }}"/&gt; sec ago</source> 2875 <source>&lt;x id="INTERPOLATION" equiv-text="{{interval}}"/&gt; sec ago</source>
2495 <context-group purpose="location"> 2876 <context-group purpose="location">
2496 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context> 2877 <context context-type="sourcefile">src/app/shared/misc/from-now.pipe.ts</context>
2497 <context context-type="linenumber">1</context> 2878 <context context-type="linenumber">1</context>
@@ -2504,8 +2885,8 @@ When you will upload a video in this channel, the video support field will be au
2504 <context context-type="linenumber">1</context> 2885 <context context-type="linenumber">1</context>
2505 </context-group> 2886 </context-group>
2506 </trans-unit> 2887 </trans-unit>
2507 <trans-unit id="3d6b54e95d42ef7586fb88f535b8d0349d431745" datatype="html"> 2888 <trans-unit id="58546fd4d14b2d9635ce3d28c216ac68587bb25b" datatype="html">
2508 <source>Too many attempts, please try again after &lt;x id="INTERPOLATION" equiv-text="{{ minutesLeft }}"/&gt; minutes.</source> 2889 <source>Too many attempts, please try again after &lt;x id="INTERPOLATION" equiv-text="{{minutesLeft}}"/&gt; minutes.</source>
2509 <context-group purpose="location"> 2890 <context-group purpose="location">
2510 <context context-type="sourcefile">src/app/shared/rest/rest-extractor.service.ts</context> 2891 <context context-type="sourcefile">src/app/shared/rest/rest-extractor.service.ts</context>
2511 <context context-type="linenumber">1</context> 2892 <context context-type="linenumber">1</context>
@@ -2525,29 +2906,29 @@ When you will upload a video in this channel, the video support field will be au
2525 <context context-type="linenumber">1</context> 2906 <context context-type="linenumber">1</context>
2526 </context-group> 2907 </context-group>
2527 </trans-unit> 2908 </trans-unit>
2528 <trans-unit id="240f841426d253c459e739c19156f05d913ac10c" datatype="html"> 2909 <trans-unit id="20deec13d8d4ff199aa04318818ca44dab0585be" datatype="html">
2529 <source>Registration for &lt;x id="INTERPOLATION" equiv-text="{{ username }}"/&gt; complete.</source> 2910 <source>Registration for &lt;x id="INTERPOLATION" equiv-text="{{username}}"/&gt; complete.</source>
2530 <context-group purpose="location"> 2911 <context-group purpose="location">
2531 <context context-type="sourcefile">src/app/signup/signup.component.ts</context> 2912 <context context-type="sourcefile">src/app/signup/signup.component.ts</context>
2532 <context context-type="linenumber">1</context> 2913 <context context-type="linenumber">1</context>
2533 </context-group> 2914 </context-group>
2534 </trans-unit> 2915 </trans-unit>
2535 <trans-unit id="cb77327761a94def3c7c0c2362e3af9e5949f57b" datatype="html"> 2916 <trans-unit id="10ffa5c3dbcee491d66f80d8d4dce3e119a6ec86" datatype="html">
2536 <source>&lt;x id="INTERPOLATION" equiv-text="{{ seconds }}"/&gt; of full HD videos</source> 2917 <source>&lt;x id="INTERPOLATION" equiv-text="{{seconds}}"/&gt; of full HD videos</source>
2537 <context-group purpose="location"> 2918 <context-group purpose="location">
2538 <context context-type="sourcefile">src/app/signup/signup.component.ts</context> 2919 <context context-type="sourcefile">src/app/signup/signup.component.ts</context>
2539 <context context-type="linenumber">1</context> 2920 <context context-type="linenumber">1</context>
2540 </context-group> 2921 </context-group>
2541 </trans-unit> 2922 </trans-unit>
2542 <trans-unit id="06dbb94903fc77f10c6760d7ebbb9cf649a0c8fd" datatype="html"> 2923 <trans-unit id="344ddae9f45b344e98e7b28cd5e33243982700f8" datatype="html">
2543 <source>&lt;x id="INTERPOLATION" equiv-text="{{ seconds }}"/&gt; of HD videos</source> 2924 <source>&lt;x id="INTERPOLATION" equiv-text="{{seconds}}"/&gt; of HD videos</source>
2544 <context-group purpose="location"> 2925 <context-group purpose="location">
2545 <context context-type="sourcefile">src/app/signup/signup.component.ts</context> 2926 <context context-type="sourcefile">src/app/signup/signup.component.ts</context>
2546 <context context-type="linenumber">1</context> 2927 <context context-type="linenumber">1</context>
2547 </context-group> 2928 </context-group>
2548 </trans-unit> 2929 </trans-unit>
2549 <trans-unit id="d44fb1f436492c547bfb99825245526958dc84e7" datatype="html"> 2930 <trans-unit id="435c012df6dd990a1ccb7ee73dd79c488bde28b5" datatype="html">
2550 <source>&lt;x id="INTERPOLATION" equiv-text="{{ seconds }}"/&gt; of average quality videos</source> 2931 <source>&lt;x id="INTERPOLATION" equiv-text="{{seconds}}"/&gt; of average quality videos</source>
2551 <context-group purpose="location"> 2932 <context-group purpose="location">
2552 <context context-type="sourcefile">src/app/signup/signup.component.ts</context> 2933 <context context-type="sourcefile">src/app/signup/signup.component.ts</context>
2553 <context context-type="linenumber">1</context> 2934 <context context-type="linenumber">1</context>
@@ -2616,8 +2997,8 @@ When you will upload a video in this channel, the video support field will be au
2616 <context context-type="linenumber">1</context> 2997 <context context-type="linenumber">1</context>
2617 </context-group> 2998 </context-group>
2618 </trans-unit> 2999 </trans-unit>
2619 <trans-unit id="36cd97a83cd16866213a1d16d1637a3639ec998f" datatype="html"> 3000 <trans-unit id="aeb61b334cac080733c3e03766165a346bbf42fd" datatype="html">
2620 <source> &lt;x id="INTERPOLATION" equiv-text="{{ totalReplies }}"/&gt; replies will be deleted too.</source> 3001 <source> &lt;x id="INTERPOLATION" equiv-text="{{totalReplies}}"/&gt; replies will be deleted too.</source>
2621 <context-group purpose="location"> 3002 <context-group purpose="location">
2622 <context context-type="sourcefile">src/app/videos/+video-watch/comment/video-comments.component.ts</context> 3003 <context context-type="sourcefile">src/app/videos/+video-watch/comment/video-comments.component.ts</context>
2623 <context context-type="linenumber">1</context> 3004 <context context-type="linenumber">1</context>
@@ -2644,8 +3025,8 @@ When you will upload a video in this channel, the video support field will be au
2644 <context context-type="linenumber">1</context> 3025 <context context-type="linenumber">1</context>
2645 </context-group> 3026 </context-group>
2646 </trans-unit> 3027 </trans-unit>
2647 <trans-unit id="085d56464b75ae5c1e370f5290e4c4cf23961a61" datatype="html"> 3028 <trans-unit id="cafd8ec6020e69f241a107b1cb7081bd9e773d4e" datatype="html">
2648 <source>Video &lt;x id="INTERPOLATION" equiv-text="{{ videoName }}"/&gt; had been blacklisted.</source> 3029 <source>Video &lt;x id="INTERPOLATION" equiv-text="{{videoName}}"/&gt; had been blacklisted.</source>
2649 <context-group purpose="location"> 3030 <context-group purpose="location">
2650 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context> 3031 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context>
2651 <context context-type="linenumber">1</context> 3032 <context context-type="linenumber">1</context>
@@ -2658,15 +3039,15 @@ When you will upload a video in this channel, the video support field will be au
2658 <context context-type="linenumber">1</context> 3039 <context context-type="linenumber">1</context>
2659 </context-group> 3040 </context-group>
2660 </trans-unit> 3041 </trans-unit>
2661 <trans-unit id="007c1d7080cf6da1ac264b23705246f0c53e3114" datatype="html"> 3042 <trans-unit id="d39a0bfa616a9a8473b2e379eefe17d8ed1af118" datatype="html">
2662 <source>Video &lt;x id="INTERPOLATION" equiv-text="{{ videoName }}"/&gt; deleted.</source> 3043 <source>Video &lt;x id="INTERPOLATION" equiv-text="{{videoName}}"/&gt; deleted.</source>
2663 <context-group purpose="location"> 3044 <context-group purpose="location">
2664 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context> 3045 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context>
2665 <context context-type="linenumber">1</context> 3046 <context context-type="linenumber">1</context>
2666 </context-group> 3047 </context-group>
2667 </trans-unit> 3048 </trans-unit>
2668 <trans-unit id="cf9a064824f2fa3f01fd5544ad21032e33e60dca" datatype="html"> 3049 <trans-unit id="d5a4811e15319ad9354e1b62e9ca0131192b489e" datatype="html">
2669 <source>&lt;x id="INTERPOLATION" equiv-text="{{ likesNumber }}"/&gt; likes / &lt;x id="INTERPOLATION_1" equiv-text="{{ dislikesNumber }}"/&gt; dislikes</source> 3050 <source>&lt;x id="INTERPOLATION" equiv-text="{{likesNumber}}"/&gt; likes / &lt;x id="INTERPOLATION_1" equiv-text="{{dislikesNumber}}"/&gt; dislikes</source>
2670 <context-group purpose="location"> 3051 <context-group purpose="location">
2671 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context> 3052 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context>
2672 <context context-type="linenumber">1</context> 3053 <context context-type="linenumber">1</context>
diff --git a/client/src/locale/target/messages_fr.xml b/client/src/locale/target/messages_fr.xml
index 18c9f64a7..e3c052446 100644
--- a/client/src/locale/target/messages_fr.xml
+++ b/client/src/locale/target/messages_fr.xml
@@ -630,9 +630,9 @@ Cochez cette case, sauvegardez la configuration et testez avec l'URL d'une vidé
630 <context context-type="linenumber">207</context> 630 <context context-type="linenumber">207</context>
631 </context-group> 631 </context-group>
632 </trans-unit> 632 </trans-unit>
633 <trans-unit id="48c189b718ed2d091e5c515bfc14b03e5ceb4f93"> 633 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
634 <source>Preview cache size</source> 634 <source>Previews cache size</source>
635 <target>Taille du cache de l'ape§u</target> 635 <target>Taille du cache des prévisualisations </target>
636 <context-group name="null"> 636 <context-group name="null">
637 <context context-type="linenumber">210</context> 637 <context context-type="linenumber">210</context>
638 </context-group> 638 </context-group>
@@ -1117,7 +1117,7 @@ Cochez cette case, sauvegardez la configuration et testez avec l'URL d'une vidé
1117 <source>Display name</source> 1117 <source>Display name</source>
1118 <target>Nom public</target> 1118 <target>Nom public</target>
1119 <context-group name="null"> 1119 <context-group name="null">
1120 <context context-type="linenumber">5</context> 1120 <context context-type="linenumber">6</context>
1121 </context-group> 1121 </context-group>
1122 </trans-unit> 1122 </trans-unit>
1123 <trans-unit id="74728de5289ea2ff3f553bc2b48f1811680b931a"> 1123 <trans-unit id="74728de5289ea2ff3f553bc2b48f1811680b931a">
@@ -1175,7 +1175,7 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
1175 <source>Update my profile</source> 1175 <source>Update my profile</source>
1176 <target>Mettre à jour mon profil</target> 1176 <target>Mettre à jour mon profil</target>
1177 <context-group name="null"> 1177 <context-group name="null">
1178 <context context-type="linenumber">23</context> 1178 <context context-type="linenumber">27</context>
1179 </context-group> 1179 </context-group>
1180 </trans-unit> 1180 </trans-unit>
1181 <trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd"> 1181 <trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd">
@@ -1793,9 +1793,9 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
1793 <context context-type="linenumber">1</context> 1793 <context context-type="linenumber">1</context>
1794 </context-group> 1794 </context-group>
1795 </trans-unit> 1795 </trans-unit>
1796 <trans-unit id="b0ea97653991a80d6324423949d37b8f165a4505"> 1796 <trans-unit id="369ef5e9c0dd1251abdbf699a5db408bca10777f">
1797 <source>Published <x id="INTERPOLATION" equiv-text="{{ totalVideos }}"/> videos</source> 1797 <source>Published <x id="INTERPOLATION" equiv-text="{{totalVideos}}"/> videos</source>
1798 <target>A publié <x id="INTERPOLATION" equiv-text="{{ totalVideos }}"/> vidéos</target> 1798 <target>A publié <x id="INTERPOLATION" equiv-text="{{totalVideos}}"/> vidéos</target>
1799 <context-group name="null"> 1799 <context-group name="null">
1800 <context context-type="linenumber">1</context> 1800 <context context-type="linenumber">1</context>
1801 </context-group> 1801 </context-group>
@@ -1807,9 +1807,9 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
1807 <context context-type="linenumber">1</context> 1807 <context context-type="linenumber">1</context>
1808 </context-group> 1808 </context-group>
1809 </trans-unit> 1809 </trans-unit>
1810 <trans-unit id="6b988bab9e171f65ed3510e8a66b9c5f7fcc5209"> 1810 <trans-unit id="27a71a0aee65258179e90ecf0841c0a68f95beed">
1811 <source>You set custom <x id="INTERPOLATION" equiv-text="{{ customizationsText }}"/>. </source> 1811 <source>You set custom <x id="INTERPOLATION" equiv-text="{{customizationsText}}"/>. </source>
1812 <target>Vous avez paramétré <x id="INTERPOLATION" equiv-text="{{ customizationsText }}"/>. </target> 1812 <target>Vous avez défini du <x id="INTERPOLATION" equiv-text="{{customizationsText}}"/>. </target>
1813 <context-group name="null"> 1813 <context-group name="null">
1814 <context context-type="linenumber">1</context> 1814 <context context-type="linenumber">1</context>
1815 </context-group> 1815 </context-group>
@@ -1828,16 +1828,16 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
1828 <context context-type="linenumber">1</context> 1828 <context context-type="linenumber">1</context>
1829 </context-group> 1829 </context-group>
1830 </trans-unit> 1830 </trans-unit>
1831 <trans-unit id="03b6bae23e3f895ed8f53e3b29fad0cafc7dd002"> 1831 <trans-unit id="1ae0ab69f5c19d179282c8d882fd2f3c00e29119">
1832 <source>Please type "I understand the <x id="INTERPOLATION" equiv-text="{{ customizationsText }}"/> I set" to confirm.</source> 1832 <source>Please type</source>
1833 <target>Merci d'écrire "Je comprends avoir rentré &lt;x id="INTERPOLATION" equiv-text="{{ customizationsText }}"/&gt;" pour confirmer votre choix.</target> 1833 <target>Merci de taper</target>
1834 <context-group name="null"> 1834 <context-group name="null">
1835 <context context-type="linenumber">1</context> 1835 <context context-type="linenumber">1</context>
1836 </context-group> 1836 </context-group>
1837 </trans-unit> 1837 </trans-unit>
1838 <trans-unit id="892eb3bbce40125f9ed1dc13078d2938b921ff53"> 1838 <trans-unit id="75f4bb68ee4c6b282abfd9d8d32be22c6202794d">
1839 <source>I understand the <x id="INTERPOLATION" equiv-text="{{ customizationsText }}"/> I set</source> 1839 <source>to confirm.</source>
1840 <target>Je comprends avoir rentré <x id="INTERPOLATION" equiv-text="{{ customizationsText }}"/></target> 1840 <target>pour confirmer.</target>
1841 <context-group name="null"> 1841 <context-group name="null">
1842 <context context-type="linenumber">1</context> 1842 <context context-type="linenumber">1</context>
1843 </context-group> 1843 </context-group>
@@ -1856,9 +1856,9 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
1856 <context context-type="linenumber">1</context> 1856 <context context-type="linenumber">1</context>
1857 </context-group> 1857 </context-group>
1858 </trans-unit> 1858 </trans-unit>
1859 <trans-unit id="511be2e1ddb087fe7a0d95654f5f72b446d3da87"> 1859 <trans-unit id="fc5731a28a99b25c62d43333ceebb250d60aff84">
1860 <source><x id="INTERPOLATION" equiv-text="{{ host }}"/> is not valid</source> 1860 <source><x id="INTERPOLATION" equiv-text="{{host}}"/> is not valid</source>
1861 <target><x id="INTERPOLATION" equiv-text="{{ host }}"/> n'est pas un hôte valide</target> 1861 <target><x id="INTERPOLATION" equiv-text="{{host}}"/> n'est pas valide</target>
1862 <context-group name="null"> 1862 <context-group name="null">
1863 <context context-type="linenumber">1</context> 1863 <context context-type="linenumber">1</context>
1864 </context-group> 1864 </context-group>
@@ -1898,9 +1898,9 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
1898 <context context-type="linenumber">1</context> 1898 <context context-type="linenumber">1</context>
1899 </context-group> 1899 </context-group>
1900 </trans-unit> 1900 </trans-unit>
1901 <trans-unit id="b1f6b95a2d83bc589955f2679de00ce70fa03594"> 1901 <trans-unit id="5729c34a858c78daa1aa606f62a3665527cf97e6">
1902 <source>Do you really want to unfollow <x id="INTERPOLATION" equiv-text="{{ host }}"/>?</source> 1902 <source>Do you really want to unfollow <x id="INTERPOLATION" equiv-text="{{host}}"/>?</source>
1903 <target>Souhaitez-vous vraiment arrêter de suivre <x id="INTERPOLATION" equiv-text="{{ host }}"/> ?</target> 1903 <target>Voulez-vous vraiment vous désabonner de <x id="INTERPOLATION" equiv-text="{{host}}"/> ?</target>
1904 <context-group name="null"> 1904 <context-group name="null">
1905 <context context-type="linenumber">1</context> 1905 <context context-type="linenumber">1</context>
1906 </context-group> 1906 </context-group>
@@ -1912,23 +1912,23 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
1912 <context context-type="linenumber">1</context> 1912 <context context-type="linenumber">1</context>
1913 </context-group> 1913 </context-group>
1914 </trans-unit> 1914 </trans-unit>
1915 <trans-unit id="c02051988cf0b04bc8bea7602c909c4835ed770f"> 1915 <trans-unit id="fb4e35e2b0ea2abc1f71295a4b34830e57c07bd0">
1916 <source>You are not following <x id="INTERPOLATION" equiv-text="{{ host }}"/> anymore.</source> 1916 <source>You are not following <x id="INTERPOLATION" equiv-text="{{host}}"/> anymore.</source>
1917 <target>Vous ne suivez plus <x id="INTERPOLATION" equiv-text="{{ host }}"/>.</target> 1917 <target>Vous n'êtes plus abonné à <x id="INTERPOLATION" equiv-text="{{host}}"/>.</target>
1918 <context-group name="null"> 1918 <context-group name="null">
1919 <context context-type="linenumber">1</context> 1919 <context context-type="linenumber">1</context>
1920 </context-group> 1920 </context-group>
1921 </trans-unit> 1921 </trans-unit>
1922 <trans-unit id="fed7ccf455d8457dfe6b8650161b2ba991fc3162"> 1922 <trans-unit id="364463fab6c5714118d6449561a0f8de1cc10bfa">
1923 <source>User <x id="INTERPOLATION" equiv-text="{{ username }}"/> created.</source> 1923 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> created.</source>
1924 <target>Utilisateur <x id="INTERPOLATION" equiv-text="{{ username }}"/> créé.</target> 1924 <target>Utilisateur <x id="INTERPOLATION" equiv-text="{{username}}"/> créé.</target>
1925 <context-group name="null"> 1925 <context-group name="null">
1926 <context context-type="linenumber">1</context> 1926 <context context-type="linenumber">1</context>
1927 </context-group> 1927 </context-group>
1928 </trans-unit> 1928 </trans-unit>
1929 <trans-unit id="047fa00d26afadba9a3c82453e653ba863ed048b"> 1929 <trans-unit id="964865a3cd90b4af99902f071644a4b2aede4c32">
1930 <source>User <x id="INTERPOLATION" equiv-text="{{ username }}"/> updated.</source> 1930 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> updated.</source>
1931 <target>Utilisateur <x id="INTERPOLATION" equiv-text="{{ username }}"/> mis à jour.</target> 1931 <target>Utilisateur <x id="INTERPOLATION" equiv-text="{{username}}"/> mis à jour.</target>
1932 <context-group name="null"> 1932 <context-group name="null">
1933 <context context-type="linenumber">1</context> 1933 <context context-type="linenumber">1</context>
1934 </context-group> 1934 </context-group>
@@ -1954,9 +1954,9 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
1954 <context context-type="linenumber">1</context> 1954 <context context-type="linenumber">1</context>
1955 </context-group> 1955 </context-group>
1956 </trans-unit> 1956 </trans-unit>
1957 <trans-unit id="383611faadd7b4cf0bbc124d2e42b535fa6c2eb0"> 1957 <trans-unit id="28220fae6799ab98ef6b41af449aa9680082357a">
1958 <source>User <x id="INTERPOLATION" equiv-text="{{ username }}"/> deleted.</source> 1958 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> deleted.</source>
1959 <target>Utilisateur <x id="INTERPOLATION" equiv-text="{{ username }}"/> supprimé.</target> 1959 <target>Utilisateur <x id="INTERPOLATION" equiv-text="{{username}}"/> supprimé.</target>
1960 <context-group name="null"> 1960 <context-group name="null">
1961 <context context-type="linenumber">1</context> 1961 <context context-type="linenumber">1</context>
1962 </context-group> 1962 </context-group>
@@ -1968,9 +1968,9 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
1968 <context context-type="linenumber">1</context> 1968 <context context-type="linenumber">1</context>
1969 </context-group> 1969 </context-group>
1970 </trans-unit> 1970 </trans-unit>
1971 <trans-unit id="4255d5c12ab55f41866ad22453d4b70e0deab89f"> 1971 <trans-unit id="1585babc36806e20e225ac27dbba0e7c7cd09e0f">
1972 <source>Video <x id="INTERPOLATION" equiv-text="{{ name }}"/> removed from the blacklist.</source> 1972 <source>Video <x id="INTERPOLATION" equiv-text="{{name}}"/> removed from the blacklist.</source>
1973 <target>La vidéo <x id="INTERPOLATION" equiv-text="{{ name }}"/> a bien été enlevée de la liste noire.</target> 1973 <target>Vidéo <x id="INTERPOLATION" equiv-text="{{name}}"/> supprimée de la liste noire.</target>
1974 <context-group name="null"> 1974 <context-group name="null">
1975 <context context-type="linenumber">1</context> 1975 <context context-type="linenumber">1</context>
1976 </context-group> 1976 </context-group>
@@ -2017,9 +2017,9 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2017 <context context-type="linenumber">1</context> 2017 <context context-type="linenumber">1</context>
2018 </context-group> 2018 </context-group>
2019 </trans-unit> 2019 </trans-unit>
2020 <trans-unit id="206542c1b57ce583f3cfe68b8609a0c4f791ae0c"> 2020 <trans-unit id="3ef8bf973a9a481a08c6f0aaa875f0259b3ea645">
2021 <source>Video channel <x id="INTERPOLATION" equiv-text="{{ videoChannelName }}"/> created.</source> 2021 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> created.</source>
2022 <target>Chaîne vidéo <x id="INTERPOLATION" equiv-text="{{ videoChannelName }}"/> créée.</target> 2022 <target>Chaîne vidéo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> créée.</target>
2023 <context-group name="null"> 2023 <context-group name="null">
2024 <context context-type="linenumber">1</context> 2024 <context context-type="linenumber">1</context>
2025 </context-group> 2025 </context-group>
@@ -2031,16 +2031,16 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2031 <context context-type="linenumber">1</context> 2031 <context context-type="linenumber">1</context>
2032 </context-group> 2032 </context-group>
2033 </trans-unit> 2033 </trans-unit>
2034 <trans-unit id="8ad57f6504ec3c791c2fc07523053ae4bf12e63e"> 2034 <trans-unit id="98ab64f0af924a60a48b40835c1b655bd17c6559">
2035 <source>Video channel <x id="INTERPOLATION" equiv-text="{{ videoChannelName }}"/> updated.</source> 2035 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> updated.</source>
2036 <target>Chaîne vidéo <x id="INTERPOLATION" equiv-text="{{ videoChannelName }}"/> mise à jour.</target> 2036 <target>Chaîne vidéo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> mise à jour.</target>
2037 <context-group name="null"> 2037 <context-group name="null">
2038 <context context-type="linenumber">1</context> 2038 <context context-type="linenumber">1</context>
2039 </context-group> 2039 </context-group>
2040 </trans-unit> 2040 </trans-unit>
2041 <trans-unit id="cb033ad5876fce7072bceb4eeba7d2154748153f"> 2041 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814">
2042 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{ videoChannelName }}"/>? It will delete all videos uploaded in this channel too.</source> 2042 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source>
2043 <target>Êtes-vous bien sûr de vouloir supprimer <x id="INTERPOLATION" equiv-text="{{ videoChannelName }}"/> ? Cette action aura aussi pour effet de supprimer toutes les vidéos ayant appartenu à cette chaîne.</target> 2043 <target>Voulez-vous vraiment supprimer <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> ? Ceci supprimera aussi toutes les vidéos téléversées dans cette chaîne.</target>
2044 <context-group name="null"> 2044 <context-group name="null">
2045 <context context-type="linenumber">1</context> 2045 <context context-type="linenumber">1</context>
2046 </context-group> 2046 </context-group>
@@ -2052,9 +2052,9 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2052 <context context-type="linenumber">1</context> 2052 <context context-type="linenumber">1</context>
2053 </context-group> 2053 </context-group>
2054 </trans-unit> 2054 </trans-unit>
2055 <trans-unit id="504b4bf7053bc5ac9853d4fd7aaa6b38703dcbd2"> 2055 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
2056 <source>Video channel {{ videoChannelName } deleted.</source> 2056 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
2057 <target>Chaîne vidéo {{ videoChannelName } supprimée.</target> 2057 <target>Chaîne vidéo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> supprimée.</target>
2058 <context-group name="null"> 2058 <context-group name="null">
2059 <context context-type="linenumber">1</context> 2059 <context context-type="linenumber">1</context>
2060 </context-group> 2060 </context-group>
@@ -2066,10 +2066,10 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2066 <context context-type="linenumber">1</context> 2066 <context context-type="linenumber">1</context>
2067 </context-group> 2067 </context-group>
2068 </trans-unit> 2068 </trans-unit>
2069 <trans-unit id="070558f351471e268ae7a690ba31ac0c1ead6d8f"> 2069 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7">
2070 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{ errorText }}"/>. 2070 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>.
2071</source> 2071</source>
2072 <target>Impossible de récupérer les identifiants Client OAuth : <x id="INTERPOLATION" equiv-text="{{ errorText }}"/>. 2072 <target>Impossible de retrouver les identifiants client OAuth : <x id="INTERPOLATION" equiv-text="{{errorText}}"/>.
2073</target> 2073</target>
2074 <context-group name="null"> 2074 <context-group name="null">
2075 <context context-type="linenumber">1</context> 2075 <context context-type="linenumber">1</context>
@@ -2117,6 +2117,363 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2117 <context context-type="linenumber">1</context> 2117 <context context-type="linenumber">1</context>
2118 </context-group> 2118 </context-group>
2119 </trans-unit> 2119 </trans-unit>
2120 <trans-unit id="b67c8e57904c67c4566610363b7f82c748d04323">
2121 <source>Instance name is required.</source>
2122 <target>Le nom de l'instance est requis.</target>
2123 <context-group name="null">
2124 <context context-type="linenumber">1</context>
2125 </context-group>
2126 </trans-unit>
2127 <trans-unit id="10a248adb1ee12830355a04ac3cde2bad2d41d7d">
2128 <source>Short description should not be longer than 250 characters.</source>
2129 <target>La courte description ne peut pas faire plus de 250 caractères.</target>
2130 <context-group name="null">
2131 <context context-type="linenumber">1</context>
2132 </context-group>
2133 </trans-unit>
2134 <trans-unit id="356e63270712273da168072ec0fc78a969919bf1">
2135 <source>Twitter username is required.</source>
2136 <target>L'identifiant Twitter est requis.</target>
2137 <context-group name="null">
2138 <context context-type="linenumber">1</context>
2139 </context-group>
2140 </trans-unit>
2141 <trans-unit id="dbb2ef02020afc05e146855f2e1dd7c9522d49b6">
2142 <source>Previews cache size is required.</source>
2143 <target>La taille du cache des prévisualisations est requis.</target>
2144 <context-group name="null">
2145 <context context-type="linenumber">1</context>
2146 </context-group>
2147 </trans-unit>
2148 <trans-unit id="97836c6e698185b4ce357de9d4b2ab3e838f2459">
2149 <source>Previews cache size must be greater than 1.</source>
2150 <target>La taille du cache des prévisualisations doit être plus grand que 1.</target>
2151 <context-group name="null">
2152 <context context-type="linenumber">1</context>
2153 </context-group>
2154 </trans-unit>
2155 <trans-unit id="e7393dc4a4aa12d005582eb9e1ddc7e5ca5bebd3">
2156 <source>Previews cache size must be a number.</source>
2157 <target>La taille du cache des prévisualisations doit être un nombre.</target>
2158 <context-group name="null">
2159 <context context-type="linenumber">1</context>
2160 </context-group>
2161 </trans-unit>
2162 <trans-unit id="2cdd5a8c604ef16c2f9a17ed81d73f4f9509e828">
2163 <source>Signup limit is required.</source>
2164 <target>La limite d'enregistrements est requis.</target>
2165 <context-group name="null">
2166 <context context-type="linenumber">1</context>
2167 </context-group>
2168 </trans-unit>
2169 <trans-unit id="0ca9f7ec55c9896add6e82d2b52e9217e1140cf7">
2170 <source>Signup limit must be greater than 1.</source>
2171 <target>La limite d'enregistrement doit faire plus de 1.</target>
2172 <context-group name="null">
2173 <context context-type="linenumber">1</context>
2174 </context-group>
2175 </trans-unit>
2176 <trans-unit id="58c2f66ba74f1400914031ef4ed635938e9e8ced">
2177 <source>Signup limit must be a number.</source>
2178 <target>La limite d'enregistrement doit être un nombre.</target>
2179 <context-group name="null">
2180 <context context-type="linenumber">1</context>
2181 </context-group>
2182 </trans-unit>
2183 <trans-unit id="1245841647f9b42d3e7554903c1c50bdd80ab021">
2184 <source>Admin email is required.</source>
2185 <target>L'email de l'administrateur est requis.</target>
2186 <context-group name="null">
2187 <context context-type="linenumber">1</context>
2188 </context-group>
2189 </trans-unit>
2190 <trans-unit id="3fd2feb77dfe57fe82573e3cdf996105e2fafc66">
2191 <source>Admin email must be valid.</source>
2192 <target>L'email de l'administrateur doit être valide</target>
2193 <context-group name="null">
2194 <context context-type="linenumber">1</context>
2195 </context-group>
2196 </trans-unit>
2197 <trans-unit id="f15f2e02b1f6a96553e98ea4a969045d17ec1400">
2198 <source>Transcoding threads is required.</source>
2199 <target>Le nombre de threads pour l'encodage est requis.</target>
2200 <context-group name="null">
2201 <context context-type="linenumber">1</context>
2202 </context-group>
2203 </trans-unit>
2204 <trans-unit id="ba88636d27c1a6a7e1f75ff57ec182b30b851c2e">
2205 <source>Transcoding threads must be greater than 1.</source>
2206 <target>Le nombre de threads pour l'encodage doit être plus grand que 1.</target>
2207 <context-group name="null">
2208 <context context-type="linenumber">1</context>
2209 </context-group>
2210 </trans-unit>
2211 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
2212 <source>Username is required.</source>
2213 <target>Le nom d'utilisateur est requis.</target>
2214 <context-group name="null">
2215 <context context-type="linenumber">1</context>
2216 </context-group>
2217 </trans-unit>
2218 <trans-unit id="4eb39d69b74d7a56652ec84fa6826994ee26c0e5">
2219 <source>Password is required.</source>
2220 <target>Le mot de passe est requis.</target>
2221 <context-group name="null">
2222 <context context-type="linenumber">1</context>
2223 </context-group>
2224 </trans-unit>
2225 <trans-unit id="c90872a06666a51c2957c4b29724e68df5c67154">
2226 <source>Confirmation of the password is required.</source>
2227 <target>La confirmation du mot de passe est requis.</target>
2228 <context-group name="null">
2229 <context context-type="linenumber">1</context>
2230 </context-group>
2231 </trans-unit>
2232 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
2233 <source>Username must be at least 3 characters long.</source>
2234 <target>Le nom d'utilisateur doit être composé d'au moins 3 caractères.</target>
2235 <context-group name="null">
2236 <context context-type="linenumber">1</context>
2237 </context-group>
2238 </trans-unit>
2239 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
2240 <source>Username cannot be more than 20 characters long.</source>
2241 <target>Le nom d'utilisateur ne peut pas faire plus de 20 caractères.</target>
2242 <context-group name="null">
2243 <context context-type="linenumber">1</context>
2244 </context-group>
2245 </trans-unit>
2246 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
2247 <source>Username should be only lowercase alphanumeric characters.</source>
2248 <target>Le nom d'utilisateur ne doit être composé que de caractères alphnumériques en minuscule.</target>
2249 <context-group name="null">
2250 <context context-type="linenumber">1</context>
2251 </context-group>
2252 </trans-unit>
2253 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
2254 <source>Email is required.</source>
2255 <target>L'email est requis.</target>
2256 <context-group name="null">
2257 <context context-type="linenumber">1</context>
2258 </context-group>
2259 </trans-unit>
2260 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
2261 <source>Email must be valid.</source>
2262 <target>L'email doit être valide.</target>
2263 <context-group name="null">
2264 <context context-type="linenumber">1</context>
2265 </context-group>
2266 </trans-unit>
2267 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
2268 <source>Password must be at least 6 characters long.</source>
2269 <target>Le mot de passe doit être composé d'au moins 6 caractères.</target>
2270 <context-group name="null">
2271 <context context-type="linenumber">1</context>
2272 </context-group>
2273 </trans-unit>
2274 <trans-unit id="0a154031f3e66985af96d5f903441cf84f0dc75e">
2275 <source>Password cannot be more than 255 characters long.</source>
2276 <target>Le mot de passe ne peut pas faire plus de 255 caractères.</target>
2277 <context-group name="null">
2278 <context context-type="linenumber">1</context>
2279 </context-group>
2280 </trans-unit>
2281 <trans-unit id="abede840116d58f04a55d99a6cbd68da8a3e1bbf">
2282 <source>Video quota is required.</source>
2283 <target>Le quota de vidéos est requis.</target>
2284 <context-group name="null">
2285 <context context-type="linenumber">1</context>
2286 </context-group>
2287 </trans-unit>
2288 <trans-unit id="93a6dc1d3aa0d3201c86ef1ec8adf5cf0ada3c80">
2289 <source>Quota must be greater than -1.</source>
2290 <target>Le quota doit être plus grand que -1.</target>
2291 <context-group name="null">
2292 <context context-type="linenumber">1</context>
2293 </context-group>
2294 </trans-unit>
2295 <trans-unit id="545e77fd5d9526228a2133109447c23225ed9c85">
2296 <source>User role is required.</source>
2297 <target>Le rôle utilisateur est requis.</target>
2298 <context-group name="null">
2299 <context context-type="linenumber">1</context>
2300 </context-group>
2301 </trans-unit>
2302 <trans-unit id="1c417b7aef730d6ef5d62fa8a0a7e25e3a2393e4">
2303 <source>Display name is required.</source>
2304 <target>Le nom d'affichage est requis.</target>
2305 <context-group name="null">
2306 <context context-type="linenumber">1</context>
2307 </context-group>
2308 </trans-unit>
2309 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674">
2310 <source>Display name must be at least 3 characters long.</source>
2311 <target>Le nom d'affichage doit être composé d'au moins 3 caractères.</target>
2312 <context-group name="null">
2313 <context context-type="linenumber">1</context>
2314 </context-group>
2315 </trans-unit>
2316 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
2317 <source>Display name cannot be more than 120 characters long.</source>
2318 <target>Le nom d'affichage ne peut pas faire plus de 120 caractères.</target>
2319 <context-group name="null">
2320 <context context-type="linenumber">1</context>
2321 </context-group>
2322 </trans-unit>
2323 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
2324 <source>Description must be at least 3 characters long.</source>
2325 <target>La description doit être composé d'au moins 3 caractères.</target>
2326 <context-group name="null">
2327 <context context-type="linenumber">1</context>
2328 </context-group>
2329 </trans-unit>
2330 <trans-unit id="916a6e4fd83ece1dc54c6135eb3b8cd064b4bac3">
2331 <source>Description cannot be more than 250 characters long.</source>
2332 <target>La description ne peut pas faire plus de 250 caractères.</target>
2333 <context-group name="null">
2334 <context context-type="linenumber">1</context>
2335 </context-group>
2336 </trans-unit>
2337 <trans-unit id="b3cf1889d2fdd6b15e697c270c9b80772fe2cae6">
2338 <source>Report reason is required.</source>
2339 <target>La raison du signalement est requise.</target>
2340 <context-group name="null">
2341 <context context-type="linenumber">1</context>
2342 </context-group>
2343 </trans-unit>
2344 <trans-unit id="993f9f5703d449a1d467243db75253d288a2947e">
2345 <source>Report reason must be at least 2 characters long.</source>
2346 <target>La raison du signalement doit être composé d'au moins 2 caractères.</target>
2347 <context-group name="null">
2348 <context context-type="linenumber">1</context>
2349 </context-group>
2350 </trans-unit>
2351 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
2352 <source>Report reason cannot be more than 300 characters long.</source>
2353 <target>La raison du signalement ne peut pas faire plus de 300 caractères.</target>
2354 <context-group name="null">
2355 <context context-type="linenumber">1</context>
2356 </context-group>
2357 </trans-unit>
2358 <trans-unit id="fac936be125163a8494f3d7e7f21d65c7e4f1ff6">
2359 <source>Description cannot be more than 500 characters long.</source>
2360 <target>La description ne peut pas faire plus de 500 caractères.</target>
2361 <context-group name="null">
2362 <context context-type="linenumber">1</context>
2363 </context-group>
2364 </trans-unit>
2365 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
2366 <source>Support text must be at least 3 characters long.</source>
2367 <target>Le texte de support doit être composé d'au moins 3 caractères.</target>
2368 <context-group name="null">
2369 <context context-type="linenumber">1</context>
2370 </context-group>
2371 </trans-unit>
2372 <trans-unit id="3fe80c71378e127dda2dda9dbcd66b059d362813">
2373 <source>Support text cannot be more than 500 characters long.</source>
2374 <target>Le texte du support ne peut pas faire plus de 500 caractères.</target>
2375 <context-group name="null">
2376 <context context-type="linenumber">1</context>
2377 </context-group>
2378 </trans-unit>
2379 <trans-unit id="6ca60e0f6dfbc0073b0514bce7d273150b0b9e79">
2380 <source>Comment is required.</source>
2381 <target>Le commentaire est requis.</target>
2382 <context-group name="null">
2383 <context context-type="linenumber">1</context>
2384 </context-group>
2385 </trans-unit>
2386 <trans-unit id="f5a94cae76685e72f33541b977efdd7845cb0ed6">
2387 <source>Comment must be at least 2 characters long.</source>
2388 <target>Le commentaire doit être composé d'au moins 2 caractères.</target>
2389 <context-group name="null">
2390 <context context-type="linenumber">1</context>
2391 </context-group>
2392 </trans-unit>
2393 <trans-unit id="7c194080446ee6901fd17a8b8648534ffe98b123">
2394 <source>Comment cannot be more than 3000 characters long.</source>
2395 <target>Le commentaire ne peut pas faire plus de 3000 caractères.</target>
2396 <context-group name="null">
2397 <context context-type="linenumber">1</context>
2398 </context-group>
2399 </trans-unit>
2400 <trans-unit id="cdc51eaeab88683610a28af8645cf91d136b39e1">
2401 <source>Video name is required.</source>
2402 <target>Le nom de la vidéo est requis.</target>
2403 <context-group name="null">
2404 <context context-type="linenumber">1</context>
2405 </context-group>
2406 </trans-unit>
2407 <trans-unit id="c27cc734f76efd221663921dd0898ea7c8bcbb5c">
2408 <source>Video name must be at least 3 characters long.</source>
2409 <target>Le nom de la vidéo doit faire au moins 3 caractères.</target>
2410 <context-group name="null">
2411 <context context-type="linenumber">1</context>
2412 </context-group>
2413 </trans-unit>
2414 <trans-unit id="0320d0f7f8eec2341e27ca53d7875217a3d99695">
2415 <source>Video name cannot be more than 120 characters long.</source>
2416 <target>Le nom de la vidéo ne doit pas faire plus de 120 caractères.</target>
2417 <context-group name="null">
2418 <context context-type="linenumber">1</context>
2419 </context-group>
2420 </trans-unit>
2421 <trans-unit id="a627c58cf1849d7d838696e7f36c1bae1a8b31a4">
2422 <source>Video privacy is required.</source>
2423 <target>La confidentialité de la vidéo est requise.</target>
2424 <context-group name="null">
2425 <context context-type="linenumber">1</context>
2426 </context-group>
2427 </trans-unit>
2428 <trans-unit id="97afb789c1ab09074495d49aaadb92a1c3e71a16">
2429 <source>Video channel is required.</source>
2430 <target>La chaîne de la vidéo est requise.</target>
2431 <context-group name="null">
2432 <context context-type="linenumber">1</context>
2433 </context-group>
2434 </trans-unit>
2435 <trans-unit id="af5e2d5f3ac817c735fb7ff9ca16322789f66fef">
2436 <source>Video description must be at least 3 characters long.</source>
2437 <target>La description de la vidéo doit faire au moins 3 caractères.</target>
2438 <context-group name="null">
2439 <context context-type="linenumber">1</context>
2440 </context-group>
2441 </trans-unit>
2442 <trans-unit id="ce28a9403c2d7e5da2e59af27118f8b6d109e906">
2443 <source>Video description cannot be more than 10000 characters long.</source>
2444 <target>La description de la vidéo ne peut pas faire plus de 10000 caractères.</target>
2445 <context-group name="null">
2446 <context context-type="linenumber">1</context>
2447 </context-group>
2448 </trans-unit>
2449 <trans-unit id="f1cffdc2e156716cd9880201d65ba457d11464f8">
2450 <source>A tag should be more than 2 characters long.</source>
2451 <target>Une étiquette doit faire au moins 2 caractères.</target>
2452 <context-group name="null">
2453 <context context-type="linenumber">1</context>
2454 </context-group>
2455 </trans-unit>
2456 <trans-unit id="34a0811f9a2a7366cc9efcdad52ea59b105326ea">
2457 <source>A tag should be less than 30 characters long.</source>
2458 <target>Une étiquette ne peut pas faire plus de 30 caractères.</target>
2459 <context-group name="null">
2460 <context context-type="linenumber">1</context>
2461 </context-group>
2462 </trans-unit>
2463 <trans-unit id="665092574f9af9fec262f8349b67b14192391ae6">
2464 <source>Video support must be at least 3 characters long.</source>
2465 <target>Le texte de support de la vidéo doit faire au moins 3 caractères.</target>
2466 <context-group name="null">
2467 <context context-type="linenumber">1</context>
2468 </context-group>
2469 </trans-unit>
2470 <trans-unit id="e61f1c05121fa5effa6ccddf5be6dcf1c822ff4b">
2471 <source>Video support cannot be more than 500 characters long.</source>
2472 <target>Le texte de support de la vidéo ne peut pas faire plus de 500 caractères.</target>
2473 <context-group name="null">
2474 <context context-type="linenumber">1</context>
2475 </context-group>
2476 </trans-unit>
2120 <trans-unit id="0bf41abaa85526711f7952b4600e4044bc7f04a4"> 2477 <trans-unit id="0bf41abaa85526711f7952b4600e4044bc7f04a4">
2121 <source>All unsaved data will be lost, are you sure you want to leave this page?</source> 2478 <source>All unsaved data will be lost, are you sure you want to leave this page?</source>
2122 <target>Toutes les données non sauvegardées seront perdues ; êtes-vous bien sûr·e de quitter cette page ?</target> 2479 <target>Toutes les données non sauvegardées seront perdues ; êtes-vous bien sûr·e de quitter cette page ?</target>
@@ -2131,79 +2488,79 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2131 <context context-type="linenumber">1</context> 2488 <context context-type="linenumber">1</context>
2132 </context-group> 2489 </context-group>
2133 </trans-unit> 2490 </trans-unit>
2134 <trans-unit id="4ae5829f2615ca2343280765e6b6adfb5cc41128"> 2491 <trans-unit id="0b2054a863319d2cf59867addd125b6717cae41d">
2135 <source><x id="INTERPOLATION" equiv-text="{{ interval }}"/> years ago</source> 2492 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> years ago</source>
2136 <target>il y a <x id="INTERPOLATION" equiv-text="{{ interval }}"/> ans</target> 2493 <target>il y a <x id="INTERPOLATION" equiv-text="{{interval}}"/> ans</target>
2137 <context-group name="null"> 2494 <context-group name="null">
2138 <context context-type="linenumber">1</context> 2495 <context context-type="linenumber">1</context>
2139 </context-group> 2496 </context-group>
2140 </trans-unit> 2497 </trans-unit>
2141 <trans-unit id="a2bada0a7274e74d4318cc86d413e3ae32f57bdd"> 2498 <trans-unit id="e622d3813449fe36371ea258281059306819199d">
2142 <source><x id="INTERPOLATION" equiv-text="{{ interval }}"/> months ago</source> 2499 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> months ago</source>
2143 <target>il y a <x id="INTERPOLATION" equiv-text="{{ interval }}"/> mois</target> 2500 <target>il y a <x id="INTERPOLATION" equiv-text="{{interval}}"/> mois</target>
2144 <context-group name="null"> 2501 <context-group name="null">
2145 <context context-type="linenumber">1</context> 2502 <context context-type="linenumber">1</context>
2146 </context-group> 2503 </context-group>
2147 </trans-unit> 2504 </trans-unit>
2148 <trans-unit id="550f8907c0a4a636d494ed945f3c10dd3a58113a"> 2505 <trans-unit id="2f8a5a5f7efb521d7d89dc659ff65dd13cb7b17b">
2149 <source><x id="INTERPOLATION" equiv-text="{{ interval }}"/> month ago</source> 2506 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> month ago</source>
2150 <target>il y a <x id="INTERPOLATION" equiv-text="{{ interval }}"/> mois</target> 2507 <target>il y a <x id="INTERPOLATION" equiv-text="{{interval}}"/> mois</target>
2151 <context-group name="null"> 2508 <context-group name="null">
2152 <context context-type="linenumber">1</context> 2509 <context context-type="linenumber">1</context>
2153 </context-group> 2510 </context-group>
2154 </trans-unit> 2511 </trans-unit>
2155 <trans-unit id="bcc068f243c2f21112b7559f88d1d599b94e2a46"> 2512 <trans-unit id="1d1a46543a29096d3c6676be2d561380a0bc94e1">
2156 <source><x id="INTERPOLATION" equiv-text="{{ interval }}"/> weeks ago</source> 2513 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> weeks ago</source>
2157 <target>il y a <x id="INTERPOLATION" equiv-text="{{ interval }}"/> semaines</target> 2514 <target>il y a <x id="INTERPOLATION" equiv-text="{{interval}}"/> semaines</target>
2158 <context-group name="null"> 2515 <context-group name="null">
2159 <context context-type="linenumber">1</context> 2516 <context context-type="linenumber">1</context>
2160 </context-group> 2517 </context-group>
2161 </trans-unit> 2518 </trans-unit>
2162 <trans-unit id="a8ab22b7de1e4a70285fe7d06962a2140d5a5252"> 2519 <trans-unit id="e1db0b98b6cdf817508195f3649c48475c32ae7e">
2163 <source><x id="INTERPOLATION" equiv-text="{{ interval }}"/> week ago</source> 2520 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> week ago</source>
2164 <target>il y a <x id="INTERPOLATION" equiv-text="{{ interval }}"/> semaines</target> 2521 <target>il y a <x id="INTERPOLATION" equiv-text="{{interval}}"/> semaine</target>
2165 <context-group name="null"> 2522 <context-group name="null">
2166 <context context-type="linenumber">1</context> 2523 <context context-type="linenumber">1</context>
2167 </context-group> 2524 </context-group>
2168 </trans-unit> 2525 </trans-unit>
2169 <trans-unit id="ca8bfebe411d4b56e2cfea8bd47346a7a51dea66"> 2526 <trans-unit id="a7654c3ece96e777527606f1c2870d6ee0b180f7">
2170 <source><x id="INTERPOLATION" equiv-text="{{ interval }}"/> days ago</source> 2527 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> days ago</source>
2171 <target>il y a <x id="INTERPOLATION" equiv-text="{{ interval }}"/> jours</target> 2528 <target>il y a <x id="INTERPOLATION" equiv-text="{{interval}}"/> jours</target>
2172 <context-group name="null"> 2529 <context-group name="null">
2173 <context context-type="linenumber">1</context> 2530 <context context-type="linenumber">1</context>
2174 </context-group> 2531 </context-group>
2175 </trans-unit> 2532 </trans-unit>
2176 <trans-unit id="853e61e6ba27292056e756194829c5498387b381"> 2533 <trans-unit id="5b465235ae55091d32535e23dd180c407f1352d1">
2177 <source><x id="INTERPOLATION" equiv-text="{{ interval }}"/> day ago</source> 2534 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> day ago</source>
2178 <target>il y a <x id="INTERPOLATION" equiv-text="{{ interval }}"/> jour</target> 2535 <target>il y a <x id="INTERPOLATION" equiv-text="{{interval}}"/> jour</target>
2179 <context-group name="null"> 2536 <context-group name="null">
2180 <context context-type="linenumber">1</context> 2537 <context context-type="linenumber">1</context>
2181 </context-group> 2538 </context-group>
2182 </trans-unit> 2539 </trans-unit>
2183 <trans-unit id="41d5a34bc1c27138d8ffbeecd7499f7854025f11"> 2540 <trans-unit id="dc7addf53bd6405a9c746db6dfca665c33679a84">
2184 <source><x id="INTERPOLATION" equiv-text="{{ interval }}"/> hours ago</source> 2541 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> hours ago</source>
2185 <target>il y a <x id="INTERPOLATION" equiv-text="{{ interval }}"/> heures</target> 2542 <target>il y a <x id="INTERPOLATION" equiv-text="{{interval}}"/> heures</target>
2186 <context-group name="null"> 2543 <context-group name="null">
2187 <context context-type="linenumber">1</context> 2544 <context context-type="linenumber">1</context>
2188 </context-group> 2545 </context-group>
2189 </trans-unit> 2546 </trans-unit>
2190 <trans-unit id="551090bafad6b52d4677e7d65fb10692b813945b"> 2547 <trans-unit id="d54a610250ed38efccf0e3afdd0004f6ad83ea8d">
2191 <source><x id="INTERPOLATION" equiv-text="{{ interval }}"/> hour ago</source> 2548 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> hour ago</source>
2192 <target>il y a <x id="INTERPOLATION" equiv-text="{{ interval }}"/> heure</target> 2549 <target>il y a <x id="INTERPOLATION" equiv-text="{{interval}}"/> heure</target>
2193 <context-group name="null"> 2550 <context-group name="null">
2194 <context context-type="linenumber">1</context> 2551 <context context-type="linenumber">1</context>
2195 </context-group> 2552 </context-group>
2196 </trans-unit> 2553 </trans-unit>
2197 <trans-unit id="5f751a2e17480da31cd12f8cac3e85a9a5ea9439"> 2554 <trans-unit id="9704e5e3adce178c127ead05f7057d3fb827308a">
2198 <source><x id="INTERPOLATION" equiv-text="{{ interval }}"/> min ago</source> 2555 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> min ago</source>
2199 <target>il y a <x id="INTERPOLATION" equiv-text="{{ interval }}"/> min</target> 2556 <target>il y a <x id="INTERPOLATION" equiv-text="{{interval}}"/> min</target>
2200 <context-group name="null"> 2557 <context-group name="null">
2201 <context context-type="linenumber">1</context> 2558 <context context-type="linenumber">1</context>
2202 </context-group> 2559 </context-group>
2203 </trans-unit> 2560 </trans-unit>
2204 <trans-unit id="a3ac5cb5be93ff145b3bf0139fe20da052060c4c"> 2561 <trans-unit id="7a158a7555a44ea7eff9fa4988df9aa24d262ceb">
2205 <source><x id="INTERPOLATION" equiv-text="{{ interval }}"/> sec ago</source> 2562 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> sec ago</source>
2206 <target>il y a <x id="INTERPOLATION" equiv-text="{{ interval }}"/> sec</target> 2563 <target>il y a <x id="INTERPOLATION" equiv-text="{{interval}}"/> sec</target>
2207 <context-group name="null"> 2564 <context-group name="null">
2208 <context context-type="linenumber">1</context> 2565 <context context-type="linenumber">1</context>
2209 </context-group> 2566 </context-group>
@@ -2215,9 +2572,9 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2215 <context context-type="linenumber">1</context> 2572 <context context-type="linenumber">1</context>
2216 </context-group> 2573 </context-group>
2217 </trans-unit> 2574 </trans-unit>
2218 <trans-unit id="3d6b54e95d42ef7586fb88f535b8d0349d431745"> 2575 <trans-unit id="58546fd4d14b2d9635ce3d28c216ac68587bb25b">
2219 <source>Too many attempts, please try again after <x id="INTERPOLATION" equiv-text="{{ minutesLeft }}"/> minutes.</source> 2576 <source>Too many attempts, please try again after <x id="INTERPOLATION" equiv-text="{{minutesLeft}}"/> minutes.</source>
2220 <target>Trop d'essais ; merci de réitérer après <x id="INTERPOLATION" equiv-text="{{ minutesLeft }}"/> minutes.</target> 2577 <target>Trop de tentatives, merci de réessayer dans <x id="INTERPOLATION" equiv-text="{{minutesLeft}}"/> minutes.</target>
2221 <context-group name="null"> 2578 <context-group name="null">
2222 <context context-type="linenumber">1</context> 2579 <context context-type="linenumber">1</context>
2223 </context-group> 2580 </context-group>
@@ -2236,30 +2593,30 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2236 <context context-type="linenumber">1</context> 2593 <context context-type="linenumber">1</context>
2237 </context-group> 2594 </context-group>
2238 </trans-unit> 2595 </trans-unit>
2239 <trans-unit id="240f841426d253c459e739c19156f05d913ac10c"> 2596 <trans-unit id="20deec13d8d4ff199aa04318818ca44dab0585be">
2240 <source>Registration for <x id="INTERPOLATION" equiv-text="{{ username }}"/> complete.</source> 2597 <source>Registration for <x id="INTERPOLATION" equiv-text="{{username}}"/> complete.</source>
2241 <target>Inscription faite pour <x id="INTERPOLATION" equiv-text="{{ username }}"/>.</target> 2598 <target>Enregistrement pour <x id="INTERPOLATION" equiv-text="{{username}}"/> complété.</target>
2242 <context-group name="null"> 2599 <context-group name="null">
2243 <context context-type="linenumber">1</context> 2600 <context context-type="linenumber">1</context>
2244 </context-group> 2601 </context-group>
2245 </trans-unit> 2602 </trans-unit>
2246 <trans-unit id="cb77327761a94def3c7c0c2362e3af9e5949f57b"> 2603 <trans-unit id="10ffa5c3dbcee491d66f80d8d4dce3e119a6ec86">
2247 <source><x id="INTERPOLATION" equiv-text="{{ seconds }}"/> of full HD videos</source> 2604 <source><x id="INTERPOLATION" equiv-text="{{seconds}}"/> of full HD videos</source>
2248 <target><x id="INTERPOLATION" equiv-text="{{ seconds }}"/> de vidéos en Full HD</target> 2605 <target><x id="INTERPOLATION" equiv-text="{{seconds}}"/> de vidéos full HD</target>
2249 <context-group name="null"> 2606 <context-group name="null">
2250 <context context-type="linenumber">1</context> 2607 <context context-type="linenumber">1</context>
2251 </context-group> 2608 </context-group>
2252 </trans-unit> 2609 </trans-unit>
2253 <trans-unit id="06dbb94903fc77f10c6760d7ebbb9cf649a0c8fd"> 2610 <trans-unit id="344ddae9f45b344e98e7b28cd5e33243982700f8">
2254 <source><x id="INTERPOLATION" equiv-text="{{ seconds }}"/> of HD videos</source> 2611 <source><x id="INTERPOLATION" equiv-text="{{seconds}}"/> of HD videos</source>
2255 <target><x id="INTERPOLATION" equiv-text="{{ seconds }}"/> de vidéos en HD</target> 2612 <target><x id="INTERPOLATION" equiv-text="{{seconds}}"/> de vidéos HD</target>
2256 <context-group name="null"> 2613 <context-group name="null">
2257 <context context-type="linenumber">1</context> 2614 <context context-type="linenumber">1</context>
2258 </context-group> 2615 </context-group>
2259 </trans-unit> 2616 </trans-unit>
2260 <trans-unit id="d44fb1f436492c547bfb99825245526958dc84e7"> 2617 <trans-unit id="435c012df6dd990a1ccb7ee73dd79c488bde28b5">
2261 <source><x id="INTERPOLATION" equiv-text="{{ seconds }}"/> of average quality videos</source> 2618 <source><x id="INTERPOLATION" equiv-text="{{seconds}}"/> of average quality videos</source>
2262 <target><x id="INTERPOLATION" equiv-text="{{ seconds }}"/> de vidéos de qualité moyenne</target> 2619 <target><x id="INTERPOLATION" equiv-text="{{seconds}}"/> de vidéos de qualité moyenne</target>
2263 <context-group name="null"> 2620 <context-group name="null">
2264 <context context-type="linenumber">1</context> 2621 <context context-type="linenumber">1</context>
2265 </context-group> 2622 </context-group>
@@ -2327,9 +2684,9 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2327 <context context-type="linenumber">1</context> 2684 <context context-type="linenumber">1</context>
2328 </context-group> 2685 </context-group>
2329 </trans-unit> 2686 </trans-unit>
2330 <trans-unit id="36cd97a83cd16866213a1d16d1637a3639ec998f"> 2687 <trans-unit id="aeb61b334cac080733c3e03766165a346bbf42fd">
2331 <source> <x id="INTERPOLATION" equiv-text="{{ totalReplies }}"/> replies will be deleted too.</source> 2688 <source> <x id="INTERPOLATION" equiv-text="{{totalReplies}}"/> replies will be deleted too.</source>
2332 <target> <x id="INTERPOLATION" equiv-text="{{ totalReplies }}"/> commentaires seront aussi supprimés.</target> 2689 <target> <x id="INTERPOLATION" equiv-text="{{totalReplies}}"/> réponses seront aussi supprimées.</target>
2333 <context-group name="null"> 2690 <context-group name="null">
2334 <context context-type="linenumber">1</context> 2691 <context context-type="linenumber">1</context>
2335 </context-group> 2692 </context-group>
@@ -2355,9 +2712,9 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2355 <context context-type="linenumber">1</context> 2712 <context context-type="linenumber">1</context>
2356 </context-group> 2713 </context-group>
2357 </trans-unit> 2714 </trans-unit>
2358 <trans-unit id="085d56464b75ae5c1e370f5290e4c4cf23961a61"> 2715 <trans-unit id="cafd8ec6020e69f241a107b1cb7081bd9e773d4e">
2359 <source>Video <x id="INTERPOLATION" equiv-text="{{ videoName }}"/> had been blacklisted.</source> 2716 <source>Video <x id="INTERPOLATION" equiv-text="{{videoName}}"/> had been blacklisted.</source>
2360 <target>La vidéo <x id="INTERPOLATION" equiv-text="{{ videoName }}"/> a bien été mise sur liste noire.</target> 2717 <target>La vidéo <x id="INTERPOLATION" equiv-text="{{videoName}}"/> a été mise sur liste noire.</target>
2361 <context-group name="null"> 2718 <context-group name="null">
2362 <context context-type="linenumber">1</context> 2719 <context context-type="linenumber">1</context>
2363 </context-group> 2720 </context-group>
@@ -2369,16 +2726,16 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2369 <context context-type="linenumber">1</context> 2726 <context context-type="linenumber">1</context>
2370 </context-group> 2727 </context-group>
2371 </trans-unit> 2728 </trans-unit>
2372 <trans-unit id="007c1d7080cf6da1ac264b23705246f0c53e3114"> 2729 <trans-unit id="d39a0bfa616a9a8473b2e379eefe17d8ed1af118">
2373 <source>Video <x id="INTERPOLATION" equiv-text="{{ videoName }}"/> deleted.</source> 2730 <source>Video <x id="INTERPOLATION" equiv-text="{{videoName}}"/> deleted.</source>
2374 <target>La vidéo <x id="INTERPOLATION" equiv-text="{{ videoName }}"/> a été supprimée.</target> 2731 <target>La vidéo <x id="INTERPOLATION" equiv-text="{{videoName}}"/> a été supprimée.</target>
2375 <context-group name="null"> 2732 <context-group name="null">
2376 <context context-type="linenumber">1</context> 2733 <context context-type="linenumber">1</context>
2377 </context-group> 2734 </context-group>
2378 </trans-unit> 2735 </trans-unit>
2379 <trans-unit id="cf9a064824f2fa3f01fd5544ad21032e33e60dca"> 2736 <trans-unit id="d5a4811e15319ad9354e1b62e9ca0131192b489e">
2380 <source><x id="INTERPOLATION" equiv-text="{{ likesNumber }}"/> likes / <x id="INTERPOLATION_1" equiv-text="{{ dislikesNumber }}"/> dislikes</source> 2737 <source><x id="INTERPOLATION" equiv-text="{{likesNumber}}"/> likes / <x id="INTERPOLATION_1" equiv-text="{{dislikesNumber}}"/> dislikes</source>
2381 <target><x id="INTERPOLATION" equiv-text="{{ likesNumber }}"/> likes / <x id="INTERPOLATION_1" equiv-text="{{ dislikesNumber }}"/> dislikes</target> 2738 <target><x id="INTERPOLATION" equiv-text="{{likesNumber}}"/> j'aime / <x id="INTERPOLATION_1" equiv-text="{{dislikesNumber}}"/> je n'aime pas</target>
2382 <context-group name="null"> 2739 <context-group name="null">
2383 <context context-type="linenumber">1</context> 2740 <context context-type="linenumber">1</context>
2384 </context-group> 2741 </context-group>
diff --git a/client/src/main.ts b/client/src/main.ts
index e1a69e4a4..85c4c0672 100644
--- a/client/src/main.ts
+++ b/client/src/main.ts
@@ -1,4 +1,4 @@
1import { enableProdMode } from '@angular/core' 1import { enableProdMode, TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core'
2import { platformBrowserDynamic } from '@angular/platform-browser-dynamic' 2import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
3 3
4import { AppModule } from './app/app.module' 4import { AppModule } from './app/app.module'
@@ -6,12 +6,22 @@ import { environment } from './environments/environment'
6 6
7import { hmrBootstrap } from './hmr' 7import { hmrBootstrap } from './hmr'
8 8
9let providers = []
9if (environment.production) { 10if (environment.production) {
10 enableProdMode() 11 enableProdMode()
11} 12}
12 13
14if (environment.production === false && window.location.search === '?lang=fr') {
15 const translations = require(`raw-loader!./locale/target/messages_fr.xml`)
16
17 providers = [
18 { provide: TRANSLATIONS, useValue: translations },
19 { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }
20 ]
21}
22
13const bootstrap = () => platformBrowserDynamic() 23const bootstrap = () => platformBrowserDynamic()
14 .bootstrapModule(AppModule) 24 .bootstrapModule(AppModule, { providers })
15 .then(bootstrapModule => { 25 .then(bootstrapModule => {
16 // TODO: Uncomment and remove unregistration when https://github.com/angular/angular/issues/21191 is fixed 26 // TODO: Uncomment and remove unregistration when https://github.com/angular/angular/issues/21191 is fixed
17 // TODO: Remove when https://github.com/angular/angular-cli/issues/8779 is fixed? 27 // TODO: Remove when https://github.com/angular/angular-cli/issues/8779 is fixed?