diff options
Diffstat (limited to 'client/src/app')
-rw-r--r-- | client/src/app/app.component.ts | 7 | ||||
-rw-r--r-- | client/src/app/app.module.ts | 20 | ||||
-rw-r--r-- | client/src/app/core/routing/redirect.service.ts | 4 | ||||
-rw-r--r-- | client/src/app/shared/misc/utils.ts | 2 | ||||
-rw-r--r-- | client/src/app/shared/shared.module.ts | 4 | ||||
-rw-r--r-- | client/src/app/videos/+video-watch/video-watch.component.html | 66 | ||||
-rw-r--r-- | client/src/app/videos/+video-watch/video-watch.component.ts | 41 | ||||
-rw-r--r-- | client/src/app/videos/video-list/video-local.component.ts | 20 | ||||
-rw-r--r-- | client/src/app/videos/video-list/video-recently-added.component.ts | 20 | ||||
-rw-r--r-- | client/src/app/videos/video-list/video-search.component.ts | 21 | ||||
-rw-r--r-- | client/src/app/videos/video-list/video-trending.component.ts | 20 |
11 files changed, 140 insertions, 85 deletions
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts index 0bd127063..6087dbf80 100644 --- a/client/src/app/app.component.ts +++ b/client/src/app/app.component.ts | |||
@@ -1,8 +1,9 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | 1 | import { Component, OnInit } from '@angular/core' |
2 | import { DomSanitizer, SafeHtml } from '@angular/platform-browser' | 2 | import { DomSanitizer, SafeHtml } from '@angular/platform-browser' |
3 | import { GuardsCheckStart, Router, NavigationEnd } from '@angular/router' | 3 | import { GuardsCheckStart, NavigationEnd, Router } from '@angular/router' |
4 | import { AuthService, RedirectService, ServerService } from '@app/core' | 4 | import { AuthService, RedirectService, ServerService } from '@app/core' |
5 | import { isInSmallView } from '@app/shared/misc/utils' | 5 | import { isInSmallView } from '@app/shared/misc/utils' |
6 | import { is18nPath } from '../../../shared/models/i18n' | ||
6 | 7 | ||
7 | @Component({ | 8 | @Component({ |
8 | selector: 'my-app', | 9 | selector: 'my-app', |
@@ -33,7 +34,7 @@ export class AppComponent implements OnInit { | |||
33 | private serverService: ServerService, | 34 | private serverService: ServerService, |
34 | private domSanitizer: DomSanitizer, | 35 | private domSanitizer: DomSanitizer, |
35 | private redirectService: RedirectService | 36 | private redirectService: RedirectService |
36 | ) {} | 37 | ) { } |
37 | 38 | ||
38 | get serverVersion () { | 39 | get serverVersion () { |
39 | return this.serverService.getConfig().serverVersion | 40 | return this.serverService.getConfig().serverVersion |
@@ -53,7 +54,7 @@ export class AppComponent implements OnInit { | |||
53 | this.router.events.subscribe(e => { | 54 | this.router.events.subscribe(e => { |
54 | if (e instanceof NavigationEnd) { | 55 | if (e instanceof NavigationEnd) { |
55 | const pathname = window.location.pathname | 56 | const pathname = window.location.pathname |
56 | if (!pathname || pathname === '/') { | 57 | if (!pathname || pathname === '/' || is18nPath(pathname)) { |
57 | this.redirectService.redirectToHomepage() | 58 | this.redirectService.redirectToHomepage() |
58 | } | 59 | } |
59 | } | 60 | } |
diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts index cf533629f..44552021f 100644 --- a/client/src/app/app.module.ts +++ b/client/src/app/app.module.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { NgModule } from '@angular/core' | 1 | import { LOCALE_ID, NgModule, TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core' |
2 | import { BrowserModule } from '@angular/platform-browser' | 2 | import { BrowserModule } from '@angular/platform-browser' |
3 | import { AboutModule } from '@app/about' | 3 | import { AboutModule } from '@app/about' |
4 | import { ServerService } from '@app/core' | 4 | import { ServerService } from '@app/core' |
@@ -16,6 +16,7 @@ import { MenuComponent } from './menu' | |||
16 | import { SharedModule } from './shared' | 16 | import { SharedModule } from './shared' |
17 | import { SignupModule } from './signup' | 17 | import { SignupModule } from './signup' |
18 | import { VideosModule } from './videos' | 18 | import { VideosModule } from './videos' |
19 | import { buildFileLocale, getDefaultLocale } from '../../../shared/models/i18n' | ||
19 | 20 | ||
20 | export function metaFactory (serverService: ServerService): MetaLoader { | 21 | export function metaFactory (serverService: ServerService): MetaLoader { |
21 | return new MetaStaticLoader({ | 22 | return new MetaStaticLoader({ |
@@ -61,6 +62,21 @@ export function metaFactory (serverService: ServerService): MetaLoader { | |||
61 | 62 | ||
62 | AppRoutingModule // Put it after all the module because it has the 404 route | 63 | AppRoutingModule // Put it after all the module because it has the 404 route |
63 | ], | 64 | ], |
64 | providers: [ ] | 65 | providers: [ |
66 | { | ||
67 | provide: TRANSLATIONS, | ||
68 | useFactory: (locale) => { | ||
69 | const fileLocale = buildFileLocale(locale) | ||
70 | |||
71 | // Default locale, nothing to translate | ||
72 | const defaultFileLocale = buildFileLocale(getDefaultLocale()) | ||
73 | if (fileLocale === defaultFileLocale) return '' | ||
74 | |||
75 | return require(`raw-loader!../locale/target/messages_${fileLocale}.xml`) | ||
76 | }, | ||
77 | deps: [ LOCALE_ID ] | ||
78 | }, | ||
79 | { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' } | ||
80 | ] | ||
65 | }) | 81 | }) |
66 | export class AppModule {} | 82 | export class AppModule {} |
diff --git a/client/src/app/core/routing/redirect.service.ts b/client/src/app/core/routing/redirect.service.ts index 844f184b4..b7803cce2 100644 --- a/client/src/app/core/routing/redirect.service.ts +++ b/client/src/app/core/routing/redirect.service.ts | |||
@@ -31,7 +31,7 @@ export class RedirectService { | |||
31 | redirectToHomepage () { | 31 | redirectToHomepage () { |
32 | console.log('Redirecting to %s...', RedirectService.DEFAULT_ROUTE) | 32 | console.log('Redirecting to %s...', RedirectService.DEFAULT_ROUTE) |
33 | 33 | ||
34 | this.router.navigate([ RedirectService.DEFAULT_ROUTE ], { replaceUrl: true }) | 34 | this.router.navigate([ RedirectService.DEFAULT_ROUTE ], { skipLocationChange: true }) |
35 | .catch(() => { | 35 | .catch(() => { |
36 | console.error( | 36 | console.error( |
37 | 'Cannot navigate to %s, resetting default route to %s.', | 37 | 'Cannot navigate to %s, resetting default route to %s.', |
@@ -40,7 +40,7 @@ export class RedirectService { | |||
40 | ) | 40 | ) |
41 | 41 | ||
42 | RedirectService.DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE | 42 | RedirectService.DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE |
43 | return this.router.navigate([ RedirectService.DEFAULT_ROUTE ], { replaceUrl: true }) | 43 | return this.router.navigate([ RedirectService.DEFAULT_ROUTE ], { skipLocationChange: true }) |
44 | }) | 44 | }) |
45 | 45 | ||
46 | } | 46 | } |
diff --git a/client/src/app/shared/misc/utils.ts b/client/src/app/shared/misc/utils.ts index 11933e90b..2219ac802 100644 --- a/client/src/app/shared/misc/utils.ts +++ b/client/src/app/shared/misc/utils.ts | |||
@@ -98,7 +98,7 @@ function lineFeedToHtml (obj: object, keyToNormalize: string) { | |||
98 | 98 | ||
99 | // Try to cache a little bit window.innerWidth | 99 | // Try to cache a little bit window.innerWidth |
100 | let windowInnerWidth = window.innerWidth | 100 | let windowInnerWidth = window.innerWidth |
101 | // setInterval(() => windowInnerWidth = window.innerWidth, 500) | 101 | setInterval(() => windowInnerWidth = window.innerWidth, 500) |
102 | 102 | ||
103 | function isInSmallView () { | 103 | function isInSmallView () { |
104 | return windowInnerWidth < 600 | 104 | return windowInnerWidth < 600 |
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index 20019e47a..fba099401 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts | |||
@@ -33,6 +33,7 @@ import { VideoThumbnailComponent } from './video/video-thumbnail.component' | |||
33 | import { VideoService } from './video/video.service' | 33 | import { VideoService } from './video/video.service' |
34 | import { AccountService } from '@app/shared/account/account.service' | 34 | import { AccountService } from '@app/shared/account/account.service' |
35 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | 35 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' |
36 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
36 | 37 | ||
37 | @NgModule({ | 38 | @NgModule({ |
38 | imports: [ | 39 | imports: [ |
@@ -108,7 +109,8 @@ import { VideoChannelService } from '@app/shared/video-channel/video-channel.ser | |||
108 | VideoService, | 109 | VideoService, |
109 | AccountService, | 110 | AccountService, |
110 | MarkdownService, | 111 | MarkdownService, |
111 | VideoChannelService | 112 | VideoChannelService, |
113 | I18n | ||
112 | ] | 114 | ] |
113 | }) | 115 | }) |
114 | export class SharedModule { } | 116 | export class SharedModule { } |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html index 583a97562..202a12fb0 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html | |||
@@ -3,7 +3,7 @@ | |||
3 | <div [hidden]="videoNotFound" id="video-element-wrapper"> | 3 | <div [hidden]="videoNotFound" id="video-element-wrapper"> |
4 | </div> | 4 | </div> |
5 | 5 | ||
6 | <div *ngIf="videoNotFound" id="video-not-found">Video not found :'(</div> | 6 | <div i18n *ngIf="videoNotFound" id="video-not-found">Video not found :'(</div> |
7 | 7 | ||
8 | <!-- Video information --> | 8 | <!-- Video information --> |
9 | <div *ngIf="video" class="margin-content video-bottom"> | 9 | <div *ngIf="video" class="margin-content video-bottom"> |
@@ -12,21 +12,21 @@ | |||
12 | <div> | 12 | <div> |
13 | <div class="video-info-name">{{ video.name }}</div> | 13 | <div class="video-info-name">{{ video.name }}</div> |
14 | 14 | ||
15 | <div class="video-info-date-views"> | 15 | <div i18n class="video-info-date-views"> |
16 | {{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views | 16 | {{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views |
17 | </div> | 17 | </div> |
18 | 18 | ||
19 | <div class="video-info-channel"> | 19 | <div class="video-info-channel"> |
20 | <a [routerLink]="[ '/video-channels', video.channel.id ]" title="Go the channel page"> | 20 | <a [routerLink]="[ '/video-channels', video.channel.id ]" i18n-title title="Go the channel page"> |
21 | {{ video.channel.displayName }} | 21 | {{ video.channel.displayName }} |
22 | </a> | 22 | </a> |
23 | <!-- Here will be the subscribe button --> | 23 | <!-- Here will be the subscribe button --> |
24 | <my-help helpType="custom" customHtml="You can subscribe to this account 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 subscribe there. Subscription as a PeerTube user is being worked on in <a href='https://github.com/Chocobozzz/PeerTube/issues/470'>#470</a>."></my-help> | 24 | <my-help helpType="custom" i18n-customHtml customHtml="You can subscribe to this account 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 subscribe there. Subscription as a PeerTube user is being worked on in <a href='https://github.com/Chocobozzz/PeerTube/issues/470'>#470</a>."></my-help> |
25 | </div> | 25 | </div> |
26 | 26 | ||
27 | <div class="video-info-by"> | 27 | <div class="video-info-by"> |
28 | <a [routerLink]="[ '/accounts', video.by ]" title="Go the account page"> | 28 | <a [routerLink]="[ '/accounts', video.by ]" i18n-title title="Go the account page"> |
29 | <span>By {{ video.by }}</span> | 29 | <span i18n>By {{ video.by }}</span> |
30 | <img [src]="video.accountAvatarUrl" alt="Account avatar" /> | 30 | <img [src]="video.accountAvatarUrl" alt="Account avatar" /> |
31 | </a> | 31 | </a> |
32 | </div> | 32 | </div> |
@@ -38,24 +38,24 @@ | |||
38 | *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'like' }" (click)="setLike()" | 38 | *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'like' }" (click)="setLike()" |
39 | class="action-button action-button-like" | 39 | class="action-button action-button-like" |
40 | > | 40 | > |
41 | <span class="icon icon-like" title="Like this video" ></span> | 41 | <span class="icon icon-like" i18n-title title="Like this video" ></span> |
42 | </div> | 42 | </div> |
43 | 43 | ||
44 | <div | 44 | <div |
45 | *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'dislike' }" (click)="setDislike()" | 45 | *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'dislike' }" (click)="setDislike()" |
46 | class="action-button action-button-dislike" | 46 | class="action-button action-button-dislike" |
47 | > | 47 | > |
48 | <span class="icon icon-dislike" title="Dislike this video"></span> | 48 | <span class="icon icon-dislike" i18n-title title="Dislike this video"></span> |
49 | </div> | 49 | </div> |
50 | 50 | ||
51 | <div *ngIf="video.support" (click)="showSupportModal()" class="action-button action-button-support"> | 51 | <div *ngIf="video.support" (click)="showSupportModal()" class="action-button action-button-support"> |
52 | <span class="icon icon-support"></span> | 52 | <span class="icon icon-support"></span> |
53 | <span class="icon-text">Support</span> | 53 | <span class="icon-text" i18n>Support</span> |
54 | </div> | 54 | </div> |
55 | 55 | ||
56 | <div (click)="showShareModal()" class="action-button action-button-share"> | 56 | <div (click)="showShareModal()" class="action-button action-button-share"> |
57 | <span class="icon icon-share"></span> | 57 | <span class="icon icon-share"></span> |
58 | <span class="icon-text">Share</span> | 58 | <span class="icon-text" i18n>Share</span> |
59 | </div> | 59 | </div> |
60 | 60 | ||
61 | <div class="action-more" dropdown dropup="true" placement="right"> | 61 | <div class="action-more" dropdown dropup="true" placement="right"> |
@@ -65,32 +65,32 @@ | |||
65 | 65 | ||
66 | <ul *dropdownMenu class="dropdown-menu" id="more-menu" role="menu" aria-labelledby="single-button"> | 66 | <ul *dropdownMenu class="dropdown-menu" id="more-menu" role="menu" aria-labelledby="single-button"> |
67 | <li role="menuitem"> | 67 | <li role="menuitem"> |
68 | <a class="dropdown-item" title="Download the video" href="#" (click)="showDownloadModal($event)"> | 68 | <a class="dropdown-item" i18n-title title="Download the video" href="#" (click)="showDownloadModal($event)"> |
69 | <span class="icon icon-download"></span> Download | 69 | <span class="icon icon-download"></span> <ng-container i18n>Download</ng-container> |
70 | </a> | 70 | </a> |
71 | </li> | 71 | </li> |
72 | 72 | ||
73 | <li *ngIf="isUserLoggedIn()" role="menuitem"> | 73 | <li *ngIf="isUserLoggedIn()" role="menuitem"> |
74 | <a class="dropdown-item" title="Report this video" href="#" (click)="showReportModal($event)"> | 74 | <a class="dropdown-item" i18n-title title="Report this video" href="#" (click)="showReportModal($event)"> |
75 | <span class="icon icon-alert"></span> Report | 75 | <span class="icon icon-alert"></span> <ng-container i18n>Report</ng-container> |
76 | </a> | 76 | </a> |
77 | </li> | 77 | </li> |
78 | 78 | ||
79 | <li *ngIf="isVideoBlacklistable()" role="menuitem"> | 79 | <li *ngIf="isVideoBlacklistable()" role="menuitem"> |
80 | <a class="dropdown-item" title="Blacklist this video" href="#" (click)="blacklistVideo($event)"> | 80 | <a class="dropdown-item" i18n-title title="Blacklist this video" href="#" (click)="blacklistVideo($event)"> |
81 | <span class="icon icon-blacklist"></span> Blacklist | 81 | <span class="icon icon-blacklist"></span> <ng-container i18n>Blacklist</ng-container> |
82 | </a> | 82 | </a> |
83 | </li> | 83 | </li> |
84 | 84 | ||
85 | <li *ngIf="isVideoUpdatable()" role="menuitem"> | 85 | <li *ngIf="isVideoUpdatable()" role="menuitem"> |
86 | <a class="dropdown-item" title="Update this video" href="#" [routerLink]="[ '/videos/update', video.uuid ]"> | 86 | <a class="dropdown-item" i18n-title title="Update this video" href="#" [routerLink]="[ '/videos/update', video.uuid ]"> |
87 | <span class="icon icon-edit"></span> Update | 87 | <span class="icon icon-edit"></span> <ng-container i18n>Update</ng-container> |
88 | </a> | 88 | </a> |
89 | </li> | 89 | </li> |
90 | 90 | ||
91 | <li *ngIf="isVideoRemovable()" role="menuitem"> | 91 | <li *ngIf="isVideoRemovable()" role="menuitem"> |
92 | <a class="dropdown-item" title="Delete this video" href="#" (click)="removeVideo($event)"> | 92 | <a class="dropdown-item" i18n-title title="Delete this video" href="#" (click)="removeVideo($event)"> |
93 | <span class="icon icon-blacklist"></span> Delete | 93 | <span class="icon icon-blacklist"></span> <ng-container i18n>Delete</ng-container> |
94 | </a> | 94 | </a> |
95 | </li> | 95 | </li> |
96 | </ul> | 96 | </ul> |
@@ -109,20 +109,20 @@ | |||
109 | <div class="video-info-description-html" [innerHTML]="videoHTMLDescription"></div> | 109 | <div class="video-info-description-html" [innerHTML]="videoHTMLDescription"></div> |
110 | 110 | ||
111 | <div class="video-info-description-more" *ngIf="completeDescriptionShown === false && video.description?.length >= 250" (click)="showMoreDescription()"> | 111 | <div class="video-info-description-more" *ngIf="completeDescriptionShown === false && video.description?.length >= 250" (click)="showMoreDescription()"> |
112 | Show more | 112 | <ng-container i18n>Show more</ng-container> |
113 | <span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-down"></span> | 113 | <span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-down"></span> |
114 | <my-loader class="description-loading" [loading]="descriptionLoading"></my-loader> | 114 | <my-loader class="description-loading" [loading]="descriptionLoading"></my-loader> |
115 | </div> | 115 | </div> |
116 | 116 | ||
117 | <div *ngIf="completeDescriptionShown === true" (click)="showLessDescription()" class="video-info-description-more"> | 117 | <div *ngIf="completeDescriptionShown === true" (click)="showLessDescription()" class="video-info-description-more"> |
118 | Show less | 118 | <ng-container i18n>Show less</ng-container> |
119 | <span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-up"></span> | 119 | <span *ngIf="descriptionLoading === false" class="glyphicon glyphicon-menu-up"></span> |
120 | </div> | 120 | </div> |
121 | </div> | 121 | </div> |
122 | 122 | ||
123 | <div class="video-attributes"> | 123 | <div class="video-attributes"> |
124 | <div class="video-attribute"> | 124 | <div class="video-attribute"> |
125 | <span class="video-attribute-label"> | 125 | <span i18n class="video-attribute-label"> |
126 | Privacy | 126 | Privacy |
127 | </span> | 127 | </span> |
128 | <span class="video-attribute-value"> | 128 | <span class="video-attribute-value"> |
@@ -131,7 +131,7 @@ | |||
131 | </div> | 131 | </div> |
132 | 132 | ||
133 | <div class="video-attribute"> | 133 | <div class="video-attribute"> |
134 | <span class="video-attribute-label"> | 134 | <span i18n class="video-attribute-label"> |
135 | Category | 135 | Category |
136 | </span> | 136 | </span> |
137 | <span class="video-attribute-value"> | 137 | <span class="video-attribute-value"> |
@@ -140,7 +140,7 @@ | |||
140 | </div> | 140 | </div> |
141 | 141 | ||
142 | <div class="video-attribute"> | 142 | <div class="video-attribute"> |
143 | <span class="video-attribute-label"> | 143 | <span i18n class="video-attribute-label"> |
144 | Licence | 144 | Licence |
145 | </span> | 145 | </span> |
146 | <span class="video-attribute-value"> | 146 | <span class="video-attribute-value"> |
@@ -149,7 +149,7 @@ | |||
149 | </div> | 149 | </div> |
150 | 150 | ||
151 | <div class="video-attribute"> | 151 | <div class="video-attribute"> |
152 | <span class="video-attribute-label"> | 152 | <span i18n class="video-attribute-label"> |
153 | Language | 153 | Language |
154 | </span> | 154 | </span> |
155 | <span class="video-attribute-value"> | 155 | <span class="video-attribute-value"> |
@@ -158,7 +158,7 @@ | |||
158 | </div> | 158 | </div> |
159 | 159 | ||
160 | <div class="video-attribute"> | 160 | <div class="video-attribute"> |
161 | <span class="video-attribute-label"> | 161 | <span i18n class="video-attribute-label"> |
162 | Tags | 162 | Tags |
163 | </span> | 163 | </span> |
164 | 164 | ||
@@ -172,7 +172,7 @@ | |||
172 | </div> | 172 | </div> |
173 | 173 | ||
174 | <div class="other-videos"> | 174 | <div class="other-videos"> |
175 | <div class="title-page title-page-single"> | 175 | <div i18n class="title-page title-page-single"> |
176 | Other videos | 176 | Other videos |
177 | </div> | 177 | </div> |
178 | 178 | ||
@@ -184,13 +184,15 @@ | |||
184 | 184 | ||
185 | 185 | ||
186 | <div class="privacy-concerns" *ngIf="hasAlreadyAcceptedPrivacyConcern === false"> | 186 | <div class="privacy-concerns" *ngIf="hasAlreadyAcceptedPrivacyConcern === false"> |
187 | <strong>Friendly Reminder:</strong> | 187 | <strong i18n>Friendly Reminder:</strong> |
188 | <div class="privacy-concerns-text"> | 188 | <div class="privacy-concerns-text"> |
189 | The sharing system used by this video implies that some technical information about your system (such as a public IP address) can be accessed publicly. | 189 | <ng-container i18n> |
190 | <a title="Get more information" target="_blank" rel="noopener noreferrer" href="/about#p2p-privacy">More information</a> | 190 | The sharing system used by this video implies that some technical information about your system (such as a public IP address) can be accessed publicly. |
191 | </ng-container> | ||
192 | <a i18n i18n-title title="Get more information" target="_blank" rel="noopener noreferrer" href="/about#p2p-privacy">More information</a> | ||
191 | </div> | 193 | </div> |
192 | 194 | ||
193 | <div class="privacy-concerns-okay" (click)="acceptedPrivacyConcern()"> | 195 | <div i18n class="privacy-concerns-okay" (click)="acceptedPrivacyConcern()"> |
194 | OK | 196 | OK |
195 | </div> | 197 | </div> |
196 | </div> | 198 | </div> |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts index ad572ef58..f3b4f7a2b 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts | |||
@@ -23,6 +23,7 @@ import { VideoReportComponent } from './modal/video-report.component' | |||
23 | import { VideoShareComponent } from './modal/video-share.component' | 23 | import { VideoShareComponent } from './modal/video-share.component' |
24 | import { getVideojsOptions } from '../../../assets/player/peertube-player' | 24 | import { getVideojsOptions } from '../../../assets/player/peertube-player' |
25 | import { ServerService } from '@app/core' | 25 | import { ServerService } from '@app/core' |
26 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
26 | 27 | ||
27 | @Component({ | 28 | @Component({ |
28 | selector: 'my-video-watch', | 29 | selector: 'my-video-watch', |
@@ -70,7 +71,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
70 | private notificationsService: NotificationsService, | 71 | private notificationsService: NotificationsService, |
71 | private markdownService: MarkdownService, | 72 | private markdownService: MarkdownService, |
72 | private zone: NgZone, | 73 | private zone: NgZone, |
73 | private redirectService: RedirectService | 74 | private redirectService: RedirectService, |
75 | private i18n: I18n | ||
74 | ) {} | 76 | ) {} |
75 | 77 | ||
76 | get user () { | 78 | get user () { |
@@ -153,17 +155,20 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
153 | async blacklistVideo (event: Event) { | 155 | async blacklistVideo (event: Event) { |
154 | event.preventDefault() | 156 | event.preventDefault() |
155 | 157 | ||
156 | const res = await this.confirmService.confirm('Do you really want to blacklist this video?', 'Blacklist') | 158 | const res = await this.confirmService.confirm(this.i18n('Do you really want to blacklist this video?'), this.i18n('Blacklist')) |
157 | if (res === false) return | 159 | if (res === false) return |
158 | 160 | ||
159 | this.videoBlacklistService.blacklistVideo(this.video.id) | 161 | this.videoBlacklistService.blacklistVideo(this.video.id) |
160 | .subscribe( | 162 | .subscribe( |
161 | status => { | 163 | status => { |
162 | this.notificationsService.success('Success', `Video ${this.video.name} had been blacklisted.`) | 164 | this.notificationsService.success( |
165 | this.i18n('Success'), | ||
166 | this.i18n('Video {{ videoName }} had been blacklisted.', { videoName: this.video.name }) | ||
167 | ) | ||
163 | this.redirectService.redirectToHomepage() | 168 | this.redirectService.redirectToHomepage() |
164 | }, | 169 | }, |
165 | 170 | ||
166 | error => this.notificationsService.error('Error', error.message) | 171 | error => this.notificationsService.error(this.i18n('Error'), error.message) |
167 | ) | 172 | ) |
168 | } | 173 | } |
169 | 174 | ||
@@ -198,7 +203,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
198 | 203 | ||
199 | error => { | 204 | error => { |
200 | this.descriptionLoading = false | 205 | this.descriptionLoading = false |
201 | this.notificationsService.error('Error', error.message) | 206 | this.notificationsService.error(this.i18n('Error'), error.message) |
202 | } | 207 | } |
203 | ) | 208 | ) |
204 | } | 209 | } |
@@ -252,19 +257,22 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
252 | async removeVideo (event: Event) { | 257 | async removeVideo (event: Event) { |
253 | event.preventDefault() | 258 | event.preventDefault() |
254 | 259 | ||
255 | const res = await this.confirmService.confirm('Do you really want to delete this video?', 'Delete') | 260 | const res = await this.confirmService.confirm(this.i18n('Do you really want to delete this video?'), this.i18n('Delete')) |
256 | if (res === false) return | 261 | if (res === false) return |
257 | 262 | ||
258 | this.videoService.removeVideo(this.video.id) | 263 | this.videoService.removeVideo(this.video.id) |
259 | .subscribe( | 264 | .subscribe( |
260 | status => { | 265 | status => { |
261 | this.notificationsService.success('Success', `Video ${this.video.name} deleted.`) | 266 | this.notificationsService.success( |
267 | this.i18n('Success'), | ||
268 | this.i18n('Video {{ videoName }} deleted.', { videoName: this.video.name }) | ||
269 | ) | ||
262 | 270 | ||
263 | // Go back to the video-list. | 271 | // Go back to the video-list. |
264 | this.redirectService.redirectToHomepage() | 272 | this.redirectService.redirectToHomepage() |
265 | }, | 273 | }, |
266 | 274 | ||
267 | error => this.notificationsService.error('Error', error.message) | 275 | error => this.notificationsService.error(this.i18n('Error'), error.message) |
268 | ) | 276 | ) |
269 | } | 277 | } |
270 | 278 | ||
@@ -288,7 +296,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
288 | } | 296 | } |
289 | 297 | ||
290 | private setVideoLikesBarTooltipText () { | 298 | private setVideoLikesBarTooltipText () { |
291 | this.likesBarTooltipText = `${this.video.likes} likes / ${this.video.dislikes} dislikes` | 299 | this.likesBarTooltipText = this.i18n( |
300 | '{{ likesNumber }} likes / {{ dislikesNumber }} dislikes', | ||
301 | { likesNumber: this.video.likes, dislikes: this.video.dislikes } | ||
302 | ) | ||
292 | } | 303 | } |
293 | 304 | ||
294 | private handleError (err: any) { | 305 | private handleError (err: any) { |
@@ -298,12 +309,12 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
298 | let message = '' | 309 | let message = '' |
299 | 310 | ||
300 | if (errorMessage.indexOf('http error') !== -1) { | 311 | if (errorMessage.indexOf('http error') !== -1) { |
301 | message = 'Cannot fetch video from server, maybe down.' | 312 | message = this.i18n('Cannot fetch video from server, maybe down.') |
302 | } else { | 313 | } else { |
303 | message = errorMessage | 314 | message = errorMessage |
304 | } | 315 | } |
305 | 316 | ||
306 | this.notificationsService.error('Error', message) | 317 | this.notificationsService.error(this.i18n('Error'), message) |
307 | } | 318 | } |
308 | 319 | ||
309 | private checkUserRating () { | 320 | private checkUserRating () { |
@@ -318,7 +329,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
318 | } | 329 | } |
319 | }, | 330 | }, |
320 | 331 | ||
321 | err => this.notificationsService.error('Error', err.message) | 332 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
322 | ) | 333 | ) |
323 | } | 334 | } |
324 | 335 | ||
@@ -333,8 +344,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
333 | 344 | ||
334 | if (this.video.isVideoNSFWForUser(this.user, this.serverService.getConfig())) { | 345 | if (this.video.isVideoNSFWForUser(this.user, this.serverService.getConfig())) { |
335 | const res = await this.confirmService.confirm( | 346 | const res = await this.confirmService.confirm( |
336 | 'This video contains mature or explicit content. Are you sure you want to watch it?', | 347 | this.i18n('This video contains mature or explicit content. Are you sure you want to watch it?'), |
337 | 'Mature or explicit content' | 348 | this.i18n('Mature or explicit content') |
338 | ) | 349 | ) |
339 | if (res === false) return this.redirectService.redirectToHomepage() | 350 | if (res === false) return this.redirectService.redirectToHomepage() |
340 | } | 351 | } |
@@ -399,7 +410,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
399 | this.updateVideoRating(this.userRating, nextRating) | 410 | this.updateVideoRating(this.userRating, nextRating) |
400 | this.userRating = nextRating | 411 | this.userRating = nextRating |
401 | }, | 412 | }, |
402 | err => this.notificationsService.error('Error', err.message) | 413 | err => this.notificationsService.error(this.i18n('Error'), err.message) |
403 | ) | 414 | ) |
404 | } | 415 | } |
405 | 416 | ||
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 abab7504f..03568b618 100644 --- a/client/src/app/videos/video-list/video-local.component.ts +++ b/client/src/app/videos/video-list/video-local.component.ts | |||
@@ -8,6 +8,7 @@ import { AbstractVideoList } from '../../shared/video/abstract-video-list' | |||
8 | import { VideoSortField } from '../../shared/video/sort-field.type' | 8 | import { VideoSortField } from '../../shared/video/sort-field.type' |
9 | import { VideoService } from '../../shared/video/video.service' | 9 | import { VideoService } from '../../shared/video/video.service' |
10 | import { VideoFilter } from '../../../../../shared/models/videos/video-query.type' | 10 | import { VideoFilter } from '../../../../../shared/models/videos/video-query.type' |
11 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
11 | 12 | ||
12 | @Component({ | 13 | @Component({ |
13 | selector: 'my-videos-local', | 14 | selector: 'my-videos-local', |
@@ -15,18 +16,23 @@ import { VideoFilter } from '../../../../../shared/models/videos/video-query.typ | |||
15 | templateUrl: '../../shared/video/abstract-video-list.html' | 16 | templateUrl: '../../shared/video/abstract-video-list.html' |
16 | }) | 17 | }) |
17 | export class VideoLocalComponent extends AbstractVideoList implements OnInit, OnDestroy { | 18 | export class VideoLocalComponent extends AbstractVideoList implements OnInit, OnDestroy { |
18 | titlePage = 'Local videos' | 19 | titlePage: string |
19 | currentRoute = '/videos/local' | 20 | currentRoute = '/videos/local' |
20 | sort = '-publishedAt' as VideoSortField | 21 | sort = '-publishedAt' as VideoSortField |
21 | filter: VideoFilter = 'local' | 22 | filter: VideoFilter = 'local' |
22 | 23 | ||
23 | constructor (protected router: Router, | 24 | constructor ( |
24 | protected route: ActivatedRoute, | 25 | protected router: Router, |
25 | protected notificationsService: NotificationsService, | 26 | protected route: ActivatedRoute, |
26 | protected authService: AuthService, | 27 | protected notificationsService: NotificationsService, |
27 | protected location: Location, | 28 | protected authService: AuthService, |
28 | private videoService: VideoService) { | 29 | protected location: Location, |
30 | private videoService: VideoService, | ||
31 | private i18n: I18n | ||
32 | ) { | ||
29 | super() | 33 | super() |
34 | |||
35 | this.titlePage = i18n('Local videos') | ||
30 | } | 36 | } |
31 | 37 | ||
32 | ngOnInit () { | 38 | ngOnInit () { |
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 d064d9628..5768d9fe0 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 | |||
@@ -7,6 +7,7 @@ import { AuthService } from '../../core/auth' | |||
7 | import { AbstractVideoList } from '../../shared/video/abstract-video-list' | 7 | import { AbstractVideoList } from '../../shared/video/abstract-video-list' |
8 | import { VideoSortField } from '../../shared/video/sort-field.type' | 8 | import { VideoSortField } from '../../shared/video/sort-field.type' |
9 | import { VideoService } from '../../shared/video/video.service' | 9 | import { VideoService } from '../../shared/video/video.service' |
10 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
10 | 11 | ||
11 | @Component({ | 12 | @Component({ |
12 | selector: 'my-videos-recently-added', | 13 | selector: 'my-videos-recently-added', |
@@ -14,17 +15,22 @@ import { VideoService } from '../../shared/video/video.service' | |||
14 | templateUrl: '../../shared/video/abstract-video-list.html' | 15 | templateUrl: '../../shared/video/abstract-video-list.html' |
15 | }) | 16 | }) |
16 | export class VideoRecentlyAddedComponent extends AbstractVideoList implements OnInit, OnDestroy { | 17 | export class VideoRecentlyAddedComponent extends AbstractVideoList implements OnInit, OnDestroy { |
17 | titlePage = 'Recently added' | 18 | titlePage: string |
18 | currentRoute = '/videos/recently-added' | 19 | currentRoute = '/videos/recently-added' |
19 | sort: VideoSortField = '-publishedAt' | 20 | sort: VideoSortField = '-publishedAt' |
20 | 21 | ||
21 | constructor (protected router: Router, | 22 | constructor ( |
22 | protected route: ActivatedRoute, | 23 | protected router: Router, |
23 | protected location: Location, | 24 | protected route: ActivatedRoute, |
24 | protected notificationsService: NotificationsService, | 25 | protected location: Location, |
25 | protected authService: AuthService, | 26 | protected notificationsService: NotificationsService, |
26 | private videoService: VideoService) { | 27 | protected authService: AuthService, |
28 | private videoService: VideoService, | ||
29 | private i18n: I18n | ||
30 | ) { | ||
27 | super() | 31 | super() |
32 | |||
33 | this.titlePage = i18n('Recently added') | ||
28 | } | 34 | } |
29 | 35 | ||
30 | ngOnInit () { | 36 | ngOnInit () { |
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 aab896d84..35566a7bd 100644 --- a/client/src/app/videos/video-list/video-search.component.ts +++ b/client/src/app/videos/video-list/video-search.component.ts | |||
@@ -8,6 +8,7 @@ import { Subscription } from 'rxjs' | |||
8 | import { AuthService } from '../../core/auth' | 8 | import { AuthService } from '../../core/auth' |
9 | import { AbstractVideoList } from '../../shared/video/abstract-video-list' | 9 | import { AbstractVideoList } from '../../shared/video/abstract-video-list' |
10 | import { VideoService } from '../../shared/video/video.service' | 10 | import { VideoService } from '../../shared/video/video.service' |
11 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
11 | 12 | ||
12 | @Component({ | 13 | @Component({ |
13 | selector: 'my-videos-search', | 14 | selector: 'my-videos-search', |
@@ -15,7 +16,7 @@ import { VideoService } from '../../shared/video/video.service' | |||
15 | templateUrl: '../../shared/video/abstract-video-list.html' | 16 | templateUrl: '../../shared/video/abstract-video-list.html' |
16 | }) | 17 | }) |
17 | export class VideoSearchComponent extends AbstractVideoList implements OnInit, OnDestroy { | 18 | export class VideoSearchComponent extends AbstractVideoList implements OnInit, OnDestroy { |
18 | titlePage = 'Search' | 19 | titlePage: string |
19 | currentRoute = '/videos/search' | 20 | currentRoute = '/videos/search' |
20 | loadOnInit = false | 21 | loadOnInit = false |
21 | 22 | ||
@@ -24,15 +25,19 @@ export class VideoSearchComponent extends AbstractVideoList implements OnInit, O | |||
24 | } | 25 | } |
25 | private subActivatedRoute: Subscription | 26 | private subActivatedRoute: Subscription |
26 | 27 | ||
27 | constructor (protected router: Router, | 28 | constructor ( |
28 | protected route: ActivatedRoute, | 29 | protected router: Router, |
29 | protected notificationsService: NotificationsService, | 30 | protected route: ActivatedRoute, |
30 | protected authService: AuthService, | 31 | protected notificationsService: NotificationsService, |
31 | protected location: Location, | 32 | protected authService: AuthService, |
32 | private videoService: VideoService, | 33 | protected location: Location, |
33 | private redirectService: RedirectService | 34 | private videoService: VideoService, |
35 | private redirectService: RedirectService, | ||
36 | private i18n: I18n | ||
34 | ) { | 37 | ) { |
35 | super() | 38 | super() |
39 | |||
40 | this.titlePage = i18n('Search') | ||
36 | } | 41 | } |
37 | 42 | ||
38 | ngOnInit () { | 43 | ngOnInit () { |
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 ea65070f9..760470e8c 100644 --- a/client/src/app/videos/video-list/video-trending.component.ts +++ b/client/src/app/videos/video-list/video-trending.component.ts | |||
@@ -7,6 +7,7 @@ import { AuthService } from '../../core/auth' | |||
7 | import { AbstractVideoList } from '../../shared/video/abstract-video-list' | 7 | import { AbstractVideoList } from '../../shared/video/abstract-video-list' |
8 | import { VideoSortField } from '../../shared/video/sort-field.type' | 8 | import { VideoSortField } from '../../shared/video/sort-field.type' |
9 | import { VideoService } from '../../shared/video/video.service' | 9 | import { VideoService } from '../../shared/video/video.service' |
10 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
10 | 11 | ||
11 | @Component({ | 12 | @Component({ |
12 | selector: 'my-videos-trending', | 13 | selector: 'my-videos-trending', |
@@ -14,17 +15,22 @@ import { VideoService } from '../../shared/video/video.service' | |||
14 | templateUrl: '../../shared/video/abstract-video-list.html' | 15 | templateUrl: '../../shared/video/abstract-video-list.html' |
15 | }) | 16 | }) |
16 | export class VideoTrendingComponent extends AbstractVideoList implements OnInit, OnDestroy { | 17 | export class VideoTrendingComponent extends AbstractVideoList implements OnInit, OnDestroy { |
17 | titlePage = 'Trending' | 18 | titlePage: string |
18 | currentRoute = '/videos/trending' | 19 | currentRoute = '/videos/trending' |
19 | defaultSort: VideoSortField = '-views' | 20 | defaultSort: VideoSortField = '-views' |
20 | 21 | ||
21 | constructor (protected router: Router, | 22 | constructor ( |
22 | protected route: ActivatedRoute, | 23 | protected router: Router, |
23 | protected notificationsService: NotificationsService, | 24 | protected route: ActivatedRoute, |
24 | protected authService: AuthService, | 25 | protected notificationsService: NotificationsService, |
25 | protected location: Location, | 26 | protected authService: AuthService, |
26 | private videoService: VideoService) { | 27 | protected location: Location, |
28 | private videoService: VideoService, | ||
29 | private i18n: I18n | ||
30 | ) { | ||
27 | super() | 31 | super() |
32 | |||
33 | this.titlePage = i18n('Trending') | ||
28 | } | 34 | } |
29 | 35 | ||
30 | ngOnInit () { | 36 | ngOnInit () { |