diff options
author | Chocobozzz <me@florianbigard.com> | 2018-06-04 16:21:17 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-06-05 08:43:01 +0200 |
commit | b1d40cff89f7cff565a98cdbcea9a624196a169a (patch) | |
tree | d24746c1cc69f50471a9eba0dfb1c1bae06a1870 /client/src/app | |
parent | 989e526abf0c0dd7958deb630df009608561bb67 (diff) | |
download | PeerTube-b1d40cff89f7cff565a98cdbcea9a624196a169a.tar.gz PeerTube-b1d40cff89f7cff565a98cdbcea9a624196a169a.tar.zst PeerTube-b1d40cff89f7cff565a98cdbcea9a624196a169a.zip |
Add i18n attributes
Diffstat (limited to 'client/src/app')
95 files changed, 672 insertions, 502 deletions
diff --git a/client/src/app/+accounts/account-about/account-about.component.html b/client/src/app/+accounts/account-about/account-about.component.html index eae1cb509..b178f5cc8 100644 --- a/client/src/app/+accounts/account-about/account-about.component.html +++ b/client/src/app/+accounts/account-about/account-about.component.html | |||
@@ -1,12 +1,12 @@ | |||
1 | <div *ngIf="account" class="row"> | 1 | <div *ngIf="account" class="row"> |
2 | <div class="block col-md-6 col-sm-12"> | 2 | <div class="block col-md-6 col-sm-12"> |
3 | <div class="small-title">Description</div> | 3 | <div i18n class="small-title">Description</div> |
4 | <div class="content">{{ getAccountDescription() }}</div> | 4 | <div class="content">{{ getAccountDescription() }}</div> |
5 | </div> | 5 | </div> |
6 | 6 | ||
7 | <div class="block col-md-6 col-sm-12"> | 7 | <div class="block col-md-6 col-sm-12"> |
8 | <div class="small-title">Stats</div> | 8 | <div i18n class="small-title">Stats</div> |
9 | 9 | ||
10 | <div class="content">Joined {{ account.createdAt | date }}</div> | 10 | <div i18n class="content">Joined {{ account.createdAt | date }}</div> |
11 | </div> | 11 | </div> |
12 | </div> \ No newline at end of file | 12 | </div> \ No newline at end of file |
diff --git a/client/src/app/+accounts/account-about/account-about.component.ts b/client/src/app/+accounts/account-about/account-about.component.ts index f063df392..4086510ba 100644 --- a/client/src/app/+accounts/account-about/account-about.component.ts +++ b/client/src/app/+accounts/account-about/account-about.component.ts | |||
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core' | |||
2 | import { ActivatedRoute } from '@angular/router' | 2 | import { ActivatedRoute } from '@angular/router' |
3 | import { Account } from '@app/shared/account/account.model' | 3 | import { Account } from '@app/shared/account/account.model' |
4 | import { AccountService } from '@app/shared/account/account.service' | 4 | import { AccountService } from '@app/shared/account/account.service' |
5 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
5 | 6 | ||
6 | @Component({ | 7 | @Component({ |
7 | selector: 'my-account-about', | 8 | selector: 'my-account-about', |
@@ -12,7 +13,8 @@ export class AccountAboutComponent implements OnInit { | |||
12 | account: Account | 13 | account: Account |
13 | 14 | ||
14 | constructor ( | 15 | constructor ( |
15 | protected route: ActivatedRoute, | 16 | private route: ActivatedRoute, |
17 | private i18n: I18n, | ||
16 | private accountService: AccountService | 18 | private accountService: AccountService |
17 | ) { } | 19 | ) { } |
18 | 20 | ||
@@ -25,6 +27,6 @@ export class AccountAboutComponent implements OnInit { | |||
25 | getAccountDescription () { | 27 | getAccountDescription () { |
26 | if (this.account.description) return this.account.description | 28 | if (this.account.description) return this.account.description |
27 | 29 | ||
28 | return 'No description' | 30 | return this.i18n('No description') |
29 | } | 31 | } |
30 | } | 32 | } |
diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.html b/client/src/app/+accounts/account-video-channels/account-video-channels.component.html index d20b40c60..bcd3beaf0 100644 --- a/client/src/app/+accounts/account-video-channels/account-video-channels.component.html +++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.html | |||
@@ -1,11 +1,11 @@ | |||
1 | <div *ngIf="account" class="row"> | 1 | <div *ngIf="account" class="row"> |
2 | <a | 2 | <a |
3 | *ngFor="let videoChannel of videoChannels" [routerLink]="[ '/video-channels', videoChannel.uuid ]" | 3 | *ngFor="let videoChannel of videoChannels" [routerLink]="[ '/video-channels', videoChannel.uuid ]" |
4 | class="video-channel" title="See this video channel" | 4 | class="video-channel" i18n-title title="See this video channel" |
5 | > | 5 | > |
6 | <img [src]="videoChannel.avatarUrl" alt="Avatar" /> | 6 | <img [src]="videoChannel.avatarUrl" alt="Avatar" /> |
7 | 7 | ||
8 | <div class="video-channel-display-name">{{ videoChannel.displayName }}</div> | 8 | <div class="video-channel-display-name">{{ videoChannel.displayName }}</div> |
9 | <div class="video-channel-followers">{{ videoChannel.followersCount }} subscribers</div> | 9 | <div i18n class="video-channel-followers">{{ videoChannel.followersCount }} subscribers</div> |
10 | </a> | 10 | </a> |
11 | </div> \ No newline at end of file | 11 | </div> \ No newline at end of file |
diff --git a/client/src/app/+accounts/account-videos/account-videos.component.ts b/client/src/app/+accounts/account-videos/account-videos.component.ts index eca9fb6b7..7b7629480 100644 --- a/client/src/app/+accounts/account-videos/account-videos.component.ts +++ b/client/src/app/+accounts/account-videos/account-videos.component.ts | |||
@@ -10,6 +10,7 @@ import { VideoService } from '../../shared/video/video.service' | |||
10 | import { Account } from '@app/shared/account/account.model' | 10 | import { Account } from '@app/shared/account/account.model' |
11 | import { AccountService } from '@app/shared/account/account.service' | 11 | import { AccountService } from '@app/shared/account/account.service' |
12 | import { tap } from 'rxjs/operators' | 12 | import { tap } from 'rxjs/operators' |
13 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
13 | 14 | ||
14 | @Component({ | 15 | @Component({ |
15 | selector: 'my-account-videos', | 16 | selector: 'my-account-videos', |
@@ -20,7 +21,7 @@ import { tap } from 'rxjs/operators' | |||
20 | ] | 21 | ] |
21 | }) | 22 | }) |
22 | export class AccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { | 23 | export class AccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { |
23 | titlePage = 'Published videos' | 24 | titlePage: string |
24 | marginContent = false // Disable margin | 25 | marginContent = false // Disable margin |
25 | currentRoute = '/account/videos' | 26 | currentRoute = '/account/videos' |
26 | loadOnInit = false | 27 | loadOnInit = false |
@@ -34,10 +35,13 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit, | |||
34 | protected notificationsService: NotificationsService, | 35 | protected notificationsService: NotificationsService, |
35 | protected confirmService: ConfirmService, | 36 | protected confirmService: ConfirmService, |
36 | protected location: Location, | 37 | protected location: Location, |
38 | protected i18n: I18n, | ||
37 | private accountService: AccountService, | 39 | private accountService: AccountService, |
38 | private videoService: VideoService | 40 | private videoService: VideoService |
39 | ) { | 41 | ) { |
40 | super() | 42 | super() |
43 | |||
44 | this.titlePage = this.i18n('Published videos') | ||
41 | } | 45 | } |
42 | 46 | ||
43 | ngOnInit () { | 47 | ngOnInit () { |
@@ -63,7 +67,11 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit, | |||
63 | 67 | ||
64 | return this.videoService | 68 | return this.videoService |
65 | .getAccountVideos(this.account, newPagination, this.sort) | 69 | .getAccountVideos(this.account, newPagination, this.sort) |
66 | .pipe(tap(({ totalVideos }) => this.titlePage = `Published ${totalVideos} videos`)) | 70 | .pipe( |
71 | tap(({ totalVideos }) => { | ||
72 | this.titlePage = this.i18n('Published {{ totalVideos }} videos', { totalVideos }) | ||
73 | }) | ||
74 | ) | ||
67 | } | 75 | } |
68 | 76 | ||
69 | generateSyndicationList () { | 77 | generateSyndicationList () { |
diff --git a/client/src/app/+accounts/accounts.component.html b/client/src/app/+accounts/accounts.component.html index e872bda03..69f648269 100644 --- a/client/src/app/+accounts/accounts.component.html +++ b/client/src/app/+accounts/accounts.component.html | |||
@@ -9,16 +9,16 @@ | |||
9 | <div class="actor-display-name">{{ account.displayName }}</div> | 9 | <div class="actor-display-name">{{ account.displayName }}</div> |
10 | <div class="actor-name">{{ account.nameWithHost }}</div> | 10 | <div class="actor-name">{{ account.nameWithHost }}</div> |
11 | </div> | 11 | </div> |
12 | <div class="actor-followers">{{ account.followersCount }} subscribers</div> | 12 | <div i18n class="actor-followers">{{ account.followersCount }} subscribers</div> |
13 | </div> | 13 | </div> |
14 | </div> | 14 | </div> |
15 | 15 | ||
16 | <div class="links"> | 16 | <div class="links"> |
17 | <a routerLink="videos" routerLinkActive="active" class="title-page">Videos</a> | 17 | <a i18n routerLink="videos" routerLinkActive="active" class="title-page">Videos</a> |
18 | 18 | ||
19 | <a routerLink="video-channels" routerLinkActive="active" class="title-page">Video channels</a> | 19 | <a i18n routerLink="video-channels" routerLinkActive="active" class="title-page">Video channels</a> |
20 | 20 | ||
21 | <a routerLink="about" routerLinkActive="active" class="title-page">About</a> | 21 | <a i18n routerLink="about" routerLinkActive="active" class="title-page">About</a> |
22 | </div> | 22 | </div> |
23 | </div> | 23 | </div> |
24 | 24 | ||
diff --git a/client/src/app/+admin/admin.component.html b/client/src/app/+admin/admin.component.html index e4644498b..1b2b89c3a 100644 --- a/client/src/app/+admin/admin.component.html +++ b/client/src/app/+admin/admin.component.html | |||
@@ -1,26 +1,26 @@ | |||
1 | <div class="row"> | 1 | <div class="row"> |
2 | <div class="sub-menu"> | 2 | <div class="sub-menu"> |
3 | <a *ngIf="hasUsersRight()" routerLink="/admin/users" routerLinkActive="active" class="title-page"> | 3 | <a i18n *ngIf="hasUsersRight()" routerLink="/admin/users" routerLinkActive="active" class="title-page"> |
4 | Users | 4 | Users |
5 | </a> | 5 | </a> |
6 | 6 | ||
7 | <a *ngIf="hasServerFollowRight()" routerLink="/admin/follows" routerLinkActive="active" class="title-page"> | 7 | <a i18n *ngIf="hasServerFollowRight()" routerLink="/admin/follows" routerLinkActive="active" class="title-page"> |
8 | Manage follows | 8 | Manage follows |
9 | </a> | 9 | </a> |
10 | 10 | ||
11 | <a *ngIf="hasVideoAbusesRight()" routerLink="/admin/video-abuses" routerLinkActive="active" class="title-page"> | 11 | <a i18n *ngIf="hasVideoAbusesRight()" routerLink="/admin/video-abuses" routerLinkActive="active" class="title-page"> |
12 | Video abuses | 12 | Video abuses |
13 | </a> | 13 | </a> |
14 | 14 | ||
15 | <a *ngIf="hasVideoBlacklistRight()" routerLink="/admin/video-blacklist" routerLinkActive="active" class="title-page"> | 15 | <a i18n *ngIf="hasVideoBlacklistRight()" routerLink="/admin/video-blacklist" routerLinkActive="active" class="title-page"> |
16 | Video blacklist | 16 | Video blacklist |
17 | </a> | 17 | </a> |
18 | 18 | ||
19 | <a *ngIf="hasJobsRight()" routerLink="/admin/jobs" routerLinkActive="active" class="title-page"> | 19 | <a i18n *ngIf="hasJobsRight()" routerLink="/admin/jobs" routerLinkActive="active" class="title-page"> |
20 | Jobs | 20 | Jobs |
21 | </a> | 21 | </a> |
22 | 22 | ||
23 | <a *ngIf="hasConfigRight()" routerLink="/admin/config" routerLinkActive="active" class="title-page"> | 23 | <a i18n *ngIf="hasConfigRight()" routerLink="/admin/config" routerLinkActive="active" class="title-page"> |
24 | Configuration | 24 | Configuration |
25 | </a> | 25 | </a> |
26 | </div> | 26 | </div> |
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 8a1e33c56..4263b7b5f 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 | |||
@@ -4,13 +4,13 @@ | |||
4 | 4 | ||
5 | <tab heading="Basic configuration"> | 5 | <tab heading="Basic configuration"> |
6 | 6 | ||
7 | <div class="inner-form-title">Instance</div> | 7 | <div i18n class="inner-form-title">Instance</div> |
8 | 8 | ||
9 | <div class="form-group"> | 9 | <div class="form-group"> |
10 | <label for="instanceName">Name</label> | 10 | <label i18n for="instanceName">Name</label> |
11 | <input | 11 | <input |
12 | type="text" id="instanceName" | 12 | type="text" id="instanceName" |
13 | formControlName="instanceName" [ngClass]="{ 'input-error': formErrors['instanceName'] }" | 13 | formControlName="instanceName" [ngClass]="{ 'input-error': formErrors['instanceName'] }" |
14 | > | 14 | > |
15 | <div *ngIf="formErrors.instanceName" class="form-error"> | 15 | <div *ngIf="formErrors.instanceName" class="form-error"> |
16 | {{ formErrors.instanceName }} | 16 | {{ formErrors.instanceName }} |
@@ -18,10 +18,10 @@ | |||
18 | </div> | 18 | </div> |
19 | 19 | ||
20 | <div class="form-group"> | 20 | <div class="form-group"> |
21 | <label for="instanceShortDescription">Short description</label> | 21 | <label i18n for="instanceShortDescription">Short description</label> |
22 | <textarea | 22 | <textarea |
23 | id="instanceShortDescription" formControlName="instanceShortDescription" | 23 | id="instanceShortDescription" formControlName="instanceShortDescription" |
24 | [ngClass]="{ 'input-error': formErrors['instanceShortDescription'] }" | 24 | [ngClass]="{ 'input-error': formErrors['instanceShortDescription'] }" |
25 | ></textarea> | 25 | ></textarea> |
26 | <div *ngIf="formErrors.instanceShortDescription" class="form-error"> | 26 | <div *ngIf="formErrors.instanceShortDescription" class="form-error"> |
27 | {{ formErrors.instanceShortDescription }} | 27 | {{ formErrors.instanceShortDescription }} |
@@ -29,10 +29,10 @@ | |||
29 | </div> | 29 | </div> |
30 | 30 | ||
31 | <div class="form-group"> | 31 | <div class="form-group"> |
32 | <label for="instanceDescription">Description</label><my-help helpType="markdownText"></my-help> | 32 | <label i18n for="instanceDescription">Description</label><my-help helpType="markdownText"></my-help> |
33 | <my-markdown-textarea | 33 | <my-markdown-textarea |
34 | id="instanceDescription" formControlName="instanceDescription" textareaWidth="500px" [previewColumn]="true" | 34 | id="instanceDescription" formControlName="instanceDescription" textareaWidth="500px" [previewColumn]="true" |
35 | [classes]="{ 'input-error': formErrors['instanceDescription'] }" | 35 | [classes]="{ 'input-error': formErrors['instanceDescription'] }" |
36 | ></my-markdown-textarea> | 36 | ></my-markdown-textarea> |
37 | <div *ngIf="formErrors.instanceDescription" class="form-error"> | 37 | <div *ngIf="formErrors.instanceDescription" class="form-error"> |
38 | {{ formErrors.instanceDescription }} | 38 | {{ formErrors.instanceDescription }} |
@@ -40,10 +40,10 @@ | |||
40 | </div> | 40 | </div> |
41 | 41 | ||
42 | <div class="form-group"> | 42 | <div class="form-group"> |
43 | <label for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help> | 43 | <label i18n for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help> |
44 | <my-markdown-textarea | 44 | <my-markdown-textarea |
45 | id="instanceTerms" formControlName="instanceTerms" textareaWidth="500px" [previewColumn]="true" | 45 | id="instanceTerms" formControlName="instanceTerms" textareaWidth="500px" [previewColumn]="true" |
46 | [ngClass]="{ 'input-error': formErrors['instanceTerms'] }" | 46 | [ngClass]="{ 'input-error': formErrors['instanceTerms'] }" |
47 | ></my-markdown-textarea> | 47 | ></my-markdown-textarea> |
48 | <div *ngIf="formErrors.instanceTerms" class="form-error"> | 48 | <div *ngIf="formErrors.instanceTerms" class="form-error"> |
49 | {{ formErrors.instanceTerms }} | 49 | {{ formErrors.instanceTerms }} |
@@ -51,12 +51,12 @@ | |||
51 | </div> | 51 | </div> |
52 | 52 | ||
53 | <div class="form-group"> | 53 | <div class="form-group"> |
54 | <label for="instanceDefaultClientRoute">Default client route</label> | 54 | <label i18n for="instanceDefaultClientRoute">Default client route</label> |
55 | <div class="peertube-select-container"> | 55 | <div class="peertube-select-container"> |
56 | <select id="instanceDefaultClientRoute" formControlName="instanceDefaultClientRoute"> | 56 | <select id="instanceDefaultClientRoute" formControlName="instanceDefaultClientRoute"> |
57 | <option value="/videos/trending">Videos Trending</option> | 57 | <option i18n value="/videos/trending">Videos Trending</option> |
58 | <option value="/videos/recently-added">Videos Recently Added</option> | 58 | <option i18n value="/videos/recently-added">Videos Recently Added</option> |
59 | <option value="/videos/local">Local videos</option> | 59 | <option i18n value="/videos/local">Local videos</option> |
60 | </select> | 60 | </select> |
61 | </div> | 61 | </div> |
62 | <div *ngIf="formErrors.instanceDefaultClientRoute" class="form-error"> | 62 | <div *ngIf="formErrors.instanceDefaultClientRoute" class="form-error"> |
@@ -65,14 +65,17 @@ | |||
65 | </div> | 65 | </div> |
66 | 66 | ||
67 | <div class="form-group"> | 67 | <div class="form-group"> |
68 | <label for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label> | 68 | <label i18n for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label> |
69 | <my-help helpType="custom" customHtml="With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video."></my-help> | 69 | <my-help |
70 | helpType="custom" i18n-customHtml | ||
71 | customHtml="With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video." | ||
72 | ></my-help> | ||
70 | 73 | ||
71 | <div class="peertube-select-container"> | 74 | <div class="peertube-select-container"> |
72 | <select id="instanceDefaultNSFWPolicy" formControlName="instanceDefaultNSFWPolicy"> | 75 | <select id="instanceDefaultNSFWPolicy" formControlName="instanceDefaultNSFWPolicy"> |
73 | <option value="do_not_list">Do not list</option> | 76 | <option i18n value="do_not_list">Do not list</option> |
74 | <option value="blur">Blur thumbnails</option> | 77 | <option i18n value="blur">Blur thumbnails</option> |
75 | <option value="display">Display</option> | 78 | <option i18n value="display">Display</option> |
76 | </select> | 79 | </select> |
77 | </div> | 80 | </div> |
78 | <div *ngIf="formErrors.instanceDefaultNSFWPolicy" class="form-error"> | 81 | <div *ngIf="formErrors.instanceDefaultNSFWPolicy" class="form-error"> |
@@ -80,43 +83,43 @@ | |||
80 | </div> | 83 | </div> |
81 | </div> | 84 | </div> |
82 | 85 | ||
83 | <div class="inner-form-title">Signup</div> | 86 | <div i18n class="inner-form-title">Signup</div> |
84 | 87 | ||
85 | <div class="form-group"> | 88 | <div class="form-group"> |
86 | <input type="checkbox" id="signupEnabled" formControlName="signupEnabled"> | 89 | <input type="checkbox" id="signupEnabled" formControlName="signupEnabled"> |
87 | 90 | ||
88 | <label for="signupEnabled"></label> | 91 | <label for="signupEnabled"></label> |
89 | <label for="signupEnabled">Signup enabled</label> | 92 | <label i18n for="signupEnabled">Signup enabled</label> |
90 | </div> | 93 | </div> |
91 | 94 | ||
92 | <div *ngIf="isSignupEnabled()" class="form-group"> | 95 | <div *ngIf="isSignupEnabled()" class="form-group"> |
93 | <label for="signupLimit">Signup limit</label> | 96 | <label i18n for="signupLimit">Signup limit</label> |
94 | <input | 97 | <input |
95 | type="text" id="signupLimit" | 98 | type="text" id="signupLimit" |
96 | formControlName="signupLimit" [ngClass]="{ 'input-error': formErrors['signupLimit'] }" | 99 | formControlName="signupLimit" [ngClass]="{ 'input-error': formErrors['signupLimit'] }" |
97 | > | 100 | > |
98 | <div *ngIf="formErrors.signupLimit" class="form-error"> | 101 | <div *ngIf="formErrors.signupLimit" class="form-error"> |
99 | {{ formErrors.signupLimit }} | 102 | {{ formErrors.signupLimit }} |
100 | </div> | 103 | </div> |
101 | </div> | 104 | </div> |
102 | 105 | ||
103 | <div class="inner-form-title">Administrator</div> | 106 | <div i18n class="inner-form-title">Administrator</div> |
104 | 107 | ||
105 | <div class="form-group"> | 108 | <div class="form-group"> |
106 | <label for="adminEmail">Admin email</label> | 109 | <label i18n for="adminEmail">Admin email</label> |
107 | <input | 110 | <input |
108 | type="text" id="adminEmail" | 111 | type="text" id="adminEmail" |
109 | formControlName="adminEmail" [ngClass]="{ 'input-error': formErrors['adminEmail'] }" | 112 | formControlName="adminEmail" [ngClass]="{ 'input-error': formErrors['adminEmail'] }" |
110 | > | 113 | > |
111 | <div *ngIf="formErrors.adminEmail" class="form-error"> | 114 | <div *ngIf="formErrors.adminEmail" class="form-error"> |
112 | {{ formErrors.adminEmail }} | 115 | {{ formErrors.adminEmail }} |
113 | </div> | 116 | </div> |
114 | </div> | 117 | </div> |
115 | 118 | ||
116 | <div class="inner-form-title">Users</div> | 119 | <div i18n class="inner-form-title">Users</div> |
117 | 120 | ||
118 | <div class="form-group"> | 121 | <div class="form-group"> |
119 | <label for="userVideoQuota">User default video quota</label> | 122 | <label i18n for="userVideoQuota">User default video quota</label> |
120 | <div class="peertube-select-container"> | 123 | <div class="peertube-select-container"> |
121 | <select id="userVideoQuota" formControlName="userVideoQuota"> | 124 | <select id="userVideoQuota" formControlName="userVideoQuota"> |
122 | <option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value"> | 125 | <option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value"> |
@@ -132,14 +135,17 @@ | |||
132 | 135 | ||
133 | <tab heading="Services"> | 136 | <tab heading="Services"> |
134 | 137 | ||
135 | <div class="inner-form-title">Twitter</div> | 138 | <div i18n class="inner-form-title">Twitter</div> |
136 | 139 | ||
137 | <div class="form-group"> | 140 | <div class="form-group"> |
138 | <label for="signupLimit">Your Twitter username</label> | 141 | <label i18n for="signupLimit">Your Twitter username</label> |
139 | <my-help helpType="custom" customHtml="Indicates the Twitter account for the website or platform on which the content was published."></my-help> | 142 | <my-help |
143 | helpType="custom" i18n-customHtml | ||
144 | customHtml="Indicates the Twitter account for the website or platform on which the content was published." | ||
145 | ></my-help> | ||
140 | <input | 146 | <input |
141 | type="text" id="servicesTwitterUsername" | 147 | type="text" id="servicesTwitterUsername" |
142 | formControlName="servicesTwitterUsername" [ngClass]="{ 'input-error': formErrors['servicesTwitterUsername'] }" | 148 | formControlName="servicesTwitterUsername" [ngClass]="{ 'input-error': formErrors['servicesTwitterUsername'] }" |
143 | > | 149 | > |
144 | <div *ngIf="formErrors.servicesTwitterUsername" class="form-error"> | 150 | <div *ngIf="formErrors.servicesTwitterUsername" class="form-error"> |
145 | {{ formErrors.servicesTwitterUsername }} | 151 | {{ formErrors.servicesTwitterUsername }} |
@@ -150,29 +156,32 @@ | |||
150 | <input type="checkbox" id="servicesTwitterWhitelisted" formControlName="servicesTwitterWhitelisted"> | 156 | <input type="checkbox" id="servicesTwitterWhitelisted" formControlName="servicesTwitterWhitelisted"> |
151 | 157 | ||
152 | <label for="servicesTwitterWhitelisted"></label> | 158 | <label for="servicesTwitterWhitelisted"></label> |
153 | <label for="servicesTwitterWhitelisted">Instance whitelisted by Twitter</label> | 159 | <label i18n for="servicesTwitterWhitelisted">Instance whitelisted by Twitter</label> |
154 | <my-help helpType="custom" customHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br /> | 160 | <my-help |
161 | helpType="custom" i18n-customHtml | ||
162 | customHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br /> | ||
155 | If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br /> | 163 | If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br /> |
156 | Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> to see if you instance is whitelisted."></my-help> | 164 | Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> to see if you instance is whitelisted." |
165 | ></my-help> | ||
157 | 166 | ||
158 | </div> | 167 | </div> |
159 | </tab> | 168 | </tab> |
160 | 169 | ||
161 | <tab heading="Advanced configuration"> | 170 | <tab heading="Advanced configuration"> |
162 | 171 | ||
163 | <div class="inner-form-title">Transcoding</div> | 172 | <div i18n class="inner-form-title">Transcoding</div> |
164 | 173 | ||
165 | <div class="form-group"> | 174 | <div class="form-group"> |
166 | <input type="checkbox" id="transcodingEnabled" formControlName="transcodingEnabled"> | 175 | <input type="checkbox" id="transcodingEnabled" formControlName="transcodingEnabled"> |
167 | 176 | ||
168 | <label for="transcodingEnabled"></label> | 177 | <label for="transcodingEnabled"></label> |
169 | <label for="transcodingEnabled">Transcoding enabled</label> | 178 | <label i18n for="transcodingEnabled">Transcoding enabled</label> |
170 | </div> | 179 | </div> |
171 | 180 | ||
172 | <ng-template [ngIf]="isTranscodingEnabled()"> | 181 | <ng-template [ngIf]="isTranscodingEnabled()"> |
173 | 182 | ||
174 | <div class="form-group"> | 183 | <div class="form-group"> |
175 | <label for="transcodingThreads">Transcoding threads</label> | 184 | <label i18n for="transcodingThreads">Transcoding threads</label> |
176 | <div class="peertube-select-container"> | 185 | <div class="peertube-select-container"> |
177 | <select id="transcodingThreads" formControlName="transcodingThreads"> | 186 | <select id="transcodingThreads" formControlName="transcodingThreads"> |
178 | <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value"> | 187 | <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value"> |
@@ -191,33 +200,39 @@ Check this checkbox, save the configuration and test with a video URL of your in | |||
191 | [formControlName]="getResolutionKey(resolution)" | 200 | [formControlName]="getResolutionKey(resolution)" |
192 | > | 201 | > |
193 | <label [for]="getResolutionKey(resolution)"></label> | 202 | <label [for]="getResolutionKey(resolution)"></label> |
194 | <label [for]="getResolutionKey(resolution)">Resolution {{ resolution }} enabled</label> | 203 | <label i18n [for]="getResolutionKey(resolution)">Resolution {{ resolution }} enabled</label> |
195 | </div> | 204 | </div> |
196 | </ng-template> | 205 | </ng-template> |
197 | 206 | ||
198 | <div class="inner-form-title">Cache</div> | 207 | <div i18n class="inner-form-title">Cache</div> |
199 | 208 | ||
200 | <div class="form-group"> | 209 | <div class="form-group"> |
201 | <label for="cachePreviewsSize">Preview cache size</label> | 210 | <label i18n for="cachePreviewsSize">Preview cache size</label> |
202 | <my-help helpType="custom" customHtml="Previews are not federated. We fetch them directly from the origin instance and cache them."></my-help> | 211 | <my-help |
212 | helpType="custom" i18n-customHtml | ||
213 | customHtml="Previews are not federated. We fetch them directly from the origin instance and cache them." | ||
214 | ></my-help> | ||
203 | 215 | ||
204 | <input | 216 | <input |
205 | type="text" id="cachePreviewsSize" | 217 | type="text" id="cachePreviewsSize" |
206 | formControlName="cachePreviewsSize" [ngClass]="{ 'input-error': formErrors['cachePreviewsSize'] }" | 218 | formControlName="cachePreviewsSize" [ngClass]="{ 'input-error': formErrors['cachePreviewsSize'] }" |
207 | > | 219 | > |
208 | <div *ngIf="formErrors.cachePreviewsSize" class="form-error"> | 220 | <div *ngIf="formErrors.cachePreviewsSize" class="form-error"> |
209 | {{ formErrors.cachePreviewsSize }} | 221 | {{ formErrors.cachePreviewsSize }} |
210 | </div> | 222 | </div> |
211 | </div> | 223 | </div> |
212 | 224 | ||
213 | <div class="inner-form-title">Customizations</div> | 225 | <div i18n class="inner-form-title">Customizations</div> |
214 | 226 | ||
215 | <div class="form-group"> | 227 | <div class="form-group"> |
216 | <label for="customizationJavascript">JavaScript</label> | 228 | <label i18n for="customizationJavascript">JavaScript</label> |
217 | <my-help helpType="custom" customHtml="Write directly JavaScript code.<br />Example: <pre>console.log('my instance is amazing');</pre>"></my-help> | 229 | <my-help |
230 | helpType="custom" i18n-customHtml | ||
231 | customHtml="Write directly JavaScript code.<br />Example: <pre>console.log('my instance is amazing');</pre>" | ||
232 | ></my-help> | ||
218 | <textarea | 233 | <textarea |
219 | id="customizationJavascript" formControlName="customizationJavascript" | 234 | id="customizationJavascript" formControlName="customizationJavascript" |
220 | [ngClass]="{ 'input-error': formErrors['customizationJavascript'] }" | 235 | [ngClass]="{ 'input-error': formErrors['customizationJavascript'] }" |
221 | ></textarea> | 236 | ></textarea> |
222 | <div *ngIf="formErrors.customizationJavascript" class="form-error"> | 237 | <div *ngIf="formErrors.customizationJavascript" class="form-error"> |
223 | {{ formErrors.customizationJavascript }} | 238 | {{ formErrors.customizationJavascript }} |
@@ -228,25 +243,26 @@ Check this checkbox, save the configuration and test with a video URL of your in | |||
228 | <label for="customizationCSS">CSS</label> | 243 | <label for="customizationCSS">CSS</label> |
229 | <my-help | 244 | <my-help |
230 | helpType="custom" | 245 | helpType="custom" |
246 | i18n-customHtml | ||
231 | customHtml=" | 247 | customHtml=" |
232 | Write directly CSS code. Example:<br /> | 248 | Write directly CSS code. Example:<br /> |
233 | <pre> | 249 | <pre> |
234 | body { | 250 | body {{ '{' }} |
235 | background-color: red; | 251 | background-color: red; |
236 | } | 252 | {{ '}' }} |
237 | </pre> | 253 | </pre> |
238 | 254 | ||
239 | Prepend with <em>#custom-css</em> to override styles. Example: | 255 | Prepend with <em>#custom-css</em> to override styles. Example: |
240 | <pre> | 256 | <pre> |
241 | #custom-css .logged-in-email { | 257 | #custom-css .logged-in-email {{ '{' }} |
242 | color: red; | 258 | color: red; |
243 | } | 259 | {{ '}' }} |
244 | </pre> | 260 | </pre> |
245 | " | 261 | " |
246 | ></my-help> | 262 | ></my-help> |
247 | <textarea | 263 | <textarea |
248 | id="customizationCSS" formControlName="customizationCSS" | 264 | id="customizationCSS" formControlName="customizationCSS" |
249 | [ngClass]="{ 'input-error': formErrors['customizationCSS'] }" | 265 | [ngClass]="{ 'input-error': formErrors['customizationCSS'] }" |
250 | ></textarea> | 266 | ></textarea> |
251 | <div *ngIf="formErrors.customizationCSS" class="form-error"> | 267 | <div *ngIf="formErrors.customizationCSS" class="form-error"> |
252 | {{ formErrors.customizationCSS }} | 268 | {{ formErrors.customizationCSS }} |
@@ -255,5 +271,5 @@ Check this checkbox, save the configuration and test with a video URL of your in | |||
255 | </tab> | 271 | </tab> |
256 | </tabset> | 272 | </tabset> |
257 | 273 | ||
258 | <input (click)="formValidated()" type="submit" value="Update configuration" [disabled]="!form.valid"> | 274 | <input (click)="formValidated()" type="submit" i18n-value value="Update configuration" [disabled]="!form.valid"> |
259 | </form> | 275 | </form> |
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 a1e334a74..3f9205460 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 | |||
@@ -8,12 +8,15 @@ import { FormReactive, USER_VIDEO_QUOTA } from '@app/shared' | |||
8 | import { | 8 | import { |
9 | ADMIN_EMAIL, | 9 | ADMIN_EMAIL, |
10 | CACHE_PREVIEWS_SIZE, | 10 | CACHE_PREVIEWS_SIZE, |
11 | INSTANCE_NAME, INSTANCE_SHORT_DESCRIPTION, SERVICES_TWITTER_USERNAME, | 11 | INSTANCE_NAME, |
12 | INSTANCE_SHORT_DESCRIPTION, | ||
13 | SERVICES_TWITTER_USERNAME, | ||
12 | SIGNUP_LIMIT, | 14 | SIGNUP_LIMIT, |
13 | TRANSCODING_THREADS | 15 | TRANSCODING_THREADS |
14 | } from '@app/shared/forms/form-validators/custom-config' | 16 | } from '@app/shared/forms/form-validators/custom-config' |
15 | import { NotificationsService } from 'angular2-notifications' | 17 | import { NotificationsService } from 'angular2-notifications' |
16 | import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model' | 18 | import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model' |
19 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
17 | 20 | ||
18 | @Component({ | 21 | @Component({ |
19 | selector: 'my-edit-custom-config', | 22 | selector: 'my-edit-custom-config', |
@@ -77,7 +80,8 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { | |||
77 | private notificationsService: NotificationsService, | 80 | private notificationsService: NotificationsService, |
78 | private configService: ConfigService, | 81 | private configService: ConfigService, |
79 | private serverService: ServerService, | 82 | private serverService: ServerService, |
80 | private confirmService: ConfirmService | 83 | private confirmService: ConfirmService, |
84 | private i18n: I18n | ||
81 | ) { | 85 | ) { |
82 | super() | 86 | super() |
83 | } | 87 | } |
@@ -133,7 +137,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { | |||
133 | this.forceCheck() | 137 | this.forceCheck() |
134 | }, | 138 | }, |
135 | 139 | ||
136 | err => this.notificationsService.error('Error', err.message) | 140 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
137 | ) | 141 | ) |
138 | } | 142 | } |
139 | 143 | ||
@@ -156,11 +160,15 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { | |||
156 | if (customizations.length !== 0) { | 160 | if (customizations.length !== 0) { |
157 | const customizationsText = customizations.join('/') | 161 | const customizationsText = customizations.join('/') |
158 | 162 | ||
159 | const message = `You set custom ${customizationsText}. ` + | 163 | // FIXME: i18n service does not support string concatenation |
160 | 'This could lead to security issues or bugs if you do not understand it. ' + | 164 | const message = this.i18n('You set custom {{ customizationsText }}. ', { customizationsText }) + |
161 | 'Are you sure you want to update the configuration?' | 165 | this.i18n('This could lead to security issues or bugs if you do not understand it. ') + |
162 | const label = `Please type "I understand the ${customizationsText} I set" to confirm.` | 166 | this.i18n('Are you sure you want to update the configuration?') |
163 | const expectedInputValue = `I understand the ${customizationsText} I set` | 167 | const label = this.i18n( |
168 | 'Please type "I understand the {{ customizationsText }} I set" to confirm.', | ||
169 | { customizationsText } | ||
170 | ) | ||
171 | const expectedInputValue = this.i18n('I understand the {{ customizationsText }} I set', { customizationsText}) | ||
164 | 172 | ||
165 | const confirmRes = await this.confirmService.confirmWithInput(message, label, expectedInputValue) | 173 | const confirmRes = await this.confirmService.confirmWithInput(message, label, expectedInputValue) |
166 | if (confirmRes === false) return | 174 | if (confirmRes === false) return |
@@ -223,10 +231,10 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { | |||
223 | 231 | ||
224 | this.updateForm() | 232 | this.updateForm() |
225 | 233 | ||
226 | this.notificationsService.success('Success', 'Configuration updated.') | 234 | this.notificationsService.success(this.i18n('Success'), this.i18n('Configuration updated.')) |
227 | }, | 235 | }, |
228 | 236 | ||
229 | err => this.notificationsService.error('Error', err.message) | 237 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
230 | ) | 238 | ) |
231 | } | 239 | } |
232 | 240 | ||
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.html b/client/src/app/+admin/follows/followers-list/followers-list.component.html index 85d2a2cf6..1a6ed616a 100644 --- a/client/src/app/+admin/follows/followers-list/followers-list.component.html +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.html | |||
@@ -4,12 +4,12 @@ | |||
4 | > | 4 | > |
5 | <ng-template pTemplate="header"> | 5 | <ng-template pTemplate="header"> |
6 | <tr> | 6 | <tr> |
7 | <th style="width: 60px">ID</th> | 7 | <th i18n style="width: 60px">ID</th> |
8 | <th>Score</th> | 8 | <th i18n>Score</th> |
9 | <th>Name</th> | 9 | <th i18n>Name</th> |
10 | <th>Host</th> | 10 | <th i18n>Host</th> |
11 | <th>State</th> | 11 | <th i18n>State</th> |
12 | <th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> | 12 | <th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> |
13 | </tr> | 13 | </tr> |
14 | </ng-template> | 14 | </ng-template> |
15 | 15 | ||
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.ts b/client/src/app/+admin/follows/followers-list/followers-list.component.ts index 69b3e5e58..96fb67588 100644 --- a/client/src/app/+admin/follows/followers-list/followers-list.component.ts +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.ts | |||
@@ -5,6 +5,7 @@ import { SortMeta } from 'primeng/primeng' | |||
5 | import { AccountFollow } from '../../../../../../shared/models/actors/follow.model' | 5 | import { AccountFollow } from '../../../../../../shared/models/actors/follow.model' |
6 | import { RestPagination, RestTable } from '../../../shared' | 6 | import { RestPagination, RestTable } from '../../../shared' |
7 | import { FollowService } from '../shared' | 7 | import { FollowService } from '../shared' |
8 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
8 | 9 | ||
9 | @Component({ | 10 | @Component({ |
10 | selector: 'my-followers-list', | 11 | selector: 'my-followers-list', |
@@ -20,7 +21,8 @@ export class FollowersListComponent extends RestTable implements OnInit { | |||
20 | 21 | ||
21 | constructor ( | 22 | constructor ( |
22 | private notificationsService: NotificationsService, | 23 | private notificationsService: NotificationsService, |
23 | private followService: FollowService | 24 | private followService: FollowService, |
25 | private i18n: I18n | ||
24 | ) { | 26 | ) { |
25 | super() | 27 | super() |
26 | } | 28 | } |
@@ -37,7 +39,7 @@ export class FollowersListComponent extends RestTable implements OnInit { | |||
37 | this.totalRecords = resultList.total | 39 | this.totalRecords = resultList.total |
38 | }, | 40 | }, |
39 | 41 | ||
40 | err => this.notificationsService.error('Error', err.message) | 42 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
41 | ) | 43 | ) |
42 | } | 44 | } |
43 | } | 45 | } |
diff --git a/client/src/app/+admin/follows/following-add/following-add.component.html b/client/src/app/+admin/follows/following-add/following-add.component.html index 25bab9d0d..72635048c 100644 --- a/client/src/app/+admin/follows/following-add/following-add.component.html +++ b/client/src/app/+admin/follows/following-add/following-add.component.html | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | <form (ngSubmit)="addFollowing()"> | 3 | <form (ngSubmit)="addFollowing()"> |
4 | <div class="form-group"> | 4 | <div class="form-group"> |
5 | <label for="hosts">1 host (without "http://") per line</label> | 5 | <label i18n for="hosts">1 host (without "http://") per line</label> |
6 | 6 | ||
7 | <textarea | 7 | <textarea |
8 | type="text" class="form-control" placeholder="example.com" id="hosts" name="hosts" | 8 | type="text" class="form-control" placeholder="example.com" id="hosts" name="hosts" |
@@ -14,9 +14,9 @@ | |||
14 | </div> | 14 | </div> |
15 | </div> | 15 | </div> |
16 | 16 | ||
17 | <div *ngIf="httpEnabled() === false" class="alert alert-warning"> | 17 | <div i18n *ngIf="httpEnabled() === false" class="alert alert-warning"> |
18 | It seems that you are not on a HTTPS server. Your webserver needs to have TLS activated in order to follow servers. | 18 | It seems that you are not on a HTTPS server. Your webserver needs to have TLS activated in order to follow servers. |
19 | </div> | 19 | </div> |
20 | 20 | ||
21 | <input type="submit" value="Add following" [disabled]="hostsError || !hostsString" class="btn btn-default"> | 21 | <input type="submit" i18n-value value="Add following" [disabled]="hostsError || !hostsString" class="btn btn-default"> |
22 | </form> | 22 | </form> |
diff --git a/client/src/app/+admin/follows/following-add/following-add.component.ts b/client/src/app/+admin/follows/following-add/following-add.component.ts index c296c8852..f197c1fe9 100644 --- a/client/src/app/+admin/follows/following-add/following-add.component.ts +++ b/client/src/app/+admin/follows/following-add/following-add.component.ts | |||
@@ -4,6 +4,7 @@ import { NotificationsService } from 'angular2-notifications' | |||
4 | import { ConfirmService } from '../../../core' | 4 | import { ConfirmService } from '../../../core' |
5 | import { validateHost } from '../../../shared' | 5 | import { validateHost } from '../../../shared' |
6 | import { FollowService } from '../shared' | 6 | import { FollowService } from '../shared' |
7 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
7 | 8 | ||
8 | @Component({ | 9 | @Component({ |
9 | selector: 'my-following-add', | 10 | selector: 'my-following-add', |
@@ -19,7 +20,8 @@ export class FollowingAddComponent { | |||
19 | private router: Router, | 20 | private router: Router, |
20 | private notificationsService: NotificationsService, | 21 | private notificationsService: NotificationsService, |
21 | private confirmService: ConfirmService, | 22 | private confirmService: ConfirmService, |
22 | private followService: FollowService | 23 | private followService: FollowService, |
24 | private i18n: I18n | ||
23 | ) {} | 25 | ) {} |
24 | 26 | ||
25 | httpEnabled () { | 27 | httpEnabled () { |
@@ -34,7 +36,7 @@ export class FollowingAddComponent { | |||
34 | 36 | ||
35 | for (const host of hosts) { | 37 | for (const host of hosts) { |
36 | if (validateHost(host) === false) { | 38 | if (validateHost(host) === false) { |
37 | newHostsErrors.push(`${host} is not valid`) | 39 | newHostsErrors.push(this.i18n('{{ host }} is not valid', { host })) |
38 | } | 40 | } |
39 | } | 41 | } |
40 | 42 | ||
@@ -48,26 +50,26 @@ export class FollowingAddComponent { | |||
48 | 50 | ||
49 | const hosts = this.getNotEmptyHosts() | 51 | const hosts = this.getNotEmptyHosts() |
50 | if (hosts.length === 0) { | 52 | if (hosts.length === 0) { |
51 | this.error = 'You need to specify hosts to follow.' | 53 | this.error = this.i18n('You need to specify hosts to follow.') |
52 | } | 54 | } |
53 | 55 | ||
54 | if (!this.isHostsUnique(hosts)) { | 56 | if (!this.isHostsUnique(hosts)) { |
55 | this.error = 'Hosts need to be unique.' | 57 | this.error = this.i18n('Hosts need to be unique.') |
56 | return | 58 | return |
57 | } | 59 | } |
58 | 60 | ||
59 | const confirmMessage = 'If you confirm, you will send a follow request to:<br /> - ' + hosts.join('<br /> - ') | 61 | const confirmMessage = this.i18n('If you confirm, you will send a follow request to:<br /> - ') + hosts.join('<br /> - ') |
60 | const res = await this.confirmService.confirm(confirmMessage, 'Follow new server(s)') | 62 | const res = await this.confirmService.confirm(confirmMessage, this.i18n('Follow new server(s)')) |
61 | if (res === false) return | 63 | if (res === false) return |
62 | 64 | ||
63 | this.followService.follow(hosts).subscribe( | 65 | this.followService.follow(hosts).subscribe( |
64 | () => { | 66 | () => { |
65 | this.notificationsService.success('Success', 'Follow request(s) sent!') | 67 | this.notificationsService.success(this.i18n('Success'), this.i18n('Follow request(s) sent!')) |
66 | 68 | ||
67 | setTimeout(() => this.router.navigate([ '/admin/follows/following-list' ]), 500) | 69 | setTimeout(() => this.router.navigate([ '/admin/follows/following-list' ]), 500) |
68 | }, | 70 | }, |
69 | 71 | ||
70 | err => this.notificationsService.error('Error', err.message) | 72 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
71 | ) | 73 | ) |
72 | } | 74 | } |
73 | 75 | ||
@@ -76,10 +78,8 @@ export class FollowingAddComponent { | |||
76 | } | 78 | } |
77 | 79 | ||
78 | private getNotEmptyHosts () { | 80 | private getNotEmptyHosts () { |
79 | const hosts = this.hostsString | 81 | return this.hostsString |
80 | .split('\n') | 82 | .split('\n') |
81 | .filter(host => host && host.length !== 0) // Eject empty hosts | 83 | .filter(host => host && host.length !== 0) // Eject empty hosts |
82 | |||
83 | return hosts | ||
84 | } | 84 | } |
85 | } | 85 | } |
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.html b/client/src/app/+admin/follows/following-list/following-list.component.html index 24981d3e9..e4a45e88c 100644 --- a/client/src/app/+admin/follows/following-list/following-list.component.html +++ b/client/src/app/+admin/follows/following-list/following-list.component.html | |||
@@ -4,10 +4,10 @@ | |||
4 | > | 4 | > |
5 | <ng-template pTemplate="header"> | 5 | <ng-template pTemplate="header"> |
6 | <tr> | 6 | <tr> |
7 | <th style="width: 60px">ID</th> | 7 | <th i18n style="width: 60px">ID</th> |
8 | <th>Host</th> | 8 | <th i18n>Host</th> |
9 | <th>State</th> | 9 | <th i18n>State</th> |
10 | <th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> | 10 | <th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> |
11 | <th></th> | 11 | <th></th> |
12 | </tr> | 12 | </tr> |
13 | </ng-template> | 13 | </ng-template> |
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.ts b/client/src/app/+admin/follows/following-list/following-list.component.ts index 873a5d965..2fb818c90 100644 --- a/client/src/app/+admin/follows/following-list/following-list.component.ts +++ b/client/src/app/+admin/follows/following-list/following-list.component.ts | |||
@@ -5,6 +5,7 @@ import { AccountFollow } from '../../../../../../shared/models/actors/follow.mod | |||
5 | import { ConfirmService } from '../../../core/confirm/confirm.service' | 5 | import { ConfirmService } from '../../../core/confirm/confirm.service' |
6 | import { RestPagination, RestTable } from '../../../shared' | 6 | import { RestPagination, RestTable } from '../../../shared' |
7 | import { FollowService } from '../shared' | 7 | import { FollowService } from '../shared' |
8 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
8 | 9 | ||
9 | @Component({ | 10 | @Component({ |
10 | selector: 'my-followers-list', | 11 | selector: 'my-followers-list', |
@@ -20,7 +21,8 @@ export class FollowingListComponent extends RestTable implements OnInit { | |||
20 | constructor ( | 21 | constructor ( |
21 | private notificationsService: NotificationsService, | 22 | private notificationsService: NotificationsService, |
22 | private confirmService: ConfirmService, | 23 | private confirmService: ConfirmService, |
23 | private followService: FollowService | 24 | private followService: FollowService, |
25 | private i18n: I18n | ||
24 | ) { | 26 | ) { |
25 | super() | 27 | super() |
26 | } | 28 | } |
@@ -30,16 +32,22 @@ export class FollowingListComponent extends RestTable implements OnInit { | |||
30 | } | 32 | } |
31 | 33 | ||
32 | async removeFollowing (follow: AccountFollow) { | 34 | async removeFollowing (follow: AccountFollow) { |
33 | const res = await this.confirmService.confirm(`Do you really want to unfollow ${follow.following.host}?`, 'Unfollow') | 35 | const res = await this.confirmService.confirm( |
36 | this.i18n('Do you really want to unfollow {{ host }}?', { host: follow.following.host }), | ||
37 | this.i18n('Unfollow') | ||
38 | ) | ||
34 | if (res === false) return | 39 | if (res === false) return |
35 | 40 | ||
36 | this.followService.unfollow(follow).subscribe( | 41 | this.followService.unfollow(follow).subscribe( |
37 | () => { | 42 | () => { |
38 | this.notificationsService.success('Success', `You are not following ${follow.following.host} anymore.`) | 43 | this.notificationsService.success( |
44 | this.i18n('Success'), | ||
45 | this.i18n('You are not following {{ host }} anymore.', { host: follow.following.host }) | ||
46 | ) | ||
39 | this.loadData() | 47 | this.loadData() |
40 | }, | 48 | }, |
41 | 49 | ||
42 | err => this.notificationsService.error('Error', err.message) | 50 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
43 | ) | 51 | ) |
44 | } | 52 | } |
45 | 53 | ||
@@ -51,7 +59,7 @@ export class FollowingListComponent extends RestTable implements OnInit { | |||
51 | this.totalRecords = resultList.total | 59 | this.totalRecords = resultList.total |
52 | }, | 60 | }, |
53 | 61 | ||
54 | err => this.notificationsService.error('Error', err.message) | 62 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
55 | ) | 63 | ) |
56 | } | 64 | } |
57 | } | 65 | } |
diff --git a/client/src/app/+admin/follows/follows.component.html b/client/src/app/+admin/follows/follows.component.html index 71e82059c..a8258bf70 100644 --- a/client/src/app/+admin/follows/follows.component.html +++ b/client/src/app/+admin/follows/follows.component.html | |||
@@ -1,5 +1,5 @@ | |||
1 | <div class="admin-sub-header"> | 1 | <div class="admin-sub-header"> |
2 | <div class="form-sub-title">Manage follows</div> | 2 | <div i18n class="form-sub-title">Manage follows</div> |
3 | 3 | ||
4 | <tabset #followsMenuTabs> | 4 | <tabset #followsMenuTabs> |
5 | <tab *ngFor="let link of links"> | 5 | <tab *ngFor="let link of links"> |
diff --git a/client/src/app/+admin/jobs/index.ts b/client/src/app/+admin/jobs/index.ts index 7b5271956..c0e0cc95d 100644 --- a/client/src/app/+admin/jobs/index.ts +++ b/client/src/app/+admin/jobs/index.ts | |||
@@ -1 +1,4 @@ | |||
1 | export * from './' | 1 | export * from './shared' |
2 | export * from './jobs-list' | ||
3 | export * from './job.routes' | ||
4 | export * from './job.component' | ||
diff --git a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.html b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.html index 0cc4dc3e0..20c35cb5b 100644 --- a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.html +++ b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.html | |||
@@ -1,5 +1,5 @@ | |||
1 | <div class="admin-sub-header"> | 1 | <div class="admin-sub-header"> |
2 | <div class="form-sub-title">Jobs list</div> | 2 | <div i18n class="form-sub-title">Jobs list</div> |
3 | 3 | ||
4 | <div class="peertube-select-container"> | 4 | <div class="peertube-select-container"> |
5 | <select [(ngModel)]="jobState" (ngModelChange)="onJobStateChanged()"> | 5 | <select [(ngModel)]="jobState" (ngModelChange)="onJobStateChanged()"> |
@@ -15,11 +15,11 @@ | |||
15 | <ng-template pTemplate="header"> | 15 | <ng-template pTemplate="header"> |
16 | <tr> | 16 | <tr> |
17 | <th style="width: 27px"></th> | 17 | <th style="width: 27px"></th> |
18 | <th style="width: 60px">ID</th> | 18 | <th i18n style="width: 60px">ID</th> |
19 | <th style="width: 210px">Type</th> | 19 | <th i18n style="width: 210px">Type</th> |
20 | <th style="width: 130px">State</th> | 20 | <th i18n style="width: 130px">State</th> |
21 | <th style="width: 250px" pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> | 21 | <th i18n style="width: 250px" pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> |
22 | <th style="width: 250px">Updated</th> | 22 | <th i18n style="width: 250px">Updated</th> |
23 | </tr> | 23 | </tr> |
24 | </ng-template> | 24 | </ng-template> |
25 | 25 | ||
diff --git a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts index ad2f05c6b..29dd9f31c 100644 --- a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts +++ b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts | |||
@@ -7,6 +7,7 @@ import { JobState } from '../../../../../../shared/models' | |||
7 | import { RestPagination, RestTable } from '../../../shared' | 7 | import { RestPagination, RestTable } from '../../../shared' |
8 | import { RestExtractor } from '../../../shared/rest/rest-extractor.service' | 8 | import { RestExtractor } from '../../../shared/rest/rest-extractor.service' |
9 | import { JobService } from '../shared' | 9 | import { JobService } from '../shared' |
10 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
10 | 11 | ||
11 | @Component({ | 12 | @Component({ |
12 | selector: 'my-jobs-list', | 13 | selector: 'my-jobs-list', |
@@ -27,7 +28,8 @@ export class JobsListComponent extends RestTable implements OnInit { | |||
27 | constructor ( | 28 | constructor ( |
28 | private notificationsService: NotificationsService, | 29 | private notificationsService: NotificationsService, |
29 | private restExtractor: RestExtractor, | 30 | private restExtractor: RestExtractor, |
30 | private jobsService: JobService | 31 | private jobsService: JobService, |
32 | private i18n: I18n | ||
31 | ) { | 33 | ) { |
32 | super() | 34 | super() |
33 | } | 35 | } |
@@ -51,7 +53,7 @@ export class JobsListComponent extends RestTable implements OnInit { | |||
51 | this.totalRecords = resultList.total | 53 | this.totalRecords = resultList.total |
52 | }, | 54 | }, |
53 | 55 | ||
54 | err => this.notificationsService.error('Error', err.message) | 56 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
55 | ) | 57 | ) |
56 | } | 58 | } |
57 | 59 | ||
diff --git a/client/src/app/+admin/users/shared/user.service.ts b/client/src/app/+admin/users/shared/user.service.ts index 578cd98c3..d8b00b862 100644 --- a/client/src/app/+admin/users/shared/user.service.ts +++ b/client/src/app/+admin/users/shared/user.service.ts | |||
@@ -7,6 +7,7 @@ import { Observable } from 'rxjs' | |||
7 | import { ResultList, UserCreate, UserUpdate } from '../../../../../../shared' | 7 | import { ResultList, UserCreate, UserUpdate } from '../../../../../../shared' |
8 | import { environment } from '../../../../environments/environment' | 8 | import { environment } from '../../../../environments/environment' |
9 | import { RestExtractor, RestPagination, RestService, User } from '../../../shared' | 9 | import { RestExtractor, RestPagination, RestService, User } from '../../../shared' |
10 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
10 | 11 | ||
11 | @Injectable() | 12 | @Injectable() |
12 | export class UserService { | 13 | export class UserService { |
@@ -16,9 +17,9 @@ export class UserService { | |||
16 | constructor ( | 17 | constructor ( |
17 | private authHttp: HttpClient, | 18 | private authHttp: HttpClient, |
18 | private restService: RestService, | 19 | private restService: RestService, |
19 | private restExtractor: RestExtractor | 20 | private restExtractor: RestExtractor, |
20 | ) { | 21 | private i18n: I18n |
21 | } | 22 | ) { } |
22 | 23 | ||
23 | addUser (userCreate: UserCreate) { | 24 | addUser (userCreate: UserCreate) { |
24 | return this.authHttp.post(UserService.BASE_USERS_URL, userCreate) | 25 | return this.authHttp.post(UserService.BASE_USERS_URL, userCreate) |
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 2a9882cde..b91ffa115 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 | |||
@@ -1,20 +1,13 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | 1 | import { Component, OnInit } from '@angular/core' |
2 | import { FormBuilder, FormGroup } from '@angular/forms' | 2 | import { FormBuilder, FormGroup } from '@angular/forms' |
3 | import { Router } from '@angular/router' | 3 | import { Router } from '@angular/router' |
4 | |||
5 | import { NotificationsService } from 'angular2-notifications' | 4 | import { NotificationsService } from 'angular2-notifications' |
6 | |||
7 | import { UserService } from '../shared' | 5 | import { UserService } from '../shared' |
8 | import { | 6 | import { USER_EMAIL, USER_PASSWORD, USER_ROLE, USER_USERNAME, USER_VIDEO_QUOTA } from '../../../shared' |
9 | USER_USERNAME, | ||
10 | USER_EMAIL, | ||
11 | USER_PASSWORD, | ||
12 | USER_VIDEO_QUOTA, | ||
13 | USER_ROLE | ||
14 | } from '../../../shared' | ||
15 | import { ServerService } from '../../../core' | 7 | import { ServerService } from '../../../core' |
16 | import { UserCreate, UserRole } from '../../../../../../shared' | 8 | import { UserCreate, UserRole } from '../../../../../../shared' |
17 | import { UserEdit } from './user-edit' | 9 | import { UserEdit } from './user-edit' |
10 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
18 | 11 | ||
19 | @Component({ | 12 | @Component({ |
20 | selector: 'my-user-create', | 13 | selector: 'my-user-create', |
@@ -45,7 +38,8 @@ export class UserCreateComponent extends UserEdit implements OnInit { | |||
45 | private formBuilder: FormBuilder, | 38 | private formBuilder: FormBuilder, |
46 | private router: Router, | 39 | private router: Router, |
47 | private notificationsService: NotificationsService, | 40 | private notificationsService: NotificationsService, |
48 | private userService: UserService | 41 | private userService: UserService, |
42 | private i18n: I18n | ||
49 | ) { | 43 | ) { |
50 | super() | 44 | super() |
51 | } | 45 | } |
@@ -76,7 +70,10 @@ export class UserCreateComponent extends UserEdit implements OnInit { | |||
76 | 70 | ||
77 | this.userService.addUser(userCreate).subscribe( | 71 | this.userService.addUser(userCreate).subscribe( |
78 | () => { | 72 | () => { |
79 | this.notificationsService.success('Success', `User ${userCreate.username} created.`) | 73 | this.notificationsService.success( |
74 | this.i18n('Success'), | ||
75 | this.i18n('User {{ username }} created.', { username: userCreate.username }) | ||
76 | ) | ||
80 | this.router.navigate([ '/admin/users/list' ]) | 77 | this.router.navigate([ '/admin/users/list' ]) |
81 | }, | 78 | }, |
82 | 79 | ||
@@ -89,6 +86,6 @@ export class UserCreateComponent extends UserEdit implements OnInit { | |||
89 | } | 86 | } |
90 | 87 | ||
91 | getFormButtonTitle () { | 88 | getFormButtonTitle () { |
92 | return 'Create user' | 89 | return this.i18n('Create user') |
93 | } | 90 | } |
94 | } | 91 | } |
diff --git a/client/src/app/+admin/users/user-edit/user-edit.component.html b/client/src/app/+admin/users/user-edit/user-edit.component.html index a8c0ddadb..4626a40c9 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.component.html +++ b/client/src/app/+admin/users/user-edit/user-edit.component.html | |||
@@ -1,13 +1,13 @@ | |||
1 | <div class="form-sub-title" *ngIf="isCreation() === true">Create user</div> | 1 | <div i18n class="form-sub-title" *ngIf="isCreation() === true">Create user</div> |
2 | <div class="form-sub-title" *ngIf="isCreation() === false">Edit user {{ username }}</div> | 2 | <div i18n class="form-sub-title" *ngIf="isCreation() === false">Edit user {{ username }}</div> |
3 | 3 | ||
4 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> | 4 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> |
5 | 5 | ||
6 | <form role="form" (ngSubmit)="formValidated()" [formGroup]="form"> | 6 | <form role="form" (ngSubmit)="formValidated()" [formGroup]="form"> |
7 | <div class="form-group" *ngIf="isCreation()"> | 7 | <div class="form-group" *ngIf="isCreation()"> |
8 | <label for="username">Username</label> | 8 | <label i18n for="username">Username</label> |
9 | <input | 9 | <input |
10 | type="text" id="username" placeholder="john" | 10 | type="text" id="username" i18n-placeholder placeholder="john" |
11 | formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }" | 11 | formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }" |
12 | > | 12 | > |
13 | <div *ngIf="formErrors.username" class="form-error"> | 13 | <div *ngIf="formErrors.username" class="form-error"> |
@@ -16,9 +16,9 @@ | |||
16 | </div> | 16 | </div> |
17 | 17 | ||
18 | <div class="form-group"> | 18 | <div class="form-group"> |
19 | <label for="email">Email</label> | 19 | <label i18n for="email">Email</label> |
20 | <input | 20 | <input |
21 | type="text" id="email" placeholder="mail@example.com" | 21 | type="text" id="email" i18n-placeholder placeholder="mail@example.com" |
22 | formControlName="email" [ngClass]="{ 'input-error': formErrors['email'] }" | 22 | formControlName="email" [ngClass]="{ 'input-error': formErrors['email'] }" |
23 | > | 23 | > |
24 | <div *ngIf="formErrors.email" class="form-error"> | 24 | <div *ngIf="formErrors.email" class="form-error"> |
@@ -27,7 +27,7 @@ | |||
27 | </div> | 27 | </div> |
28 | 28 | ||
29 | <div class="form-group" *ngIf="isCreation()"> | 29 | <div class="form-group" *ngIf="isCreation()"> |
30 | <label for="password">Password</label> | 30 | <label i18n for="password">Password</label> |
31 | <input | 31 | <input |
32 | type="password" id="password" | 32 | type="password" id="password" |
33 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | 33 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" |
@@ -38,7 +38,7 @@ | |||
38 | </div> | 38 | </div> |
39 | 39 | ||
40 | <div class="form-group"> | 40 | <div class="form-group"> |
41 | <label for="role">Role</label> | 41 | <label i18n for="role">Role</label> |
42 | <div class="peertube-select-container"> | 42 | <div class="peertube-select-container"> |
43 | <select id="role" formControlName="role"> | 43 | <select id="role" formControlName="role"> |
44 | <option *ngFor="let role of roles" [value]="role.value"> | 44 | <option *ngFor="let role of roles" [value]="role.value"> |
@@ -53,7 +53,7 @@ | |||
53 | </div> | 53 | </div> |
54 | 54 | ||
55 | <div class="form-group"> | 55 | <div class="form-group"> |
56 | <label for="videoQuota">Video quota</label> | 56 | <label i18n for="videoQuota">Video quota</label> |
57 | <div class="peertube-select-container"> | 57 | <div class="peertube-select-container"> |
58 | <select id="videoQuota" formControlName="videoQuota"> | 58 | <select id="videoQuota" formControlName="videoQuota"> |
59 | <option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value"> | 59 | <option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value"> |
@@ -62,7 +62,7 @@ | |||
62 | </select> | 62 | </select> |
63 | </div> | 63 | </div> |
64 | 64 | ||
65 | <div class="transcoding-information" *ngIf="isTranscodingInformationDisplayed()"> | 65 | <div i18n class="transcoding-information" *ngIf="isTranscodingInformationDisplayed()"> |
66 | Transcoding is enabled on server. The video quota only take in account <strong>original</strong> video. <br /> | 66 | Transcoding is enabled on server. The video quota only take in account <strong>original</strong> video. <br /> |
67 | At most, this user could use ~ {{ computeQuotaWithTranscoding() | bytes: 0 }}. | 67 | At most, this user could use ~ {{ computeQuotaWithTranscoding() | bytes: 0 }}. |
68 | </div> | 68 | </div> |
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 3cde07c65..dca555706 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 | |||
@@ -8,6 +8,7 @@ import { User, USER_EMAIL, USER_ROLE, USER_VIDEO_QUOTA } from '../../../shared' | |||
8 | import { ServerService } from '../../../core' | 8 | import { ServerService } from '../../../core' |
9 | import { UserEdit } from './user-edit' | 9 | import { UserEdit } from './user-edit' |
10 | import { UserUpdate } from '../../../../../../shared' | 10 | import { UserUpdate } from '../../../../../../shared' |
11 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
11 | 12 | ||
12 | @Component({ | 13 | @Component({ |
13 | selector: 'my-user-update', | 14 | selector: 'my-user-update', |
@@ -39,7 +40,8 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { | |||
39 | private router: Router, | 40 | private router: Router, |
40 | private notificationsService: NotificationsService, | 41 | private notificationsService: NotificationsService, |
41 | private formBuilder: FormBuilder, | 42 | private formBuilder: FormBuilder, |
42 | private userService: UserService | 43 | private userService: UserService, |
44 | private i18n: I18n | ||
43 | ) { | 45 | ) { |
44 | super() | 46 | super() |
45 | } | 47 | } |
@@ -81,7 +83,10 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { | |||
81 | 83 | ||
82 | this.userService.updateUser(this.userId, userUpdate).subscribe( | 84 | this.userService.updateUser(this.userId, userUpdate).subscribe( |
83 | () => { | 85 | () => { |
84 | this.notificationsService.success('Success', `User ${this.username} updated.`) | 86 | this.notificationsService.success( |
87 | this.i18n('Success'), | ||
88 | this.i18n('User {{ username }} updated.', { username: this.username }) | ||
89 | ) | ||
85 | this.router.navigate([ '/admin/users/list' ]) | 90 | this.router.navigate([ '/admin/users/list' ]) |
86 | }, | 91 | }, |
87 | 92 | ||
@@ -94,7 +99,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { | |||
94 | } | 99 | } |
95 | 100 | ||
96 | getFormButtonTitle () { | 101 | getFormButtonTitle () { |
97 | return 'Update user' | 102 | return this.i18n('Update user') |
98 | } | 103 | } |
99 | 104 | ||
100 | private onUserFetched (userJson: User) { | 105 | private onUserFetched (userJson: User) { |
diff --git a/client/src/app/+admin/users/user-list/user-list.component.html b/client/src/app/+admin/users/user-list/user-list.component.html index 09a4ac1e7..166fafef0 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.html +++ b/client/src/app/+admin/users/user-list/user-list.component.html | |||
@@ -1,9 +1,9 @@ | |||
1 | <div class="admin-sub-header"> | 1 | <div class="admin-sub-header"> |
2 | <div class="form-sub-title">Users list</div> | 2 | <div i18n class="form-sub-title">Users list</div> |
3 | 3 | ||
4 | <a class="add-button" routerLink="/admin/users/create"> | 4 | <a class="add-button" routerLink="/admin/users/create"> |
5 | <span class="icon icon-add"></span> | 5 | <span class="icon icon-add"></span> |
6 | Create user | 6 | <ng-container i18n>Create user</ng-container> |
7 | </a> | 7 | </a> |
8 | </div> | 8 | </div> |
9 | 9 | ||
@@ -13,11 +13,11 @@ | |||
13 | > | 13 | > |
14 | <ng-template pTemplate="header"> | 14 | <ng-template pTemplate="header"> |
15 | <tr> | 15 | <tr> |
16 | <th pSortableColumn="username">Username <p-sortIcon field="username"></p-sortIcon></th> | 16 | <th i18n pSortableColumn="username">Username <p-sortIcon field="username"></p-sortIcon></th> |
17 | <th>Email</th> | 17 | <th i18n>Email</th> |
18 | <th>Video quota</th> | 18 | <th i18n>Video quota</th> |
19 | <th>Role</th> | 19 | <th i18n>Role</th> |
20 | <th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> | 20 | <th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> |
21 | <th></th> | 21 | <th></th> |
22 | </tr> | 22 | </tr> |
23 | </ng-template> | 23 | </ng-template> |
diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts index 2cc4d4349..b644fcf71 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.ts +++ b/client/src/app/+admin/users/user-list/user-list.component.ts | |||
@@ -1,11 +1,10 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | 1 | import { Component, OnInit } from '@angular/core' |
2 | |||
3 | import { NotificationsService } from 'angular2-notifications' | 2 | import { NotificationsService } from 'angular2-notifications' |
4 | import { SortMeta } from 'primeng/components/common/sortmeta' | 3 | import { SortMeta } from 'primeng/components/common/sortmeta' |
5 | |||
6 | import { ConfirmService } from '../../../core' | 4 | import { ConfirmService } from '../../../core' |
7 | import { RestPagination, RestTable, User } from '../../../shared' | 5 | import { RestPagination, RestTable, User } from '../../../shared' |
8 | import { UserService } from '../shared' | 6 | import { UserService } from '../shared' |
7 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
9 | 8 | ||
10 | @Component({ | 9 | @Component({ |
11 | selector: 'my-user-list', | 10 | selector: 'my-user-list', |
@@ -22,7 +21,8 @@ export class UserListComponent extends RestTable implements OnInit { | |||
22 | constructor ( | 21 | constructor ( |
23 | private notificationsService: NotificationsService, | 22 | private notificationsService: NotificationsService, |
24 | private confirmService: ConfirmService, | 23 | private confirmService: ConfirmService, |
25 | private userService: UserService | 24 | private userService: UserService, |
25 | private i18n: I18n | ||
26 | ) { | 26 | ) { |
27 | super() | 27 | super() |
28 | } | 28 | } |
@@ -33,20 +33,23 @@ export class UserListComponent extends RestTable implements OnInit { | |||
33 | 33 | ||
34 | async removeUser (user: User) { | 34 | async removeUser (user: User) { |
35 | if (user.username === 'root') { | 35 | if (user.username === 'root') { |
36 | this.notificationsService.error('Error', 'You cannot delete root.') | 36 | this.notificationsService.error(this.i18n('Error'), this.i18n('You cannot delete root.')) |
37 | return | 37 | return |
38 | } | 38 | } |
39 | 39 | ||
40 | const res = await this.confirmService.confirm('Do you really want to delete this user?', 'Delete') | 40 | const res = await this.confirmService.confirm(this.i18n('Do you really want to delete this user?'), this.i18n('Delete')) |
41 | if (res === false) return | 41 | if (res === false) return |
42 | 42 | ||
43 | this.userService.removeUser(user).subscribe( | 43 | this.userService.removeUser(user).subscribe( |
44 | () => { | 44 | () => { |
45 | this.notificationsService.success('Success', `User ${user.username} deleted.`) | 45 | this.notificationsService.success( |
46 | this.i18n('Success'), | ||
47 | this.i18n('User {{ username }} deleted.', { username: user.username }) | ||
48 | ) | ||
46 | this.loadData() | 49 | this.loadData() |
47 | }, | 50 | }, |
48 | 51 | ||
49 | err => this.notificationsService.error('Error', err.message) | 52 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
50 | ) | 53 | ) |
51 | } | 54 | } |
52 | 55 | ||
@@ -62,7 +65,7 @@ export class UserListComponent extends RestTable implements OnInit { | |||
62 | this.totalRecords = resultList.total | 65 | this.totalRecords = resultList.total |
63 | }, | 66 | }, |
64 | 67 | ||
65 | err => this.notificationsService.error('Error', err.message) | 68 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
66 | ) | 69 | ) |
67 | } | 70 | } |
68 | } | 71 | } |
diff --git a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html index 5f70db991..8111e5f73 100644 --- a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html +++ b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html | |||
@@ -1,5 +1,5 @@ | |||
1 | <div class="admin-sub-header"> | 1 | <div class="admin-sub-header"> |
2 | <div class="form-sub-title">Video abuses list</div> | 2 | <div i18n class="form-sub-title">Video abuses list</div> |
3 | </div> | 3 | </div> |
4 | 4 | ||
5 | <p-table | 5 | <p-table |
@@ -8,10 +8,10 @@ | |||
8 | > | 8 | > |
9 | <ng-template pTemplate="header"> | 9 | <ng-template pTemplate="header"> |
10 | <tr> | 10 | <tr> |
11 | <th>Reason</th> | 11 | <th i18n>Reason</th> |
12 | <th>Reporter</th> | 12 | <th i18n>Reporter</th> |
13 | <th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> | 13 | <th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> |
14 | <th>Video</th> | 14 | <th i18n>Video</th> |
15 | </tr> | 15 | </tr> |
16 | </ng-template> | 16 | </ng-template> |
17 | 17 | ||
@@ -19,13 +19,13 @@ | |||
19 | <tr> | 19 | <tr> |
20 | <td>{{ videoAbuse.reason }}</td> | 20 | <td>{{ videoAbuse.reason }}</td> |
21 | <td> | 21 | <td> |
22 | <a [href]="videoAbuse.reporterAccount.url" title="Go to the account" target="_blank" rel="noopener noreferrer"> | 22 | <a [href]="videoAbuse.reporterAccount.url" i18n-title title="Go to the account" target="_blank" rel="noopener noreferrer"> |
23 | {{ createByString(videoAbuse.reporterAccount) }} | 23 | {{ createByString(videoAbuse.reporterAccount) }} |
24 | </a> | 24 | </a> |
25 | </td> | 25 | </td> |
26 | <td>{{ videoAbuse.createdAt }}</td> | 26 | <td>{{ videoAbuse.createdAt }}</td> |
27 | <td> | 27 | <td> |
28 | <a [href]="videoAbuse.video.url" title="Go to the video" target="_blank" rel="noopener noreferrer"> | 28 | <a [href]="videoAbuse.video.url" i18n-title title="Go to the video" target="_blank" rel="noopener noreferrer"> |
29 | {{ videoAbuse.video.name }} | 29 | {{ videoAbuse.video.name }} |
30 | </a> | 30 | </a> |
31 | </td> | 31 | </td> |
diff --git a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts index b650194b7..6ddebff7e 100644 --- a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts +++ b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.ts | |||
@@ -5,6 +5,7 @@ import { SortMeta } from 'primeng/components/common/sortmeta' | |||
5 | import { VideoAbuse } from '../../../../../../shared' | 5 | import { VideoAbuse } from '../../../../../../shared' |
6 | 6 | ||
7 | import { RestPagination, RestTable, VideoAbuseService } from '../../../shared' | 7 | import { RestPagination, RestTable, VideoAbuseService } from '../../../shared' |
8 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
8 | 9 | ||
9 | @Component({ | 10 | @Component({ |
10 | selector: 'my-video-abuse-list', | 11 | selector: 'my-video-abuse-list', |
@@ -20,7 +21,8 @@ export class VideoAbuseListComponent extends RestTable implements OnInit { | |||
20 | 21 | ||
21 | constructor ( | 22 | constructor ( |
22 | private notificationsService: NotificationsService, | 23 | private notificationsService: NotificationsService, |
23 | private videoAbuseService: VideoAbuseService | 24 | private videoAbuseService: VideoAbuseService, |
25 | private i18n: I18n | ||
24 | ) { | 26 | ) { |
25 | super() | 27 | super() |
26 | } | 28 | } |
@@ -41,7 +43,7 @@ export class VideoAbuseListComponent extends RestTable implements OnInit { | |||
41 | this.totalRecords = resultList.total | 43 | this.totalRecords = resultList.total |
42 | }, | 44 | }, |
43 | 45 | ||
44 | err => this.notificationsService.error('Error', err.message) | 46 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
45 | ) | 47 | ) |
46 | } | 48 | } |
47 | } | 49 | } |
diff --git a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html index 0a0fcb762..04f0e3b5c 100644 --- a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html +++ b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html | |||
@@ -1,5 +1,5 @@ | |||
1 | <div class="admin-sub-header"> | 1 | <div class="admin-sub-header"> |
2 | <div class="form-sub-title">Blacklisted videos</div> | 2 | <div i18n class="form-sub-title">Blacklisted videos</div> |
3 | </div> | 3 | </div> |
4 | 4 | ||
5 | <p-table | 5 | <p-table |
@@ -8,12 +8,12 @@ | |||
8 | > | 8 | > |
9 | <ng-template pTemplate="header"> | 9 | <ng-template pTemplate="header"> |
10 | <tr> | 10 | <tr> |
11 | <th pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th> | 11 | <th i18n pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th> |
12 | <th>Description</th> | 12 | <th i18n>Description</th> |
13 | <th pSortableColumn="views">Views <p-sortIcon field="views"></p-sortIcon></th> | 13 | <th i18n pSortableColumn="views">Views <p-sortIcon field="views"></p-sortIcon></th> |
14 | <th>NSFW</th> | 14 | <th i18n>NSFW</th> |
15 | <th>UUID</th> | 15 | <th i18n>UUID</th> |
16 | <th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> | 16 | <th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> |
17 | <th></th> | 17 | <th></th> |
18 | </tr> | 18 | </tr> |
19 | </ng-template> | 19 | </ng-template> |
@@ -27,7 +27,7 @@ | |||
27 | <td>{{ videoBlacklist.uuid }}</td> | 27 | <td>{{ videoBlacklist.uuid }}</td> |
28 | <td>{{ videoBlacklist.createdAt }}</td> | 28 | <td>{{ videoBlacklist.createdAt }}</td> |
29 | <td class="action-cell"> | 29 | <td class="action-cell"> |
30 | <my-delete-button label="Unblacklist" (click)="removeVideoFromBlacklist(videoBlacklist)"></my-delete-button> | 30 | <my-delete-button i18n-label label="Unblacklist" (click)="removeVideoFromBlacklist(videoBlacklist)"></my-delete-button> |
31 | </td> | 31 | </td> |
32 | </tr> | 32 | </tr> |
33 | </ng-template> | 33 | </ng-template> |
diff --git a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts index 7210e677c..1864e5f65 100644 --- a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts +++ b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts | |||
@@ -1,11 +1,10 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | 1 | import { Component, OnInit } from '@angular/core' |
2 | import { SortMeta } from 'primeng/components/common/sortmeta' | 2 | import { SortMeta } from 'primeng/components/common/sortmeta' |
3 | |||
4 | import { NotificationsService } from 'angular2-notifications' | 3 | import { NotificationsService } from 'angular2-notifications' |
5 | |||
6 | import { ConfirmService } from '../../../core' | 4 | import { ConfirmService } from '../../../core' |
7 | import { VideoBlacklistService, RestTable, RestPagination } from '../../../shared' | 5 | import { RestPagination, RestTable, VideoBlacklistService } from '../../../shared' |
8 | import { BlacklistedVideo } from '../../../../../../shared' | 6 | import { BlacklistedVideo } from '../../../../../../shared' |
7 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
9 | 8 | ||
10 | @Component({ | 9 | @Component({ |
11 | selector: 'my-video-blacklist-list', | 10 | selector: 'my-video-blacklist-list', |
@@ -22,7 +21,8 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit { | |||
22 | constructor ( | 21 | constructor ( |
23 | private notificationsService: NotificationsService, | 22 | private notificationsService: NotificationsService, |
24 | private confirmService: ConfirmService, | 23 | private confirmService: ConfirmService, |
25 | private videoBlacklistService: VideoBlacklistService | 24 | private videoBlacklistService: VideoBlacklistService, |
25 | private i18n: I18n | ||
26 | ) { | 26 | ) { |
27 | super() | 27 | super() |
28 | } | 28 | } |
@@ -32,18 +32,23 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | async removeVideoFromBlacklist (entry: BlacklistedVideo) { | 34 | async removeVideoFromBlacklist (entry: BlacklistedVideo) { |
35 | const confirmMessage = 'Do you really want to remove this video from the blacklist ? It will be available again in the videos list.' | 35 | const confirmMessage = this.i18n( |
36 | 'Do you really want to remove this video from the blacklist ? It will be available again in the videos list.' | ||
37 | ) | ||
36 | 38 | ||
37 | const res = await this.confirmService.confirm(confirmMessage, 'Unblacklist') | 39 | const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblacklist')) |
38 | if (res === false) return | 40 | if (res === false) return |
39 | 41 | ||
40 | this.videoBlacklistService.removeVideoFromBlacklist(entry.videoId).subscribe( | 42 | this.videoBlacklistService.removeVideoFromBlacklist(entry.videoId).subscribe( |
41 | () => { | 43 | () => { |
42 | this.notificationsService.success('Success', `Video ${entry.name} removed from the blacklist.`) | 44 | this.notificationsService.success( |
45 | this.i18n('Success'), | ||
46 | this.i18n('Video {{ name }} removed from the blacklist.', { name: entry.name }) | ||
47 | ) | ||
43 | this.loadData() | 48 | this.loadData() |
44 | }, | 49 | }, |
45 | 50 | ||
46 | err => this.notificationsService.error('Error', err.message) | 51 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
47 | ) | 52 | ) |
48 | } | 53 | } |
49 | 54 | ||
@@ -55,7 +60,7 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit { | |||
55 | this.totalRecords = resultList.total | 60 | this.totalRecords = resultList.total |
56 | }, | 61 | }, |
57 | 62 | ||
58 | err => this.notificationsService.error('Error', err.message) | 63 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
59 | ) | 64 | ) |
60 | } | 65 | } |
61 | } | 66 | } |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html index b0e3cada4..767ef0336 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html +++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html | |||
@@ -2,9 +2,9 @@ | |||
2 | 2 | ||
3 | <form role="form" (ngSubmit)="changePassword()" [formGroup]="form"> | 3 | <form role="form" (ngSubmit)="changePassword()" [formGroup]="form"> |
4 | 4 | ||
5 | <label for="new-password">Change password</label> | 5 | <label i18n for="new-password">Change password</label> |
6 | <input | 6 | <input |
7 | type="password" id="new-password" placeholder="New password" | 7 | type="password" id="new-password" i18n-placeholder placeholder="New password" |
8 | formControlName="new-password" [ngClass]="{ 'input-error': formErrors['new-password'] }" | 8 | formControlName="new-password" [ngClass]="{ 'input-error': formErrors['new-password'] }" |
9 | > | 9 | > |
10 | <div *ngIf="formErrors['new-password']" class="form-error"> | 10 | <div *ngIf="formErrors['new-password']" class="form-error"> |
@@ -12,9 +12,9 @@ | |||
12 | </div> | 12 | </div> |
13 | 13 | ||
14 | <input | 14 | <input |
15 | type="password" id="new-confirmed-password" placeholder="Confirm new password" | 15 | type="password" id="new-confirmed-password" i18n-placeholder placeholder="Confirm new password" |
16 | formControlName="new-confirmed-password" | 16 | formControlName="new-confirmed-password" |
17 | > | 17 | > |
18 | 18 | ||
19 | <input type="submit" value="Change password" [disabled]="!form.valid"> | 19 | <input type="submit" i18n-value value="Change password" [disabled]="!form.valid"> |
20 | </form> | 20 | </form> |
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 80af668f9..1a88aa82e 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 | |||
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core' | |||
2 | import { FormBuilder, FormGroup } from '@angular/forms' | 2 | import { FormBuilder, FormGroup } from '@angular/forms' |
3 | import { NotificationsService } from 'angular2-notifications' | 3 | import { NotificationsService } from 'angular2-notifications' |
4 | import { FormReactive, USER_PASSWORD, UserService } from '../../../shared' | 4 | import { FormReactive, USER_PASSWORD, UserService } from '../../../shared' |
5 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
5 | 6 | ||
6 | @Component({ | 7 | @Component({ |
7 | selector: 'my-account-change-password', | 8 | selector: 'my-account-change-password', |
@@ -24,7 +25,8 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On | |||
24 | constructor ( | 25 | constructor ( |
25 | private formBuilder: FormBuilder, | 26 | private formBuilder: FormBuilder, |
26 | private notificationsService: NotificationsService, | 27 | private notificationsService: NotificationsService, |
27 | private userService: UserService | 28 | private userService: UserService, |
29 | private i18n: I18n | ||
28 | ) { | 30 | ) { |
29 | super() | 31 | super() |
30 | } | 32 | } |
@@ -49,12 +51,12 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On | |||
49 | this.error = null | 51 | this.error = null |
50 | 52 | ||
51 | if (newPassword !== newConfirmedPassword) { | 53 | if (newPassword !== newConfirmedPassword) { |
52 | this.error = 'The new password and the confirmed password do not correspond.' | 54 | this.error = this.i18n('The new password and the confirmed password do not correspond.') |
53 | return | 55 | return |
54 | } | 56 | } |
55 | 57 | ||
56 | this.userService.changePassword(newPassword).subscribe( | 58 | this.userService.changePassword(newPassword).subscribe( |
57 | () => this.notificationsService.success('Success', 'Password updated.'), | 59 | () => this.notificationsService.success(this.i18n('Success'), this.i18n('Password updated.')), |
58 | 60 | ||
59 | err => this.error = err.message | 61 | err => this.error = err.message |
60 | ) | 62 | ) |
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 306f3a12c..bbdce5b02 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,7 +2,7 @@ | |||
2 | 2 | ||
3 | <form role="form" (ngSubmit)="updateMyProfile()" [formGroup]="form"> | 3 | <form role="form" (ngSubmit)="updateMyProfile()" [formGroup]="form"> |
4 | 4 | ||
5 | <label for="display-name">Display name</label> | 5 | <label i18n for="display-name">Display name</label> |
6 | <input | 6 | <input |
7 | type="text" id="display-name" | 7 | type="text" id="display-name" |
8 | formControlName="display-name" [ngClass]="{ 'input-error': formErrors['display-name'] }" | 8 | formControlName="display-name" [ngClass]="{ 'input-error': formErrors['display-name'] }" |
@@ -11,7 +11,7 @@ | |||
11 | {{ formErrors['display-name'] }} | 11 | {{ formErrors['display-name'] }} |
12 | </div> | 12 | </div> |
13 | 13 | ||
14 | <label for="description">Description</label> | 14 | <label i18n for="description">Description</label> |
15 | <textarea | 15 | <textarea |
16 | id="description" formControlName="description" | 16 | id="description" formControlName="description" |
17 | [ngClass]="{ 'input-error': formErrors['description'] }" | 17 | [ngClass]="{ 'input-error': formErrors['description'] }" |
@@ -20,5 +20,5 @@ | |||
20 | {{ formErrors.description }} | 20 | {{ formErrors.description }} |
21 | </div> | 21 | </div> |
22 | 22 | ||
23 | <input type="submit" value="Update my profile" [disabled]="!form.valid"> | 23 | <input type="submit" i18n-value value="Update my profile" [disabled]="!form.valid"> |
24 | </form> | 24 | </form> |
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 468be022c..35843ecd9 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 | |||
@@ -3,6 +3,7 @@ import { FormBuilder, FormGroup } from '@angular/forms' | |||
3 | import { NotificationsService } from 'angular2-notifications' | 3 | import { NotificationsService } from 'angular2-notifications' |
4 | import { FormReactive, USER_DESCRIPTION, USER_DISPLAY_NAME, UserService } from '../../../shared' | 4 | import { FormReactive, USER_DESCRIPTION, USER_DISPLAY_NAME, UserService } from '../../../shared' |
5 | import { User } from '@app/shared' | 5 | import { User } from '@app/shared' |
6 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
6 | 7 | ||
7 | @Component({ | 8 | @Component({ |
8 | selector: 'my-account-profile', | 9 | selector: 'my-account-profile', |
@@ -27,7 +28,8 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit { | |||
27 | constructor ( | 28 | constructor ( |
28 | private formBuilder: FormBuilder, | 29 | private formBuilder: FormBuilder, |
29 | private notificationsService: NotificationsService, | 30 | private notificationsService: NotificationsService, |
30 | private userService: UserService | 31 | private userService: UserService, |
32 | private i18n: I18n | ||
31 | ) { | 33 | ) { |
32 | super() | 34 | super() |
33 | } | 35 | } |
@@ -56,7 +58,7 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit { | |||
56 | this.user.account.displayName = displayName | 58 | this.user.account.displayName = displayName |
57 | this.user.account.description = description | 59 | this.user.account.description = description |
58 | 60 | ||
59 | this.notificationsService.success('Success', 'Profile updated.') | 61 | this.notificationsService.success(this.i18n('Success'), this.i18n('Profile updated.')) |
60 | }, | 62 | }, |
61 | 63 | ||
62 | err => this.error = err.message | 64 | err => this.error = err.message |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html index 0fcc7782e..056c2a7d7 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html +++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html | |||
@@ -6,27 +6,27 @@ | |||
6 | <div class="user-info-display-name">{{ user.account.displayName }}</div> | 6 | <div class="user-info-display-name">{{ user.account.displayName }}</div> |
7 | <div class="user-info-username">{{ user.username }}</div> | 7 | <div class="user-info-username">{{ user.username }}</div> |
8 | </div> | 8 | </div> |
9 | <div class="user-info-followers">{{ user.account?.followersCount }} subscribers</div> | 9 | <div i18n class="user-info-followers">{{ user.account?.followersCount }} subscribers</div> |
10 | </div> | 10 | </div> |
11 | </div> | 11 | </div> |
12 | 12 | ||
13 | <div class="button-file"> | 13 | <div class="button-file"> |
14 | <span>Change your avatar</span> | 14 | <span i18n>Change your avatar</span> |
15 | <input #avatarfileInput type="file" name="avatarfile" id="avatarfile" [accept]="avatarExtensions" (change)="changeAvatar()" /> | 15 | <input #avatarfileInput type="file" name="avatarfile" id="avatarfile" [accept]="avatarExtensions" (change)="changeAvatar()" /> |
16 | </div> | 16 | </div> |
17 | <div class="file-max-size">(extensions: {{ avatarExtensions }}, max size: {{ maxAvatarSize | bytes }})</div> | 17 | <div i18n class="file-max-size">(extensions: {{ avatarExtensions }}, max size: {{ maxAvatarSize | bytes }})</div> |
18 | 18 | ||
19 | <div class="user-quota"> | 19 | <div class="user-quota"> |
20 | <span class="user-quota-label">Video quota:</span> {{ userVideoQuotaUsed | bytes: 0 }} / {{ userVideoQuota }} | 20 | <span i18n class="user-quota-label">Video quota:</span> {{ userVideoQuotaUsed | bytes: 0 }} / {{ userVideoQuota }} |
21 | </div> | 21 | </div> |
22 | 22 | ||
23 | <ng-template [ngIf]="user && user.account"> | 23 | <ng-template [ngIf]="user && user.account"> |
24 | <div class="account-title">Profile</div> | 24 | <div i18n class="account-title">Profile</div> |
25 | <my-account-profile [user]="user"></my-account-profile> | 25 | <my-account-profile [user]="user"></my-account-profile> |
26 | </ng-template> | 26 | </ng-template> |
27 | 27 | ||
28 | <div class="account-title">Password</div> | 28 | <div i18n class="account-title">Password</div> |
29 | <my-account-change-password></my-account-change-password> | 29 | <my-account-change-password></my-account-change-password> |
30 | 30 | ||
31 | <div class="account-title">Video settings</div> | 31 | <div i18n class="account-title">Video settings</div> |
32 | <my-account-video-settings [user]="user"></my-account-video-settings> | 32 | <my-account-video-settings [user]="user"></my-account-video-settings> |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts index 06d1138e7..44eddaa7c 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts | |||
@@ -5,6 +5,7 @@ import { AuthService } from '../../core' | |||
5 | import { ServerService } from '../../core/server' | 5 | import { ServerService } from '../../core/server' |
6 | import { User } from '../../shared' | 6 | import { User } from '../../shared' |
7 | import { UserService } from '../../shared/users' | 7 | import { UserService } from '../../shared/users' |
8 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
8 | 9 | ||
9 | @Component({ | 10 | @Component({ |
10 | selector: 'my-account-settings', | 11 | selector: 'my-account-settings', |
@@ -22,7 +23,8 @@ export class MyAccountSettingsComponent implements OnInit { | |||
22 | private userService: UserService, | 23 | private userService: UserService, |
23 | private authService: AuthService, | 24 | private authService: AuthService, |
24 | private serverService: ServerService, | 25 | private serverService: ServerService, |
25 | private notificationsService: NotificationsService | 26 | private notificationsService: NotificationsService, |
27 | private i18n: I18n | ||
26 | ) {} | 28 | ) {} |
27 | 29 | ||
28 | ngOnInit () { | 30 | ngOnInit () { |
@@ -33,7 +35,7 @@ export class MyAccountSettingsComponent implements OnInit { | |||
33 | if (this.user.videoQuota !== -1) { | 35 | if (this.user.videoQuota !== -1) { |
34 | this.userVideoQuota = new BytesPipe().transform(this.user.videoQuota, 0).toString() | 36 | this.userVideoQuota = new BytesPipe().transform(this.user.videoQuota, 0).toString() |
35 | } else { | 37 | } else { |
36 | this.userVideoQuota = 'Unlimited' | 38 | this.userVideoQuota = this.i18n('Unlimited') |
37 | } | 39 | } |
38 | } | 40 | } |
39 | ) | 41 | ) |
@@ -51,12 +53,12 @@ export class MyAccountSettingsComponent implements OnInit { | |||
51 | this.userService.changeAvatar(formData) | 53 | this.userService.changeAvatar(formData) |
52 | .subscribe( | 54 | .subscribe( |
53 | data => { | 55 | data => { |
54 | this.notificationsService.success('Success', 'Avatar changed.') | 56 | this.notificationsService.success(this.i18n('Success'), this.i18n('Avatar changed.')) |
55 | 57 | ||
56 | this.user.account.avatar = data.avatar | 58 | this.user.account.avatar = data.avatar |
57 | }, | 59 | }, |
58 | 60 | ||
59 | err => this.notificationsService.error('Error', err.message) | 61 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
60 | ) | 62 | ) |
61 | } | 63 | } |
62 | 64 | ||
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html index 0e8598e9e..98587eb18 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html +++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html | |||
@@ -1,13 +1,16 @@ | |||
1 | <form role="form" (ngSubmit)="updateDetails()" [formGroup]="form"> | 1 | <form role="form" (ngSubmit)="updateDetails()" [formGroup]="form"> |
2 | <div class="form-group"> | 2 | <div class="form-group"> |
3 | <label for="nsfwPolicy">Default policy on videos containing sensitive content</label> | 3 | <label i18n for="nsfwPolicy">Default policy on videos containing sensitive content</label> |
4 | <my-help helpType="custom" customHtml="With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video."></my-help> | 4 | <my-help |
5 | helpType="custom" i18n-customHtml | ||
6 | customHtml="With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video." | ||
7 | ></my-help> | ||
5 | 8 | ||
6 | <div class="peertube-select-container"> | 9 | <div class="peertube-select-container"> |
7 | <select id="nsfwPolicy" formControlName="nsfwPolicy"> | 10 | <select id="nsfwPolicy" formControlName="nsfwPolicy"> |
8 | <option value="do_not_list">Do not list</option> | 11 | <option i18n value="do_not_list">Do not list</option> |
9 | <option value="blur">Blur thumbnails</option> | 12 | <option i18n value="blur">Blur thumbnails</option> |
10 | <option value="display">Display</option> | 13 | <option i18n value="display">Display</option> |
11 | </select> | 14 | </select> |
12 | </div> | 15 | </div> |
13 | </div> | 16 | </div> |
@@ -18,8 +21,8 @@ | |||
18 | formControlName="autoPlayVideo" | 21 | formControlName="autoPlayVideo" |
19 | > | 22 | > |
20 | <label for="autoPlayVideo"></label> | 23 | <label for="autoPlayVideo"></label> |
21 | <label for="autoPlayVideo">Automatically plays video</label> | 24 | <label i18n for="autoPlayVideo">Automatically plays video</label> |
22 | </div> | 25 | </div> |
23 | 26 | ||
24 | <input type="submit" value="Save" [disabled]="!form.valid"> | 27 | <input type="submit" i18n-value value="Save" [disabled]="!form.valid"> |
25 | </form> | 28 | </form> |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts index acc70c14d..4588f73db 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts | |||
@@ -4,6 +4,7 @@ import { NotificationsService } from 'angular2-notifications' | |||
4 | import { UserUpdateMe } from '../../../../../../shared' | 4 | import { UserUpdateMe } from '../../../../../../shared' |
5 | import { AuthService } from '../../../core' | 5 | import { AuthService } from '../../../core' |
6 | import { FormReactive, User, UserService } from '../../../shared' | 6 | import { FormReactive, User, UserService } from '../../../shared' |
7 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
7 | 8 | ||
8 | @Component({ | 9 | @Component({ |
9 | selector: 'my-account-video-settings', | 10 | selector: 'my-account-video-settings', |
@@ -21,7 +22,8 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI | |||
21 | private authService: AuthService, | 22 | private authService: AuthService, |
22 | private formBuilder: FormBuilder, | 23 | private formBuilder: FormBuilder, |
23 | private notificationsService: NotificationsService, | 24 | private notificationsService: NotificationsService, |
24 | private userService: UserService | 25 | private userService: UserService, |
26 | private i18n: I18n | ||
25 | ) { | 27 | ) { |
26 | super() | 28 | super() |
27 | } | 29 | } |
@@ -49,12 +51,12 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI | |||
49 | 51 | ||
50 | this.userService.updateMyProfile(details).subscribe( | 52 | this.userService.updateMyProfile(details).subscribe( |
51 | () => { | 53 | () => { |
52 | this.notificationsService.success('Success', 'Information updated.') | 54 | this.notificationsService.success(this.i18n('Success'), this.i18n('Information updated.')) |
53 | 55 | ||
54 | this.authService.refreshUserInformation() | 56 | this.authService.refreshUserInformation() |
55 | }, | 57 | }, |
56 | 58 | ||
57 | err => this.notificationsService.error('Error', err.message) | 59 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
58 | ) | 60 | ) |
59 | } | 61 | } |
60 | } | 62 | } |
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 c82bb39c8..9b5a12d18 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 | |||
@@ -11,6 +11,7 @@ import { | |||
11 | } from '@app/shared/forms/form-validators/video-channel' | 11 | } from '@app/shared/forms/form-validators/video-channel' |
12 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | 12 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' |
13 | import { AuthService } from '@app/core' | 13 | import { AuthService } from '@app/core' |
14 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
14 | 15 | ||
15 | @Component({ | 16 | @Component({ |
16 | selector: 'my-account-video-channel-create', | 17 | selector: 'my-account-video-channel-create', |
@@ -37,7 +38,8 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE | |||
37 | private notificationsService: NotificationsService, | 38 | private notificationsService: NotificationsService, |
38 | private router: Router, | 39 | private router: Router, |
39 | private formBuilder: FormBuilder, | 40 | private formBuilder: FormBuilder, |
40 | private videoChannelService: VideoChannelService | 41 | private videoChannelService: VideoChannelService, |
42 | private i18n: I18n | ||
41 | ) { | 43 | ) { |
42 | super() | 44 | super() |
43 | } | 45 | } |
@@ -69,7 +71,10 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE | |||
69 | this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe( | 71 | this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe( |
70 | () => { | 72 | () => { |
71 | this.authService.refreshUserInformation() | 73 | this.authService.refreshUserInformation() |
72 | this.notificationsService.success('Success', `Video channel ${videoChannelCreate.displayName} created.`) | 74 | this.notificationsService.success( |
75 | this.i18n('Success'), | ||
76 | this.i18n('Video channel {{ videoChannelName }} created.', { videoChannelName: videoChannelCreate.displayName }) | ||
77 | ) | ||
73 | this.router.navigate([ '/my-account', 'video-channels' ]) | 78 | this.router.navigate([ '/my-account', 'video-channels' ]) |
74 | }, | 79 | }, |
75 | 80 | ||
@@ -82,6 +87,6 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE | |||
82 | } | 87 | } |
83 | 88 | ||
84 | getFormButtonTitle () { | 89 | getFormButtonTitle () { |
85 | return 'Create' | 90 | return this.i18n('Create') |
86 | } | 91 | } |
87 | } | 92 | } |
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html index 10d408d55..1c08cfdca 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html | |||
@@ -1,11 +1,11 @@ | |||
1 | <div class="form-sub-title" *ngIf="isCreation() === true">Create a video channel</div> | 1 | <div i18n class="form-sub-title" *ngIf="isCreation() === true">Create a video channel</div> |
2 | <div class="form-sub-title" *ngIf="isCreation() === false">Update {{ videoChannel?.displayName }}</div> | 2 | <div i18n class="form-sub-title" *ngIf="isCreation() === false">Update {{ videoChannel?.displayName }}</div> |
3 | 3 | ||
4 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> | 4 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> |
5 | 5 | ||
6 | <form role="form" (ngSubmit)="formValidated()" [formGroup]="form"> | 6 | <form role="form" (ngSubmit)="formValidated()" [formGroup]="form"> |
7 | <div class="form-group"> | 7 | <div class="form-group"> |
8 | <label for="display-name">Display name</label> | 8 | <label i18n for="display-name">Display name</label> |
9 | <input | 9 | <input |
10 | type="text" id="display-name" | 10 | type="text" id="display-name" |
11 | formControlName="display-name" [ngClass]="{ 'input-error': formErrors['display-name'] }" | 11 | formControlName="display-name" [ngClass]="{ 'input-error': formErrors['display-name'] }" |
@@ -16,7 +16,7 @@ | |||
16 | </div> | 16 | </div> |
17 | 17 | ||
18 | <div class="form-group"> | 18 | <div class="form-group"> |
19 | <label for="description">Description</label> | 19 | <label i18n for="description">Description</label> |
20 | <textarea | 20 | <textarea |
21 | id="description" formControlName="description" | 21 | id="description" formControlName="description" |
22 | [ngClass]="{ 'input-error': formErrors['description'] }" | 22 | [ngClass]="{ 'input-error': formErrors['description'] }" |
@@ -29,7 +29,7 @@ | |||
29 | <div class="form-group"> | 29 | <div class="form-group"> |
30 | <label for="support">Support</label> | 30 | <label for="support">Support</label> |
31 | <my-help | 31 | <my-help |
32 | helpType="markdownEnhanced" preHtml="Short text to tell people how they can support your channel (membership platform...).<br /><br /> | 32 | helpType="markdownEnhanced" i18n-preHtml preHtml="Short text to tell people how they can support your channel (membership platform...).<br /><br /> |
33 | When you will upload a video in this channel, the video support field will be automatically filled by this text." | 33 | When you will upload a video in this channel, the video support field will be automatically filled by this text." |
34 | ></my-help> | 34 | ></my-help> |
35 | <my-markdown-textarea | 35 | <my-markdown-textarea |
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 b4c8df3cd..78c578764 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 | |||
@@ -13,6 +13,7 @@ import { VideoChannelService } from '@app/shared/video-channel/video-channel.ser | |||
13 | import { Subscription } from 'rxjs' | 13 | import { Subscription } from 'rxjs' |
14 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | 14 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' |
15 | import { AuthService } from '@app/core' | 15 | import { AuthService } from '@app/core' |
16 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
16 | 17 | ||
17 | @Component({ | 18 | @Component({ |
18 | selector: 'my-account-video-channel-update', | 19 | selector: 'my-account-video-channel-update', |
@@ -43,7 +44,8 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE | |||
43 | private router: Router, | 44 | private router: Router, |
44 | private route: ActivatedRoute, | 45 | private route: ActivatedRoute, |
45 | private formBuilder: FormBuilder, | 46 | private formBuilder: FormBuilder, |
46 | private videoChannelService: VideoChannelService | 47 | private videoChannelService: VideoChannelService, |
48 | private i18n: I18n | ||
47 | ) { | 49 | ) { |
48 | super() | 50 | super() |
49 | } | 51 | } |
@@ -97,7 +99,10 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE | |||
97 | this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.uuid, videoChannelUpdate).subscribe( | 99 | this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.uuid, videoChannelUpdate).subscribe( |
98 | () => { | 100 | () => { |
99 | this.authService.refreshUserInformation() | 101 | this.authService.refreshUserInformation() |
100 | this.notificationsService.success('Success', `Video channel ${videoChannelUpdate.displayName} updated.`) | 102 | this.notificationsService.success( |
103 | this.i18n('Success'), | ||
104 | this.i18n('Video channel {{ videoChannelName }} updated.', { videoChannelName: videoChannelUpdate.displayName }) | ||
105 | ) | ||
101 | this.router.navigate([ '/my-account', 'video-channels' ]) | 106 | this.router.navigate([ '/my-account', 'video-channels' ]) |
102 | }, | 107 | }, |
103 | 108 | ||
@@ -110,6 +115,6 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE | |||
110 | } | 115 | } |
111 | 116 | ||
112 | getFormButtonTitle () { | 117 | getFormButtonTitle () { |
113 | return 'Update' | 118 | return this.i18n('Update') |
114 | } | 119 | } |
115 | } | 120 | } |
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html index 90c401bc5..d27c3b4ec 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html | |||
@@ -1,7 +1,7 @@ | |||
1 | <div class="video-channels-header"> | 1 | <div class="video-channels-header"> |
2 | <a class="create-button" routerLink="create"> | 2 | <a class="create-button" routerLink="create"> |
3 | <span class="icon icon-add"></span> | 3 | <span class="icon icon-add"></span> |
4 | Create another video channel | 4 | <ng-container i18n>Create another video channel</ng-container> |
5 | </a> | 5 | </a> |
6 | </div> | 6 | </div> |
7 | 7 | ||
@@ -12,13 +12,13 @@ | |||
12 | </a> | 12 | </a> |
13 | 13 | ||
14 | <div class="video-channel-info"> | 14 | <div class="video-channel-info"> |
15 | <a [routerLink]="[ '/video-channels', videoChannel.uuid ]" class="video-channel-names" title="Go to the channel"> | 15 | <a [routerLink]="[ '/video-channels', videoChannel.uuid ]" class="video-channel-names" i18n-title title="Go to the channel"> |
16 | <div class="video-channel-display-name">{{ videoChannel.displayName }}</div> | 16 | <div class="video-channel-display-name">{{ videoChannel.displayName }}</div> |
17 | <!-- Hide the name for now, because it's an UUID not very friendly --> | 17 | <!-- Hide the name for now, because it's an UUID not very friendly --> |
18 | <!--<div class="video-channel-name">{{ videoChannel.name }}</div>--> | 18 | <!--<div class="video-channel-name">{{ videoChannel.name }}</div>--> |
19 | </a> | 19 | </a> |
20 | 20 | ||
21 | <div class="video-channel-followers">{{ videoChannel.followersCount }} subscribers</div> | 21 | <div i18n class="video-channel-followers">{{ videoChannel.followersCount }} subscribers</div> |
22 | </div> | 22 | </div> |
23 | 23 | ||
24 | <div class="video-channel-buttons"> | 24 | <div class="video-channel-buttons"> |
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts index 20c8798d1..cff1041f6 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts | |||
@@ -6,6 +6,7 @@ import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | |||
6 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | 6 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' |
7 | import { User } from '@app/shared' | 7 | import { User } from '@app/shared' |
8 | import { flatMap } from 'rxjs/operators' | 8 | import { flatMap } from 'rxjs/operators' |
9 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
9 | 10 | ||
10 | @Component({ | 11 | @Component({ |
11 | selector: 'my-account-video-channels', | 12 | selector: 'my-account-video-channels', |
@@ -21,7 +22,8 @@ export class MyAccountVideoChannelsComponent implements OnInit { | |||
21 | private authService: AuthService, | 22 | private authService: AuthService, |
22 | private notificationsService: NotificationsService, | 23 | private notificationsService: NotificationsService, |
23 | private confirmService: ConfirmService, | 24 | private confirmService: ConfirmService, |
24 | private videoChannelService: VideoChannelService | 25 | private videoChannelService: VideoChannelService, |
26 | private i18n: I18n | ||
25 | ) {} | 27 | ) {} |
26 | 28 | ||
27 | ngOnInit () { | 29 | ngOnInit () { |
@@ -32,10 +34,13 @@ export class MyAccountVideoChannelsComponent implements OnInit { | |||
32 | 34 | ||
33 | async deleteVideoChannel (videoChannel: VideoChannel) { | 35 | async deleteVideoChannel (videoChannel: VideoChannel) { |
34 | const res = await this.confirmService.confirmWithInput( | 36 | const res = await this.confirmService.confirmWithInput( |
35 | `Do you really want to delete ${videoChannel.displayName}? It will delete all videos uploaded in this channel too.`, | 37 | this.i18n( |
36 | 'Please type the name of the video channel to confirm', | 38 | 'Do you really want to delete {{ videoChannelName }}? It will delete all videos uploaded in this channel too.', |
39 | { videoChannelName: videoChannel.displayName } | ||
40 | ), | ||
41 | this.i18n('Please type the name of the video channel to confirm'), | ||
37 | videoChannel.displayName, | 42 | videoChannel.displayName, |
38 | 'Delete' | 43 | this.i18n('Delete') |
39 | ) | 44 | ) |
40 | if (res === false) return | 45 | if (res === false) return |
41 | 46 | ||
@@ -43,10 +48,13 @@ export class MyAccountVideoChannelsComponent implements OnInit { | |||
43 | .subscribe( | 48 | .subscribe( |
44 | status => { | 49 | status => { |
45 | this.loadVideoChannels() | 50 | this.loadVideoChannels() |
46 | this.notificationsService.success('Success', `Video channel ${videoChannel.name} deleted.`) | 51 | this.notificationsService.success( |
52 | this.i18n('Success'), | ||
53 | this.i18n('Video channel {{ videoChannelName } deleted.', { videoChannelName: videoChannel.displayName }) | ||
54 | ) | ||
47 | }, | 55 | }, |
48 | 56 | ||
49 | error => this.notificationsService.error('Error', error.message) | 57 | error => this.notificationsService.error(this.i18n('Error'), error.message) |
50 | ) | 58 | ) |
51 | } | 59 | } |
52 | 60 | ||
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html index a31cb0c3d..35a99d0b3 100644 --- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html | |||
@@ -1,4 +1,4 @@ | |||
1 | <div *ngIf="pagination.totalItems === 0">No results.</div> | 1 | <div i18n *ngIf="pagination.totalItems === 0">No results.</div> |
2 | 2 | ||
3 | <div | 3 | <div |
4 | myInfiniteScroller | 4 | myInfiniteScroller |
@@ -17,18 +17,18 @@ | |||
17 | 17 | ||
18 | <div class="video-info"> | 18 | <div class="video-info"> |
19 | <a class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a> | 19 | <a class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a> |
20 | <span class="video-info-date-views">{{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> | 20 | <span i18n class="video-info-date-views">{{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> |
21 | <div class="video-info-private">{{ video.privacy.label }}</div> | 21 | <div class="video-info-private">{{ video.privacy.label }}</div> |
22 | </div> | 22 | </div> |
23 | 23 | ||
24 | <!-- Display only once --> | 24 | <!-- Display only once --> |
25 | <div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0 && j === 0"> | 25 | <div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0 && j === 0"> |
26 | <div class="action-selection-mode-child"> | 26 | <div class="action-selection-mode-child"> |
27 | <span class="action-button action-button-cancel-selection" (click)="abortSelectionMode()"> | 27 | <span i18n class="action-button action-button-cancel-selection" (click)="abortSelectionMode()"> |
28 | Cancel | 28 | Cancel |
29 | </span> | 29 | </span> |
30 | 30 | ||
31 | <span class="action-button action-button-delete-selection" (click)="deleteSelectedVideos()"> | 31 | <span i18n class="action-button action-button-delete-selection" (click)="deleteSelectedVideos()"> |
32 | <span class="icon icon-delete-white"></span> | 32 | <span class="icon icon-delete-white"></span> |
33 | Delete | 33 | Delete |
34 | </span> | 34 | </span> |
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts index 6ab6c2aa5..eed4be01f 100644 --- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts | |||
@@ -11,6 +11,7 @@ import { ConfirmService } from '../../core/confirm' | |||
11 | import { AbstractVideoList } from '../../shared/video/abstract-video-list' | 11 | import { AbstractVideoList } from '../../shared/video/abstract-video-list' |
12 | import { Video } from '../../shared/video/video.model' | 12 | import { Video } from '../../shared/video/video.model' |
13 | import { VideoService } from '../../shared/video/video.service' | 13 | import { VideoService } from '../../shared/video/video.service' |
14 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
14 | 15 | ||
15 | @Component({ | 16 | @Component({ |
16 | selector: 'my-account-videos', | 17 | selector: 'my-account-videos', |
@@ -18,7 +19,7 @@ import { VideoService } from '../../shared/video/video.service' | |||
18 | styleUrls: [ './my-account-videos.component.scss' ] | 19 | styleUrls: [ './my-account-videos.component.scss' ] |
19 | }) | 20 | }) |
20 | export class MyAccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { | 21 | export class MyAccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { |
21 | titlePage = 'My videos' | 22 | titlePage: string |
22 | currentRoute = '/my-account/videos' | 23 | currentRoute = '/my-account/videos' |
23 | checkedVideos: { [ id: number ]: boolean } = {} | 24 | checkedVideos: { [ id: number ]: boolean } = {} |
24 | pagination: ComponentPagination = { | 25 | pagination: ComponentPagination = { |
@@ -30,14 +31,19 @@ export class MyAccountVideosComponent extends AbstractVideoList implements OnIni | |||
30 | protected baseVideoWidth = -1 | 31 | protected baseVideoWidth = -1 |
31 | protected baseVideoHeight = 155 | 32 | protected baseVideoHeight = 155 |
32 | 33 | ||
33 | constructor (protected router: Router, | 34 | constructor ( |
34 | protected route: ActivatedRoute, | 35 | protected router: Router, |
35 | protected authService: AuthService, | 36 | protected route: ActivatedRoute, |
36 | protected notificationsService: NotificationsService, | 37 | protected authService: AuthService, |
37 | protected confirmService: ConfirmService, | 38 | protected notificationsService: NotificationsService, |
38 | protected location: Location, | 39 | protected confirmService: ConfirmService, |
39 | private videoService: VideoService) { | 40 | protected location: Location, |
41 | protected i18n: I18n, | ||
42 | private videoService: VideoService | ||
43 | ) { | ||
40 | super() | 44 | super() |
45 | |||
46 | this.titlePage = this.i18n('My videos') | ||
41 | } | 47 | } |
42 | 48 | ||
43 | ngOnInit () { | 49 | ngOnInit () { |
diff --git a/client/src/app/+my-account/my-account.component.html b/client/src/app/+my-account/my-account.component.html index 591d58cf9..48db55ad3 100644 --- a/client/src/app/+my-account/my-account.component.html +++ b/client/src/app/+my-account/my-account.component.html | |||
@@ -1,10 +1,10 @@ | |||
1 | <div class="row"> | 1 | <div class="row"> |
2 | <div class="sub-menu"> | 2 | <div class="sub-menu"> |
3 | <a routerLink="/my-account/settings" routerLinkActive="active" class="title-page">My settings</a> | 3 | <a i18n routerLink="/my-account/settings" routerLinkActive="active" class="title-page">My settings</a> |
4 | 4 | ||
5 | <a routerLink="/my-account/video-channels" routerLinkActive="active" class="title-page">My video channels</a> | 5 | <a i18n routerLink="/my-account/video-channels" routerLinkActive="active" class="title-page">My video channels</a> |
6 | 6 | ||
7 | <a routerLink="/my-account/videos" routerLinkActive="active" class="title-page">My videos</a> | 7 | <a i18n routerLink="/my-account/videos" routerLinkActive="active" class="title-page">My videos</a> |
8 | </div> | 8 | </div> |
9 | 9 | ||
10 | <div class="margin-content"> | 10 | <div class="margin-content"> |
diff --git a/client/src/app/+page-not-found/page-not-found.component.html b/client/src/app/+page-not-found/page-not-found.component.html index 66aa2aec7..2934003ab 100644 --- a/client/src/app/+page-not-found/page-not-found.component.html +++ b/client/src/app/+page-not-found/page-not-found.component.html | |||
@@ -1,3 +1,3 @@ | |||
1 | <div> | 1 | <div i18n> |
2 | Sorry, but we couldn't find the page you were looking for. | 2 | Sorry, but we couldn't find the page you were looking for. |
3 | </div> \ No newline at end of file | 3 | </div> \ No newline at end of file |
diff --git a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.html b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.html index a4338121f..b7125ff71 100644 --- a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.html +++ b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.html | |||
@@ -1,20 +1,20 @@ | |||
1 | <div *ngIf="videoChannel" class="row"> | 1 | <div *ngIf="videoChannel" class="row"> |
2 | <div class="description col-md-6 col-sm-12"> | 2 | <div class="description col-md-6 col-sm-12"> |
3 | <div class="block"> | 3 | <div class="block"> |
4 | <div class="small-title">Description</div> | 4 | <div i18n class="small-title">Description</div> |
5 | <div class="content">{{ getVideoChannelDescription() }}</div> | 5 | <div class="content">{{ getVideoChannelDescription() }}</div> |
6 | </div> | 6 | </div> |
7 | 7 | ||
8 | <div class="block" *ngIf="videoChannel.support"> | 8 | <div class="block" *ngIf="videoChannel.support"> |
9 | <div class="small-title">Support this channel</div> | 9 | <div i18n class="small-title">Support this channel</div> |
10 | <div class="content">{{ videoChannel.support }}</div> | 10 | <div class="content">{{ videoChannel.support }}</div> |
11 | </div> | 11 | </div> |
12 | </div> | 12 | </div> |
13 | 13 | ||
14 | <div class="stats col-md-6 col-sm-12"> | 14 | <div class="stats col-md-6 col-sm-12"> |
15 | <div class="block"> | 15 | <div class="block"> |
16 | <div class="small-title">Stats</div> | 16 | <div i18n class="small-title">Stats</div> |
17 | <div class="content">Created {{ videoChannel.createdAt | date }}</div> | 17 | <div i18n class="content">Created {{ videoChannel.createdAt | date }}</div> |
18 | </div> | 18 | </div> |
19 | </div> | 19 | </div> |
20 | </div> \ No newline at end of file | 20 | </div> \ No newline at end of file |
diff --git a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts index 6f862718f..c5fd442c6 100644 --- a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts +++ b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts | |||
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core' | |||
2 | import { ActivatedRoute } from '@angular/router' | 2 | import { ActivatedRoute } from '@angular/router' |
3 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | 3 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' |
4 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | 4 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' |
5 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
5 | 6 | ||
6 | @Component({ | 7 | @Component({ |
7 | selector: 'my-video-channel-about', | 8 | selector: 'my-video-channel-about', |
@@ -12,7 +13,8 @@ export class VideoChannelAboutComponent implements OnInit { | |||
12 | videoChannel: VideoChannel | 13 | videoChannel: VideoChannel |
13 | 14 | ||
14 | constructor ( | 15 | constructor ( |
15 | protected route: ActivatedRoute, | 16 | private route: ActivatedRoute, |
17 | private i18n: I18n, | ||
16 | private videoChannelService: VideoChannelService | 18 | private videoChannelService: VideoChannelService |
17 | ) { } | 19 | ) { } |
18 | 20 | ||
@@ -25,6 +27,6 @@ export class VideoChannelAboutComponent implements OnInit { | |||
25 | getVideoChannelDescription () { | 27 | getVideoChannelDescription () { |
26 | if (this.videoChannel.description) return this.videoChannel.description | 28 | if (this.videoChannel.description) return this.videoChannel.description |
27 | 29 | ||
28 | return 'No description' | 30 | return this.i18n('No description') |
29 | } | 31 | } |
30 | } | 32 | } |
diff --git a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts index c9e72e512..22239d75b 100644 --- a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts +++ b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts | |||
@@ -10,6 +10,7 @@ import { VideoService } from '../../shared/video/video.service' | |||
10 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | 10 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' |
11 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | 11 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' |
12 | import { tap } from 'rxjs/operators' | 12 | import { tap } from 'rxjs/operators' |
13 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
13 | 14 | ||
14 | @Component({ | 15 | @Component({ |
15 | selector: 'my-video-channel-videos', | 16 | selector: 'my-video-channel-videos', |
@@ -20,7 +21,7 @@ import { tap } from 'rxjs/operators' | |||
20 | ] | 21 | ] |
21 | }) | 22 | }) |
22 | export class VideoChannelVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { | 23 | export class VideoChannelVideosComponent extends AbstractVideoList implements OnInit, OnDestroy { |
23 | titlePage = 'Published videos' | 24 | titlePage: string |
24 | marginContent = false // Disable margin | 25 | marginContent = false // Disable margin |
25 | currentRoute = '/video-channel/videos' | 26 | currentRoute = '/video-channel/videos' |
26 | loadOnInit = false | 27 | loadOnInit = false |
@@ -34,10 +35,13 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On | |||
34 | protected notificationsService: NotificationsService, | 35 | protected notificationsService: NotificationsService, |
35 | protected confirmService: ConfirmService, | 36 | protected confirmService: ConfirmService, |
36 | protected location: Location, | 37 | protected location: Location, |
38 | protected i18n: I18n, | ||
37 | private videoChannelService: VideoChannelService, | 39 | private videoChannelService: VideoChannelService, |
38 | private videoService: VideoService | 40 | private videoService: VideoService |
39 | ) { | 41 | ) { |
40 | super() | 42 | super() |
43 | |||
44 | this.titlePage = this.i18n('Published videos') | ||
41 | } | 45 | } |
42 | 46 | ||
43 | ngOnInit () { | 47 | ngOnInit () { |
@@ -63,7 +67,11 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On | |||
63 | 67 | ||
64 | return this.videoService | 68 | return this.videoService |
65 | .getVideoChannelVideos(this.videoChannel, newPagination, this.sort) | 69 | .getVideoChannelVideos(this.videoChannel, newPagination, this.sort) |
66 | .pipe(tap(({ totalVideos }) => this.titlePage = `Published ${totalVideos} videos`)) | 70 | .pipe( |
71 | tap(({ totalVideos }) => { | ||
72 | this.titlePage = this.i18n('Published {{ totalVideos }} videos', { totalVideos }) | ||
73 | }) | ||
74 | ) | ||
67 | } | 75 | } |
68 | 76 | ||
69 | generateSyndicationList () { | 77 | generateSyndicationList () { |
diff --git a/client/src/app/+video-channels/video-channels.component.html b/client/src/app/+video-channels/video-channels.component.html index 6b25d16ab..a52894cac 100644 --- a/client/src/app/+video-channels/video-channels.component.html +++ b/client/src/app/+video-channels/video-channels.component.html | |||
@@ -8,19 +8,19 @@ | |||
8 | <div class="actor-names"> | 8 | <div class="actor-names"> |
9 | <div class="actor-display-name">{{ videoChannel.displayName }}</div> | 9 | <div class="actor-display-name">{{ videoChannel.displayName }}</div> |
10 | </div> | 10 | </div> |
11 | <div class="actor-followers">{{ videoChannel.followersCount }} subscribers</div> | 11 | <div i18n class="actor-followers">{{ videoChannel.followersCount }} subscribers</div> |
12 | 12 | ||
13 | <a [routerLink]="[ '/accounts', videoChannel.ownerBy ]" title="Go the owner account page" class="actor-owner"> | 13 | <a [routerLink]="[ '/accounts', videoChannel.ownerBy ]" i18n-title title="Go the owner account page" class="actor-owner"> |
14 | <span>Created by {{ videoChannel.ownerBy }}</span> | 14 | <span i18n>Created by {{ videoChannel.ownerBy }}</span> |
15 | <img [src]="videoChannel.ownerAvatarUrl" alt="Owner account avatar" /> | 15 | <img [src]="videoChannel.ownerAvatarUrl" alt="Owner account avatar" /> |
16 | </a> | 16 | </a> |
17 | </div> | 17 | </div> |
18 | </div> | 18 | </div> |
19 | 19 | ||
20 | <div class="links"> | 20 | <div class="links"> |
21 | <a routerLink="videos" routerLinkActive="active" class="title-page">Videos</a> | 21 | <a i18n routerLink="videos" routerLinkActive="active" class="title-page">Videos</a> |
22 | 22 | ||
23 | <a routerLink="about" routerLinkActive="active" class="title-page">About</a> | 23 | <a i18n routerLink="about" routerLinkActive="active" class="title-page">About</a> |
24 | </div> | 24 | </div> |
25 | </div> | 25 | </div> |
26 | 26 | ||
diff --git a/client/src/app/about/about.component.html b/client/src/app/about/about.component.html index 6fa856742..22d3c9a36 100644 --- a/client/src/app/about/about.component.html +++ b/client/src/app/about/about.component.html | |||
@@ -1,5 +1,5 @@ | |||
1 | <div class="margin-content"> | 1 | <div class="margin-content"> |
2 | <div class="title-page title-page-single"> | 2 | <div i18n class="title-page title-page-single"> |
3 | Welcome to the {{ instanceName }} instance | 3 | Welcome to the {{ instanceName }} instance |
4 | </div> | 4 | </div> |
5 | 5 | ||
@@ -8,41 +8,41 @@ | |||
8 | </div> | 8 | </div> |
9 | 9 | ||
10 | <div class="description"> | 10 | <div class="description"> |
11 | <div class="section-title">Description</div> | 11 | <div i18n class="section-title">Description</div> |
12 | 12 | ||
13 | <div [innerHTML]="descriptionHTML"></div> | 13 | <div [innerHTML]="descriptionHTML"></div> |
14 | </div> | 14 | </div> |
15 | 15 | ||
16 | <div class="terms"> | 16 | <div class="terms"> |
17 | <div class="section-title">Terms</div> | 17 | <div i18n class="section-title">Terms</div> |
18 | 18 | ||
19 | <div [innerHTML]="termsHTML"></div> | 19 | <div [innerHTML]="termsHTML"></div> |
20 | </div> | 20 | </div> |
21 | 21 | ||
22 | <div class="signup"> | 22 | <div class="signup"> |
23 | <div class="section-title">Signup</div> | 23 | <div i18n class="section-title">Signup</div> |
24 | 24 | ||
25 | <div *ngIf="isSignupAllowed"> | 25 | <div *ngIf="isSignupAllowed"> |
26 | User registration is allowed and | 26 | <ng-container i18n>User registration is allowed and</ng-container> |
27 | 27 | ||
28 | <ng-template [ngIf]="userVideoQuota !== -1"> | 28 | <ng-container i18n *ngIf="userVideoQuota !== -1"> |
29 | this instance provides a baseline quota of {{ userVideoQuota | bytes: 0 }} space for the videos of its users. | 29 | this instance provides a baseline quota of {{ userVideoQuota | bytes: 0 }} space for the videos of its users. |
30 | </ng-template> | 30 | </ng-container> |
31 | 31 | ||
32 | <ng-template [ngIf]="userVideoQuota === -1"> | 32 | <ng-container i18n *ngIf="userVideoQuota === -1"> |
33 | this instance provides unlimited space for the videos of its users. | 33 | this instance provides unlimited space for the videos of its users. |
34 | </ng-template> | 34 | </ng-container> |
35 | </div> | 35 | </div> |
36 | 36 | ||
37 | <div *ngIf="isSignupAllowed === false"> | 37 | <div i18n *ngIf="isSignupAllowed === false"> |
38 | User registration is currently not allowed. | 38 | User registration is currently not allowed. |
39 | </div> | 39 | </div> |
40 | </div> | 40 | </div> |
41 | 41 | ||
42 | <div id="p2p-privacy"> | 42 | <div id="p2p-privacy"> |
43 | <div class="section-title">P2P & Privacy</div> | 43 | <div i18n class="section-title">P2P & Privacy</div> |
44 | 44 | ||
45 | <p> | 45 | <p i18n> |
46 | PeerTube uses the BitTorrent protocol to share bandwidth between users. It implies that your public IP address is stored in the public BitTorrent tracker of the video PeerTube instance as long as you're watching the video. | 46 | PeerTube uses the BitTorrent protocol to share bandwidth between users. It implies that your public IP address is stored in the public BitTorrent tracker of the video PeerTube instance as long as you're watching the video. |
47 | If you want to keep your public IP address private, please use a VPN or Tor. | 47 | If you want to keep your public IP address private, please use a VPN or Tor. |
48 | </p> | 48 | </p> |
diff --git a/client/src/app/about/about.component.ts b/client/src/app/about/about.component.ts index 3948d5c46..c37b9318b 100644 --- a/client/src/app/about/about.component.ts +++ b/client/src/app/about/about.component.ts | |||
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core' | |||
2 | import { ServerService } from '@app/core' | 2 | import { ServerService } from '@app/core' |
3 | import { MarkdownService } from '@app/videos/shared' | 3 | import { MarkdownService } from '@app/videos/shared' |
4 | import { NotificationsService } from 'angular2-notifications' | 4 | import { NotificationsService } from 'angular2-notifications' |
5 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
5 | 6 | ||
6 | @Component({ | 7 | @Component({ |
7 | selector: 'my-about', | 8 | selector: 'my-about', |
@@ -17,7 +18,8 @@ export class AboutComponent implements OnInit { | |||
17 | constructor ( | 18 | constructor ( |
18 | private notificationsService: NotificationsService, | 19 | private notificationsService: NotificationsService, |
19 | private serverService: ServerService, | 20 | private serverService: ServerService, |
20 | private markdownService: MarkdownService | 21 | private markdownService: MarkdownService, |
22 | private i18n: I18n | ||
21 | ) {} | 23 | ) {} |
22 | 24 | ||
23 | get instanceName () { | 25 | get instanceName () { |
@@ -41,7 +43,7 @@ export class AboutComponent implements OnInit { | |||
41 | this.termsHTML = this.markdownService.textMarkdownToHTML(res.instance.terms) | 43 | this.termsHTML = this.markdownService.textMarkdownToHTML(res.instance.terms) |
42 | }, | 44 | }, |
43 | 45 | ||
44 | err => this.notificationsService.error('Error getting about from server', err) | 46 | err => this.notificationsService.error(this.i18n('Error getting about from server'), err) |
45 | ) | 47 | ) |
46 | } | 48 | } |
47 | 49 | ||
diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts index 614d38d08..363f58155 100644 --- a/client/src/app/core/auth/auth.service.ts +++ b/client/src/app/core/auth/auth.service.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { Observable, ReplaySubject, Subject, throwError as observableThrowError } from 'rxjs' | 1 | import { Observable, ReplaySubject, Subject, throwError as observableThrowError } from 'rxjs' |
2 | import { catchError, map, mergeMap, tap, share } from 'rxjs/operators' | 2 | import { catchError, map, mergeMap, share, tap } from 'rxjs/operators' |
3 | import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http' | 3 | import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http' |
4 | import { Injectable } from '@angular/core' | 4 | import { Injectable } from '@angular/core' |
5 | import { Router } from '@angular/router' | 5 | import { Router } from '@angular/router' |
@@ -13,6 +13,7 @@ import { AuthStatus } from './auth-status.model' | |||
13 | import { AuthUser } from './auth-user.model' | 13 | import { AuthUser } from './auth-user.model' |
14 | import { objectToUrlEncoded } from '@app/shared/misc/utils' | 14 | import { objectToUrlEncoded } from '@app/shared/misc/utils' |
15 | import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' | 15 | import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' |
16 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
16 | 17 | ||
17 | interface UserLoginWithUsername extends UserLogin { | 18 | interface UserLoginWithUsername extends UserLogin { |
18 | access_token: string | 19 | access_token: string |
@@ -46,7 +47,8 @@ export class AuthService { | |||
46 | private http: HttpClient, | 47 | private http: HttpClient, |
47 | private notificationsService: NotificationsService, | 48 | private notificationsService: NotificationsService, |
48 | private restExtractor: RestExtractor, | 49 | private restExtractor: RestExtractor, |
49 | private router: Router | 50 | private router: Router, |
51 | private i18n: I18n | ||
50 | ) { | 52 | ) { |
51 | this.loginChanged = new Subject<AuthStatus>() | 53 | this.loginChanged = new Subject<AuthStatus>() |
52 | this.loginChangedSource = this.loginChanged.asObservable() | 54 | this.loginChangedSource = this.loginChanged.asObservable() |
@@ -74,14 +76,15 @@ export class AuthService { | |||
74 | let errorMessage = error.message | 76 | let errorMessage = error.message |
75 | 77 | ||
76 | if (error.status === 403) { | 78 | if (error.status === 403) { |
77 | errorMessage = `Cannot retrieve OAuth Client credentials: ${error.text}. \n` | 79 | errorMessage = this.i18n('Cannot retrieve OAuth Client credentials: {{ errorText }}.\n', { errorText: error.text }) |
78 | errorMessage += 'Ensure you have correctly configured PeerTube (config/ directory), ' + | 80 | errorMessage += this.i18n( |
79 | 'in particular the "webserver" section.' | 81 | 'Ensure you have correctly configured PeerTube (config/ directory), in particular the "webserver" section.' |
82 | ) | ||
80 | } | 83 | } |
81 | 84 | ||
82 | // We put a bigger timeout | 85 | // We put a bigger timeout |
83 | // This is an important message | 86 | // This is an important message |
84 | this.notificationsService.error('Error', errorMessage, { timeOut: 7000 }) | 87 | this.notificationsService.error(this.i18n('Error'), errorMessage, { timeOut: 7000 }) |
85 | } | 88 | } |
86 | ) | 89 | ) |
87 | } | 90 | } |
@@ -180,7 +183,7 @@ export class AuthService { | |||
180 | this.router.navigate([ '/login' ]) | 183 | this.router.navigate([ '/login' ]) |
181 | 184 | ||
182 | return observableThrowError({ | 185 | return observableThrowError({ |
183 | error: 'You need to reconnect.' | 186 | error: this.i18n('You need to reconnect.') |
184 | }) | 187 | }) |
185 | }), | 188 | }), |
186 | share() | 189 | share() |
diff --git a/client/src/app/core/confirm/confirm.component.html b/client/src/app/core/confirm/confirm.component.html index 01a4e0ac4..3253de4a0 100644 --- a/client/src/app/core/confirm/confirm.component.html +++ b/client/src/app/core/confirm/confirm.component.html | |||
@@ -16,7 +16,7 @@ | |||
16 | </div> | 16 | </div> |
17 | 17 | ||
18 | <div class="form-group inputs"> | 18 | <div class="form-group inputs"> |
19 | <span class="action-button action-button-cancel" (click)="cancel()"> | 19 | <span i18n class="action-button action-button-cancel" (click)="cancel()"> |
20 | Cancel | 20 | Cancel |
21 | </span> | 21 | </span> |
22 | 22 | ||
diff --git a/client/src/app/core/confirm/confirm.component.ts b/client/src/app/core/confirm/confirm.component.ts index 147bc9d65..02b38489a 100644 --- a/client/src/app/core/confirm/confirm.component.ts +++ b/client/src/app/core/confirm/confirm.component.ts | |||
@@ -3,6 +3,7 @@ import { Component, HostListener, OnInit, ViewChild } from '@angular/core' | |||
3 | import { ModalDirective } from 'ngx-bootstrap/modal' | 3 | import { ModalDirective } from 'ngx-bootstrap/modal' |
4 | 4 | ||
5 | import { ConfirmService } from './confirm.service' | 5 | import { ConfirmService } from './confirm.service' |
6 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
6 | 7 | ||
7 | @Component({ | 8 | @Component({ |
8 | selector: 'my-confirm', | 9 | selector: 'my-confirm', |
@@ -20,7 +21,10 @@ export class ConfirmComponent implements OnInit { | |||
20 | inputValue = '' | 21 | inputValue = '' |
21 | confirmButtonText = '' | 22 | confirmButtonText = '' |
22 | 23 | ||
23 | constructor (private confirmService: ConfirmService) { | 24 | constructor ( |
25 | private confirmService: ConfirmService, | ||
26 | private i18n: I18n | ||
27 | ) { | ||
24 | // Empty | 28 | // Empty |
25 | } | 29 | } |
26 | 30 | ||
@@ -38,7 +42,7 @@ export class ConfirmComponent implements OnInit { | |||
38 | this.inputLabel = inputLabel | 42 | this.inputLabel = inputLabel |
39 | this.expectedInputValue = expectedInputValue | 43 | this.expectedInputValue = expectedInputValue |
40 | 44 | ||
41 | this.confirmButtonText = confirmButtonText || 'Confirm' | 45 | this.confirmButtonText = confirmButtonText || this.i18n('Confirm') |
42 | 46 | ||
43 | this.showModal() | 47 | this.showModal() |
44 | } | 48 | } |
diff --git a/client/src/app/header/header.component.html b/client/src/app/header/header.component.html index c853d2b1b..a04354db5 100644 --- a/client/src/app/header/header.component.html +++ b/client/src/app/header/header.component.html | |||
@@ -1,10 +1,10 @@ | |||
1 | <input | 1 | <input |
2 | type="text" id="search-video" name="search-video" placeholder="Search..." | 2 | type="text" id="search-video" name="search-video" i18n-placeholder placeholder="Search..." |
3 | [(ngModel)]="searchValue" (keyup.enter)="doSearch()" | 3 | [(ngModel)]="searchValue" (keyup.enter)="doSearch()" |
4 | > | 4 | > |
5 | <span (click)="doSearch()" class="icon icon-search"></span> | 5 | <span (click)="doSearch()" class="icon icon-search"></span> |
6 | 6 | ||
7 | <a class="upload-button" routerLink="/videos/upload"> | 7 | <a class="upload-button" routerLink="/videos/upload"> |
8 | <span class="icon icon-upload"></span> | 8 | <span class="icon icon-upload"></span> |
9 | <span class="upload-button-label">Upload</span> | 9 | <span i18n class="upload-button-label">Upload</span> |
10 | </a> | 10 | </a> |
diff --git a/client/src/app/login/login.component.html b/client/src/app/login/login.component.html index b7fd25d27..1f6cfdb90 100644 --- a/client/src/app/login/login.component.html +++ b/client/src/app/login/login.component.html | |||
@@ -1,5 +1,5 @@ | |||
1 | <div class="margin-content"> | 1 | <div class="margin-content"> |
2 | <div class="title-page title-page-single"> | 2 | <div i18n class="title-page title-page-single"> |
3 | Login | 3 | Login |
4 | </div> | 4 | </div> |
5 | 5 | ||
@@ -8,21 +8,21 @@ | |||
8 | <form role="form" (ngSubmit)="login()" [formGroup]="form"> | 8 | <form role="form" (ngSubmit)="login()" [formGroup]="form"> |
9 | <div class="form-group"> | 9 | <div class="form-group"> |
10 | <div> | 10 | <div> |
11 | <label for="username">User</label> | 11 | <label i18n for="username">User</label> |
12 | <input | 12 | <input |
13 | type="text" id="username" placeholder="Username or email address" required tabindex="1" | 13 | type="text" id="username" i18n-placeholder placeholder="Username or email address" required tabindex="1" |
14 | formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }" | 14 | formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }" |
15 | > | 15 | > |
16 | <a *ngIf="signupAllowed === true" routerLink="/signup" class="create-an-account"> | 16 | <a i18n *ngIf="signupAllowed === true" routerLink="/signup" class="create-an-account"> |
17 | or create an account | 17 | or create an account |
18 | </a> | 18 | </a> |
19 | 19 | ||
20 | <a *ngIf="signupAllowed === false" href="https://joinpeertube.org/en/#getting-started" target="_blank" class="create-an-account"> | 20 | <a i18n *ngIf="signupAllowed === false" href="https://joinpeertube.org/en/#getting-started" target="_blank" class="create-an-account"> |
21 | or create an account on another instance | 21 | or create an account on another instance |
22 | </a> | 22 | </a> |
23 | 23 | ||
24 | <my-help | 24 | <my-help |
25 | *ngIf="signupAllowed === false" helpType="custom" | 25 | *ngIf="signupAllowed === false" helpType="custom" i18n-customHtml |
26 | customHtml="User registration is not allowed on this instance, but you can register on many others!" | 26 | customHtml="User registration is not allowed on this instance, but you can register on many others!" |
27 | ></my-help> | 27 | ></my-help> |
28 | </div> | 28 | </div> |
@@ -33,13 +33,13 @@ | |||
33 | </div> | 33 | </div> |
34 | 34 | ||
35 | <div class="form-group"> | 35 | <div class="form-group"> |
36 | <label for="password">Password</label> | 36 | <label i18n for="password">Password</label> |
37 | <div> | 37 | <div> |
38 | <input | 38 | <input |
39 | type="password" name="password" id="password" placeholder="Password" required tabindex="2" | 39 | type="password" name="password" id="password" i18n-placeholder placeholder="Password" required tabindex="2" |
40 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | 40 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" |
41 | > | 41 | > |
42 | <div class="forgot-password-button" (click)="openForgotPasswordModal()">I forgot my password</div> | 42 | <div i18n class="forgot-password-button" (click)="openForgotPasswordModal()">I forgot my password</div> |
43 | </div> | 43 | </div> |
44 | <div *ngIf="formErrors.password" class="form-error"> | 44 | <div *ngIf="formErrors.password" class="form-error"> |
45 | {{ formErrors.password }} | 45 | {{ formErrors.password }} |
@@ -56,25 +56,25 @@ | |||
56 | 56 | ||
57 | <div class="modal-header"> | 57 | <div class="modal-header"> |
58 | <span class="close" aria-hidden="true" (click)="hideForgotPasswordModal()"></span> | 58 | <span class="close" aria-hidden="true" (click)="hideForgotPasswordModal()"></span> |
59 | <h4 class="modal-title">Forgot your password</h4> | 59 | <h4 i18n class="modal-title">Forgot your password</h4> |
60 | </div> | 60 | </div> |
61 | 61 | ||
62 | <div class="modal-body"> | 62 | <div class="modal-body"> |
63 | <div class="form-group"> | 63 | <div class="form-group"> |
64 | <label for="forgot-password-email">Email</label> | 64 | <label i18n for="forgot-password-email">Email</label> |
65 | <input | 65 | <input |
66 | type="email" id="forgot-password-email" placeholder="Email address" required | 66 | type="email" id="forgot-password-email" i18n-placeholder placeholder="Email address" required |
67 | [(ngModel)]="forgotPasswordEmail" #forgotPasswordEmailInput | 67 | [(ngModel)]="forgotPasswordEmail" #forgotPasswordEmailInput |
68 | > | 68 | > |
69 | </div> | 69 | </div> |
70 | 70 | ||
71 | <div class="form-group inputs"> | 71 | <div class="form-group inputs"> |
72 | <span class="action-button action-button-cancel" (click)="hideForgotPasswordModal()"> | 72 | <span i18n class="action-button action-button-cancel" (click)="hideForgotPasswordModal()"> |
73 | Cancel | 73 | Cancel |
74 | </span> | 74 | </span> |
75 | 75 | ||
76 | <input | 76 | <input |
77 | type="submit" value="Send me an email to reset my password" class="action-button-submit" | 77 | type="submit" i18n-value value="Send me an email to reset my password" class="action-button-submit" |
78 | (click)="askResetPassword()" [disabled]="!forgotPasswordEmailInput.validity.valid" | 78 | (click)="askResetPassword()" [disabled]="!forgotPasswordEmailInput.validity.valid" |
79 | > | 79 | > |
80 | </div> | 80 | </div> |
diff --git a/client/src/app/login/login.component.ts b/client/src/app/login/login.component.ts index 2514faf94..a14cb2eb7 100644 --- a/client/src/app/login/login.component.ts +++ b/client/src/app/login/login.component.ts | |||
@@ -7,6 +7,7 @@ import { NotificationsService } from 'angular2-notifications' | |||
7 | import { ModalDirective } from 'ngx-bootstrap/modal' | 7 | import { ModalDirective } from 'ngx-bootstrap/modal' |
8 | import { AuthService } from '../core' | 8 | import { AuthService } from '../core' |
9 | import { FormReactive } from '../shared' | 9 | import { FormReactive } from '../shared' |
10 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
10 | 11 | ||
11 | @Component({ | 12 | @Component({ |
12 | selector: 'my-login', | 13 | selector: 'my-login', |
@@ -35,12 +36,15 @@ export class LoginComponent extends FormReactive implements OnInit { | |||
35 | } | 36 | } |
36 | forgotPasswordEmail = '' | 37 | forgotPasswordEmail = '' |
37 | 38 | ||
38 | constructor (private authService: AuthService, | 39 | constructor ( |
39 | private userService: UserService, | 40 | private authService: AuthService, |
40 | private serverService: ServerService, | 41 | private userService: UserService, |
41 | private redirectService: RedirectService, | 42 | private serverService: ServerService, |
42 | private notificationsService: NotificationsService, | 43 | private redirectService: RedirectService, |
43 | private formBuilder: FormBuilder) { | 44 | private notificationsService: NotificationsService, |
45 | private formBuilder: FormBuilder, | ||
46 | private i18n: I18n | ||
47 | ) { | ||
44 | super() | 48 | super() |
45 | } | 49 | } |
46 | 50 | ||
@@ -78,12 +82,15 @@ export class LoginComponent extends FormReactive implements OnInit { | |||
78 | this.userService.askResetPassword(this.forgotPasswordEmail) | 82 | this.userService.askResetPassword(this.forgotPasswordEmail) |
79 | .subscribe( | 83 | .subscribe( |
80 | res => { | 84 | res => { |
81 | const message = `An email with the reset password instructions will be sent to ${this.forgotPasswordEmail}.` | 85 | const message = this.i18n( |
82 | this.notificationsService.success('Success', message) | 86 | 'An email with the reset password instructions will be sent to {{ email }}.', |
87 | { email: this.forgotPasswordEmail } | ||
88 | ) | ||
89 | this.notificationsService.success(this.i18n('Success'), message) | ||
83 | this.hideForgotPasswordModal() | 90 | this.hideForgotPasswordModal() |
84 | }, | 91 | }, |
85 | 92 | ||
86 | err => this.notificationsService.error('Error', err.message) | 93 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
87 | ) | 94 | ) |
88 | } | 95 | } |
89 | 96 | ||
diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html index 1a95477b7..167729405 100644 --- a/client/src/app/menu/menu.component.html +++ b/client/src/app/menu/menu.component.html | |||
@@ -18,11 +18,11 @@ | |||
18 | My public profile | 18 | My public profile |
19 | </a> | 19 | </a> |
20 | 20 | ||
21 | <a routerLink="/my-account/settings" class="dropdown-item" title="My settings"> | 21 | <a i18n routerLink="/my-account/settings" class="dropdown-item" title="My settings"> |
22 | My settings | 22 | My settings |
23 | </a> | 23 | </a> |
24 | 24 | ||
25 | <a (click)="logout($event)" class="dropdown-item" title="Log out" href="#"> | 25 | <a i18n (click)="logout($event)" class="dropdown-item" title="Log out" href="#"> |
26 | Log out | 26 | Log out |
27 | </a> | 27 | </a> |
28 | </li> | 28 | </li> |
@@ -31,26 +31,26 @@ | |||
31 | </div> | 31 | </div> |
32 | 32 | ||
33 | <div *ngIf="!isLoggedIn" class="button-block"> | 33 | <div *ngIf="!isLoggedIn" class="button-block"> |
34 | <a routerLink="/login" class="login-button">Login</a> | 34 | <a i18n routerLink="/login" class="login-button">Login</a> |
35 | <a *ngIf="isRegistrationAllowed()" routerLink="/signup" class="create-account-button">Create an account</a> | 35 | <a i18n *ngIf="isRegistrationAllowed()" routerLink="/signup" class="create-account-button">Create an account</a> |
36 | </div> | 36 | </div> |
37 | 37 | ||
38 | <div class="panel-block"> | 38 | <div class="panel-block"> |
39 | <div class="block-title">Videos</div> | 39 | <div i18n class="block-title">Videos</div> |
40 | 40 | ||
41 | <a routerLink="/videos/trending" routerLinkActive="active"> | 41 | <a routerLink="/videos/trending" routerLinkActive="active"> |
42 | <span class="icon icon-videos-trending"></span> | 42 | <span class="icon icon-videos-trending"></span> |
43 | Trending | 43 | <ng-container i18n>Trending</ng-container> |
44 | </a> | 44 | </a> |
45 | 45 | ||
46 | <a routerLink="/videos/recently-added" routerLinkActive="active"> | 46 | <a routerLink="/videos/recently-added" routerLinkActive="active"> |
47 | <span class="icon icon-videos-recently-added"></span> | 47 | <span class="icon icon-videos-recently-added"></span> |
48 | Recently added | 48 | <ng-container i18n>Recently added</ng-container> |
49 | </a> | 49 | </a> |
50 | 50 | ||
51 | <a routerLink="/videos/local" routerLinkActive="active"> | 51 | <a routerLink="/videos/local" routerLinkActive="active"> |
52 | <span class="icon icon-videos-local"></span> | 52 | <span class="icon icon-videos-local"></span> |
53 | Local | 53 | <ng-container i18n>Local</ng-container> |
54 | </a> | 54 | </a> |
55 | </div> | 55 | </div> |
56 | 56 | ||
@@ -59,12 +59,12 @@ | |||
59 | 59 | ||
60 | <a *ngIf="userHasAdminAccess" [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active"> | 60 | <a *ngIf="userHasAdminAccess" [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active"> |
61 | <span class="icon icon-administration"></span> | 61 | <span class="icon icon-administration"></span> |
62 | Administration | 62 | <ng-container i18n>Administration</ng-container> |
63 | </a> | 63 | </a> |
64 | 64 | ||
65 | <a routerLink="/about" routerLinkActive="active"> | 65 | <a routerLink="/about" routerLinkActive="active"> |
66 | <span class="icon icon-about"></span> | 66 | <span class="icon icon-about"></span> |
67 | About | 67 | <ng-container i18n>About</ng-container> |
68 | </a> | 68 | </a> |
69 | </div> | 69 | </div> |
70 | </menu> | 70 | </menu> |
diff --git a/client/src/app/menu/menu.component.ts b/client/src/app/menu/menu.component.ts index 69216e215..c0aea89b3 100644 --- a/client/src/app/menu/menu.component.ts +++ b/client/src/app/menu/menu.component.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | 1 | import { Component, OnInit } from '@angular/core' |
2 | import { Router } from '@angular/router' | 2 | import { Router } from '@angular/router' |
3 | import { UserRight } from '../../../../shared/models/users/user-right.enum' | 3 | import { UserRight } from '../../../../shared/models/users/user-right.enum' |
4 | import { AuthService, AuthStatus, ServerService } from '../core' | 4 | import { AuthService, AuthStatus, RedirectService, ServerService } from '../core' |
5 | import { User } from '../shared/users/user.model' | 5 | import { User } from '../shared/users/user.model' |
6 | 6 | ||
7 | @Component({ | 7 | @Component({ |
@@ -24,7 +24,7 @@ export class MenuComponent implements OnInit { | |||
24 | constructor ( | 24 | constructor ( |
25 | private authService: AuthService, | 25 | private authService: AuthService, |
26 | private serverService: ServerService, | 26 | private serverService: ServerService, |
27 | private router: Router | 27 | private redirectService: RedirectService |
28 | ) {} | 28 | ) {} |
29 | 29 | ||
30 | ngOnInit () { | 30 | ngOnInit () { |
@@ -87,7 +87,7 @@ export class MenuComponent implements OnInit { | |||
87 | 87 | ||
88 | this.authService.logout() | 88 | this.authService.logout() |
89 | // Redirect to home page | 89 | // Redirect to home page |
90 | this.router.navigate(['/videos/list']) | 90 | this.redirectService.redirectToHomepage() |
91 | } | 91 | } |
92 | 92 | ||
93 | private computeIsUserHasAdminAccess () { | 93 | private computeIsUserHasAdminAccess () { |
diff --git a/client/src/app/reset-password/reset-password.component.html b/client/src/app/reset-password/reset-password.component.html index 9cf623c64..20e62d0b7 100644 --- a/client/src/app/reset-password/reset-password.component.html +++ b/client/src/app/reset-password/reset-password.component.html | |||
@@ -1,13 +1,13 @@ | |||
1 | <div class="margin-content"> | 1 | <div class="margin-content"> |
2 | <div class="title-page title-page-single"> | 2 | <div i18n class="title-page title-page-single"> |
3 | Reset my password | 3 | Reset my password |
4 | </div> | 4 | </div> |
5 | 5 | ||
6 | <form role="form" (ngSubmit)="resetPassword()" [formGroup]="form"> | 6 | <form role="form" (ngSubmit)="resetPassword()" [formGroup]="form"> |
7 | <div class="form-group"> | 7 | <div class="form-group"> |
8 | <label for="password">Password</label> | 8 | <label i18n for="password">Password</label> |
9 | <input | 9 | <input |
10 | type="password" name="password" id="password" placeholder="Password" required | 10 | type="password" name="password" id="password" i18n-placeholder placeholder="Password" required |
11 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | 11 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" |
12 | > | 12 | > |
13 | <div *ngIf="formErrors.password" class="form-error"> | 13 | <div *ngIf="formErrors.password" class="form-error"> |
@@ -16,9 +16,9 @@ | |||
16 | </div> | 16 | </div> |
17 | 17 | ||
18 | <div class="form-group"> | 18 | <div class="form-group"> |
19 | <label for="password-confirm">Confirm password</label> | 19 | <label i18n for="password-confirm">Confirm password</label> |
20 | <input | 20 | <input |
21 | type="password" name="password-confirm" id="password-confirm" placeholder="Confirmed password" required | 21 | type="password" name="password-confirm" id="password-confirm" i18n-placeholder placeholder="Confirmed password" required |
22 | formControlName="password-confirm" [ngClass]="{ 'input-error': formErrors['password-confirm'] }" | 22 | formControlName="password-confirm" [ngClass]="{ 'input-error': formErrors['password-confirm'] }" |
23 | > | 23 | > |
24 | <div *ngIf="formErrors['password-confirm']" class="form-error"> | 24 | <div *ngIf="formErrors['password-confirm']" class="form-error"> |
@@ -26,6 +26,6 @@ | |||
26 | </div> | 26 | </div> |
27 | </div> | 27 | </div> |
28 | 28 | ||
29 | <input type="submit" value="Reset my password" [disabled]="!form.valid && isConfirmedPasswordValid()"> | 29 | <input type="submit" i18n-value value="Reset my password" [disabled]="!form.valid && isConfirmedPasswordValid()"> |
30 | </form> | 30 | </form> |
31 | </div> | 31 | </div> |
diff --git a/client/src/app/reset-password/reset-password.component.ts b/client/src/app/reset-password/reset-password.component.ts index 408374779..c8bd368c1 100644 --- a/client/src/app/reset-password/reset-password.component.ts +++ b/client/src/app/reset-password/reset-password.component.ts | |||
@@ -5,6 +5,7 @@ import { USER_PASSWORD, UserService } from '@app/shared' | |||
5 | import { NotificationsService } from 'angular2-notifications' | 5 | import { NotificationsService } from 'angular2-notifications' |
6 | import { AuthService } from '../core' | 6 | import { AuthService } from '../core' |
7 | import { FormReactive } from '../shared' | 7 | import { FormReactive } from '../shared' |
8 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
8 | 9 | ||
9 | @Component({ | 10 | @Component({ |
10 | selector: 'my-login', | 11 | selector: 'my-login', |
@@ -34,7 +35,8 @@ export class ResetPasswordComponent extends FormReactive implements OnInit { | |||
34 | private notificationsService: NotificationsService, | 35 | private notificationsService: NotificationsService, |
35 | private formBuilder: FormBuilder, | 36 | private formBuilder: FormBuilder, |
36 | private router: Router, | 37 | private router: Router, |
37 | private route: ActivatedRoute | 38 | private route: ActivatedRoute, |
39 | private i18n: I18n | ||
38 | ) { | 40 | ) { |
39 | super() | 41 | super() |
40 | } | 42 | } |
@@ -55,7 +57,7 @@ export class ResetPasswordComponent extends FormReactive implements OnInit { | |||
55 | this.verificationString = this.route.snapshot.queryParams['verificationString'] | 57 | this.verificationString = this.route.snapshot.queryParams['verificationString'] |
56 | 58 | ||
57 | if (!this.userId || !this.verificationString) { | 59 | if (!this.userId || !this.verificationString) { |
58 | this.notificationsService.error('Error', 'Unable to find user id or verification string.') | 60 | this.notificationsService.error(this.i18n('Error'), this.i18n('Unable to find user id or verification string.')) |
59 | this.router.navigate([ '/' ]) | 61 | this.router.navigate([ '/' ]) |
60 | } | 62 | } |
61 | } | 63 | } |
@@ -64,7 +66,7 @@ export class ResetPasswordComponent extends FormReactive implements OnInit { | |||
64 | this.userService.resetPassword(this.userId, this.verificationString, this.form.value.password) | 66 | this.userService.resetPassword(this.userId, this.verificationString, this.form.value.password) |
65 | .subscribe( | 67 | .subscribe( |
66 | () => { | 68 | () => { |
67 | this.notificationsService.success('Success', 'Your password has been successfully reset!') | 69 | this.notificationsService.success(this.i18n('Success'), this.i18n('Your password has been successfully reset!')) |
68 | this.router.navigate([ '/login' ]) | 70 | this.router.navigate([ '/login' ]) |
69 | }, | 71 | }, |
70 | 72 | ||
diff --git a/client/src/app/shared/forms/markdown-textarea.component.html b/client/src/app/shared/forms/markdown-textarea.component.html index 46a97b163..6effda5b8 100644 --- a/client/src/app/shared/forms/markdown-textarea.component.html +++ b/client/src/app/shared/forms/markdown-textarea.component.html | |||
@@ -6,7 +6,7 @@ | |||
6 | </textarea> | 6 | </textarea> |
7 | 7 | ||
8 | <tabset *ngIf="arePreviewsDisplayed()" class="previews"> | 8 | <tabset *ngIf="arePreviewsDisplayed()" class="previews"> |
9 | <tab *ngIf="truncate !== undefined" heading="Truncated preview" [innerHTML]="truncatedPreviewHTML"></tab> | 9 | <tab *ngIf="truncate !== undefined" i18n-heading heading="Truncated preview" [innerHTML]="truncatedPreviewHTML"></tab> |
10 | <tab heading="Complete preview" [innerHTML]="previewHTML"></tab> | 10 | <tab i18n-heading heading="Complete preview" [innerHTML]="previewHTML"></tab> |
11 | </tabset> | 11 | </tabset> |
12 | </div> | 12 | </div> |
diff --git a/client/src/app/shared/forms/markdown-textarea.component.ts b/client/src/app/shared/forms/markdown-textarea.component.ts index dcc85f3cd..8b932cd15 100644 --- a/client/src/app/shared/forms/markdown-textarea.component.ts +++ b/client/src/app/shared/forms/markdown-textarea.component.ts | |||
@@ -3,7 +3,7 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core' | |||
3 | import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' | 3 | import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' |
4 | import { isInSmallView } from '@app/shared/misc/utils' | 4 | import { isInSmallView } from '@app/shared/misc/utils' |
5 | import { MarkdownService } from '@app/videos/shared' | 5 | import { MarkdownService } from '@app/videos/shared' |
6 | import { Subject } from 'rxjs' | 6 | import { Subject } from 'rxjs/Subject' |
7 | import truncate from 'lodash-es/truncate' | 7 | import truncate from 'lodash-es/truncate' |
8 | 8 | ||
9 | @Component({ | 9 | @Component({ |
diff --git a/client/src/app/shared/guards/can-deactivate-guard.service.ts b/client/src/app/shared/guards/can-deactivate-guard.service.ts index 550dd656e..c038a5c0e 100644 --- a/client/src/app/shared/guards/can-deactivate-guard.service.ts +++ b/client/src/app/shared/guards/can-deactivate-guard.service.ts | |||
@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core' | |||
2 | import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot } from '@angular/router' | 2 | import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot } from '@angular/router' |
3 | import { Observable } from 'rxjs' | 3 | import { Observable } from 'rxjs' |
4 | import { ConfirmService } from '../../core/index' | 4 | import { ConfirmService } from '../../core/index' |
5 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
5 | 6 | ||
6 | export interface CanComponentDeactivate { | 7 | export interface CanComponentDeactivate { |
7 | canDeactivate: () => { text?: string, canDeactivate: Observable<boolean> | boolean } | 8 | canDeactivate: () => { text?: string, canDeactivate: Observable<boolean> | boolean } |
@@ -9,7 +10,10 @@ export interface CanComponentDeactivate { | |||
9 | 10 | ||
10 | @Injectable() | 11 | @Injectable() |
11 | export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> { | 12 | export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> { |
12 | constructor (private confirmService: ConfirmService) { } | 13 | constructor ( |
14 | private confirmService: ConfirmService, | ||
15 | private i18n: I18n | ||
16 | ) { } | ||
13 | 17 | ||
14 | canDeactivate (component: CanComponentDeactivate, | 18 | canDeactivate (component: CanComponentDeactivate, |
15 | currentRoute: ActivatedRouteSnapshot, | 19 | currentRoute: ActivatedRouteSnapshot, |
@@ -17,11 +21,11 @@ export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> | |||
17 | nextState: RouterStateSnapshot | 21 | nextState: RouterStateSnapshot |
18 | ) { | 22 | ) { |
19 | const result = component.canDeactivate() | 23 | const result = component.canDeactivate() |
20 | const text = result.text || 'All unsaved data will be lost, are you sure you want to leave this page?' | 24 | const text = result.text || this.i18n('All unsaved data will be lost, are you sure you want to leave this page?') |
21 | 25 | ||
22 | return result.canDeactivate || this.confirmService.confirm( | 26 | return result.canDeactivate || this.confirmService.confirm( |
23 | text, | 27 | text, |
24 | 'Warning' | 28 | this.i18n('Warning') |
25 | ) | 29 | ) |
26 | } | 30 | } |
27 | 31 | ||
diff --git a/client/src/app/shared/misc/edit-button.component.html b/client/src/app/shared/misc/edit-button.component.html index 632d6bba2..78fbc326e 100644 --- a/client/src/app/shared/misc/edit-button.component.html +++ b/client/src/app/shared/misc/edit-button.component.html | |||
@@ -1,4 +1,4 @@ | |||
1 | <a class="action-button action-button-edit" [routerLink]="routerLink" title="Edit"> | 1 | <a class="action-button action-button-edit" [routerLink]="routerLink" title="Edit"> |
2 | <span class="icon icon-edit"></span> | 2 | <span class="icon icon-edit"></span> |
3 | <span class="button-label">Edit</span> | 3 | <span i18n class="button-label">Edit</span> |
4 | </a> | 4 | </a> |
diff --git a/client/src/app/shared/misc/from-now.pipe.ts b/client/src/app/shared/misc/from-now.pipe.ts index fac02af0b..3a64a4077 100644 --- a/client/src/app/shared/misc/from-now.pipe.ts +++ b/client/src/app/shared/misc/from-now.pipe.ts | |||
@@ -1,36 +1,39 @@ | |||
1 | import { Pipe, PipeTransform } from '@angular/core' | 1 | import { Pipe, PipeTransform } from '@angular/core' |
2 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
2 | 3 | ||
3 | // Thanks: https://stackoverflow.com/questions/3177836/how-to-format-time-since-xxx-e-g-4-minutes-ago-similar-to-stack-exchange-site | 4 | // Thanks: https://stackoverflow.com/questions/3177836/how-to-format-time-since-xxx-e-g-4-minutes-ago-similar-to-stack-exchange-site |
4 | @Pipe({ name: 'myFromNow' }) | 5 | @Pipe({ name: 'myFromNow' }) |
5 | export class FromNowPipe implements PipeTransform { | 6 | export class FromNowPipe implements PipeTransform { |
6 | 7 | ||
8 | constructor (private i18n: I18n) { } | ||
9 | |||
7 | transform (value: number) { | 10 | transform (value: number) { |
8 | const seconds = Math.floor((Date.now() - value) / 1000) | 11 | const seconds = Math.floor((Date.now() - value) / 1000) |
9 | 12 | ||
10 | let interval = Math.floor(seconds / 31536000) | 13 | let interval = Math.floor(seconds / 31536000) |
11 | if (interval > 1) { | 14 | if (interval > 1) { |
12 | return interval + ' years ago' | 15 | return this.i18n('{{ interval }} years ago', { interval }) |
13 | } | 16 | } |
14 | 17 | ||
15 | interval = Math.floor(seconds / 2592000) | 18 | interval = Math.floor(seconds / 2592000) |
16 | if (interval > 1) return interval + ' months ago' | 19 | if (interval > 1) return this.i18n('{{ interval }} months ago', { interval }) |
17 | if (interval === 1) return interval + ' month ago' | 20 | if (interval === 1) return this.i18n('{{ interval }} month ago', { interval }) |
18 | 21 | ||
19 | interval = Math.floor(seconds / 604800) | 22 | interval = Math.floor(seconds / 604800) |
20 | if (interval > 1) return interval + ' weeks ago' | 23 | if (interval > 1) return this.i18n('{{ interval }} weeks ago', { interval }) |
21 | if (interval === 1) return interval + ' week ago' | 24 | if (interval === 1) return this.i18n('{{ interval }} week ago', { interval }) |
22 | 25 | ||
23 | interval = Math.floor(seconds / 86400) | 26 | interval = Math.floor(seconds / 86400) |
24 | if (interval > 1) return interval + ' days ago' | 27 | if (interval > 1) return this.i18n('{{ interval }} days ago', { interval }) |
25 | if (interval === 1) return interval + ' day ago' | 28 | if (interval === 1) return this.i18n('{{ interval }} day ago', { interval }) |
26 | 29 | ||
27 | interval = Math.floor(seconds / 3600) | 30 | interval = Math.floor(seconds / 3600) |
28 | if (interval > 1) return interval + ' hours ago' | 31 | if (interval > 1) return this.i18n('{{ interval }} hours ago', { interval }) |
29 | if (interval === 1) return interval + ' hour ago' | 32 | if (interval === 1) return this.i18n('{{ interval }} hour ago', { interval }) |
30 | 33 | ||
31 | interval = Math.floor(seconds / 60) | 34 | interval = Math.floor(seconds / 60) |
32 | if (interval >= 1) return interval + ' min ago' | 35 | if (interval >= 1) return this.i18n('{{ interval }} min ago', { interval }) |
33 | 36 | ||
34 | return Math.floor(seconds) + ' sec ago' | 37 | return this.i18n('{{ interval }} sec ago', { interval: Math.floor(seconds) }) |
35 | } | 38 | } |
36 | } | 39 | } |
diff --git a/client/src/app/shared/misc/help.component.html b/client/src/app/shared/misc/help.component.html index 3da5701a0..f2b6eca33 100644 --- a/client/src/app/shared/misc/help.component.html +++ b/client/src/app/shared/misc/help.component.html | |||
@@ -15,6 +15,7 @@ | |||
15 | <span | 15 | <span |
16 | class="help-tooltip-button" | 16 | class="help-tooltip-button" |
17 | title="Get help" | 17 | title="Get help" |
18 | i18n-title | ||
18 | [popover]="tooltipTemplate" | 19 | [popover]="tooltipTemplate" |
19 | [placement]="tooltipPlacement" | 20 | [placement]="tooltipPlacement" |
20 | [outsideClick]="true" | 21 | [outsideClick]="true" |
diff --git a/client/src/app/shared/rest/rest-extractor.service.ts b/client/src/app/shared/rest/rest-extractor.service.ts index 39e601e20..468ac3e32 100644 --- a/client/src/app/shared/rest/rest-extractor.service.ts +++ b/client/src/app/shared/rest/rest-extractor.service.ts | |||
@@ -3,11 +3,15 @@ import { Injectable } from '@angular/core' | |||
3 | import { dateToHuman } from '@app/shared/misc/utils' | 3 | import { dateToHuman } from '@app/shared/misc/utils' |
4 | import { ResultList } from '../../../../../shared' | 4 | import { ResultList } from '../../../../../shared' |
5 | import { Router } from '@angular/router' | 5 | import { Router } from '@angular/router' |
6 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
6 | 7 | ||
7 | @Injectable() | 8 | @Injectable() |
8 | export class RestExtractor { | 9 | export class RestExtractor { |
9 | 10 | ||
10 | constructor (private router: Router) { | 11 | constructor ( |
12 | private router: Router, | ||
13 | private i18n: I18n | ||
14 | ) { | ||
11 | // empty | 15 | // empty |
12 | } | 16 | } |
13 | 17 | ||
@@ -60,17 +64,19 @@ export class RestExtractor { | |||
60 | } else if (err.error && err.error.error) { | 64 | } else if (err.error && err.error.error) { |
61 | errorMessage = err.error.error | 65 | errorMessage = err.error.error |
62 | } else if (err.status === 413) { | 66 | } else if (err.status === 413) { |
63 | errorMessage = 'Request is too large for the server. Please contact you administrator if you want to increase the limit size.' | 67 | errorMessage = this.i18n( |
68 | 'Request is too large for the server. Please contact you administrator if you want to increase the limit size.' | ||
69 | ) | ||
64 | } else if (err.status === 429) { | 70 | } else if (err.status === 429) { |
65 | const secondsLeft = err.headers.get('retry-after') | 71 | const secondsLeft = err.headers.get('retry-after') |
66 | if (secondsLeft) { | 72 | if (secondsLeft) { |
67 | const minutesLeft = Math.floor(parseInt(secondsLeft, 10) / 60) | 73 | const minutesLeft = Math.floor(parseInt(secondsLeft, 10) / 60) |
68 | errorMessage = 'Too many attempts, please try again after ' + minutesLeft + ' minutes.' | 74 | errorMessage = this.i18n('Too many attempts, please try again after {{ minutesLeft }} minutes.', { minutesLeft }) |
69 | } else { | 75 | } else { |
70 | errorMessage = 'Too many attempts, please try again later.' | 76 | errorMessage = this.i18n('Too many attempts, please try again later.') |
71 | } | 77 | } |
72 | } else if (err.status === 500) { | 78 | } else if (err.status === 500) { |
73 | errorMessage = 'Server error. Please retry later.' | 79 | errorMessage = this.i18n('Server error. Please retry later.') |
74 | } | 80 | } |
75 | 81 | ||
76 | errorMessage = errorMessage ? errorMessage : 'Unknown error.' | 82 | errorMessage = errorMessage ? errorMessage : 'Unknown error.' |
diff --git a/client/src/app/shared/video/abstract-video-list.html b/client/src/app/shared/video/abstract-video-list.html index 690529dcf..e8ded6ab8 100644 --- a/client/src/app/shared/video/abstract-video-list.html +++ b/client/src/app/shared/video/abstract-video-list.html | |||
@@ -4,7 +4,7 @@ | |||
4 | </div> | 4 | </div> |
5 | <my-video-feed [syndicationItems]="syndicationItems"></my-video-feed> | 5 | <my-video-feed [syndicationItems]="syndicationItems"></my-video-feed> |
6 | 6 | ||
7 | <div *ngIf="pagination.totalItems === 0">No results.</div> | 7 | <div i18n *ngIf="pagination.totalItems === 0">No results.</div> |
8 | <div | 8 | <div |
9 | myInfiniteScroller | 9 | myInfiniteScroller |
10 | [pageHeight]="pageHeight" | 10 | [pageHeight]="pageHeight" |
diff --git a/client/src/app/shared/video/abstract-video-list.ts b/client/src/app/shared/video/abstract-video-list.ts index 100cbff8d..1c84573da 100644 --- a/client/src/app/shared/video/abstract-video-list.ts +++ b/client/src/app/shared/video/abstract-video-list.ts | |||
@@ -10,6 +10,7 @@ import { AuthService } from '../../core/auth' | |||
10 | import { ComponentPagination } from '../rest/component-pagination.model' | 10 | import { ComponentPagination } from '../rest/component-pagination.model' |
11 | import { VideoSortField } from './sort-field.type' | 11 | import { VideoSortField } from './sort-field.type' |
12 | import { Video } from './video.model' | 12 | import { Video } from './video.model' |
13 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
13 | 14 | ||
14 | export abstract class AbstractVideoList implements OnInit, OnDestroy { | 15 | export abstract class AbstractVideoList implements OnInit, OnDestroy { |
15 | private static LINES_PER_PAGE = 4 | 16 | private static LINES_PER_PAGE = 4 |
@@ -40,6 +41,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy { | |||
40 | protected abstract authService: AuthService | 41 | protected abstract authService: AuthService |
41 | protected abstract router: Router | 42 | protected abstract router: Router |
42 | protected abstract route: ActivatedRoute | 43 | protected abstract route: ActivatedRoute |
44 | protected abstract i18n: I18n | ||
43 | protected abstract location: Location | 45 | protected abstract location: Location |
44 | protected abstract currentRoute: string | 46 | protected abstract currentRoute: string |
45 | abstract titlePage: string | 47 | abstract titlePage: string |
@@ -124,7 +126,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy { | |||
124 | }, | 126 | }, |
125 | error => { | 127 | error => { |
126 | this.loadingPage[page] = false | 128 | this.loadingPage[page] = false |
127 | this.notificationsService.error('Error', error.message) | 129 | this.notificationsService.error(this.i18n('Error'), error.message) |
128 | } | 130 | } |
129 | ) | 131 | ) |
130 | } | 132 | } |
diff --git a/client/src/app/shared/video/video-miniature.component.html b/client/src/app/shared/video/video-miniature.component.html index 09ce0ef7f..3010e5ccc 100644 --- a/client/src/app/shared/video/video-miniature.component.html +++ b/client/src/app/shared/video/video-miniature.component.html | |||
@@ -9,7 +9,7 @@ | |||
9 | {{ video.name }} | 9 | {{ video.name }} |
10 | </a> | 10 | </a> |
11 | 11 | ||
12 | <span class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> | 12 | <span i18n class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> |
13 | <a class="video-miniature-account" [routerLink]="[ '/accounts', video.by ]">{{ video.by }}</a> | 13 | <a class="video-miniature-account" [routerLink]="[ '/accounts', video.by ]">{{ video.by }}</a> |
14 | </div> | 14 | </div> |
15 | </div> | 15 | </div> |
diff --git a/client/src/app/shared/video/video-thumbnail.component.html b/client/src/app/shared/video/video-thumbnail.component.html index 4604d10e2..971f352ba 100644 --- a/client/src/app/shared/video/video-thumbnail.component.html +++ b/client/src/app/shared/video/video-thumbnail.component.html | |||
@@ -1,6 +1,6 @@ | |||
1 | <a | 1 | <a |
2 | [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name" | 2 | [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name" |
3 | class="video-thumbnail" | 3 | class="video-thumbnail" |
4 | > | 4 | > |
5 | <img [attr.src]="getImageUrl()" [ngClass]="{ 'blur-filter': nsfw }" /> | 5 | <img [attr.src]="getImageUrl()" [ngClass]="{ 'blur-filter': nsfw }" /> |
6 | 6 | ||
diff --git a/client/src/app/signup/signup.component.html b/client/src/app/signup/signup.component.html index 5f48786e5..2fe9a4281 100644 --- a/client/src/app/signup/signup.component.html +++ b/client/src/app/signup/signup.component.html | |||
@@ -1,11 +1,11 @@ | |||
1 | <div class="margin-content"> | 1 | <div class="margin-content"> |
2 | 2 | ||
3 | <div class="title-page title-page-single"> | 3 | <div i18n class="title-page title-page-single"> |
4 | Create an account | 4 | Create an account |
5 | </div> | 5 | </div> |
6 | 6 | ||
7 | <div class="initial-user-quota"> | 7 | <div class="initial-user-quota"> |
8 | <span class="initial-user-quota-label">Initial video quota:</span> | 8 | <span i18n class="initial-user-quota-label">Initial video quota:</span> |
9 | 9 | ||
10 | <span *ngIf="initialUserVideoQuota !== -1"> | 10 | <span *ngIf="initialUserVideoQuota !== -1"> |
11 | {{ initialUserVideoQuota | bytes: 0 }} | 11 | {{ initialUserVideoQuota | bytes: 0 }} |
@@ -13,18 +13,18 @@ | |||
13 | <my-help helpType="custom" [customHtml]="quotaHelpIndication"></my-help> | 13 | <my-help helpType="custom" [customHtml]="quotaHelpIndication"></my-help> |
14 | </span> | 14 | </span> |
15 | 15 | ||
16 | <ng-template [ngIf]="initialUserVideoQuota === -1"> | 16 | <ng-container i18n *ngIf="initialUserVideoQuota === -1"> |
17 | Unlimited | 17 | Unlimited |
18 | </ng-template> | 18 | </ng-container> |
19 | </div> | 19 | </div> |
20 | 20 | ||
21 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> | 21 | <div *ngIf="error" class="alert alert-danger">{{ error }}</div> |
22 | 22 | ||
23 | <form role="form" (ngSubmit)="signup()" [formGroup]="form"> | 23 | <form role="form" (ngSubmit)="signup()" [formGroup]="form"> |
24 | <div class="form-group"> | 24 | <div class="form-group"> |
25 | <label for="username">Username</label> | 25 | <label for="username" i18n>Username</label> |
26 | <input | 26 | <input |
27 | type="text" id="username" placeholder="Username" | 27 | type="text" id="username" i18n-placeholder placeholder="Username" |
28 | formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }" | 28 | formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }" |
29 | > | 29 | > |
30 | <div *ngIf="formErrors.username" class="form-error"> | 30 | <div *ngIf="formErrors.username" class="form-error"> |
@@ -33,9 +33,9 @@ | |||
33 | </div> | 33 | </div> |
34 | 34 | ||
35 | <div class="form-group"> | 35 | <div class="form-group"> |
36 | <label for="email">Email</label> | 36 | <label for="email" i18n>Email</label> |
37 | <input | 37 | <input |
38 | type="text" id="email" placeholder="Email" | 38 | type="text" id="email" i18n-placeholder placeholder="Email" |
39 | formControlName="email" [ngClass]="{ 'input-error': formErrors['email'] }" | 39 | formControlName="email" [ngClass]="{ 'input-error': formErrors['email'] }" |
40 | > | 40 | > |
41 | <div *ngIf="formErrors.email" class="form-error"> | 41 | <div *ngIf="formErrors.email" class="form-error"> |
@@ -44,9 +44,9 @@ | |||
44 | </div> | 44 | </div> |
45 | 45 | ||
46 | <div class="form-group"> | 46 | <div class="form-group"> |
47 | <label for="password">Password</label> | 47 | <label for="password" i18n>Password</label> |
48 | <input | 48 | <input |
49 | type="password" id="password" placeholder="Password" | 49 | type="password" id="password" i18n-placeholder placeholder="Password" |
50 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | 50 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" |
51 | > | 51 | > |
52 | <div *ngIf="formErrors.password" class="form-error"> | 52 | <div *ngIf="formErrors.password" class="form-error"> |
@@ -54,7 +54,7 @@ | |||
54 | </div> | 54 | </div> |
55 | </div> | 55 | </div> |
56 | 56 | ||
57 | <input type="submit" value="Signup" [disabled]="!form.valid"> | 57 | <input type="submit" i18n-value value="Signup" [disabled]="!form.valid"> |
58 | </form> | 58 | </form> |
59 | 59 | ||
60 | </div> | 60 | </div> |
diff --git a/client/src/app/signup/signup.component.ts b/client/src/app/signup/signup.component.ts index 1f3e2e146..4a49ead50 100644 --- a/client/src/app/signup/signup.component.ts +++ b/client/src/app/signup/signup.component.ts | |||
@@ -6,6 +6,8 @@ import { ServerService } from '@app/core/server' | |||
6 | import { NotificationsService } from 'angular2-notifications' | 6 | import { NotificationsService } from 'angular2-notifications' |
7 | import { UserCreate } from '../../../../shared' | 7 | import { UserCreate } from '../../../../shared' |
8 | import { FormReactive, USER_EMAIL, USER_PASSWORD, USER_USERNAME, UserService } from '../shared' | 8 | import { FormReactive, USER_EMAIL, USER_PASSWORD, USER_USERNAME, UserService } from '../shared' |
9 | import { RedirectService } from '@app/core' | ||
10 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
9 | 11 | ||
10 | @Component({ | 12 | @Component({ |
11 | selector: 'my-signup', | 13 | selector: 'my-signup', |
@@ -45,7 +47,9 @@ export class SignupComponent extends FormReactive implements OnInit { | |||
45 | private router: Router, | 47 | private router: Router, |
46 | private notificationsService: NotificationsService, | 48 | private notificationsService: NotificationsService, |
47 | private userService: UserService, | 49 | private userService: UserService, |
48 | private serverService: ServerService | 50 | private redirectService: RedirectService, |
51 | private serverService: ServerService, | ||
52 | private i18n: I18n | ||
49 | ) { | 53 | ) { |
50 | super() | 54 | super() |
51 | } | 55 | } |
@@ -78,8 +82,11 @@ export class SignupComponent extends FormReactive implements OnInit { | |||
78 | 82 | ||
79 | this.userService.signup(userCreate).subscribe( | 83 | this.userService.signup(userCreate).subscribe( |
80 | () => { | 84 | () => { |
81 | this.notificationsService.success('Success', `Registration for ${userCreate.username} complete.`) | 85 | this.notificationsService.success( |
82 | this.router.navigate([ '/videos/list' ]) | 86 | this.i18n('Success'), |
87 | this.i18n('Registration for {{ username }} complete.', { username: userCreate.username}) | ||
88 | ) | ||
89 | this.redirectService.redirectToHomepage() | ||
83 | }, | 90 | }, |
84 | 91 | ||
85 | err => this.error = err.message | 92 | err => this.error = err.message |
@@ -99,9 +106,9 @@ export class SignupComponent extends FormReactive implements OnInit { | |||
99 | const normalSeconds = initialUserVideoQuotaBit / (1.5 * 1000 * 1000) | 106 | const normalSeconds = initialUserVideoQuotaBit / (1.5 * 1000 * 1000) |
100 | 107 | ||
101 | const lines = [ | 108 | const lines = [ |
102 | SignupComponent.getApproximateTime(fullHdSeconds) + ' of full HD videos', | 109 | this.i18n('{{ seconds }} of full HD videos', { seconds: SignupComponent.getApproximateTime(fullHdSeconds) }), |
103 | SignupComponent.getApproximateTime(hdSeconds) + ' of HD videos', | 110 | this.i18n('{{ seconds }} of HD videos', { seconds: SignupComponent.getApproximateTime(hdSeconds) }), |
104 | SignupComponent.getApproximateTime(normalSeconds) + ' of average quality videos' | 111 | this.i18n('{{ seconds }} of average quality videos', { seconds: SignupComponent.getApproximateTime(normalSeconds) }) |
105 | ] | 112 | ] |
106 | 113 | ||
107 | this.quotaHelpIndication = lines.join('<br />') | 114 | this.quotaHelpIndication = lines.join('<br />') |
diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.html b/client/src/app/videos/+video-edit/shared/video-edit.component.html index 7e1be4467..bd9f69362 100644 --- a/client/src/app/videos/+video-edit/shared/video-edit.component.html +++ b/client/src/app/videos/+video-edit/shared/video-edit.component.html | |||
@@ -4,7 +4,7 @@ | |||
4 | <tab heading="Basic info"> | 4 | <tab heading="Basic info"> |
5 | <div class="col-md-8"> | 5 | <div class="col-md-8"> |
6 | <div class="form-group"> | 6 | <div class="form-group"> |
7 | <label for="name">Title</label> | 7 | <label i18n for="name">Title</label> |
8 | <input type="text" id="name" formControlName="name" /> | 8 | <input type="text" id="name" formControlName="name" /> |
9 | <div *ngIf="formErrors.name" class="form-error"> | 9 | <div *ngIf="formErrors.name" class="form-error"> |
10 | {{ formErrors.name }} | 10 | {{ formErrors.name }} |
@@ -12,7 +12,7 @@ | |||
12 | </div> | 12 | </div> |
13 | 13 | ||
14 | <div class="form-group"> | 14 | <div class="form-group"> |
15 | <label class="label-tags">Tags</label> <span>(press Enter to add)</span> | 15 | <label i18n class="label-tags">Tags</label> <span i18n>(press Enter to add)</span> |
16 | <tag-input | 16 | <tag-input |
17 | [validators]="tagValidators" [errorMessages]="tagValidatorsMessages" | 17 | [validators]="tagValidators" [errorMessages]="tagValidatorsMessages" |
18 | formControlName="tags" maxItems="5" modelAsStrings="true" | 18 | formControlName="tags" maxItems="5" modelAsStrings="true" |
@@ -20,8 +20,8 @@ | |||
20 | </div> | 20 | </div> |
21 | 21 | ||
22 | <div class="form-group"> | 22 | <div class="form-group"> |
23 | <label for="description">Description</label> | 23 | <label i18n for="description">Description</label> |
24 | <my-help helpType="markdownText" preHtml="Video descriptions are truncated by default and require manual action to expand them."></my-help> | 24 | <my-help helpType="markdownText" i18n-preHtml preHtml="Video descriptions are truncated by default and require manual action to expand them."></my-help> |
25 | <my-markdown-textarea truncate="250" formControlName="description"></my-markdown-textarea> | 25 | <my-markdown-textarea truncate="250" formControlName="description"></my-markdown-textarea> |
26 | 26 | ||
27 | <div *ngIf="formErrors.description" class="form-error"> | 27 | <div *ngIf="formErrors.description" class="form-error"> |
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | <div class="col-md-4"> | 33 | <div class="col-md-4"> |
34 | <div class="form-group"> | 34 | <div class="form-group"> |
35 | <label>Channel</label> | 35 | <label i18n>Channel</label> |
36 | <div class="peertube-select-container"> | 36 | <div class="peertube-select-container"> |
37 | <select formControlName="channelId"> | 37 | <select formControlName="channelId"> |
38 | <option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option> | 38 | <option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option> |
@@ -41,7 +41,7 @@ | |||
41 | </div> | 41 | </div> |
42 | 42 | ||
43 | <div class="form-group"> | 43 | <div class="form-group"> |
44 | <label for="category">Category</label> | 44 | <label i18n for="category">Category</label> |
45 | <div class="peertube-select-container"> | 45 | <div class="peertube-select-container"> |
46 | <select id="category" formControlName="category"> | 46 | <select id="category" formControlName="category"> |
47 | <option></option> | 47 | <option></option> |
@@ -55,7 +55,7 @@ | |||
55 | </div> | 55 | </div> |
56 | 56 | ||
57 | <div class="form-group"> | 57 | <div class="form-group"> |
58 | <label for="licence">Licence</label> | 58 | <label i18n for="licence">Licence</label> |
59 | <div class="peertube-select-container"> | 59 | <div class="peertube-select-container"> |
60 | <select id="licence" formControlName="licence"> | 60 | <select id="licence" formControlName="licence"> |
61 | <option></option> | 61 | <option></option> |
@@ -69,7 +69,7 @@ | |||
69 | </div> | 69 | </div> |
70 | 70 | ||
71 | <div class="form-group"> | 71 | <div class="form-group"> |
72 | <label for="language">Language</label> | 72 | <label i18n for="language">Language</label> |
73 | <div class="peertube-select-container"> | 73 | <div class="peertube-select-container"> |
74 | <select id="language" formControlName="language"> | 74 | <select id="language" formControlName="language"> |
75 | <option></option> | 75 | <option></option> |
@@ -83,7 +83,7 @@ | |||
83 | </div> | 83 | </div> |
84 | 84 | ||
85 | <div class="form-group"> | 85 | <div class="form-group"> |
86 | <label for="privacy">Privacy</label> | 86 | <label i18n for="privacy">Privacy</label> |
87 | <div class="peertube-select-container"> | 87 | <div class="peertube-select-container"> |
88 | <select id="privacy" formControlName="privacy"> | 88 | <select id="privacy" formControlName="privacy"> |
89 | <option></option> | 89 | <option></option> |
@@ -99,14 +99,14 @@ | |||
99 | <div class="form-group form-group-checkbox"> | 99 | <div class="form-group form-group-checkbox"> |
100 | <input type="checkbox" id="nsfw" formControlName="nsfw" /> | 100 | <input type="checkbox" id="nsfw" formControlName="nsfw" /> |
101 | <label for="nsfw"></label> | 101 | <label for="nsfw"></label> |
102 | <label for="nsfw">This video contains mature or explicit content</label> | 102 | <label i18n for="nsfw">This video contains mature or explicit content</label> |
103 | <my-help tooltipPlacement="top" helpType="custom" customHtml="Some instances do not list NSFW videos by default."></my-help> | 103 | <my-help tooltipPlacement="top" helpType="custom" i18n-customHtml customHtml="Some instances do not list NSFW videos by default."></my-help> |
104 | </div> | 104 | </div> |
105 | 105 | ||
106 | <div class="form-group form-group-checkbox"> | 106 | <div class="form-group form-group-checkbox"> |
107 | <input type="checkbox" id="commentsEnabled" formControlName="commentsEnabled" /> | 107 | <input type="checkbox" id="commentsEnabled" formControlName="commentsEnabled" /> |
108 | <label for="commentsEnabled"></label> | 108 | <label for="commentsEnabled"></label> |
109 | <label for="commentsEnabled">Enable video comments</label> | 109 | <label i18n for="commentsEnabled">Enable video comments</label> |
110 | </div> | 110 | </div> |
111 | 111 | ||
112 | </div> | 112 | </div> |
@@ -116,24 +116,24 @@ | |||
116 | <div class="col-md-12 advanced-settings"> | 116 | <div class="col-md-12 advanced-settings"> |
117 | <div class="form-group"> | 117 | <div class="form-group"> |
118 | <my-video-image | 118 | <my-video-image |
119 | inputLabel="Upload thumbnail" inputName="thumbnailfile" formControlName="thumbnailfile" | 119 | i18n-inputLabel inputLabel="Upload thumbnail" inputName="thumbnailfile" formControlName="thumbnailfile" |
120 | previewWidth="200px" previewHeight="110px" | 120 | previewWidth="200px" previewHeight="110px" |
121 | ></my-video-image> | 121 | ></my-video-image> |
122 | </div> | 122 | </div> |
123 | 123 | ||
124 | <div class="form-group"> | 124 | <div class="form-group"> |
125 | <my-video-image | 125 | <my-video-image |
126 | inputLabel="Upload preview" inputName="previewfile" formControlName="previewfile" | 126 | i18n-inputLabel inputLabel="Upload preview" inputName="previewfile" formControlName="previewfile" |
127 | previewWidth="360px" previewHeight="200px" | 127 | previewWidth="360px" previewHeight="200px" |
128 | ></my-video-image> | 128 | ></my-video-image> |
129 | </div> | 129 | </div> |
130 | 130 | ||
131 | <div class="form-group"> | 131 | <div class="form-group"> |
132 | <label for="support">Support</label> | 132 | <label i18n for="support">Support</label> |
133 | <my-help helpType="markdownEnhanced" preHtml="Short text to tell people how they can support you (membership platform...)."></my-help> | 133 | <my-help helpType="markdownEnhanced" i18n-preHtml preHtml="Short text to tell people how they can support you (membership platform...)."></my-help> |
134 | <my-markdown-textarea | 134 | <my-markdown-textarea |
135 | id="support" formControlName="support" textareaWidth="500px" [previewColumn]="true" markdownType="enhanced" | 135 | id="support" formControlName="support" textareaWidth="500px" [previewColumn]="true" markdownType="enhanced" |
136 | [classes]="{ 'input-error': formErrors['support'] }" | 136 | [classes]="{ 'input-error': formErrors['support'] }" |
137 | ></my-markdown-textarea> | 137 | ></my-markdown-textarea> |
138 | <div *ngIf="formErrors.support" class="form-error"> | 138 | <div *ngIf="formErrors.support" class="form-error"> |
139 | {{ formErrors.support }} | 139 | {{ formErrors.support }} |
diff --git a/client/src/app/videos/+video-edit/shared/video-image.component.html b/client/src/app/videos/+video-edit/shared/video-image.component.html index 5d0624f8c..e319d7ee7 100644 --- a/client/src/app/videos/+video-edit/shared/video-image.component.html +++ b/client/src/app/videos/+video-edit/shared/video-image.component.html | |||
@@ -8,7 +8,7 @@ | |||
8 | (change)="fileChange($event)" | 8 | (change)="fileChange($event)" |
9 | /> | 9 | /> |
10 | </div> | 10 | </div> |
11 | <div class="image-constraints">(extensions: {{ videoImageExtensions }}, max size: {{ maxVideoImageSize | bytes }})</div> | 11 | <div i18n class="image-constraints">(extensions: {{ videoImageExtensions }}, max size: {{ maxVideoImageSize | bytes }})</div> |
12 | </div> | 12 | </div> |
13 | 13 | ||
14 | <img *ngIf="imageSrc" [ngStyle]="{ width: previewWidth, height: previewHeight }" [src]="imageSrc" class="preview" /> | 14 | <img *ngIf="imageSrc" [ngStyle]="{ width: previewWidth, height: previewHeight }" [src]="imageSrc" class="preview" /> |
diff --git a/client/src/app/videos/+video-edit/video-add.component.html b/client/src/app/videos/+video-edit/video-add.component.html index 440556562..f00cfe016 100644 --- a/client/src/app/videos/+video-edit/video-add.component.html +++ b/client/src/app/videos/+video-edit/video-add.component.html | |||
@@ -1,7 +1,7 @@ | |||
1 | <div class="margin-content"> | 1 | <div class="margin-content"> |
2 | <div class="title-page title-page-single"> | 2 | <div class="title-page title-page-single"> |
3 | <ng-template [ngIf]="!videoFileName">Upload your video</ng-template> | 3 | <ng-container *ngIf="!videoFileName" i18n>Upload your video</ng-container> |
4 | <ng-template [ngIf]="videoFileName">Upload {{ videoFileName }}</ng-template> | 4 | <ng-container *ngIf="videoFileName" i18n>Upload {{ videoFileName }}</ng-container> |
5 | </div> | 5 | </div> |
6 | 6 | ||
7 | <div *ngIf="!isUploadingVideo" class="upload-video-container"> | 7 | <div *ngIf="!isUploadingVideo" class="upload-video-container"> |
@@ -9,12 +9,12 @@ | |||
9 | <div class="icon icon-upload"></div> | 9 | <div class="icon icon-upload"></div> |
10 | 10 | ||
11 | <div class="button-file"> | 11 | <div class="button-file"> |
12 | <span>Select the file to upload</span> | 12 | <span i18n>Select the file to upload</span> |
13 | <input #videofileInput type="file" name="videofile" id="videofile" [accept]="videoExtensions" (change)="fileChange()" /> | 13 | <input #videofileInput type="file" name="videofile" id="videofile" [accept]="videoExtensions" (change)="fileChange()" /> |
14 | </div> | 14 | </div> |
15 | 15 | ||
16 | <div class="form-group form-group-channel"> | 16 | <div class="form-group form-group-channel"> |
17 | <label for="first-step-channel">Channel</label> | 17 | <label i18n for="first-step-channel">Channel</label> |
18 | <div class="peertube-select-container"> | 18 | <div class="peertube-select-container"> |
19 | <select id="first-step-channel" [(ngModel)]="firstStepChannelId"> | 19 | <select id="first-step-channel" [(ngModel)]="firstStepChannelId"> |
20 | <option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option> | 20 | <option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option> |
@@ -23,7 +23,7 @@ | |||
23 | </div> | 23 | </div> |
24 | 24 | ||
25 | <div class="form-group"> | 25 | <div class="form-group"> |
26 | <label for="first-step-privacy">Privacy</label> | 26 | <label i18n for="first-step-privacy">Privacy</label> |
27 | <div class="peertube-select-container"> | 27 | <div class="peertube-select-container"> |
28 | <select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId"> | 28 | <select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId"> |
29 | <option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option> | 29 | <option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option> |
@@ -49,14 +49,14 @@ | |||
49 | ></my-video-edit> | 49 | ></my-video-edit> |
50 | 50 | ||
51 | <div class="submit-container"> | 51 | <div class="submit-container"> |
52 | <div *ngIf="videoUploaded === false" class="message-submit">Publish will be available when upload is finished</div> | 52 | <div i18n *ngIf="videoUploaded === false" class="message-submit">Publish will be available when upload is finished</div> |
53 | 53 | ||
54 | <div class="submit-button" | 54 | <div class="submit-button" |
55 | (click)="updateSecondStep()" | 55 | (click)="updateSecondStep()" |
56 | [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true || videoUploaded !== true }" | 56 | [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true || videoUploaded !== true }" |
57 | > | 57 | > |
58 | <span class="icon icon-validate"></span> | 58 | <span class="icon icon-validate"></span> |
59 | <input type="button" value="Publish" /> | 59 | <input type="button" i18n-value value="Publish" /> |
60 | </div> | 60 | </div> |
61 | </div> | 61 | </div> |
62 | </form> | 62 | </form> |
diff --git a/client/src/app/videos/+video-edit/video-add.component.ts b/client/src/app/videos/+video-edit/video-add.component.ts index 997f033b7..a615fd92c 100644 --- a/client/src/app/videos/+video-edit/video-add.component.ts +++ b/client/src/app/videos/+video-edit/video-add.component.ts | |||
@@ -15,6 +15,7 @@ import { ValidatorMessage } from '../../shared/forms/form-validators/validator-m | |||
15 | import { populateAsyncUserVideoChannels } from '../../shared/misc/utils' | 15 | import { populateAsyncUserVideoChannels } from '../../shared/misc/utils' |
16 | import { VideoEdit } from '../../shared/video/video-edit.model' | 16 | import { VideoEdit } from '../../shared/video/video-edit.model' |
17 | import { VideoService } from '../../shared/video/video.service' | 17 | import { VideoService } from '../../shared/video/video.service' |
18 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
18 | 19 | ||
19 | @Component({ | 20 | @Component({ |
20 | selector: 'my-videos-add', | 21 | selector: 'my-videos-add', |
@@ -56,7 +57,8 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy | |||
56 | private userService: UserService, | 57 | private userService: UserService, |
57 | private serverService: ServerService, | 58 | private serverService: ServerService, |
58 | private videoService: VideoService, | 59 | private videoService: VideoService, |
59 | private loadingBar: LoadingBarService | 60 | private loadingBar: LoadingBarService, |
61 | private i18n: I18n | ||
60 | ) { | 62 | ) { |
61 | super() | 63 | super() |
62 | } | 64 | } |
@@ -99,10 +101,11 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy | |||
99 | let text = '' | 101 | let text = '' |
100 | 102 | ||
101 | if (this.videoUploaded === true) { | 103 | if (this.videoUploaded === true) { |
102 | text = 'Your video was uploaded in your account and is private.' + | 104 | // FIXME: cannot concatenate strings inside i18n service :/ |
103 | ' But associated data (tags, description...) will be lost, are you sure you want to leave this page?' | 105 | text = this.i18n('Your video was uploaded in your account and is private.') + |
106 | this.i18n('But associated data (tags, description...) will be lost, are you sure you want to leave this page?') | ||
104 | } else { | 107 | } else { |
105 | text = 'Your video is not uploaded yet, are you sure you want to leave this page?' | 108 | text = this.i18n('Your video is not uploaded yet, are you sure you want to leave this page?') |
106 | } | 109 | } |
107 | 110 | ||
108 | return { | 111 | return { |
@@ -127,7 +130,7 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy | |||
127 | this.isUploadingVideo = false | 130 | this.isUploadingVideo = false |
128 | this.videoUploadPercents = 0 | 131 | this.videoUploadPercents = 0 |
129 | this.videoUploadObservable = null | 132 | this.videoUploadObservable = null |
130 | this.notificationsService.info('Info', 'Upload cancelled') | 133 | this.notificationsService.info(this.i18n('Info'), this.i18n('Upload cancelled')) |
131 | } | 134 | } |
132 | } | 135 | } |
133 | 136 | ||
@@ -137,7 +140,7 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy | |||
137 | 140 | ||
138 | // Cannot upload videos > 4GB for now | 141 | // Cannot upload videos > 4GB for now |
139 | if (videofile.size > 4 * 1024 * 1024 * 1024) { | 142 | if (videofile.size > 4 * 1024 * 1024 * 1024) { |
140 | this.notificationsService.error('Error', 'We are sorry but PeerTube cannot handle videos > 4GB') | 143 | this.notificationsService.error(this.i18n('Error'), this.i18n('We are sorry but PeerTube cannot handle videos > 4GB')) |
141 | return | 144 | return |
142 | } | 145 | } |
143 | 146 | ||
@@ -145,11 +148,15 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy | |||
145 | if (videoQuota !== -1 && (this.userVideoQuotaUsed + videofile.size) > videoQuota) { | 148 | if (videoQuota !== -1 && (this.userVideoQuotaUsed + videofile.size) > videoQuota) { |
146 | const bytePipes = new BytesPipe() | 149 | const bytePipes = new BytesPipe() |
147 | 150 | ||
148 | const msg = 'Your video quota is exceeded with this video ' + | 151 | const msg = this.i18n( |
149 | `(video size: ${bytePipes.transform(videofile.size, 0)}, ` + | 152 | 'Your video quota is exceeded with this video (video size: {{ videoSize }}, used: {{ videoQuotaUsed }}, quota: {{ videoQuota }})', |
150 | `used: ${bytePipes.transform(this.userVideoQuotaUsed, 0)}, ` + | 153 | { |
151 | `quota: ${bytePipes.transform(videoQuota, 0)})` | 154 | videoSize: bytePipes.transform(videofile.size, 0), |
152 | this.notificationsService.error('Error', msg) | 155 | videoQuotaUsed: bytePipes.transform(this.userVideoQuotaUsed, 0), |
156 | videoQuota: bytePipes.transform(videoQuota, 0) | ||
157 | } | ||
158 | ) | ||
159 | this.notificationsService.error(this.i18n('Error'), msg) | ||
153 | return | 160 | return |
154 | } | 161 | } |
155 | 162 | ||
@@ -192,8 +199,6 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy | |||
192 | if (event.type === HttpEventType.UploadProgress) { | 199 | if (event.type === HttpEventType.UploadProgress) { |
193 | this.videoUploadPercents = Math.round(100 * event.loaded / event.total) | 200 | this.videoUploadPercents = Math.round(100 * event.loaded / event.total) |
194 | } else if (event instanceof HttpResponse) { | 201 | } else if (event instanceof HttpResponse) { |
195 | console.log('Video uploaded.') | ||
196 | |||
197 | this.videoUploaded = true | 202 | this.videoUploaded = true |
198 | 203 | ||
199 | this.videoUploadedIds = event.body.video | 204 | this.videoUploadedIds = event.body.video |
@@ -207,7 +212,7 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy | |||
207 | this.isUploadingVideo = false | 212 | this.isUploadingVideo = false |
208 | this.videoUploadPercents = 0 | 213 | this.videoUploadPercents = 0 |
209 | this.videoUploadObservable = null | 214 | this.videoUploadObservable = null |
210 | this.notificationsService.error('Error', err.message) | 215 | this.notificationsService.error(this.i18n('Error'), err.message) |
211 | } | 216 | } |
212 | ) | 217 | ) |
213 | } | 218 | } |
@@ -231,13 +236,13 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy | |||
231 | this.isUploadingVideo = false | 236 | this.isUploadingVideo = false |
232 | this.loadingBar.complete() | 237 | this.loadingBar.complete() |
233 | 238 | ||
234 | this.notificationsService.success('Success', 'Video published.') | 239 | this.notificationsService.success(this.i18n('Success'), this.i18n('Video published.')) |
235 | this.router.navigate([ '/videos/watch', video.uuid ]) | 240 | this.router.navigate([ '/videos/watch', video.uuid ]) |
236 | }, | 241 | }, |
237 | 242 | ||
238 | err => { | 243 | err => { |
239 | this.isUpdatingVideo = false | 244 | this.isUpdatingVideo = false |
240 | this.notificationsService.error('Error', err.message) | 245 | this.notificationsService.error(this.i18n('Error'), err.message) |
241 | console.error(err) | 246 | console.error(err) |
242 | } | 247 | } |
243 | ) | 248 | ) |
diff --git a/client/src/app/videos/+video-edit/video-update.component.html b/client/src/app/videos/+video-edit/video-update.component.html index a1b4707be..73b2bc08f 100644 --- a/client/src/app/videos/+video-edit/video-update.component.html +++ b/client/src/app/videos/+video-edit/video-update.component.html | |||
@@ -1,5 +1,5 @@ | |||
1 | <div class="margin-content"> | 1 | <div class="margin-content"> |
2 | <div class="title-page title-page-single"> | 2 | <div i18n class="title-page title-page-single"> |
3 | Update {{ video?.name }} | 3 | Update {{ video?.name }} |
4 | </div> | 4 | </div> |
5 | 5 | ||
@@ -13,7 +13,7 @@ | |||
13 | <div class="submit-container"> | 13 | <div class="submit-container"> |
14 | <div class="submit-button" (click)="update()" [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true }"> | 14 | <div class="submit-button" (click)="update()" [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true }"> |
15 | <span class="icon icon-validate"></span> | 15 | <span class="icon icon-validate"></span> |
16 | <input type="button" value="Update" /> | 16 | <input type="button" i18n-value value="Update" /> |
17 | </div> | 17 | </div> |
18 | </div> | 18 | </div> |
19 | </form> | 19 | </form> |
diff --git a/client/src/app/videos/+video-edit/video-update.component.ts b/client/src/app/videos/+video-edit/video-update.component.ts index 310285f92..e37dd526f 100644 --- a/client/src/app/videos/+video-edit/video-update.component.ts +++ b/client/src/app/videos/+video-edit/video-update.component.ts | |||
@@ -12,6 +12,7 @@ import { ValidatorMessage } from '../../shared/forms/form-validators/validator-m | |||
12 | import { VideoEdit } from '../../shared/video/video-edit.model' | 12 | import { VideoEdit } from '../../shared/video/video-edit.model' |
13 | import { VideoService } from '../../shared/video/video.service' | 13 | import { VideoService } from '../../shared/video/video.service' |
14 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | 14 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' |
15 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
15 | 16 | ||
16 | @Component({ | 17 | @Component({ |
17 | selector: 'my-videos-update', | 18 | selector: 'my-videos-update', |
@@ -37,7 +38,8 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { | |||
37 | private videoService: VideoService, | 38 | private videoService: VideoService, |
38 | private authService: AuthService, | 39 | private authService: AuthService, |
39 | private loadingBar: LoadingBarService, | 40 | private loadingBar: LoadingBarService, |
40 | private videoChannelService: VideoChannelService | 41 | private videoChannelService: VideoChannelService, |
42 | private i18n: I18n | ||
41 | ) { | 43 | ) { |
42 | super() | 44 | super() |
43 | } | 45 | } |
@@ -91,7 +93,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { | |||
91 | 93 | ||
92 | err => { | 94 | err => { |
93 | console.error(err) | 95 | console.error(err) |
94 | this.notificationsService.error('Error', err.message) | 96 | this.notificationsService.error(this.i18n('Error'), err.message) |
95 | } | 97 | } |
96 | ) | 98 | ) |
97 | } | 99 | } |
@@ -116,13 +118,13 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { | |||
116 | () => { | 118 | () => { |
117 | this.isUpdatingVideo = false | 119 | this.isUpdatingVideo = false |
118 | this.loadingBar.complete() | 120 | this.loadingBar.complete() |
119 | this.notificationsService.success('Success', 'Video updated.') | 121 | this.notificationsService.success(this.i18n('Success'), this.i18n('Video updated.')) |
120 | this.router.navigate([ '/videos/watch', this.video.uuid ]) | 122 | this.router.navigate([ '/videos/watch', this.video.uuid ]) |
121 | }, | 123 | }, |
122 | 124 | ||
123 | err => { | 125 | err => { |
124 | this.isUpdatingVideo = false | 126 | this.isUpdatingVideo = false |
125 | this.notificationsService.error('Error', err.message) | 127 | this.notificationsService.error(this.i18n('Error'), err.message) |
126 | console.error(err) | 128 | console.error(err) |
127 | } | 129 | } |
128 | ) | 130 | ) |
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.html b/client/src/app/videos/+video-watch/comment/video-comment-add.component.html index 54d7286db..eaf068cfa 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.html +++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.html | |||
@@ -3,7 +3,7 @@ | |||
3 | <img [src]="user.accountAvatarUrl" alt="Avatar" /> | 3 | <img [src]="user.accountAvatarUrl" alt="Avatar" /> |
4 | 4 | ||
5 | <div class="form-group"> | 5 | <div class="form-group"> |
6 | <textarea placeholder="Add comment..." formControlName="text" [ngClass]="{ 'input-error': formErrors['text'] }" | 6 | <textarea i18n-placeholder placeholder="Add comment..." formControlName="text" [ngClass]="{ 'input-error': formErrors['text'] }" |
7 | (keyup.control.enter)="onValidKey()" (keyup.meta.enter)="onValidKey()" #textarea> | 7 | (keyup.control.enter)="onValidKey()" (keyup.meta.enter)="onValidKey()" #textarea> |
8 | 8 | ||
9 | </textarea> | 9 | </textarea> |
@@ -14,7 +14,7 @@ | |||
14 | </div> | 14 | </div> |
15 | 15 | ||
16 | <div class="submit-comment"> | 16 | <div class="submit-comment"> |
17 | <button *ngIf="isAddButtonDisplayed()" [ngClass]="{ disabled: !form.valid }"> | 17 | <button *ngIf="isAddButtonDisplayed()" [ngClass]="{ disabled: !form.valid }" i18n> |
18 | Post comment | 18 | Post comment |
19 | </button> | 19 | </button> |
20 | </div> | 20 | </div> |
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 b1f446475..2ee5f5ef1 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 | |||
@@ -9,6 +9,7 @@ import { User } from '../../../shared/users' | |||
9 | import { Video } from '../../../shared/video/video.model' | 9 | import { Video } from '../../../shared/video/video.model' |
10 | import { VideoComment } from './video-comment.model' | 10 | import { VideoComment } from './video-comment.model' |
11 | import { VideoCommentService } from './video-comment.service' | 11 | import { VideoCommentService } from './video-comment.service' |
12 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
12 | 13 | ||
13 | @Component({ | 14 | @Component({ |
14 | selector: 'my-video-comment-add', | 15 | selector: 'my-video-comment-add', |
@@ -37,7 +38,8 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit { | |||
37 | constructor ( | 38 | constructor ( |
38 | private formBuilder: FormBuilder, | 39 | private formBuilder: FormBuilder, |
39 | private notificationsService: NotificationsService, | 40 | private notificationsService: NotificationsService, |
40 | private videoCommentService: VideoCommentService | 41 | private videoCommentService: VideoCommentService, |
42 | private i18n: I18n | ||
41 | ) { | 43 | ) { |
42 | super() | 44 | super() |
43 | } | 45 | } |
@@ -92,7 +94,7 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit { | |||
92 | this.form.reset() | 94 | this.form.reset() |
93 | }, | 95 | }, |
94 | 96 | ||
95 | err => this.notificationsService.error('Error', err.text) | 97 | err => this.notificationsService.error(this.i18n('Error'), err.text) |
96 | ) | 98 | ) |
97 | } | 99 | } |
98 | 100 | ||
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.component.html b/client/src/app/videos/+video-watch/comment/video-comment.component.html index 06808ef80..60b803206 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment.component.html +++ b/client/src/app/videos/+video-watch/comment/video-comment.component.html | |||
@@ -2,7 +2,7 @@ | |||
2 | <img [src]="comment.accountAvatarUrl" alt="Avatar" /> | 2 | <img [src]="comment.accountAvatarUrl" alt="Avatar" /> |
3 | 3 | ||
4 | <div class="comment"> | 4 | <div class="comment"> |
5 | <div *ngIf="highlightedComment === true" class="highlighted-comment">Highlighted comment</div> | 5 | <div *ngIf="highlightedComment === true" class="highlighted-comment" i18n>Highlighted comment</div> |
6 | 6 | ||
7 | <div class="comment-account-date"> | 7 | <div class="comment-account-date"> |
8 | <a [href]="comment.account.url" target="_blank" rel="noopener noreferrer" class="comment-account">{{ comment.by }}</a> | 8 | <a [href]="comment.account.url" target="_blank" rel="noopener noreferrer" class="comment-account">{{ comment.by }}</a> |
@@ -11,8 +11,8 @@ | |||
11 | <div class="comment-html" [innerHTML]="sanitizedCommentHTML"></div> | 11 | <div class="comment-html" [innerHTML]="sanitizedCommentHTML"></div> |
12 | 12 | ||
13 | <div class="comment-actions"> | 13 | <div class="comment-actions"> |
14 | <div *ngIf="isUserLoggedIn()" (click)="onWantToReply()" class="comment-action-reply">Reply</div> | 14 | <div *ngIf="isUserLoggedIn()" (click)="onWantToReply()" class="comment-action-reply" i18n>Reply</div> |
15 | <div *ngIf="isRemovableByUser()" (click)="onWantToDelete()" class="comment-action-delete">Delete</div> | 15 | <div *ngIf="isRemovableByUser()" (click)="onWantToDelete()" class="comment-action-delete" i18n>Delete</div> |
16 | </div> | 16 | </div> |
17 | 17 | ||
18 | <my-video-comment-add | 18 | <my-video-comment-add |
diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.html b/client/src/app/videos/+video-watch/comment/video-comments.component.html index 114a56dc7..ac7c03648 100644 --- a/client/src/app/videos/+video-watch/comment/video-comments.component.html +++ b/client/src/app/videos/+video-watch/comment/video-comments.component.html | |||
@@ -3,7 +3,10 @@ | |||
3 | <div class="title-page title-page-single"> | 3 | <div class="title-page title-page-single"> |
4 | Comments | 4 | Comments |
5 | </div> | 5 | </div> |
6 | <my-help *ngIf="video.commentsEnabled === true" helpType="custom" customHtml="You can either comment on the page of your instance where this video is federated with your PeerTube account, or via any ActivityPub-capable fediverse instance. For instance with Mastodon or Pleroma you can type in the search box <strong>@{{video.account.displayName}}@{{video.account.host}}</strong> and find back the video. Direct commenting capabilities are being worked on in <a href='https://github.com/Chocobozzz/PeerTube/issues/224'>#224</a>."></my-help> | 6 | <my-help |
7 | *ngIf="video.commentsEnabled === true" helpType="custom" i18n-customHtml | ||
8 | customHtml="You can either comment on the page of your instance where this video is federated with your PeerTube account, or via any ActivityPub-capable fediverse instance. For instance with Mastodon or Pleroma you can type in the search box <strong>@{{video.account.displayName}}@{{video.account.host}}</strong> and find back the video. Direct commenting capabilities are being worked on in <a href='https://github.com/Chocobozzz/PeerTube/issues/224'>#224</a>." | ||
9 | ></my-help> | ||
7 | </div> | 10 | </div> |
8 | 11 | ||
9 | <ng-template [ngIf]="video.commentsEnabled === true"> | 12 | <ng-template [ngIf]="video.commentsEnabled === true"> |
@@ -14,7 +17,7 @@ | |||
14 | (commentCreated)="onCommentThreadCreated($event)" | 17 | (commentCreated)="onCommentThreadCreated($event)" |
15 | ></my-video-comment-add> | 18 | ></my-video-comment-add> |
16 | 19 | ||
17 | <div *ngIf="componentPagination.totalItems === 0 && comments.length === 0">No comments.</div> | 20 | <div *ngIf="componentPagination.totalItems === 0 && comments.length === 0" i18n>No comments.</div> |
18 | 21 | ||
19 | <div | 22 | <div |
20 | class="comment-threads" | 23 | class="comment-threads" |
@@ -24,15 +27,15 @@ | |||
24 | > | 27 | > |
25 | <div *ngIf="highlightedThread" id="highlighted-comment"> | 28 | <div *ngIf="highlightedThread" id="highlighted-comment"> |
26 | <my-video-comment | 29 | <my-video-comment |
27 | [comment]="highlightedThread" | 30 | [comment]="highlightedThread" |
28 | [video]="video" | 31 | [video]="video" |
29 | [inReplyToCommentId]="inReplyToCommentId" | 32 | [inReplyToCommentId]="inReplyToCommentId" |
30 | [commentTree]="threadComments[highlightedThread.id]" | 33 | [commentTree]="threadComments[highlightedThread.id]" |
31 | [highlightedComment]="true" | 34 | [highlightedComment]="true" |
32 | (wantedToReply)="onWantedToReply($event)" | 35 | (wantedToReply)="onWantedToReply($event)" |
33 | (wantedToDelete)="onWantedToDelete($event)" | 36 | (wantedToDelete)="onWantedToDelete($event)" |
34 | (threadCreated)="onThreadCreated($event)" | 37 | (threadCreated)="onThreadCreated($event)" |
35 | (resetReply)="onResetReply()" | 38 | (resetReply)="onResetReply()" |
36 | ></my-video-comment> | 39 | ></my-video-comment> |
37 | </div> | 40 | </div> |
38 | 41 | ||
@@ -50,7 +53,7 @@ | |||
50 | ></my-video-comment> | 53 | ></my-video-comment> |
51 | 54 | ||
52 | <div *ngIf="comment.totalReplies !== 0 && !threadComments[comment.id]" (click)="viewReplies(comment.id)" class="view-replies"> | 55 | <div *ngIf="comment.totalReplies !== 0 && !threadComments[comment.id]" (click)="viewReplies(comment.id)" class="view-replies"> |
53 | View all {{ comment.totalReplies }} replies | 56 | <ng-container i18n>View all {{ comment.totalReplies }} replies</ng-container> |
54 | 57 | ||
55 | <span *ngIf="!threadLoading[comment.id]" class="glyphicon glyphicon-menu-down"></span> | 58 | <span *ngIf="!threadLoading[comment.id]" class="glyphicon glyphicon-menu-down"></span> |
56 | <my-loader class="comment-thread-loading" [loading]="threadLoading[comment.id]"></my-loader> | 59 | <my-loader class="comment-thread-loading" [loading]="threadLoading[comment.id]"></my-loader> |
@@ -59,7 +62,7 @@ | |||
59 | </div> | 62 | </div> |
60 | </ng-template> | 63 | </ng-template> |
61 | 64 | ||
62 | <div *ngIf="video.commentsEnabled === false"> | 65 | <div *ngIf="video.commentsEnabled === false" i18n> |
63 | Comments are disabled. | 66 | Comments are disabled. |
64 | </div> | 67 | </div> |
65 | </div> | 68 | </div> |
diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.ts b/client/src/app/videos/+video-watch/comment/video-comments.component.ts index 34f4a0701..8c6ddb89e 100644 --- a/client/src/app/videos/+video-watch/comment/video-comments.component.ts +++ b/client/src/app/videos/+video-watch/comment/video-comments.component.ts | |||
@@ -11,6 +11,7 @@ import { VideoSortField } from '../../../shared/video/sort-field.type' | |||
11 | import { VideoDetails } from '../../../shared/video/video-details.model' | 11 | import { VideoDetails } from '../../../shared/video/video-details.model' |
12 | import { VideoComment } from './video-comment.model' | 12 | import { VideoComment } from './video-comment.model' |
13 | import { VideoCommentService } from './video-comment.service' | 13 | import { VideoCommentService } from './video-comment.service' |
14 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
14 | 15 | ||
15 | @Component({ | 16 | @Component({ |
16 | selector: 'my-video-comments', | 17 | selector: 'my-video-comments', |
@@ -40,7 +41,8 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy { | |||
40 | private notificationsService: NotificationsService, | 41 | private notificationsService: NotificationsService, |
41 | private confirmService: ConfirmService, | 42 | private confirmService: ConfirmService, |
42 | private videoCommentService: VideoCommentService, | 43 | private videoCommentService: VideoCommentService, |
43 | private activatedRoute: ActivatedRoute | 44 | private activatedRoute: ActivatedRoute, |
45 | private i18n: I18n | ||
44 | ) {} | 46 | ) {} |
45 | 47 | ||
46 | ngOnInit () { | 48 | ngOnInit () { |
@@ -77,7 +79,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy { | |||
77 | if (highlightThread) this.highlightedThread = new VideoComment(res.comment) | 79 | if (highlightThread) this.highlightedThread = new VideoComment(res.comment) |
78 | }, | 80 | }, |
79 | 81 | ||
80 | err => this.notificationsService.error('Error', err.message) | 82 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
81 | ) | 83 | ) |
82 | } | 84 | } |
83 | 85 | ||
@@ -89,7 +91,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy { | |||
89 | this.componentPagination.totalItems = res.totalComments | 91 | this.componentPagination.totalItems = res.totalComments |
90 | }, | 92 | }, |
91 | 93 | ||
92 | err => this.notificationsService.error('Error', err.message) | 94 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
93 | ) | 95 | ) |
94 | } | 96 | } |
95 | 97 | ||
@@ -111,9 +113,11 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy { | |||
111 | 113 | ||
112 | async onWantedToDelete (commentToDelete: VideoComment) { | 114 | async onWantedToDelete (commentToDelete: VideoComment) { |
113 | let message = 'Do you really want to delete this comment?' | 115 | let message = 'Do you really want to delete this comment?' |
114 | if (commentToDelete.totalReplies !== 0) message += `${commentToDelete.totalReplies} would be deleted too.` | 116 | if (commentToDelete.totalReplies !== 0) { |
117 | message += this.i18n(' {{ totalReplies }} replies will be deleted too.', { totalReplies: commentToDelete.totalReplies }) | ||
118 | } | ||
115 | 119 | ||
116 | const res = await this.confirmService.confirm(message, 'Delete') | 120 | const res = await this.confirmService.confirm(message, this.i18n('Delete')) |
117 | if (res === false) return | 121 | if (res === false) return |
118 | 122 | ||
119 | this.videoCommentService.deleteVideoComment(commentToDelete.videoId, commentToDelete.id) | 123 | this.videoCommentService.deleteVideoComment(commentToDelete.videoId, commentToDelete.id) |
@@ -136,7 +140,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy { | |||
136 | this.componentPagination.totalItems-- | 140 | this.componentPagination.totalItems-- |
137 | }, | 141 | }, |
138 | 142 | ||
139 | err => this.notificationsService.error('Error', err.message) | 143 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
140 | ) | 144 | ) |
141 | } | 145 | } |
142 | 146 | ||
diff --git a/client/src/app/videos/+video-watch/modal/video-download.component.html b/client/src/app/videos/+video-watch/modal/video-download.component.html index 617892b11..d30a49345 100644 --- a/client/src/app/videos/+video-watch/modal/video-download.component.html +++ b/client/src/app/videos/+video-watch/modal/video-download.component.html | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | <div class="modal-header"> | 5 | <div class="modal-header"> |
6 | <span class="close" aria-hidden="true" (click)="hide()"></span> | 6 | <span class="close" aria-hidden="true" (click)="hide()"></span> |
7 | <h4 class="modal-title">Download video</h4> | 7 | <h4 i18n class="modal-title">Download video</h4> |
8 | </div> | 8 | </div> |
9 | 9 | ||
10 | <div class="modal-body"> | 10 | <div class="modal-body"> |
@@ -17,22 +17,22 @@ | |||
17 | <div class="download-type"> | 17 | <div class="download-type"> |
18 | <div class="peertube-radio-container"> | 18 | <div class="peertube-radio-container"> |
19 | <input type="radio" name="download" id="download-torrent" [(ngModel)]="downloadType" value="torrent"> | 19 | <input type="radio" name="download" id="download-torrent" [(ngModel)]="downloadType" value="torrent"> |
20 | <label for="download-torrent">Torrent</label> | 20 | <label i18n for="download-torrent">Torrent</label> |
21 | </div> | 21 | </div> |
22 | 22 | ||
23 | <div class="peertube-radio-container"> | 23 | <div class="peertube-radio-container"> |
24 | <input type="radio" name="download" id="download-direct" [(ngModel)]="downloadType" value="direct"> | 24 | <input type="radio" name="download" id="download-direct" [(ngModel)]="downloadType" value="direct"> |
25 | <label for="download-direct">Direct download</label> | 25 | <label i18n for="download-direct">Direct download</label> |
26 | </div> | 26 | </div> |
27 | </div> | 27 | </div> |
28 | 28 | ||
29 | <div class="form-group inputs"> | 29 | <div class="form-group inputs"> |
30 | <span class="action-button action-button-cancel" (click)="hide()"> | 30 | <span i18n class="action-button action-button-cancel" (click)="hide()"> |
31 | Cancel | 31 | Cancel |
32 | </span> | 32 | </span> |
33 | 33 | ||
34 | <input | 34 | <input |
35 | type="submit" value="Download" class="action-button-submit" | 35 | type="submit" i18n-value value="Download" class="action-button-submit" |
36 | (click)="download()" | 36 | (click)="download()" |
37 | > | 37 | > |
38 | </div> | 38 | </div> |
diff --git a/client/src/app/videos/+video-watch/modal/video-report.component.html b/client/src/app/videos/+video-watch/modal/video-report.component.html index a9a7beb48..4ee3721fb 100644 --- a/client/src/app/videos/+video-watch/modal/video-report.component.html +++ b/client/src/app/videos/+video-watch/modal/video-report.component.html | |||
@@ -4,14 +4,14 @@ | |||
4 | 4 | ||
5 | <div class="modal-header"> | 5 | <div class="modal-header"> |
6 | <span class="close" aria-hidden="true" (click)="hide()"></span> | 6 | <span class="close" aria-hidden="true" (click)="hide()"></span> |
7 | <h4 class="modal-title">Report video</h4> | 7 | <h4 i18n class="modal-title">Report video</h4> |
8 | </div> | 8 | </div> |
9 | 9 | ||
10 | <div class="modal-body"> | 10 | <div class="modal-body"> |
11 | 11 | ||
12 | <form novalidate [formGroup]="form" (ngSubmit)="report()"> | 12 | <form novalidate [formGroup]="form" (ngSubmit)="report()"> |
13 | <div class="form-group"> | 13 | <div class="form-group"> |
14 | <textarea placeholder="Reason..." formControlName="reason" [ngClass]="{ 'input-error': formErrors['reason'] }"> | 14 | <textarea i18n-placeholder placeholder="Reason..." formControlName="reason" [ngClass]="{ 'input-error': formErrors['reason'] }"> |
15 | </textarea> | 15 | </textarea> |
16 | <div *ngIf="formErrors.reason" class="form-error"> | 16 | <div *ngIf="formErrors.reason" class="form-error"> |
17 | {{ formErrors.reason }} | 17 | {{ formErrors.reason }} |
@@ -19,12 +19,12 @@ | |||
19 | </div> | 19 | </div> |
20 | 20 | ||
21 | <div class="form-group inputs"> | 21 | <div class="form-group inputs"> |
22 | <span class="action-button action-button-cancel" (click)="hide()"> | 22 | <span i18n class="action-button action-button-cancel" (click)="hide()"> |
23 | Cancel | 23 | Cancel |
24 | </span> | 24 | </span> |
25 | 25 | ||
26 | <input | 26 | <input |
27 | type="submit" value="Submit" class="action-button-submit" | 27 | type="submit" i18n-value value="Submit" class="action-button-submit" |
28 | [disabled]="!form.valid" | 28 | [disabled]="!form.valid" |
29 | > | 29 | > |
30 | </div> | 30 | </div> |
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 050e827e7..1bbd30226 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 | |||
@@ -4,6 +4,7 @@ import { NotificationsService } from 'angular2-notifications' | |||
4 | import { ModalDirective } from 'ngx-bootstrap/modal' | 4 | import { ModalDirective } from 'ngx-bootstrap/modal' |
5 | import { FormReactive, VIDEO_ABUSE_REASON, VideoAbuseService } from '../../../shared/index' | 5 | import { FormReactive, VIDEO_ABUSE_REASON, VideoAbuseService } from '../../../shared/index' |
6 | import { VideoDetails } from '../../../shared/video/video-details.model' | 6 | import { VideoDetails } from '../../../shared/video/video-details.model' |
7 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
7 | 8 | ||
8 | @Component({ | 9 | @Component({ |
9 | selector: 'my-video-report', | 10 | selector: 'my-video-report', |
@@ -27,8 +28,9 @@ export class VideoReportComponent extends FormReactive implements OnInit { | |||
27 | constructor ( | 28 | constructor ( |
28 | private formBuilder: FormBuilder, | 29 | private formBuilder: FormBuilder, |
29 | private videoAbuseService: VideoAbuseService, | 30 | private videoAbuseService: VideoAbuseService, |
30 | private notificationsService: NotificationsService | 31 | private notificationsService: NotificationsService, |
31 | ) { | 32 | private i18n: I18n |
33 | ) { | ||
32 | super() | 34 | super() |
33 | } | 35 | } |
34 | 36 | ||
@@ -58,11 +60,11 @@ export class VideoReportComponent extends FormReactive implements OnInit { | |||
58 | this.videoAbuseService.reportVideo(this.video.id, reason) | 60 | this.videoAbuseService.reportVideo(this.video.id, reason) |
59 | .subscribe( | 61 | .subscribe( |
60 | () => { | 62 | () => { |
61 | this.notificationsService.success('Success', 'Video reported.') | 63 | this.notificationsService.success(this.i18n('Success'), this.i18n('Video reported.')) |
62 | this.hide() | 64 | this.hide() |
63 | }, | 65 | }, |
64 | 66 | ||
65 | err => this.notificationsService.error('Error', err.message) | 67 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
66 | ) | 68 | ) |
67 | } | 69 | } |
68 | } | 70 | } |
diff --git a/client/src/app/videos/+video-watch/modal/video-share.component.html b/client/src/app/videos/+video-watch/modal/video-share.component.html index 85cf10a6c..26ab5144a 100644 --- a/client/src/app/videos/+video-watch/modal/video-share.component.html +++ b/client/src/app/videos/+video-watch/modal/video-share.component.html | |||
@@ -4,12 +4,12 @@ | |||
4 | 4 | ||
5 | <div class="modal-header"> | 5 | <div class="modal-header"> |
6 | <span class="close" aria-hidden="true" (click)="hide()"></span> | 6 | <span class="close" aria-hidden="true" (click)="hide()"></span> |
7 | <h4 class="modal-title">Share</h4> | 7 | <h4 i18n class="modal-title">Share</h4> |
8 | </div> | 8 | </div> |
9 | 9 | ||
10 | <div class="modal-body"> | 10 | <div class="modal-body"> |
11 | <div class="form-group"> | 11 | <div class="form-group"> |
12 | <label>URL</label> | 12 | <label i18n>URL</label> |
13 | <div class="input-group input-group-sm"> | 13 | <div class="input-group input-group-sm"> |
14 | <input #urlInput (click)="urlInput.select()" type="text" class="form-control input-sm readonly" readonly [value]="getVideoUrl()" /> | 14 | <input #urlInput (click)="urlInput.select()" type="text" class="form-control input-sm readonly" readonly [value]="getVideoUrl()" /> |
15 | <div class="input-group-btn" placement="bottom right"> | 15 | <div class="input-group-btn" placement="bottom right"> |
@@ -21,7 +21,7 @@ | |||
21 | </div> | 21 | </div> |
22 | 22 | ||
23 | <div class="form-group"> | 23 | <div class="form-group"> |
24 | <label>Embed</label> | 24 | <label i18n>Embed</label> |
25 | <div class="input-group input-group-sm"> | 25 | <div class="input-group input-group-sm"> |
26 | <input #shareInput (click)="shareInput.select()" type="text" class="form-control input-sm readonly" readonly [value]="getVideoIframeCode()" /> | 26 | <input #shareInput (click)="shareInput.select()" type="text" class="form-control input-sm readonly" readonly [value]="getVideoIframeCode()" /> |
27 | <div class="input-group-btn" placement="bottom right"> | 27 | <div class="input-group-btn" placement="bottom right"> |
@@ -32,12 +32,12 @@ | |||
32 | </div> | 32 | </div> |
33 | </div> | 33 | </div> |
34 | 34 | ||
35 | <div *ngIf="notSecure()" class="alert alert-warning"> | 35 | <div i18n *ngIf="notSecure()" class="alert alert-warning"> |
36 | The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites). | 36 | The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites). |
37 | </div> | 37 | </div> |
38 | 38 | ||
39 | <div class="form-group inputs"> | 39 | <div class="form-group inputs"> |
40 | <span class="action-button action-button-cancel" (click)="hide()"> | 40 | <span i18n class="action-button action-button-cancel" (click)="hide()"> |
41 | Cancel | 41 | Cancel |
42 | </span> | 42 | </span> |
43 | </div> | 43 | </div> |
diff --git a/client/src/app/videos/+video-watch/modal/video-share.component.ts b/client/src/app/videos/+video-watch/modal/video-share.component.ts index 33998c5d8..5c988a43b 100644 --- a/client/src/app/videos/+video-watch/modal/video-share.component.ts +++ b/client/src/app/videos/+video-watch/modal/video-share.component.ts | |||
@@ -5,6 +5,7 @@ import { NotificationsService } from 'angular2-notifications' | |||
5 | import { ModalDirective } from 'ngx-bootstrap/modal' | 5 | import { ModalDirective } from 'ngx-bootstrap/modal' |
6 | import { VideoDetails } from '../../../shared/video/video-details.model' | 6 | import { VideoDetails } from '../../../shared/video/video-details.model' |
7 | import { buildVideoEmbed } from '../../../../assets/player/utils' | 7 | import { buildVideoEmbed } from '../../../../assets/player/utils' |
8 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
8 | 9 | ||
9 | @Component({ | 10 | @Component({ |
10 | selector: 'my-video-share', | 11 | selector: 'my-video-share', |
@@ -16,7 +17,10 @@ export class VideoShareComponent { | |||
16 | 17 | ||
17 | @ViewChild('modal') modal: ModalDirective | 18 | @ViewChild('modal') modal: ModalDirective |
18 | 19 | ||
19 | constructor (private notificationsService: NotificationsService) { | 20 | constructor ( |
21 | private notificationsService: NotificationsService, | ||
22 | private i18n: I18n | ||
23 | ) { | ||
20 | // empty | 24 | // empty |
21 | } | 25 | } |
22 | 26 | ||
@@ -41,6 +45,6 @@ export class VideoShareComponent { | |||
41 | } | 45 | } |
42 | 46 | ||
43 | activateCopiedMessage () { | 47 | activateCopiedMessage () { |
44 | this.notificationsService.success('Success', 'Copied') | 48 | this.notificationsService.success(this.i18n('Success'), this.i18n('Copied')) |
45 | } | 49 | } |
46 | } | 50 | } |
diff --git a/client/src/app/videos/+video-watch/modal/video-support.component.html b/client/src/app/videos/+video-watch/modal/video-support.component.html index 16ad9502a..9bcfcea47 100644 --- a/client/src/app/videos/+video-watch/modal/video-support.component.html +++ b/client/src/app/videos/+video-watch/modal/video-support.component.html | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | <div class="modal-header"> | 5 | <div class="modal-header"> |
6 | <span class="close" aria-hidden="true" (click)="hide()"></span> | 6 | <span class="close" aria-hidden="true" (click)="hide()"></span> |
7 | <h4 class="modal-title">Support</h4> | 7 | <h4 i18n class="modal-title">Support</h4> |
8 | </div> | 8 | </div> |
9 | 9 | ||
10 | <div class="modal-body"> | 10 | <div class="modal-body"> |
@@ -12,7 +12,7 @@ | |||
12 | <div [innerHTML]="videoHTMLSupport"></div> | 12 | <div [innerHTML]="videoHTMLSupport"></div> |
13 | 13 | ||
14 | <div class="form-group inputs"> | 14 | <div class="form-group inputs"> |
15 | <span class="action-button action-button-cancel" (click)="hide()"> | 15 | <span i18n class="action-button action-button-cancel" (click)="hide()"> |
16 | Cancel | 16 | Cancel |
17 | </span> | 17 | </span> |
18 | </div> | 18 | </div> |
diff --git a/client/src/app/videos/video-list/video-local.component.ts b/client/src/app/videos/video-list/video-local.component.ts index 03568b618..2fd82a940 100644 --- a/client/src/app/videos/video-list/video-local.component.ts +++ b/client/src/app/videos/video-list/video-local.component.ts | |||
@@ -27,8 +27,8 @@ export class VideoLocalComponent extends AbstractVideoList implements OnInit, On | |||
27 | protected notificationsService: NotificationsService, | 27 | protected notificationsService: NotificationsService, |
28 | protected authService: AuthService, | 28 | protected authService: AuthService, |
29 | protected location: Location, | 29 | protected location: Location, |
30 | private videoService: VideoService, | 30 | protected i18n: I18n, |
31 | private i18n: I18n | 31 | private videoService: VideoService |
32 | ) { | 32 | ) { |
33 | super() | 33 | super() |
34 | 34 | ||
diff --git a/client/src/app/videos/video-list/video-recently-added.component.ts b/client/src/app/videos/video-list/video-recently-added.component.ts index 5768d9fe0..8183357f8 100644 --- a/client/src/app/videos/video-list/video-recently-added.component.ts +++ b/client/src/app/videos/video-list/video-recently-added.component.ts | |||
@@ -25,8 +25,8 @@ export class VideoRecentlyAddedComponent extends AbstractVideoList implements On | |||
25 | protected location: Location, | 25 | protected location: Location, |
26 | protected notificationsService: NotificationsService, | 26 | protected notificationsService: NotificationsService, |
27 | protected authService: AuthService, | 27 | protected authService: AuthService, |
28 | private videoService: VideoService, | 28 | protected i18n: I18n, |
29 | private i18n: I18n | 29 | private videoService: VideoService |
30 | ) { | 30 | ) { |
31 | super() | 31 | super() |
32 | 32 | ||
diff --git a/client/src/app/videos/video-list/video-search.component.ts b/client/src/app/videos/video-list/video-search.component.ts index 35566a7bd..b6434f347 100644 --- a/client/src/app/videos/video-list/video-search.component.ts +++ b/client/src/app/videos/video-list/video-search.component.ts | |||
@@ -31,9 +31,9 @@ export class VideoSearchComponent extends AbstractVideoList implements OnInit, O | |||
31 | protected notificationsService: NotificationsService, | 31 | protected notificationsService: NotificationsService, |
32 | protected authService: AuthService, | 32 | protected authService: AuthService, |
33 | protected location: Location, | 33 | protected location: Location, |
34 | protected i18n: I18n, | ||
34 | private videoService: VideoService, | 35 | private videoService: VideoService, |
35 | private redirectService: RedirectService, | 36 | private redirectService: RedirectService |
36 | private i18n: I18n | ||
37 | ) { | 37 | ) { |
38 | super() | 38 | super() |
39 | 39 | ||
diff --git a/client/src/app/videos/video-list/video-trending.component.ts b/client/src/app/videos/video-list/video-trending.component.ts index 760470e8c..e56b749d1 100644 --- a/client/src/app/videos/video-list/video-trending.component.ts +++ b/client/src/app/videos/video-list/video-trending.component.ts | |||
@@ -25,8 +25,8 @@ export class VideoTrendingComponent extends AbstractVideoList implements OnInit, | |||
25 | protected notificationsService: NotificationsService, | 25 | protected notificationsService: NotificationsService, |
26 | protected authService: AuthService, | 26 | protected authService: AuthService, |
27 | protected location: Location, | 27 | protected location: Location, |
28 | private videoService: VideoService, | 28 | protected i18n: I18n, |
29 | private i18n: I18n | 29 | private videoService: VideoService |
30 | ) { | 30 | ) { |
31 | super() | 31 | super() |
32 | 32 | ||