Add i18n attributes
This commit is contained in:
parent
989e526abf
commit
b1d40cff89
|
@ -1,12 +1,12 @@
|
|||
<div *ngIf="account" class="row">
|
||||
<div class="block col-md-6 col-sm-12">
|
||||
<div class="small-title">Description</div>
|
||||
<div i18n class="small-title">Description</div>
|
||||
<div class="content">{{ getAccountDescription() }}</div>
|
||||
</div>
|
||||
|
||||
<div class="block col-md-6 col-sm-12">
|
||||
<div class="small-title">Stats</div>
|
||||
<div i18n class="small-title">Stats</div>
|
||||
|
||||
<div class="content">Joined {{ account.createdAt | date }}</div>
|
||||
<div i18n class="content">Joined {{ account.createdAt | date }}</div>
|
||||
</div>
|
||||
</div>
|
|
@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'
|
|||
import { ActivatedRoute } from '@angular/router'
|
||||
import { Account } from '@app/shared/account/account.model'
|
||||
import { AccountService } from '@app/shared/account/account.service'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-account-about',
|
||||
|
@ -12,7 +13,8 @@ export class AccountAboutComponent implements OnInit {
|
|||
account: Account
|
||||
|
||||
constructor (
|
||||
protected route: ActivatedRoute,
|
||||
private route: ActivatedRoute,
|
||||
private i18n: I18n,
|
||||
private accountService: AccountService
|
||||
) { }
|
||||
|
||||
|
@ -25,6 +27,6 @@ export class AccountAboutComponent implements OnInit {
|
|||
getAccountDescription () {
|
||||
if (this.account.description) return this.account.description
|
||||
|
||||
return 'No description'
|
||||
return this.i18n('No description')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<div *ngIf="account" class="row">
|
||||
<a
|
||||
*ngFor="let videoChannel of videoChannels" [routerLink]="[ '/video-channels', videoChannel.uuid ]"
|
||||
class="video-channel" title="See this video channel"
|
||||
class="video-channel" i18n-title title="See this video channel"
|
||||
>
|
||||
<img [src]="videoChannel.avatarUrl" alt="Avatar" />
|
||||
|
||||
<div class="video-channel-display-name">{{ videoChannel.displayName }}</div>
|
||||
<div class="video-channel-followers">{{ videoChannel.followersCount }} subscribers</div>
|
||||
<div i18n class="video-channel-followers">{{ videoChannel.followersCount }} subscribers</div>
|
||||
</a>
|
||||
</div>
|
|
@ -10,6 +10,7 @@ import { VideoService } from '../../shared/video/video.service'
|
|||
import { Account } from '@app/shared/account/account.model'
|
||||
import { AccountService } from '@app/shared/account/account.service'
|
||||
import { tap } from 'rxjs/operators'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-account-videos',
|
||||
|
@ -20,7 +21,7 @@ import { tap } from 'rxjs/operators'
|
|||
]
|
||||
})
|
||||
export class AccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy {
|
||||
titlePage = 'Published videos'
|
||||
titlePage: string
|
||||
marginContent = false // Disable margin
|
||||
currentRoute = '/account/videos'
|
||||
loadOnInit = false
|
||||
|
@ -34,10 +35,13 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit,
|
|||
protected notificationsService: NotificationsService,
|
||||
protected confirmService: ConfirmService,
|
||||
protected location: Location,
|
||||
protected i18n: I18n,
|
||||
private accountService: AccountService,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
super()
|
||||
|
||||
this.titlePage = this.i18n('Published videos')
|
||||
}
|
||||
|
||||
ngOnInit () {
|
||||
|
@ -63,7 +67,11 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit,
|
|||
|
||||
return this.videoService
|
||||
.getAccountVideos(this.account, newPagination, this.sort)
|
||||
.pipe(tap(({ totalVideos }) => this.titlePage = `Published ${totalVideos} videos`))
|
||||
.pipe(
|
||||
tap(({ totalVideos }) => {
|
||||
this.titlePage = this.i18n('Published {{ totalVideos }} videos', { totalVideos })
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
generateSyndicationList () {
|
||||
|
|
|
@ -9,16 +9,16 @@
|
|||
<div class="actor-display-name">{{ account.displayName }}</div>
|
||||
<div class="actor-name">{{ account.nameWithHost }}</div>
|
||||
</div>
|
||||
<div class="actor-followers">{{ account.followersCount }} subscribers</div>
|
||||
<div i18n class="actor-followers">{{ account.followersCount }} subscribers</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="links">
|
||||
<a routerLink="videos" routerLinkActive="active" class="title-page">Videos</a>
|
||||
<a i18n routerLink="videos" routerLinkActive="active" class="title-page">Videos</a>
|
||||
|
||||
<a routerLink="video-channels" routerLinkActive="active" class="title-page">Video channels</a>
|
||||
<a i18n routerLink="video-channels" routerLinkActive="active" class="title-page">Video channels</a>
|
||||
|
||||
<a routerLink="about" routerLinkActive="active" class="title-page">About</a>
|
||||
<a i18n routerLink="about" routerLinkActive="active" class="title-page">About</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
<div class="row">
|
||||
<div class="sub-menu">
|
||||
<a *ngIf="hasUsersRight()" routerLink="/admin/users" routerLinkActive="active" class="title-page">
|
||||
<a i18n *ngIf="hasUsersRight()" routerLink="/admin/users" routerLinkActive="active" class="title-page">
|
||||
Users
|
||||
</a>
|
||||
|
||||
<a *ngIf="hasServerFollowRight()" routerLink="/admin/follows" routerLinkActive="active" class="title-page">
|
||||
<a i18n *ngIf="hasServerFollowRight()" routerLink="/admin/follows" routerLinkActive="active" class="title-page">
|
||||
Manage follows
|
||||
</a>
|
||||
|
||||
<a *ngIf="hasVideoAbusesRight()" routerLink="/admin/video-abuses" routerLinkActive="active" class="title-page">
|
||||
<a i18n *ngIf="hasVideoAbusesRight()" routerLink="/admin/video-abuses" routerLinkActive="active" class="title-page">
|
||||
Video abuses
|
||||
</a>
|
||||
|
||||
<a *ngIf="hasVideoBlacklistRight()" routerLink="/admin/video-blacklist" routerLinkActive="active" class="title-page">
|
||||
<a i18n *ngIf="hasVideoBlacklistRight()" routerLink="/admin/video-blacklist" routerLinkActive="active" class="title-page">
|
||||
Video blacklist
|
||||
</a>
|
||||
|
||||
<a *ngIf="hasJobsRight()" routerLink="/admin/jobs" routerLinkActive="active" class="title-page">
|
||||
<a i18n *ngIf="hasJobsRight()" routerLink="/admin/jobs" routerLinkActive="active" class="title-page">
|
||||
Jobs
|
||||
</a>
|
||||
|
||||
<a *ngIf="hasConfigRight()" routerLink="/admin/config" routerLinkActive="active" class="title-page">
|
||||
<a i18n *ngIf="hasConfigRight()" routerLink="/admin/config" routerLinkActive="active" class="title-page">
|
||||
Configuration
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
|
||||
<tab heading="Basic configuration">
|
||||
|
||||
<div class="inner-form-title">Instance</div>
|
||||
<div i18n class="inner-form-title">Instance</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="instanceName">Name</label>
|
||||
<label i18n for="instanceName">Name</label>
|
||||
<input
|
||||
type="text" id="instanceName"
|
||||
formControlName="instanceName" [ngClass]="{ 'input-error': formErrors['instanceName'] }"
|
||||
type="text" id="instanceName"
|
||||
formControlName="instanceName" [ngClass]="{ 'input-error': formErrors['instanceName'] }"
|
||||
>
|
||||
<div *ngIf="formErrors.instanceName" class="form-error">
|
||||
{{ formErrors.instanceName }}
|
||||
|
@ -18,10 +18,10 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="instanceShortDescription">Short description</label>
|
||||
<label i18n for="instanceShortDescription">Short description</label>
|
||||
<textarea
|
||||
id="instanceShortDescription" formControlName="instanceShortDescription"
|
||||
[ngClass]="{ 'input-error': formErrors['instanceShortDescription'] }"
|
||||
id="instanceShortDescription" formControlName="instanceShortDescription"
|
||||
[ngClass]="{ 'input-error': formErrors['instanceShortDescription'] }"
|
||||
></textarea>
|
||||
<div *ngIf="formErrors.instanceShortDescription" class="form-error">
|
||||
{{ formErrors.instanceShortDescription }}
|
||||
|
@ -29,10 +29,10 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="instanceDescription">Description</label><my-help helpType="markdownText"></my-help>
|
||||
<label i18n for="instanceDescription">Description</label><my-help helpType="markdownText"></my-help>
|
||||
<my-markdown-textarea
|
||||
id="instanceDescription" formControlName="instanceDescription" textareaWidth="500px" [previewColumn]="true"
|
||||
[classes]="{ 'input-error': formErrors['instanceDescription'] }"
|
||||
id="instanceDescription" formControlName="instanceDescription" textareaWidth="500px" [previewColumn]="true"
|
||||
[classes]="{ 'input-error': formErrors['instanceDescription'] }"
|
||||
></my-markdown-textarea>
|
||||
<div *ngIf="formErrors.instanceDescription" class="form-error">
|
||||
{{ formErrors.instanceDescription }}
|
||||
|
@ -40,10 +40,10 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help>
|
||||
<label i18n for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help>
|
||||
<my-markdown-textarea
|
||||
id="instanceTerms" formControlName="instanceTerms" textareaWidth="500px" [previewColumn]="true"
|
||||
[ngClass]="{ 'input-error': formErrors['instanceTerms'] }"
|
||||
id="instanceTerms" formControlName="instanceTerms" textareaWidth="500px" [previewColumn]="true"
|
||||
[ngClass]="{ 'input-error': formErrors['instanceTerms'] }"
|
||||
></my-markdown-textarea>
|
||||
<div *ngIf="formErrors.instanceTerms" class="form-error">
|
||||
{{ formErrors.instanceTerms }}
|
||||
|
@ -51,12 +51,12 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="instanceDefaultClientRoute">Default client route</label>
|
||||
<label i18n for="instanceDefaultClientRoute">Default client route</label>
|
||||
<div class="peertube-select-container">
|
||||
<select id="instanceDefaultClientRoute" formControlName="instanceDefaultClientRoute">
|
||||
<option value="/videos/trending">Videos Trending</option>
|
||||
<option value="/videos/recently-added">Videos Recently Added</option>
|
||||
<option value="/videos/local">Local videos</option>
|
||||
<option i18n value="/videos/trending">Videos Trending</option>
|
||||
<option i18n value="/videos/recently-added">Videos Recently Added</option>
|
||||
<option i18n value="/videos/local">Local videos</option>
|
||||
</select>
|
||||
</div>
|
||||
<div *ngIf="formErrors.instanceDefaultClientRoute" class="form-error">
|
||||
|
@ -65,14 +65,17 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label>
|
||||
<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>
|
||||
<label i18n for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label>
|
||||
<my-help
|
||||
helpType="custom" i18n-customHtml
|
||||
customHtml="With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video."
|
||||
></my-help>
|
||||
|
||||
<div class="peertube-select-container">
|
||||
<select id="instanceDefaultNSFWPolicy" formControlName="instanceDefaultNSFWPolicy">
|
||||
<option value="do_not_list">Do not list</option>
|
||||
<option value="blur">Blur thumbnails</option>
|
||||
<option value="display">Display</option>
|
||||
<option i18n value="do_not_list">Do not list</option>
|
||||
<option i18n value="blur">Blur thumbnails</option>
|
||||
<option i18n value="display">Display</option>
|
||||
</select>
|
||||
</div>
|
||||
<div *ngIf="formErrors.instanceDefaultNSFWPolicy" class="form-error">
|
||||
|
@ -80,43 +83,43 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inner-form-title">Signup</div>
|
||||
<div i18n class="inner-form-title">Signup</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="checkbox" id="signupEnabled" formControlName="signupEnabled">
|
||||
|
||||
<label for="signupEnabled"></label>
|
||||
<label for="signupEnabled">Signup enabled</label>
|
||||
<label i18n for="signupEnabled">Signup enabled</label>
|
||||
</div>
|
||||
|
||||
<div *ngIf="isSignupEnabled()" class="form-group">
|
||||
<label for="signupLimit">Signup limit</label>
|
||||
<label i18n for="signupLimit">Signup limit</label>
|
||||
<input
|
||||
type="text" id="signupLimit"
|
||||
formControlName="signupLimit" [ngClass]="{ 'input-error': formErrors['signupLimit'] }"
|
||||
type="text" id="signupLimit"
|
||||
formControlName="signupLimit" [ngClass]="{ 'input-error': formErrors['signupLimit'] }"
|
||||
>
|
||||
<div *ngIf="formErrors.signupLimit" class="form-error">
|
||||
{{ formErrors.signupLimit }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inner-form-title">Administrator</div>
|
||||
<div i18n class="inner-form-title">Administrator</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="adminEmail">Admin email</label>
|
||||
<label i18n for="adminEmail">Admin email</label>
|
||||
<input
|
||||
type="text" id="adminEmail"
|
||||
formControlName="adminEmail" [ngClass]="{ 'input-error': formErrors['adminEmail'] }"
|
||||
type="text" id="adminEmail"
|
||||
formControlName="adminEmail" [ngClass]="{ 'input-error': formErrors['adminEmail'] }"
|
||||
>
|
||||
<div *ngIf="formErrors.adminEmail" class="form-error">
|
||||
{{ formErrors.adminEmail }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inner-form-title">Users</div>
|
||||
<div i18n class="inner-form-title">Users</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="userVideoQuota">User default video quota</label>
|
||||
<label i18n for="userVideoQuota">User default video quota</label>
|
||||
<div class="peertube-select-container">
|
||||
<select id="userVideoQuota" formControlName="userVideoQuota">
|
||||
<option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value">
|
||||
|
@ -132,14 +135,17 @@
|
|||
|
||||
<tab heading="Services">
|
||||
|
||||
<div class="inner-form-title">Twitter</div>
|
||||
<div i18n class="inner-form-title">Twitter</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="signupLimit">Your Twitter username</label>
|
||||
<my-help helpType="custom" customHtml="Indicates the Twitter account for the website or platform on which the content was published."></my-help>
|
||||
<label i18n for="signupLimit">Your Twitter username</label>
|
||||
<my-help
|
||||
helpType="custom" i18n-customHtml
|
||||
customHtml="Indicates the Twitter account for the website or platform on which the content was published."
|
||||
></my-help>
|
||||
<input
|
||||
type="text" id="servicesTwitterUsername"
|
||||
formControlName="servicesTwitterUsername" [ngClass]="{ 'input-error': formErrors['servicesTwitterUsername'] }"
|
||||
type="text" id="servicesTwitterUsername"
|
||||
formControlName="servicesTwitterUsername" [ngClass]="{ 'input-error': formErrors['servicesTwitterUsername'] }"
|
||||
>
|
||||
<div *ngIf="formErrors.servicesTwitterUsername" class="form-error">
|
||||
{{ formErrors.servicesTwitterUsername }}
|
||||
|
@ -150,29 +156,32 @@
|
|||
<input type="checkbox" id="servicesTwitterWhitelisted" formControlName="servicesTwitterWhitelisted">
|
||||
|
||||
<label for="servicesTwitterWhitelisted"></label>
|
||||
<label for="servicesTwitterWhitelisted">Instance whitelisted by Twitter</label>
|
||||
<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 />
|
||||
<label i18n for="servicesTwitterWhitelisted">Instance whitelisted by Twitter</label>
|
||||
<my-help
|
||||
helpType="custom" i18n-customHtml
|
||||
customHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br />
|
||||
If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br />
|
||||
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>
|
||||
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>
|
||||
|
||||
</div>
|
||||
</tab>
|
||||
|
||||
<tab heading="Advanced configuration">
|
||||
|
||||
<div class="inner-form-title">Transcoding</div>
|
||||
<div i18n class="inner-form-title">Transcoding</div>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="checkbox" id="transcodingEnabled" formControlName="transcodingEnabled">
|
||||
|
||||
<label for="transcodingEnabled"></label>
|
||||
<label for="transcodingEnabled">Transcoding enabled</label>
|
||||
<label i18n for="transcodingEnabled">Transcoding enabled</label>
|
||||
</div>
|
||||
|
||||
<ng-template [ngIf]="isTranscodingEnabled()">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="transcodingThreads">Transcoding threads</label>
|
||||
<label i18n for="transcodingThreads">Transcoding threads</label>
|
||||
<div class="peertube-select-container">
|
||||
<select id="transcodingThreads" formControlName="transcodingThreads">
|
||||
<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
|
|||
[formControlName]="getResolutionKey(resolution)"
|
||||
>
|
||||
<label [for]="getResolutionKey(resolution)"></label>
|
||||
<label [for]="getResolutionKey(resolution)">Resolution {{ resolution }} enabled</label>
|
||||
<label i18n [for]="getResolutionKey(resolution)">Resolution {{ resolution }} enabled</label>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<div class="inner-form-title">Cache</div>
|
||||
<div i18n class="inner-form-title">Cache</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="cachePreviewsSize">Preview cache size</label>
|
||||
<my-help helpType="custom" customHtml="Previews are not federated. We fetch them directly from the origin instance and cache them."></my-help>
|
||||
<label i18n for="cachePreviewsSize">Preview cache size</label>
|
||||
<my-help
|
||||
helpType="custom" i18n-customHtml
|
||||
customHtml="Previews are not federated. We fetch them directly from the origin instance and cache them."
|
||||
></my-help>
|
||||
|
||||
<input
|
||||
type="text" id="cachePreviewsSize"
|
||||
formControlName="cachePreviewsSize" [ngClass]="{ 'input-error': formErrors['cachePreviewsSize'] }"
|
||||
type="text" id="cachePreviewsSize"
|
||||
formControlName="cachePreviewsSize" [ngClass]="{ 'input-error': formErrors['cachePreviewsSize'] }"
|
||||
>
|
||||
<div *ngIf="formErrors.cachePreviewsSize" class="form-error">
|
||||
{{ formErrors.cachePreviewsSize }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inner-form-title">Customizations</div>
|
||||
<div i18n class="inner-form-title">Customizations</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="customizationJavascript">JavaScript</label>
|
||||
<my-help helpType="custom" customHtml="Write directly JavaScript code.<br />Example: <pre>console.log('my instance is amazing');</pre>"></my-help>
|
||||
<label i18n for="customizationJavascript">JavaScript</label>
|
||||
<my-help
|
||||
helpType="custom" i18n-customHtml
|
||||
customHtml="Write directly JavaScript code.<br />Example: <pre>console.log('my instance is amazing');</pre>"
|
||||
></my-help>
|
||||
<textarea
|
||||
id="customizationJavascript" formControlName="customizationJavascript"
|
||||
[ngClass]="{ 'input-error': formErrors['customizationJavascript'] }"
|
||||
id="customizationJavascript" formControlName="customizationJavascript"
|
||||
[ngClass]="{ 'input-error': formErrors['customizationJavascript'] }"
|
||||
></textarea>
|
||||
<div *ngIf="formErrors.customizationJavascript" class="form-error">
|
||||
{{ formErrors.customizationJavascript }}
|
||||
|
@ -228,25 +243,26 @@ Check this checkbox, save the configuration and test with a video URL of your in
|
|||
<label for="customizationCSS">CSS</label>
|
||||
<my-help
|
||||
helpType="custom"
|
||||
i18n-customHtml
|
||||
customHtml="
|
||||
Write directly CSS code. Example:<br />
|
||||
<pre>
|
||||
body {
|
||||
body {{ '{' }}
|
||||
background-color: red;
|
||||
}
|
||||
{{ '}' }}
|
||||
</pre>
|
||||
|
||||
Prepend with <em>#custom-css</em> to override styles. Example:
|
||||
<pre>
|
||||
#custom-css .logged-in-email {
|
||||
#custom-css .logged-in-email {{ '{' }}
|
||||
color: red;
|
||||
}
|
||||
{{ '}' }}
|
||||
</pre>
|
||||
"
|
||||
></my-help>
|
||||
<textarea
|
||||
id="customizationCSS" formControlName="customizationCSS"
|
||||
[ngClass]="{ 'input-error': formErrors['customizationCSS'] }"
|
||||
id="customizationCSS" formControlName="customizationCSS"
|
||||
[ngClass]="{ 'input-error': formErrors['customizationCSS'] }"
|
||||
></textarea>
|
||||
<div *ngIf="formErrors.customizationCSS" class="form-error">
|
||||
{{ formErrors.customizationCSS }}
|
||||
|
@ -255,5 +271,5 @@ Check this checkbox, save the configuration and test with a video URL of your in
|
|||
</tab>
|
||||
</tabset>
|
||||
|
||||
<input (click)="formValidated()" type="submit" value="Update configuration" [disabled]="!form.valid">
|
||||
<input (click)="formValidated()" type="submit" i18n-value value="Update configuration" [disabled]="!form.valid">
|
||||
</form>
|
||||
|
|
|
@ -8,12 +8,15 @@ import { FormReactive, USER_VIDEO_QUOTA } from '@app/shared'
|
|||
import {
|
||||
ADMIN_EMAIL,
|
||||
CACHE_PREVIEWS_SIZE,
|
||||
INSTANCE_NAME, INSTANCE_SHORT_DESCRIPTION, SERVICES_TWITTER_USERNAME,
|
||||
INSTANCE_NAME,
|
||||
INSTANCE_SHORT_DESCRIPTION,
|
||||
SERVICES_TWITTER_USERNAME,
|
||||
SIGNUP_LIMIT,
|
||||
TRANSCODING_THREADS
|
||||
} from '@app/shared/forms/form-validators/custom-config'
|
||||
import { NotificationsService } from 'angular2-notifications'
|
||||
import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-edit-custom-config',
|
||||
|
@ -77,7 +80,8 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
|
|||
private notificationsService: NotificationsService,
|
||||
private configService: ConfigService,
|
||||
private serverService: ServerService,
|
||||
private confirmService: ConfirmService
|
||||
private confirmService: ConfirmService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -133,7 +137,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
|
|||
this.forceCheck()
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -156,11 +160,15 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
|
|||
if (customizations.length !== 0) {
|
||||
const customizationsText = customizations.join('/')
|
||||
|
||||
const message = `You set custom ${customizationsText}. ` +
|
||||
'This could lead to security issues or bugs if you do not understand it. ' +
|
||||
'Are you sure you want to update the configuration?'
|
||||
const label = `Please type "I understand the ${customizationsText} I set" to confirm.`
|
||||
const expectedInputValue = `I understand the ${customizationsText} I set`
|
||||
// FIXME: i18n service does not support string concatenation
|
||||
const message = this.i18n('You set custom {{ customizationsText }}. ', { customizationsText }) +
|
||||
this.i18n('This could lead to security issues or bugs if you do not understand it. ') +
|
||||
this.i18n('Are you sure you want to update the configuration?')
|
||||
const label = this.i18n(
|
||||
'Please type "I understand the {{ customizationsText }} I set" to confirm.',
|
||||
{ customizationsText }
|
||||
)
|
||||
const expectedInputValue = this.i18n('I understand the {{ customizationsText }} I set', { customizationsText})
|
||||
|
||||
const confirmRes = await this.confirmService.confirmWithInput(message, label, expectedInputValue)
|
||||
if (confirmRes === false) return
|
||||
|
@ -223,10 +231,10 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
|
|||
|
||||
this.updateForm()
|
||||
|
||||
this.notificationsService.success('Success', 'Configuration updated.')
|
||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Configuration updated.'))
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
>
|
||||
<ng-template pTemplate="header">
|
||||
<tr>
|
||||
<th style="width: 60px">ID</th>
|
||||
<th>Score</th>
|
||||
<th>Name</th>
|
||||
<th>Host</th>
|
||||
<th>State</th>
|
||||
<th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th i18n style="width: 60px">ID</th>
|
||||
<th i18n>Score</th>
|
||||
<th i18n>Name</th>
|
||||
<th i18n>Host</th>
|
||||
<th i18n>State</th>
|
||||
<th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import { SortMeta } from 'primeng/primeng'
|
|||
import { AccountFollow } from '../../../../../../shared/models/actors/follow.model'
|
||||
import { RestPagination, RestTable } from '../../../shared'
|
||||
import { FollowService } from '../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-followers-list',
|
||||
|
@ -20,7 +21,8 @@ export class FollowersListComponent extends RestTable implements OnInit {
|
|||
|
||||
constructor (
|
||||
private notificationsService: NotificationsService,
|
||||
private followService: FollowService
|
||||
private followService: FollowService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -37,7 +39,7 @@ export class FollowersListComponent extends RestTable implements OnInit {
|
|||
this.totalRecords = resultList.total
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<form (ngSubmit)="addFollowing()">
|
||||
<div class="form-group">
|
||||
<label for="hosts">1 host (without "http://") per line</label>
|
||||
<label i18n for="hosts">1 host (without "http://") per line</label>
|
||||
|
||||
<textarea
|
||||
type="text" class="form-control" placeholder="example.com" id="hosts" name="hosts"
|
||||
|
@ -14,9 +14,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="httpEnabled() === false" class="alert alert-warning">
|
||||
<div i18n *ngIf="httpEnabled() === false" class="alert alert-warning">
|
||||
It seems that you are not on a HTTPS server. Your webserver needs to have TLS activated in order to follow servers.
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Add following" [disabled]="hostsError || !hostsString" class="btn btn-default">
|
||||
<input type="submit" i18n-value value="Add following" [disabled]="hostsError || !hostsString" class="btn btn-default">
|
||||
</form>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { NotificationsService } from 'angular2-notifications'
|
|||
import { ConfirmService } from '../../../core'
|
||||
import { validateHost } from '../../../shared'
|
||||
import { FollowService } from '../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-following-add',
|
||||
|
@ -19,7 +20,8 @@ export class FollowingAddComponent {
|
|||
private router: Router,
|
||||
private notificationsService: NotificationsService,
|
||||
private confirmService: ConfirmService,
|
||||
private followService: FollowService
|
||||
private followService: FollowService,
|
||||
private i18n: I18n
|
||||
) {}
|
||||
|
||||
httpEnabled () {
|
||||
|
@ -34,7 +36,7 @@ export class FollowingAddComponent {
|
|||
|
||||
for (const host of hosts) {
|
||||
if (validateHost(host) === false) {
|
||||
newHostsErrors.push(`${host} is not valid`)
|
||||
newHostsErrors.push(this.i18n('{{ host }} is not valid', { host }))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,26 +50,26 @@ export class FollowingAddComponent {
|
|||
|
||||
const hosts = this.getNotEmptyHosts()
|
||||
if (hosts.length === 0) {
|
||||
this.error = 'You need to specify hosts to follow.'
|
||||
this.error = this.i18n('You need to specify hosts to follow.')
|
||||
}
|
||||
|
||||
if (!this.isHostsUnique(hosts)) {
|
||||
this.error = 'Hosts need to be unique.'
|
||||
this.error = this.i18n('Hosts need to be unique.')
|
||||
return
|
||||
}
|
||||
|
||||
const confirmMessage = 'If you confirm, you will send a follow request to:<br /> - ' + hosts.join('<br /> - ')
|
||||
const res = await this.confirmService.confirm(confirmMessage, 'Follow new server(s)')
|
||||
const confirmMessage = this.i18n('If you confirm, you will send a follow request to:<br /> - ') + hosts.join('<br /> - ')
|
||||
const res = await this.confirmService.confirm(confirmMessage, this.i18n('Follow new server(s)'))
|
||||
if (res === false) return
|
||||
|
||||
this.followService.follow(hosts).subscribe(
|
||||
() => {
|
||||
this.notificationsService.success('Success', 'Follow request(s) sent!')
|
||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Follow request(s) sent!'))
|
||||
|
||||
setTimeout(() => this.router.navigate([ '/admin/follows/following-list' ]), 500)
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -76,10 +78,8 @@ export class FollowingAddComponent {
|
|||
}
|
||||
|
||||
private getNotEmptyHosts () {
|
||||
const hosts = this.hostsString
|
||||
return this.hostsString
|
||||
.split('\n')
|
||||
.filter(host => host && host.length !== 0) // Eject empty hosts
|
||||
|
||||
return hosts
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
>
|
||||
<ng-template pTemplate="header">
|
||||
<tr>
|
||||
<th style="width: 60px">ID</th>
|
||||
<th>Host</th>
|
||||
<th>State</th>
|
||||
<th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th i18n style="width: 60px">ID</th>
|
||||
<th i18n>Host</th>
|
||||
<th i18n>State</th>
|
||||
<th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { AccountFollow } from '../../../../../../shared/models/actors/follow.mod
|
|||
import { ConfirmService } from '../../../core/confirm/confirm.service'
|
||||
import { RestPagination, RestTable } from '../../../shared'
|
||||
import { FollowService } from '../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-followers-list',
|
||||
|
@ -20,7 +21,8 @@ export class FollowingListComponent extends RestTable implements OnInit {
|
|||
constructor (
|
||||
private notificationsService: NotificationsService,
|
||||
private confirmService: ConfirmService,
|
||||
private followService: FollowService
|
||||
private followService: FollowService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -30,16 +32,22 @@ export class FollowingListComponent extends RestTable implements OnInit {
|
|||
}
|
||||
|
||||
async removeFollowing (follow: AccountFollow) {
|
||||
const res = await this.confirmService.confirm(`Do you really want to unfollow ${follow.following.host}?`, 'Unfollow')
|
||||
const res = await this.confirmService.confirm(
|
||||
this.i18n('Do you really want to unfollow {{ host }}?', { host: follow.following.host }),
|
||||
this.i18n('Unfollow')
|
||||
)
|
||||
if (res === false) return
|
||||
|
||||
this.followService.unfollow(follow).subscribe(
|
||||
() => {
|
||||
this.notificationsService.success('Success', `You are not following ${follow.following.host} anymore.`)
|
||||
this.notificationsService.success(
|
||||
this.i18n('Success'),
|
||||
this.i18n('You are not following {{ host }} anymore.', { host: follow.following.host })
|
||||
)
|
||||
this.loadData()
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -51,7 +59,7 @@ export class FollowingListComponent extends RestTable implements OnInit {
|
|||
this.totalRecords = resultList.total
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="admin-sub-header">
|
||||
<div class="form-sub-title">Manage follows</div>
|
||||
<div i18n class="form-sub-title">Manage follows</div>
|
||||
|
||||
<tabset #followsMenuTabs>
|
||||
<tab *ngFor="let link of links">
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
export * from './'
|
||||
export * from './shared'
|
||||
export * from './jobs-list'
|
||||
export * from './job.routes'
|
||||
export * from './job.component'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="admin-sub-header">
|
||||
<div class="form-sub-title">Jobs list</div>
|
||||
<div i18n class="form-sub-title">Jobs list</div>
|
||||
|
||||
<div class="peertube-select-container">
|
||||
<select [(ngModel)]="jobState" (ngModelChange)="onJobStateChanged()">
|
||||
|
@ -15,11 +15,11 @@
|
|||
<ng-template pTemplate="header">
|
||||
<tr>
|
||||
<th style="width: 27px"></th>
|
||||
<th style="width: 60px">ID</th>
|
||||
<th style="width: 210px">Type</th>
|
||||
<th style="width: 130px">State</th>
|
||||
<th style="width: 250px" pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th style="width: 250px">Updated</th>
|
||||
<th i18n style="width: 60px">ID</th>
|
||||
<th i18n style="width: 210px">Type</th>
|
||||
<th i18n style="width: 130px">State</th>
|
||||
<th i18n style="width: 250px" pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th i18n style="width: 250px">Updated</th>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import { JobState } from '../../../../../../shared/models'
|
|||
import { RestPagination, RestTable } from '../../../shared'
|
||||
import { RestExtractor } from '../../../shared/rest/rest-extractor.service'
|
||||
import { JobService } from '../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-jobs-list',
|
||||
|
@ -27,7 +28,8 @@ export class JobsListComponent extends RestTable implements OnInit {
|
|||
constructor (
|
||||
private notificationsService: NotificationsService,
|
||||
private restExtractor: RestExtractor,
|
||||
private jobsService: JobService
|
||||
private jobsService: JobService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -51,7 +53,7 @@ export class JobsListComponent extends RestTable implements OnInit {
|
|||
this.totalRecords = resultList.total
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import { Observable } from 'rxjs'
|
|||
import { ResultList, UserCreate, UserUpdate } from '../../../../../../shared'
|
||||
import { environment } from '../../../../environments/environment'
|
||||
import { RestExtractor, RestPagination, RestService, User } from '../../../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
|
@ -16,9 +17,9 @@ export class UserService {
|
|||
constructor (
|
||||
private authHttp: HttpClient,
|
||||
private restService: RestService,
|
||||
private restExtractor: RestExtractor
|
||||
) {
|
||||
}
|
||||
private restExtractor: RestExtractor,
|
||||
private i18n: I18n
|
||||
) { }
|
||||
|
||||
addUser (userCreate: UserCreate) {
|
||||
return this.authHttp.post(UserService.BASE_USERS_URL, userCreate)
|
||||
|
|
|
@ -1,20 +1,13 @@
|
|||
import { Component, OnInit } from '@angular/core'
|
||||
import { FormBuilder, FormGroup } from '@angular/forms'
|
||||
import { Router } from '@angular/router'
|
||||
|
||||
import { NotificationsService } from 'angular2-notifications'
|
||||
|
||||
import { UserService } from '../shared'
|
||||
import {
|
||||
USER_USERNAME,
|
||||
USER_EMAIL,
|
||||
USER_PASSWORD,
|
||||
USER_VIDEO_QUOTA,
|
||||
USER_ROLE
|
||||
} from '../../../shared'
|
||||
import { USER_EMAIL, USER_PASSWORD, USER_ROLE, USER_USERNAME, USER_VIDEO_QUOTA } from '../../../shared'
|
||||
import { ServerService } from '../../../core'
|
||||
import { UserCreate, UserRole } from '../../../../../../shared'
|
||||
import { UserEdit } from './user-edit'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-user-create',
|
||||
|
@ -45,7 +38,8 @@ export class UserCreateComponent extends UserEdit implements OnInit {
|
|||
private formBuilder: FormBuilder,
|
||||
private router: Router,
|
||||
private notificationsService: NotificationsService,
|
||||
private userService: UserService
|
||||
private userService: UserService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -76,7 +70,10 @@ export class UserCreateComponent extends UserEdit implements OnInit {
|
|||
|
||||
this.userService.addUser(userCreate).subscribe(
|
||||
() => {
|
||||
this.notificationsService.success('Success', `User ${userCreate.username} created.`)
|
||||
this.notificationsService.success(
|
||||
this.i18n('Success'),
|
||||
this.i18n('User {{ username }} created.', { username: userCreate.username })
|
||||
)
|
||||
this.router.navigate([ '/admin/users/list' ])
|
||||
},
|
||||
|
||||
|
@ -89,6 +86,6 @@ export class UserCreateComponent extends UserEdit implements OnInit {
|
|||
}
|
||||
|
||||
getFormButtonTitle () {
|
||||
return 'Create user'
|
||||
return this.i18n('Create user')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<div class="form-sub-title" *ngIf="isCreation() === true">Create user</div>
|
||||
<div class="form-sub-title" *ngIf="isCreation() === false">Edit user {{ username }}</div>
|
||||
<div i18n class="form-sub-title" *ngIf="isCreation() === true">Create user</div>
|
||||
<div i18n class="form-sub-title" *ngIf="isCreation() === false">Edit user {{ username }}</div>
|
||||
|
||||
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
|
||||
|
||||
<form role="form" (ngSubmit)="formValidated()" [formGroup]="form">
|
||||
<div class="form-group" *ngIf="isCreation()">
|
||||
<label for="username">Username</label>
|
||||
<label i18n for="username">Username</label>
|
||||
<input
|
||||
type="text" id="username" placeholder="john"
|
||||
type="text" id="username" i18n-placeholder placeholder="john"
|
||||
formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }"
|
||||
>
|
||||
<div *ngIf="formErrors.username" class="form-error">
|
||||
|
@ -16,9 +16,9 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">Email</label>
|
||||
<label i18n for="email">Email</label>
|
||||
<input
|
||||
type="text" id="email" placeholder="mail@example.com"
|
||||
type="text" id="email" i18n-placeholder placeholder="mail@example.com"
|
||||
formControlName="email" [ngClass]="{ 'input-error': formErrors['email'] }"
|
||||
>
|
||||
<div *ngIf="formErrors.email" class="form-error">
|
||||
|
@ -27,7 +27,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group" *ngIf="isCreation()">
|
||||
<label for="password">Password</label>
|
||||
<label i18n for="password">Password</label>
|
||||
<input
|
||||
type="password" id="password"
|
||||
formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }"
|
||||
|
@ -38,7 +38,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="role">Role</label>
|
||||
<label i18n for="role">Role</label>
|
||||
<div class="peertube-select-container">
|
||||
<select id="role" formControlName="role">
|
||||
<option *ngFor="let role of roles" [value]="role.value">
|
||||
|
@ -53,7 +53,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="videoQuota">Video quota</label>
|
||||
<label i18n for="videoQuota">Video quota</label>
|
||||
<div class="peertube-select-container">
|
||||
<select id="videoQuota" formControlName="videoQuota">
|
||||
<option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value">
|
||||
|
@ -62,7 +62,7 @@
|
|||
</select>
|
||||
</div>
|
||||
|
||||
<div class="transcoding-information" *ngIf="isTranscodingInformationDisplayed()">
|
||||
<div i18n class="transcoding-information" *ngIf="isTranscodingInformationDisplayed()">
|
||||
Transcoding is enabled on server. The video quota only take in account <strong>original</strong> video. <br />
|
||||
At most, this user could use ~ {{ computeQuotaWithTranscoding() | bytes: 0 }}.
|
||||
</div>
|
||||
|
|
|
@ -8,6 +8,7 @@ import { User, USER_EMAIL, USER_ROLE, USER_VIDEO_QUOTA } from '../../../shared'
|
|||
import { ServerService } from '../../../core'
|
||||
import { UserEdit } from './user-edit'
|
||||
import { UserUpdate } from '../../../../../../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-user-update',
|
||||
|
@ -39,7 +40,8 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
|
|||
private router: Router,
|
||||
private notificationsService: NotificationsService,
|
||||
private formBuilder: FormBuilder,
|
||||
private userService: UserService
|
||||
private userService: UserService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -81,7 +83,10 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
|
|||
|
||||
this.userService.updateUser(this.userId, userUpdate).subscribe(
|
||||
() => {
|
||||
this.notificationsService.success('Success', `User ${this.username} updated.`)
|
||||
this.notificationsService.success(
|
||||
this.i18n('Success'),
|
||||
this.i18n('User {{ username }} updated.', { username: this.username })
|
||||
)
|
||||
this.router.navigate([ '/admin/users/list' ])
|
||||
},
|
||||
|
||||
|
@ -94,7 +99,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
getFormButtonTitle () {
|
||||
return 'Update user'
|
||||
return this.i18n('Update user')
|
||||
}
|
||||
|
||||
private onUserFetched (userJson: User) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<div class="admin-sub-header">
|
||||
<div class="form-sub-title">Users list</div>
|
||||
<div i18n class="form-sub-title">Users list</div>
|
||||
|
||||
<a class="add-button" routerLink="/admin/users/create">
|
||||
<span class="icon icon-add"></span>
|
||||
Create user
|
||||
<ng-container i18n>Create user</ng-container>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -13,11 +13,11 @@
|
|||
>
|
||||
<ng-template pTemplate="header">
|
||||
<tr>
|
||||
<th pSortableColumn="username">Username <p-sortIcon field="username"></p-sortIcon></th>
|
||||
<th>Email</th>
|
||||
<th>Video quota</th>
|
||||
<th>Role</th>
|
||||
<th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th i18n pSortableColumn="username">Username <p-sortIcon field="username"></p-sortIcon></th>
|
||||
<th i18n>Email</th>
|
||||
<th i18n>Video quota</th>
|
||||
<th i18n>Role</th>
|
||||
<th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { Component, OnInit } from '@angular/core'
|
||||
|
||||
import { NotificationsService } from 'angular2-notifications'
|
||||
import { SortMeta } from 'primeng/components/common/sortmeta'
|
||||
|
||||
import { ConfirmService } from '../../../core'
|
||||
import { RestPagination, RestTable, User } from '../../../shared'
|
||||
import { UserService } from '../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-user-list',
|
||||
|
@ -22,7 +21,8 @@ export class UserListComponent extends RestTable implements OnInit {
|
|||
constructor (
|
||||
private notificationsService: NotificationsService,
|
||||
private confirmService: ConfirmService,
|
||||
private userService: UserService
|
||||
private userService: UserService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -33,20 +33,23 @@ export class UserListComponent extends RestTable implements OnInit {
|
|||
|
||||
async removeUser (user: User) {
|
||||
if (user.username === 'root') {
|
||||
this.notificationsService.error('Error', 'You cannot delete root.')
|
||||
this.notificationsService.error(this.i18n('Error'), this.i18n('You cannot delete root.'))
|
||||
return
|
||||
}
|
||||
|
||||
const res = await this.confirmService.confirm('Do you really want to delete this user?', 'Delete')
|
||||
const res = await this.confirmService.confirm(this.i18n('Do you really want to delete this user?'), this.i18n('Delete'))
|
||||
if (res === false) return
|
||||
|
||||
this.userService.removeUser(user).subscribe(
|
||||
() => {
|
||||
this.notificationsService.success('Success', `User ${user.username} deleted.`)
|
||||
this.notificationsService.success(
|
||||
this.i18n('Success'),
|
||||
this.i18n('User {{ username }} deleted.', { username: user.username })
|
||||
)
|
||||
this.loadData()
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -62,7 +65,7 @@ export class UserListComponent extends RestTable implements OnInit {
|
|||
this.totalRecords = resultList.total
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="admin-sub-header">
|
||||
<div class="form-sub-title">Video abuses list</div>
|
||||
<div i18n class="form-sub-title">Video abuses list</div>
|
||||
</div>
|
||||
|
||||
<p-table
|
||||
|
@ -8,10 +8,10 @@
|
|||
>
|
||||
<ng-template pTemplate="header">
|
||||
<tr>
|
||||
<th>Reason</th>
|
||||
<th>Reporter</th>
|
||||
<th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th>Video</th>
|
||||
<th i18n>Reason</th>
|
||||
<th i18n>Reporter</th>
|
||||
<th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th i18n>Video</th>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
||||
|
@ -19,13 +19,13 @@
|
|||
<tr>
|
||||
<td>{{ videoAbuse.reason }}</td>
|
||||
<td>
|
||||
<a [href]="videoAbuse.reporterAccount.url" title="Go to the account" target="_blank" rel="noopener noreferrer">
|
||||
<a [href]="videoAbuse.reporterAccount.url" i18n-title title="Go to the account" target="_blank" rel="noopener noreferrer">
|
||||
{{ createByString(videoAbuse.reporterAccount) }}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ videoAbuse.createdAt }}</td>
|
||||
<td>
|
||||
<a [href]="videoAbuse.video.url" title="Go to the video" target="_blank" rel="noopener noreferrer">
|
||||
<a [href]="videoAbuse.video.url" i18n-title title="Go to the video" target="_blank" rel="noopener noreferrer">
|
||||
{{ videoAbuse.video.name }}
|
||||
</a>
|
||||
</td>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { SortMeta } from 'primeng/components/common/sortmeta'
|
|||
import { VideoAbuse } from '../../../../../../shared'
|
||||
|
||||
import { RestPagination, RestTable, VideoAbuseService } from '../../../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-abuse-list',
|
||||
|
@ -20,7 +21,8 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
|||
|
||||
constructor (
|
||||
private notificationsService: NotificationsService,
|
||||
private videoAbuseService: VideoAbuseService
|
||||
private videoAbuseService: VideoAbuseService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -41,7 +43,7 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
|
|||
this.totalRecords = resultList.total
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="admin-sub-header">
|
||||
<div class="form-sub-title">Blacklisted videos</div>
|
||||
<div i18n class="form-sub-title">Blacklisted videos</div>
|
||||
</div>
|
||||
|
||||
<p-table
|
||||
|
@ -8,12 +8,12 @@
|
|||
>
|
||||
<ng-template pTemplate="header">
|
||||
<tr>
|
||||
<th pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th>
|
||||
<th>Description</th>
|
||||
<th pSortableColumn="views">Views <p-sortIcon field="views"></p-sortIcon></th>
|
||||
<th>NSFW</th>
|
||||
<th>UUID</th>
|
||||
<th pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th i18n pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th>
|
||||
<th i18n>Description</th>
|
||||
<th i18n pSortableColumn="views">Views <p-sortIcon field="views"></p-sortIcon></th>
|
||||
<th i18n>NSFW</th>
|
||||
<th i18n>UUID</th>
|
||||
<th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
@ -27,7 +27,7 @@
|
|||
<td>{{ videoBlacklist.uuid }}</td>
|
||||
<td>{{ videoBlacklist.createdAt }}</td>
|
||||
<td class="action-cell">
|
||||
<my-delete-button label="Unblacklist" (click)="removeVideoFromBlacklist(videoBlacklist)"></my-delete-button>
|
||||
<my-delete-button i18n-label label="Unblacklist" (click)="removeVideoFromBlacklist(videoBlacklist)"></my-delete-button>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { Component, OnInit } from '@angular/core'
|
||||
import { SortMeta } from 'primeng/components/common/sortmeta'
|
||||
|
||||
import { NotificationsService } from 'angular2-notifications'
|
||||
|
||||
import { ConfirmService } from '../../../core'
|
||||
import { VideoBlacklistService, RestTable, RestPagination } from '../../../shared'
|
||||
import { RestPagination, RestTable, VideoBlacklistService } from '../../../shared'
|
||||
import { BlacklistedVideo } from '../../../../../../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-blacklist-list',
|
||||
|
@ -22,7 +21,8 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
|||
constructor (
|
||||
private notificationsService: NotificationsService,
|
||||
private confirmService: ConfirmService,
|
||||
private videoBlacklistService: VideoBlacklistService
|
||||
private videoBlacklistService: VideoBlacklistService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -32,18 +32,23 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
|||
}
|
||||
|
||||
async removeVideoFromBlacklist (entry: BlacklistedVideo) {
|
||||
const confirmMessage = 'Do you really want to remove this video from the blacklist ? It will be available again in the videos list.'
|
||||
const confirmMessage = this.i18n(
|
||||
'Do you really want to remove this video from the blacklist ? It will be available again in the videos list.'
|
||||
)
|
||||
|
||||
const res = await this.confirmService.confirm(confirmMessage, 'Unblacklist')
|
||||
const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblacklist'))
|
||||
if (res === false) return
|
||||
|
||||
this.videoBlacklistService.removeVideoFromBlacklist(entry.videoId).subscribe(
|
||||
() => {
|
||||
this.notificationsService.success('Success', `Video ${entry.name} removed from the blacklist.`)
|
||||
this.notificationsService.success(
|
||||
this.i18n('Success'),
|
||||
this.i18n('Video {{ name }} removed from the blacklist.', { name: entry.name })
|
||||
)
|
||||
this.loadData()
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -55,7 +60,7 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
|
|||
this.totalRecords = resultList.total
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
<form role="form" (ngSubmit)="changePassword()" [formGroup]="form">
|
||||
|
||||
<label for="new-password">Change password</label>
|
||||
<label i18n for="new-password">Change password</label>
|
||||
<input
|
||||
type="password" id="new-password" placeholder="New password"
|
||||
type="password" id="new-password" i18n-placeholder placeholder="New password"
|
||||
formControlName="new-password" [ngClass]="{ 'input-error': formErrors['new-password'] }"
|
||||
>
|
||||
<div *ngIf="formErrors['new-password']" class="form-error">
|
||||
|
@ -12,9 +12,9 @@
|
|||
</div>
|
||||
|
||||
<input
|
||||
type="password" id="new-confirmed-password" placeholder="Confirm new password"
|
||||
type="password" id="new-confirmed-password" i18n-placeholder placeholder="Confirm new password"
|
||||
formControlName="new-confirmed-password"
|
||||
>
|
||||
|
||||
<input type="submit" value="Change password" [disabled]="!form.valid">
|
||||
<input type="submit" i18n-value value="Change password" [disabled]="!form.valid">
|
||||
</form>
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'
|
|||
import { FormBuilder, FormGroup } from '@angular/forms'
|
||||
import { NotificationsService } from 'angular2-notifications'
|
||||
import { FormReactive, USER_PASSWORD, UserService } from '../../../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-account-change-password',
|
||||
|
@ -24,7 +25,8 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On
|
|||
constructor (
|
||||
private formBuilder: FormBuilder,
|
||||
private notificationsService: NotificationsService,
|
||||
private userService: UserService
|
||||
private userService: UserService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -49,12 +51,12 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On
|
|||
this.error = null
|
||||
|
||||
if (newPassword !== newConfirmedPassword) {
|
||||
this.error = 'The new password and the confirmed password do not correspond.'
|
||||
this.error = this.i18n('The new password and the confirmed password do not correspond.')
|
||||
return
|
||||
}
|
||||
|
||||
this.userService.changePassword(newPassword).subscribe(
|
||||
() => this.notificationsService.success('Success', 'Password updated.'),
|
||||
() => this.notificationsService.success(this.i18n('Success'), this.i18n('Password updated.')),
|
||||
|
||||
err => this.error = err.message
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<form role="form" (ngSubmit)="updateMyProfile()" [formGroup]="form">
|
||||
|
||||
<label for="display-name">Display name</label>
|
||||
<label i18n for="display-name">Display name</label>
|
||||
<input
|
||||
type="text" id="display-name"
|
||||
formControlName="display-name" [ngClass]="{ 'input-error': formErrors['display-name'] }"
|
||||
|
@ -11,7 +11,7 @@
|
|||
{{ formErrors['display-name'] }}
|
||||
</div>
|
||||
|
||||
<label for="description">Description</label>
|
||||
<label i18n for="description">Description</label>
|
||||
<textarea
|
||||
id="description" formControlName="description"
|
||||
[ngClass]="{ 'input-error': formErrors['description'] }"
|
||||
|
@ -20,5 +20,5 @@
|
|||
{{ formErrors.description }}
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Update my profile" [disabled]="!form.valid">
|
||||
<input type="submit" i18n-value value="Update my profile" [disabled]="!form.valid">
|
||||
</form>
|
||||
|
|
|
@ -3,6 +3,7 @@ import { FormBuilder, FormGroup } from '@angular/forms'
|
|||
import { NotificationsService } from 'angular2-notifications'
|
||||
import { FormReactive, USER_DESCRIPTION, USER_DISPLAY_NAME, UserService } from '../../../shared'
|
||||
import { User } from '@app/shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-account-profile',
|
||||
|
@ -27,7 +28,8 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit {
|
|||
constructor (
|
||||
private formBuilder: FormBuilder,
|
||||
private notificationsService: NotificationsService,
|
||||
private userService: UserService
|
||||
private userService: UserService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -56,7 +58,7 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit {
|
|||
this.user.account.displayName = displayName
|
||||
this.user.account.description = description
|
||||
|
||||
this.notificationsService.success('Success', 'Profile updated.')
|
||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Profile updated.'))
|
||||
},
|
||||
|
||||
err => this.error = err.message
|
||||
|
|
|
@ -6,27 +6,27 @@
|
|||
<div class="user-info-display-name">{{ user.account.displayName }}</div>
|
||||
<div class="user-info-username">{{ user.username }}</div>
|
||||
</div>
|
||||
<div class="user-info-followers">{{ user.account?.followersCount }} subscribers</div>
|
||||
<div i18n class="user-info-followers">{{ user.account?.followersCount }} subscribers</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="button-file">
|
||||
<span>Change your avatar</span>
|
||||
<span i18n>Change your avatar</span>
|
||||
<input #avatarfileInput type="file" name="avatarfile" id="avatarfile" [accept]="avatarExtensions" (change)="changeAvatar()" />
|
||||
</div>
|
||||
<div class="file-max-size">(extensions: {{ avatarExtensions }}, max size: {{ maxAvatarSize | bytes }})</div>
|
||||
<div i18n class="file-max-size">(extensions: {{ avatarExtensions }}, max size: {{ maxAvatarSize | bytes }})</div>
|
||||
|
||||
<div class="user-quota">
|
||||
<span class="user-quota-label">Video quota:</span> {{ userVideoQuotaUsed | bytes: 0 }} / {{ userVideoQuota }}
|
||||
<span i18n class="user-quota-label">Video quota:</span> {{ userVideoQuotaUsed | bytes: 0 }} / {{ userVideoQuota }}
|
||||
</div>
|
||||
|
||||
<ng-template [ngIf]="user && user.account">
|
||||
<div class="account-title">Profile</div>
|
||||
<div i18n class="account-title">Profile</div>
|
||||
<my-account-profile [user]="user"></my-account-profile>
|
||||
</ng-template>
|
||||
|
||||
<div class="account-title">Password</div>
|
||||
<div i18n class="account-title">Password</div>
|
||||
<my-account-change-password></my-account-change-password>
|
||||
|
||||
<div class="account-title">Video settings</div>
|
||||
<div i18n class="account-title">Video settings</div>
|
||||
<my-account-video-settings [user]="user"></my-account-video-settings>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { AuthService } from '../../core'
|
|||
import { ServerService } from '../../core/server'
|
||||
import { User } from '../../shared'
|
||||
import { UserService } from '../../shared/users'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-account-settings',
|
||||
|
@ -22,7 +23,8 @@ export class MyAccountSettingsComponent implements OnInit {
|
|||
private userService: UserService,
|
||||
private authService: AuthService,
|
||||
private serverService: ServerService,
|
||||
private notificationsService: NotificationsService
|
||||
private notificationsService: NotificationsService,
|
||||
private i18n: I18n
|
||||
) {}
|
||||
|
||||
ngOnInit () {
|
||||
|
@ -33,7 +35,7 @@ export class MyAccountSettingsComponent implements OnInit {
|
|||
if (this.user.videoQuota !== -1) {
|
||||
this.userVideoQuota = new BytesPipe().transform(this.user.videoQuota, 0).toString()
|
||||
} else {
|
||||
this.userVideoQuota = 'Unlimited'
|
||||
this.userVideoQuota = this.i18n('Unlimited')
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -51,12 +53,12 @@ export class MyAccountSettingsComponent implements OnInit {
|
|||
this.userService.changeAvatar(formData)
|
||||
.subscribe(
|
||||
data => {
|
||||
this.notificationsService.success('Success', 'Avatar changed.')
|
||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Avatar changed.'))
|
||||
|
||||
this.user.account.avatar = data.avatar
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
<form role="form" (ngSubmit)="updateDetails()" [formGroup]="form">
|
||||
<div class="form-group">
|
||||
<label for="nsfwPolicy">Default policy on videos containing sensitive content</label>
|
||||
<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>
|
||||
<label i18n for="nsfwPolicy">Default policy on videos containing sensitive content</label>
|
||||
<my-help
|
||||
helpType="custom" i18n-customHtml
|
||||
customHtml="With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video."
|
||||
></my-help>
|
||||
|
||||
<div class="peertube-select-container">
|
||||
<select id="nsfwPolicy" formControlName="nsfwPolicy">
|
||||
<option value="do_not_list">Do not list</option>
|
||||
<option value="blur">Blur thumbnails</option>
|
||||
<option value="display">Display</option>
|
||||
<option i18n value="do_not_list">Do not list</option>
|
||||
<option i18n value="blur">Blur thumbnails</option>
|
||||
<option i18n value="display">Display</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -18,8 +21,8 @@
|
|||
formControlName="autoPlayVideo"
|
||||
>
|
||||
<label for="autoPlayVideo"></label>
|
||||
<label for="autoPlayVideo">Automatically plays video</label>
|
||||
<label i18n for="autoPlayVideo">Automatically plays video</label>
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Save" [disabled]="!form.valid">
|
||||
<input type="submit" i18n-value value="Save" [disabled]="!form.valid">
|
||||
</form>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { NotificationsService } from 'angular2-notifications'
|
|||
import { UserUpdateMe } from '../../../../../../shared'
|
||||
import { AuthService } from '../../../core'
|
||||
import { FormReactive, User, UserService } from '../../../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-account-video-settings',
|
||||
|
@ -21,7 +22,8 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
|
|||
private authService: AuthService,
|
||||
private formBuilder: FormBuilder,
|
||||
private notificationsService: NotificationsService,
|
||||
private userService: UserService
|
||||
private userService: UserService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -49,12 +51,12 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
|
|||
|
||||
this.userService.updateMyProfile(details).subscribe(
|
||||
() => {
|
||||
this.notificationsService.success('Success', 'Information updated.')
|
||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Information updated.'))
|
||||
|
||||
this.authService.refreshUserInformation()
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
} from '@app/shared/forms/form-validators/video-channel'
|
||||
import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
|
||||
import { AuthService } from '@app/core'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-account-video-channel-create',
|
||||
|
@ -37,7 +38,8 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE
|
|||
private notificationsService: NotificationsService,
|
||||
private router: Router,
|
||||
private formBuilder: FormBuilder,
|
||||
private videoChannelService: VideoChannelService
|
||||
private videoChannelService: VideoChannelService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -69,7 +71,10 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE
|
|||
this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe(
|
||||
() => {
|
||||
this.authService.refreshUserInformation()
|
||||
this.notificationsService.success('Success', `Video channel ${videoChannelCreate.displayName} created.`)
|
||||
this.notificationsService.success(
|
||||
this.i18n('Success'),
|
||||
this.i18n('Video channel {{ videoChannelName }} created.', { videoChannelName: videoChannelCreate.displayName })
|
||||
)
|
||||
this.router.navigate([ '/my-account', 'video-channels' ])
|
||||
},
|
||||
|
||||
|
@ -82,6 +87,6 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE
|
|||
}
|
||||
|
||||
getFormButtonTitle () {
|
||||
return 'Create'
|
||||
return this.i18n('Create')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<div class="form-sub-title" *ngIf="isCreation() === true">Create a video channel</div>
|
||||
<div class="form-sub-title" *ngIf="isCreation() === false">Update {{ videoChannel?.displayName }}</div>
|
||||
<div i18n class="form-sub-title" *ngIf="isCreation() === true">Create a video channel</div>
|
||||
<div i18n class="form-sub-title" *ngIf="isCreation() === false">Update {{ videoChannel?.displayName }}</div>
|
||||
|
||||
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
|
||||
|
||||
<form role="form" (ngSubmit)="formValidated()" [formGroup]="form">
|
||||
<div class="form-group">
|
||||
<label for="display-name">Display name</label>
|
||||
<label i18n for="display-name">Display name</label>
|
||||
<input
|
||||
type="text" id="display-name"
|
||||
formControlName="display-name" [ngClass]="{ 'input-error': formErrors['display-name'] }"
|
||||
|
@ -16,7 +16,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="description">Description</label>
|
||||
<label i18n for="description">Description</label>
|
||||
<textarea
|
||||
id="description" formControlName="description"
|
||||
[ngClass]="{ 'input-error': formErrors['description'] }"
|
||||
|
@ -29,7 +29,7 @@
|
|||
<div class="form-group">
|
||||
<label for="support">Support</label>
|
||||
<my-help
|
||||
helpType="markdownEnhanced" preHtml="Short text to tell people how they can support your channel (membership platform...).<br /><br />
|
||||
helpType="markdownEnhanced" i18n-preHtml preHtml="Short text to tell people how they can support your channel (membership platform...).<br /><br />
|
||||
When you will upload a video in this channel, the video support field will be automatically filled by this text."
|
||||
></my-help>
|
||||
<my-markdown-textarea
|
||||
|
|
|
@ -13,6 +13,7 @@ import { VideoChannelService } from '@app/shared/video-channel/video-channel.ser
|
|||
import { Subscription } from 'rxjs'
|
||||
import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
|
||||
import { AuthService } from '@app/core'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-account-video-channel-update',
|
||||
|
@ -43,7 +44,8 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
|
|||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private formBuilder: FormBuilder,
|
||||
private videoChannelService: VideoChannelService
|
||||
private videoChannelService: VideoChannelService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -97,7 +99,10 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
|
|||
this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.uuid, videoChannelUpdate).subscribe(
|
||||
() => {
|
||||
this.authService.refreshUserInformation()
|
||||
this.notificationsService.success('Success', `Video channel ${videoChannelUpdate.displayName} updated.`)
|
||||
this.notificationsService.success(
|
||||
this.i18n('Success'),
|
||||
this.i18n('Video channel {{ videoChannelName }} updated.', { videoChannelName: videoChannelUpdate.displayName })
|
||||
)
|
||||
this.router.navigate([ '/my-account', 'video-channels' ])
|
||||
},
|
||||
|
||||
|
@ -110,6 +115,6 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
|
|||
}
|
||||
|
||||
getFormButtonTitle () {
|
||||
return 'Update'
|
||||
return this.i18n('Update')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="video-channels-header">
|
||||
<a class="create-button" routerLink="create">
|
||||
<span class="icon icon-add"></span>
|
||||
Create another video channel
|
||||
<ng-container i18n>Create another video channel</ng-container>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
|||
</a>
|
||||
|
||||
<div class="video-channel-info">
|
||||
<a [routerLink]="[ '/video-channels', videoChannel.uuid ]" class="video-channel-names" title="Go to the channel">
|
||||
<a [routerLink]="[ '/video-channels', videoChannel.uuid ]" class="video-channel-names" i18n-title title="Go to the channel">
|
||||
<div class="video-channel-display-name">{{ videoChannel.displayName }}</div>
|
||||
<!-- Hide the name for now, because it's an UUID not very friendly -->
|
||||
<!--<div class="video-channel-name">{{ videoChannel.name }}</div>-->
|
||||
</a>
|
||||
|
||||
<div class="video-channel-followers">{{ videoChannel.followersCount }} subscribers</div>
|
||||
<div i18n class="video-channel-followers">{{ videoChannel.followersCount }} subscribers</div>
|
||||
</div>
|
||||
|
||||
<div class="video-channel-buttons">
|
||||
|
|
|
@ -6,6 +6,7 @@ import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
|
|||
import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
|
||||
import { User } from '@app/shared'
|
||||
import { flatMap } from 'rxjs/operators'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-account-video-channels',
|
||||
|
@ -21,7 +22,8 @@ export class MyAccountVideoChannelsComponent implements OnInit {
|
|||
private authService: AuthService,
|
||||
private notificationsService: NotificationsService,
|
||||
private confirmService: ConfirmService,
|
||||
private videoChannelService: VideoChannelService
|
||||
private videoChannelService: VideoChannelService,
|
||||
private i18n: I18n
|
||||
) {}
|
||||
|
||||
ngOnInit () {
|
||||
|
@ -32,10 +34,13 @@ export class MyAccountVideoChannelsComponent implements OnInit {
|
|||
|
||||
async deleteVideoChannel (videoChannel: VideoChannel) {
|
||||
const res = await this.confirmService.confirmWithInput(
|
||||
`Do you really want to delete ${videoChannel.displayName}? It will delete all videos uploaded in this channel too.`,
|
||||
'Please type the name of the video channel to confirm',
|
||||
this.i18n(
|
||||
'Do you really want to delete {{ videoChannelName }}? It will delete all videos uploaded in this channel too.',
|
||||
{ videoChannelName: videoChannel.displayName }
|
||||
),
|
||||
this.i18n('Please type the name of the video channel to confirm'),
|
||||
videoChannel.displayName,
|
||||
'Delete'
|
||||
this.i18n('Delete')
|
||||
)
|
||||
if (res === false) return
|
||||
|
||||
|
@ -43,10 +48,13 @@ export class MyAccountVideoChannelsComponent implements OnInit {
|
|||
.subscribe(
|
||||
status => {
|
||||
this.loadVideoChannels()
|
||||
this.notificationsService.success('Success', `Video channel ${videoChannel.name} deleted.`)
|
||||
this.notificationsService.success(
|
||||
this.i18n('Success'),
|
||||
this.i18n('Video channel {{ videoChannelName } deleted.', { videoChannelName: videoChannel.displayName })
|
||||
)
|
||||
},
|
||||
|
||||
error => this.notificationsService.error('Error', error.message)
|
||||
error => this.notificationsService.error(this.i18n('Error'), error.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div *ngIf="pagination.totalItems === 0">No results.</div>
|
||||
<div i18n *ngIf="pagination.totalItems === 0">No results.</div>
|
||||
|
||||
<div
|
||||
myInfiniteScroller
|
||||
|
@ -17,18 +17,18 @@
|
|||
|
||||
<div class="video-info">
|
||||
<a class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a>
|
||||
<span class="video-info-date-views">{{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
|
||||
<span i18n class="video-info-date-views">{{ video.createdAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
|
||||
<div class="video-info-private">{{ video.privacy.label }}</div>
|
||||
</div>
|
||||
|
||||
<!-- Display only once -->
|
||||
<div class="action-selection-mode" *ngIf="isInSelectionMode() === true && i === 0 && j === 0">
|
||||
<div class="action-selection-mode-child">
|
||||
<span class="action-button action-button-cancel-selection" (click)="abortSelectionMode()">
|
||||
<span i18n class="action-button action-button-cancel-selection" (click)="abortSelectionMode()">
|
||||
Cancel
|
||||
</span>
|
||||
|
||||
<span class="action-button action-button-delete-selection" (click)="deleteSelectedVideos()">
|
||||
<span i18n class="action-button action-button-delete-selection" (click)="deleteSelectedVideos()">
|
||||
<span class="icon icon-delete-white"></span>
|
||||
Delete
|
||||
</span>
|
||||
|
|
|
@ -11,6 +11,7 @@ import { ConfirmService } from '../../core/confirm'
|
|||
import { AbstractVideoList } from '../../shared/video/abstract-video-list'
|
||||
import { Video } from '../../shared/video/video.model'
|
||||
import { VideoService } from '../../shared/video/video.service'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-account-videos',
|
||||
|
@ -18,7 +19,7 @@ import { VideoService } from '../../shared/video/video.service'
|
|||
styleUrls: [ './my-account-videos.component.scss' ]
|
||||
})
|
||||
export class MyAccountVideosComponent extends AbstractVideoList implements OnInit, OnDestroy {
|
||||
titlePage = 'My videos'
|
||||
titlePage: string
|
||||
currentRoute = '/my-account/videos'
|
||||
checkedVideos: { [ id: number ]: boolean } = {}
|
||||
pagination: ComponentPagination = {
|
||||
|
@ -30,14 +31,19 @@ export class MyAccountVideosComponent extends AbstractVideoList implements OnIni
|
|||
protected baseVideoWidth = -1
|
||||
protected baseVideoHeight = 155
|
||||
|
||||
constructor (protected router: Router,
|
||||
protected route: ActivatedRoute,
|
||||
protected authService: AuthService,
|
||||
protected notificationsService: NotificationsService,
|
||||
protected confirmService: ConfirmService,
|
||||
protected location: Location,
|
||||
private videoService: VideoService) {
|
||||
constructor (
|
||||
protected router: Router,
|
||||
protected route: ActivatedRoute,
|
||||
protected authService: AuthService,
|
||||
protected notificationsService: NotificationsService,
|
||||
protected confirmService: ConfirmService,
|
||||
protected location: Location,
|
||||
protected i18n: I18n,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
super()
|
||||
|
||||
this.titlePage = this.i18n('My videos')
|
||||
}
|
||||
|
||||
ngOnInit () {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<div class="row">
|
||||
<div class="sub-menu">
|
||||
<a routerLink="/my-account/settings" routerLinkActive="active" class="title-page">My settings</a>
|
||||
<a i18n routerLink="/my-account/settings" routerLinkActive="active" class="title-page">My settings</a>
|
||||
|
||||
<a routerLink="/my-account/video-channels" routerLinkActive="active" class="title-page">My video channels</a>
|
||||
<a i18n routerLink="/my-account/video-channels" routerLinkActive="active" class="title-page">My video channels</a>
|
||||
|
||||
<a routerLink="/my-account/videos" routerLinkActive="active" class="title-page">My videos</a>
|
||||
<a i18n routerLink="/my-account/videos" routerLinkActive="active" class="title-page">My videos</a>
|
||||
</div>
|
||||
|
||||
<div class="margin-content">
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<div>
|
||||
<div i18n>
|
||||
Sorry, but we couldn't find the page you were looking for.
|
||||
</div>
|
|
@ -1,20 +1,20 @@
|
|||
<div *ngIf="videoChannel" class="row">
|
||||
<div class="description col-md-6 col-sm-12">
|
||||
<div class="block">
|
||||
<div class="small-title">Description</div>
|
||||
<div i18n class="small-title">Description</div>
|
||||
<div class="content">{{ getVideoChannelDescription() }}</div>
|
||||
</div>
|
||||
|
||||
<div class="block" *ngIf="videoChannel.support">
|
||||
<div class="small-title">Support this channel</div>
|
||||
<div i18n class="small-title">Support this channel</div>
|
||||
<div class="content">{{ videoChannel.support }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats col-md-6 col-sm-12">
|
||||
<div class="block">
|
||||
<div class="small-title">Stats</div>
|
||||
<div class="content">Created {{ videoChannel.createdAt | date }}</div>
|
||||
<div i18n class="small-title">Stats</div>
|
||||
<div i18n class="content">Created {{ videoChannel.createdAt | date }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'
|
|||
import { ActivatedRoute } from '@angular/router'
|
||||
import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
|
||||
import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-channel-about',
|
||||
|
@ -12,7 +13,8 @@ export class VideoChannelAboutComponent implements OnInit {
|
|||
videoChannel: VideoChannel
|
||||
|
||||
constructor (
|
||||
protected route: ActivatedRoute,
|
||||
private route: ActivatedRoute,
|
||||
private i18n: I18n,
|
||||
private videoChannelService: VideoChannelService
|
||||
) { }
|
||||
|
||||
|
@ -25,6 +27,6 @@ export class VideoChannelAboutComponent implements OnInit {
|
|||
getVideoChannelDescription () {
|
||||
if (this.videoChannel.description) return this.videoChannel.description
|
||||
|
||||
return 'No description'
|
||||
return this.i18n('No description')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { VideoService } from '../../shared/video/video.service'
|
|||
import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
|
||||
import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
|
||||
import { tap } from 'rxjs/operators'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-channel-videos',
|
||||
|
@ -20,7 +21,7 @@ import { tap } from 'rxjs/operators'
|
|||
]
|
||||
})
|
||||
export class VideoChannelVideosComponent extends AbstractVideoList implements OnInit, OnDestroy {
|
||||
titlePage = 'Published videos'
|
||||
titlePage: string
|
||||
marginContent = false // Disable margin
|
||||
currentRoute = '/video-channel/videos'
|
||||
loadOnInit = false
|
||||
|
@ -34,10 +35,13 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On
|
|||
protected notificationsService: NotificationsService,
|
||||
protected confirmService: ConfirmService,
|
||||
protected location: Location,
|
||||
protected i18n: I18n,
|
||||
private videoChannelService: VideoChannelService,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
super()
|
||||
|
||||
this.titlePage = this.i18n('Published videos')
|
||||
}
|
||||
|
||||
ngOnInit () {
|
||||
|
@ -63,7 +67,11 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On
|
|||
|
||||
return this.videoService
|
||||
.getVideoChannelVideos(this.videoChannel, newPagination, this.sort)
|
||||
.pipe(tap(({ totalVideos }) => this.titlePage = `Published ${totalVideos} videos`))
|
||||
.pipe(
|
||||
tap(({ totalVideos }) => {
|
||||
this.titlePage = this.i18n('Published {{ totalVideos }} videos', { totalVideos })
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
generateSyndicationList () {
|
||||
|
|
|
@ -8,19 +8,19 @@
|
|||
<div class="actor-names">
|
||||
<div class="actor-display-name">{{ videoChannel.displayName }}</div>
|
||||
</div>
|
||||
<div class="actor-followers">{{ videoChannel.followersCount }} subscribers</div>
|
||||
<div i18n class="actor-followers">{{ videoChannel.followersCount }} subscribers</div>
|
||||
|
||||
<a [routerLink]="[ '/accounts', videoChannel.ownerBy ]" title="Go the owner account page" class="actor-owner">
|
||||
<span>Created by {{ videoChannel.ownerBy }}</span>
|
||||
<a [routerLink]="[ '/accounts', videoChannel.ownerBy ]" i18n-title title="Go the owner account page" class="actor-owner">
|
||||
<span i18n>Created by {{ videoChannel.ownerBy }}</span>
|
||||
<img [src]="videoChannel.ownerAvatarUrl" alt="Owner account avatar" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="links">
|
||||
<a routerLink="videos" routerLinkActive="active" class="title-page">Videos</a>
|
||||
<a i18n routerLink="videos" routerLinkActive="active" class="title-page">Videos</a>
|
||||
|
||||
<a routerLink="about" routerLinkActive="active" class="title-page">About</a>
|
||||
<a i18n routerLink="about" routerLinkActive="active" class="title-page">About</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="margin-content">
|
||||
<div class="title-page title-page-single">
|
||||
<div i18n class="title-page title-page-single">
|
||||
Welcome to the {{ instanceName }} instance
|
||||
</div>
|
||||
|
||||
|
@ -8,41 +8,41 @@
|
|||
</div>
|
||||
|
||||
<div class="description">
|
||||
<div class="section-title">Description</div>
|
||||
<div i18n class="section-title">Description</div>
|
||||
|
||||
<div [innerHTML]="descriptionHTML"></div>
|
||||
</div>
|
||||
|
||||
<div class="terms">
|
||||
<div class="section-title">Terms</div>
|
||||
<div i18n class="section-title">Terms</div>
|
||||
|
||||
<div [innerHTML]="termsHTML"></div>
|
||||
</div>
|
||||
|
||||
<div class="signup">
|
||||
<div class="section-title">Signup</div>
|
||||
<div i18n class="section-title">Signup</div>
|
||||
|
||||
<div *ngIf="isSignupAllowed">
|
||||
User registration is allowed and
|
||||
<ng-container i18n>User registration is allowed and</ng-container>
|
||||
|
||||
<ng-template [ngIf]="userVideoQuota !== -1">
|
||||
<ng-container i18n *ngIf="userVideoQuota !== -1">
|
||||
this instance provides a baseline quota of {{ userVideoQuota | bytes: 0 }} space for the videos of its users.
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
|
||||
<ng-template [ngIf]="userVideoQuota === -1">
|
||||
<ng-container i18n *ngIf="userVideoQuota === -1">
|
||||
this instance provides unlimited space for the videos of its users.
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div *ngIf="isSignupAllowed === false">
|
||||
<div i18n *ngIf="isSignupAllowed === false">
|
||||
User registration is currently not allowed.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="p2p-privacy">
|
||||
<div class="section-title">P2P & Privacy</div>
|
||||
<div i18n class="section-title">P2P & Privacy</div>
|
||||
|
||||
<p>
|
||||
<p i18n>
|
||||
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.
|
||||
If you want to keep your public IP address private, please use a VPN or Tor.
|
||||
</p>
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'
|
|||
import { ServerService } from '@app/core'
|
||||
import { MarkdownService } from '@app/videos/shared'
|
||||
import { NotificationsService } from 'angular2-notifications'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-about',
|
||||
|
@ -17,7 +18,8 @@ export class AboutComponent implements OnInit {
|
|||
constructor (
|
||||
private notificationsService: NotificationsService,
|
||||
private serverService: ServerService,
|
||||
private markdownService: MarkdownService
|
||||
private markdownService: MarkdownService,
|
||||
private i18n: I18n
|
||||
) {}
|
||||
|
||||
get instanceName () {
|
||||
|
@ -41,7 +43,7 @@ export class AboutComponent implements OnInit {
|
|||
this.termsHTML = this.markdownService.textMarkdownToHTML(res.instance.terms)
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error getting about from server', err)
|
||||
err => this.notificationsService.error(this.i18n('Error getting about from server'), err)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Observable, ReplaySubject, Subject, throwError as observableThrowError } from 'rxjs'
|
||||
import { catchError, map, mergeMap, tap, share } from 'rxjs/operators'
|
||||
import { catchError, map, mergeMap, share, tap } from 'rxjs/operators'
|
||||
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { Router } from '@angular/router'
|
||||
|
@ -13,6 +13,7 @@ import { AuthStatus } from './auth-status.model'
|
|||
import { AuthUser } from './auth-user.model'
|
||||
import { objectToUrlEncoded } from '@app/shared/misc/utils'
|
||||
import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
interface UserLoginWithUsername extends UserLogin {
|
||||
access_token: string
|
||||
|
@ -46,7 +47,8 @@ export class AuthService {
|
|||
private http: HttpClient,
|
||||
private notificationsService: NotificationsService,
|
||||
private restExtractor: RestExtractor,
|
||||
private router: Router
|
||||
private router: Router,
|
||||
private i18n: I18n
|
||||
) {
|
||||
this.loginChanged = new Subject<AuthStatus>()
|
||||
this.loginChangedSource = this.loginChanged.asObservable()
|
||||
|
@ -74,14 +76,15 @@ export class AuthService {
|
|||
let errorMessage = error.message
|
||||
|
||||
if (error.status === 403) {
|
||||
errorMessage = `Cannot retrieve OAuth Client credentials: ${error.text}. \n`
|
||||
errorMessage += 'Ensure you have correctly configured PeerTube (config/ directory), ' +
|
||||
'in particular the "webserver" section.'
|
||||
errorMessage = this.i18n('Cannot retrieve OAuth Client credentials: {{ errorText }}.\n', { errorText: error.text })
|
||||
errorMessage += this.i18n(
|
||||
'Ensure you have correctly configured PeerTube (config/ directory), in particular the "webserver" section.'
|
||||
)
|
||||
}
|
||||
|
||||
// We put a bigger timeout
|
||||
// This is an important message
|
||||
this.notificationsService.error('Error', errorMessage, { timeOut: 7000 })
|
||||
this.notificationsService.error(this.i18n('Error'), errorMessage, { timeOut: 7000 })
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -180,7 +183,7 @@ export class AuthService {
|
|||
this.router.navigate([ '/login' ])
|
||||
|
||||
return observableThrowError({
|
||||
error: 'You need to reconnect.'
|
||||
error: this.i18n('You need to reconnect.')
|
||||
})
|
||||
}),
|
||||
share()
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group inputs">
|
||||
<span class="action-button action-button-cancel" (click)="cancel()">
|
||||
<span i18n class="action-button action-button-cancel" (click)="cancel()">
|
||||
Cancel
|
||||
</span>
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Component, HostListener, OnInit, ViewChild } from '@angular/core'
|
|||
import { ModalDirective } from 'ngx-bootstrap/modal'
|
||||
|
||||
import { ConfirmService } from './confirm.service'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-confirm',
|
||||
|
@ -20,7 +21,10 @@ export class ConfirmComponent implements OnInit {
|
|||
inputValue = ''
|
||||
confirmButtonText = ''
|
||||
|
||||
constructor (private confirmService: ConfirmService) {
|
||||
constructor (
|
||||
private confirmService: ConfirmService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
// Empty
|
||||
}
|
||||
|
||||
|
@ -38,7 +42,7 @@ export class ConfirmComponent implements OnInit {
|
|||
this.inputLabel = inputLabel
|
||||
this.expectedInputValue = expectedInputValue
|
||||
|
||||
this.confirmButtonText = confirmButtonText || 'Confirm'
|
||||
this.confirmButtonText = confirmButtonText || this.i18n('Confirm')
|
||||
|
||||
this.showModal()
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<input
|
||||
type="text" id="search-video" name="search-video" placeholder="Search..."
|
||||
type="text" id="search-video" name="search-video" i18n-placeholder placeholder="Search..."
|
||||
[(ngModel)]="searchValue" (keyup.enter)="doSearch()"
|
||||
>
|
||||
<span (click)="doSearch()" class="icon icon-search"></span>
|
||||
|
||||
<a class="upload-button" routerLink="/videos/upload">
|
||||
<span class="icon icon-upload"></span>
|
||||
<span class="upload-button-label">Upload</span>
|
||||
<span i18n class="upload-button-label">Upload</span>
|
||||
</a>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="margin-content">
|
||||
<div class="title-page title-page-single">
|
||||
<div i18n class="title-page title-page-single">
|
||||
Login
|
||||
</div>
|
||||
|
||||
|
@ -8,21 +8,21 @@
|
|||
<form role="form" (ngSubmit)="login()" [formGroup]="form">
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<label for="username">User</label>
|
||||
<label i18n for="username">User</label>
|
||||
<input
|
||||
type="text" id="username" placeholder="Username or email address" required tabindex="1"
|
||||
type="text" id="username" i18n-placeholder placeholder="Username or email address" required tabindex="1"
|
||||
formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }"
|
||||
>
|
||||
<a *ngIf="signupAllowed === true" routerLink="/signup" class="create-an-account">
|
||||
<a i18n *ngIf="signupAllowed === true" routerLink="/signup" class="create-an-account">
|
||||
or create an account
|
||||
</a>
|
||||
|
||||
<a *ngIf="signupAllowed === false" href="https://joinpeertube.org/en/#getting-started" target="_blank" class="create-an-account">
|
||||
<a i18n *ngIf="signupAllowed === false" href="https://joinpeertube.org/en/#getting-started" target="_blank" class="create-an-account">
|
||||
or create an account on another instance
|
||||
</a>
|
||||
|
||||
<my-help
|
||||
*ngIf="signupAllowed === false" helpType="custom"
|
||||
*ngIf="signupAllowed === false" helpType="custom" i18n-customHtml
|
||||
customHtml="User registration is not allowed on this instance, but you can register on many others!"
|
||||
></my-help>
|
||||
</div>
|
||||
|
@ -33,13 +33,13 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<label i18n for="password">Password</label>
|
||||
<div>
|
||||
<input
|
||||
type="password" name="password" id="password" placeholder="Password" required tabindex="2"
|
||||
type="password" name="password" id="password" i18n-placeholder placeholder="Password" required tabindex="2"
|
||||
formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }"
|
||||
>
|
||||
<div class="forgot-password-button" (click)="openForgotPasswordModal()">I forgot my password</div>
|
||||
<div i18n class="forgot-password-button" (click)="openForgotPasswordModal()">I forgot my password</div>
|
||||
</div>
|
||||
<div *ngIf="formErrors.password" class="form-error">
|
||||
{{ formErrors.password }}
|
||||
|
@ -56,25 +56,25 @@
|
|||
|
||||
<div class="modal-header">
|
||||
<span class="close" aria-hidden="true" (click)="hideForgotPasswordModal()"></span>
|
||||
<h4 class="modal-title">Forgot your password</h4>
|
||||
<h4 i18n class="modal-title">Forgot your password</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="forgot-password-email">Email</label>
|
||||
<label i18n for="forgot-password-email">Email</label>
|
||||
<input
|
||||
type="email" id="forgot-password-email" placeholder="Email address" required
|
||||
type="email" id="forgot-password-email" i18n-placeholder placeholder="Email address" required
|
||||
[(ngModel)]="forgotPasswordEmail" #forgotPasswordEmailInput
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="form-group inputs">
|
||||
<span class="action-button action-button-cancel" (click)="hideForgotPasswordModal()">
|
||||
<span i18n class="action-button action-button-cancel" (click)="hideForgotPasswordModal()">
|
||||
Cancel
|
||||
</span>
|
||||
|
||||
<input
|
||||
type="submit" value="Send me an email to reset my password" class="action-button-submit"
|
||||
type="submit" i18n-value value="Send me an email to reset my password" class="action-button-submit"
|
||||
(click)="askResetPassword()" [disabled]="!forgotPasswordEmailInput.validity.valid"
|
||||
>
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,7 @@ import { NotificationsService } from 'angular2-notifications'
|
|||
import { ModalDirective } from 'ngx-bootstrap/modal'
|
||||
import { AuthService } from '../core'
|
||||
import { FormReactive } from '../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-login',
|
||||
|
@ -35,12 +36,15 @@ export class LoginComponent extends FormReactive implements OnInit {
|
|||
}
|
||||
forgotPasswordEmail = ''
|
||||
|
||||
constructor (private authService: AuthService,
|
||||
private userService: UserService,
|
||||
private serverService: ServerService,
|
||||
private redirectService: RedirectService,
|
||||
private notificationsService: NotificationsService,
|
||||
private formBuilder: FormBuilder) {
|
||||
constructor (
|
||||
private authService: AuthService,
|
||||
private userService: UserService,
|
||||
private serverService: ServerService,
|
||||
private redirectService: RedirectService,
|
||||
private notificationsService: NotificationsService,
|
||||
private formBuilder: FormBuilder,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
|
@ -78,12 +82,15 @@ export class LoginComponent extends FormReactive implements OnInit {
|
|||
this.userService.askResetPassword(this.forgotPasswordEmail)
|
||||
.subscribe(
|
||||
res => {
|
||||
const message = `An email with the reset password instructions will be sent to ${this.forgotPasswordEmail}.`
|
||||
this.notificationsService.success('Success', message)
|
||||
const message = this.i18n(
|
||||
'An email with the reset password instructions will be sent to {{ email }}.',
|
||||
{ email: this.forgotPasswordEmail }
|
||||
)
|
||||
this.notificationsService.success(this.i18n('Success'), message)
|
||||
this.hideForgotPasswordModal()
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
My public profile
|
||||
</a>
|
||||
|
||||
<a routerLink="/my-account/settings" class="dropdown-item" title="My settings">
|
||||
<a i18n routerLink="/my-account/settings" class="dropdown-item" title="My settings">
|
||||
My settings
|
||||
</a>
|
||||
|
||||
<a (click)="logout($event)" class="dropdown-item" title="Log out" href="#">
|
||||
<a i18n (click)="logout($event)" class="dropdown-item" title="Log out" href="#">
|
||||
Log out
|
||||
</a>
|
||||
</li>
|
||||
|
@ -31,26 +31,26 @@
|
|||
</div>
|
||||
|
||||
<div *ngIf="!isLoggedIn" class="button-block">
|
||||
<a routerLink="/login" class="login-button">Login</a>
|
||||
<a *ngIf="isRegistrationAllowed()" routerLink="/signup" class="create-account-button">Create an account</a>
|
||||
<a i18n routerLink="/login" class="login-button">Login</a>
|
||||
<a i18n *ngIf="isRegistrationAllowed()" routerLink="/signup" class="create-account-button">Create an account</a>
|
||||
</div>
|
||||
|
||||
<div class="panel-block">
|
||||
<div class="block-title">Videos</div>
|
||||
<div i18n class="block-title">Videos</div>
|
||||
|
||||
<a routerLink="/videos/trending" routerLinkActive="active">
|
||||
<span class="icon icon-videos-trending"></span>
|
||||
Trending
|
||||
<ng-container i18n>Trending</ng-container>
|
||||
</a>
|
||||
|
||||
<a routerLink="/videos/recently-added" routerLinkActive="active">
|
||||
<span class="icon icon-videos-recently-added"></span>
|
||||
Recently added
|
||||
<ng-container i18n>Recently added</ng-container>
|
||||
</a>
|
||||
|
||||
<a routerLink="/videos/local" routerLinkActive="active">
|
||||
<span class="icon icon-videos-local"></span>
|
||||
Local
|
||||
<ng-container i18n>Local</ng-container>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -59,12 +59,12 @@
|
|||
|
||||
<a *ngIf="userHasAdminAccess" [routerLink]="getFirstAdminRouteAvailable()" routerLinkActive="active">
|
||||
<span class="icon icon-administration"></span>
|
||||
Administration
|
||||
<ng-container i18n>Administration</ng-container>
|
||||
</a>
|
||||
|
||||
<a routerLink="/about" routerLinkActive="active">
|
||||
<span class="icon icon-about"></span>
|
||||
About
|
||||
<ng-container i18n>About</ng-container>
|
||||
</a>
|
||||
</div>
|
||||
</menu>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, OnInit } from '@angular/core'
|
||||
import { Router } from '@angular/router'
|
||||
import { UserRight } from '../../../../shared/models/users/user-right.enum'
|
||||
import { AuthService, AuthStatus, ServerService } from '../core'
|
||||
import { AuthService, AuthStatus, RedirectService, ServerService } from '../core'
|
||||
import { User } from '../shared/users/user.model'
|
||||
|
||||
@Component({
|
||||
|
@ -24,7 +24,7 @@ export class MenuComponent implements OnInit {
|
|||
constructor (
|
||||
private authService: AuthService,
|
||||
private serverService: ServerService,
|
||||
private router: Router
|
||||
private redirectService: RedirectService
|
||||
) {}
|
||||
|
||||
ngOnInit () {
|
||||
|
@ -87,7 +87,7 @@ export class MenuComponent implements OnInit {
|
|||
|
||||
this.authService.logout()
|
||||
// Redirect to home page
|
||||
this.router.navigate(['/videos/list'])
|
||||
this.redirectService.redirectToHomepage()
|
||||
}
|
||||
|
||||
private computeIsUserHasAdminAccess () {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<div class="margin-content">
|
||||
<div class="title-page title-page-single">
|
||||
<div i18n class="title-page title-page-single">
|
||||
Reset my password
|
||||
</div>
|
||||
|
||||
<form role="form" (ngSubmit)="resetPassword()" [formGroup]="form">
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<label i18n for="password">Password</label>
|
||||
<input
|
||||
type="password" name="password" id="password" placeholder="Password" required
|
||||
type="password" name="password" id="password" i18n-placeholder placeholder="Password" required
|
||||
formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }"
|
||||
>
|
||||
<div *ngIf="formErrors.password" class="form-error">
|
||||
|
@ -16,9 +16,9 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password-confirm">Confirm password</label>
|
||||
<label i18n for="password-confirm">Confirm password</label>
|
||||
<input
|
||||
type="password" name="password-confirm" id="password-confirm" placeholder="Confirmed password" required
|
||||
type="password" name="password-confirm" id="password-confirm" i18n-placeholder placeholder="Confirmed password" required
|
||||
formControlName="password-confirm" [ngClass]="{ 'input-error': formErrors['password-confirm'] }"
|
||||
>
|
||||
<div *ngIf="formErrors['password-confirm']" class="form-error">
|
||||
|
@ -26,6 +26,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Reset my password" [disabled]="!form.valid && isConfirmedPasswordValid()">
|
||||
<input type="submit" i18n-value value="Reset my password" [disabled]="!form.valid && isConfirmedPasswordValid()">
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { USER_PASSWORD, UserService } from '@app/shared'
|
|||
import { NotificationsService } from 'angular2-notifications'
|
||||
import { AuthService } from '../core'
|
||||
import { FormReactive } from '../shared'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-login',
|
||||
|
@ -34,7 +35,8 @@ export class ResetPasswordComponent extends FormReactive implements OnInit {
|
|||
private notificationsService: NotificationsService,
|
||||
private formBuilder: FormBuilder,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute
|
||||
private route: ActivatedRoute,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -55,7 +57,7 @@ export class ResetPasswordComponent extends FormReactive implements OnInit {
|
|||
this.verificationString = this.route.snapshot.queryParams['verificationString']
|
||||
|
||||
if (!this.userId || !this.verificationString) {
|
||||
this.notificationsService.error('Error', 'Unable to find user id or verification string.')
|
||||
this.notificationsService.error(this.i18n('Error'), this.i18n('Unable to find user id or verification string.'))
|
||||
this.router.navigate([ '/' ])
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +66,7 @@ export class ResetPasswordComponent extends FormReactive implements OnInit {
|
|||
this.userService.resetPassword(this.userId, this.verificationString, this.form.value.password)
|
||||
.subscribe(
|
||||
() => {
|
||||
this.notificationsService.success('Success', 'Your password has been successfully reset!')
|
||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Your password has been successfully reset!'))
|
||||
this.router.navigate([ '/login' ])
|
||||
},
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</textarea>
|
||||
|
||||
<tabset *ngIf="arePreviewsDisplayed()" class="previews">
|
||||
<tab *ngIf="truncate !== undefined" heading="Truncated preview" [innerHTML]="truncatedPreviewHTML"></tab>
|
||||
<tab heading="Complete preview" [innerHTML]="previewHTML"></tab>
|
||||
<tab *ngIf="truncate !== undefined" i18n-heading heading="Truncated preview" [innerHTML]="truncatedPreviewHTML"></tab>
|
||||
<tab i18n-heading heading="Complete preview" [innerHTML]="previewHTML"></tab>
|
||||
</tabset>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core'
|
|||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
|
||||
import { isInSmallView } from '@app/shared/misc/utils'
|
||||
import { MarkdownService } from '@app/videos/shared'
|
||||
import { Subject } from 'rxjs'
|
||||
import { Subject } from 'rxjs/Subject'
|
||||
import truncate from 'lodash-es/truncate'
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Injectable } from '@angular/core'
|
|||
import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot } from '@angular/router'
|
||||
import { Observable } from 'rxjs'
|
||||
import { ConfirmService } from '../../core/index'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
export interface CanComponentDeactivate {
|
||||
canDeactivate: () => { text?: string, canDeactivate: Observable<boolean> | boolean }
|
||||
|
@ -9,7 +10,10 @@ export interface CanComponentDeactivate {
|
|||
|
||||
@Injectable()
|
||||
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
|
||||
constructor (private confirmService: ConfirmService) { }
|
||||
constructor (
|
||||
private confirmService: ConfirmService,
|
||||
private i18n: I18n
|
||||
) { }
|
||||
|
||||
canDeactivate (component: CanComponentDeactivate,
|
||||
currentRoute: ActivatedRouteSnapshot,
|
||||
|
@ -17,11 +21,11 @@ export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate>
|
|||
nextState: RouterStateSnapshot
|
||||
) {
|
||||
const result = component.canDeactivate()
|
||||
const text = result.text || 'All unsaved data will be lost, are you sure you want to leave this page?'
|
||||
const text = result.text || this.i18n('All unsaved data will be lost, are you sure you want to leave this page?')
|
||||
|
||||
return result.canDeactivate || this.confirmService.confirm(
|
||||
text,
|
||||
'Warning'
|
||||
this.i18n('Warning')
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<a class="action-button action-button-edit" [routerLink]="routerLink" title="Edit">
|
||||
<span class="icon icon-edit"></span>
|
||||
<span class="button-label">Edit</span>
|
||||
<span i18n class="button-label">Edit</span>
|
||||
</a>
|
||||
|
|
|
@ -1,36 +1,39 @@
|
|||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
// Thanks: https://stackoverflow.com/questions/3177836/how-to-format-time-since-xxx-e-g-4-minutes-ago-similar-to-stack-exchange-site
|
||||
@Pipe({ name: 'myFromNow' })
|
||||
export class FromNowPipe implements PipeTransform {
|
||||
|
||||
constructor (private i18n: I18n) { }
|
||||
|
||||
transform (value: number) {
|
||||
const seconds = Math.floor((Date.now() - value) / 1000)
|
||||
|
||||
let interval = Math.floor(seconds / 31536000)
|
||||
if (interval > 1) {
|
||||
return interval + ' years ago'
|
||||
return this.i18n('{{ interval }} years ago', { interval })
|
||||
}
|
||||
|
||||
interval = Math.floor(seconds / 2592000)
|
||||
if (interval > 1) return interval + ' months ago'
|
||||
if (interval === 1) return interval + ' month ago'
|
||||
if (interval > 1) return this.i18n('{{ interval }} months ago', { interval })
|
||||
if (interval === 1) return this.i18n('{{ interval }} month ago', { interval })
|
||||
|
||||
interval = Math.floor(seconds / 604800)
|
||||
if (interval > 1) return interval + ' weeks ago'
|
||||
if (interval === 1) return interval + ' week ago'
|
||||
if (interval > 1) return this.i18n('{{ interval }} weeks ago', { interval })
|
||||
if (interval === 1) return this.i18n('{{ interval }} week ago', { interval })
|
||||
|
||||
interval = Math.floor(seconds / 86400)
|
||||
if (interval > 1) return interval + ' days ago'
|
||||
if (interval === 1) return interval + ' day ago'
|
||||
if (interval > 1) return this.i18n('{{ interval }} days ago', { interval })
|
||||
if (interval === 1) return this.i18n('{{ interval }} day ago', { interval })
|
||||
|
||||
interval = Math.floor(seconds / 3600)
|
||||
if (interval > 1) return interval + ' hours ago'
|
||||
if (interval === 1) return interval + ' hour ago'
|
||||
if (interval > 1) return this.i18n('{{ interval }} hours ago', { interval })
|
||||
if (interval === 1) return this.i18n('{{ interval }} hour ago', { interval })
|
||||
|
||||
interval = Math.floor(seconds / 60)
|
||||
if (interval >= 1) return interval + ' min ago'
|
||||
if (interval >= 1) return this.i18n('{{ interval }} min ago', { interval })
|
||||
|
||||
return Math.floor(seconds) + ' sec ago'
|
||||
return this.i18n('{{ interval }} sec ago', { interval: Math.floor(seconds) })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<span
|
||||
class="help-tooltip-button"
|
||||
title="Get help"
|
||||
i18n-title
|
||||
[popover]="tooltipTemplate"
|
||||
[placement]="tooltipPlacement"
|
||||
[outsideClick]="true"
|
||||
|
|
|
@ -3,11 +3,15 @@ import { Injectable } from '@angular/core'
|
|||
import { dateToHuman } from '@app/shared/misc/utils'
|
||||
import { ResultList } from '../../../../../shared'
|
||||
import { Router } from '@angular/router'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Injectable()
|
||||
export class RestExtractor {
|
||||
|
||||
constructor (private router: Router) {
|
||||
constructor (
|
||||
private router: Router,
|
||||
private i18n: I18n
|
||||
) {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
@ -60,17 +64,19 @@ export class RestExtractor {
|
|||
} else if (err.error && err.error.error) {
|
||||
errorMessage = err.error.error
|
||||
} else if (err.status === 413) {
|
||||
errorMessage = 'Request is too large for the server. Please contact you administrator if you want to increase the limit size.'
|
||||
errorMessage = this.i18n(
|
||||
'Request is too large for the server. Please contact you administrator if you want to increase the limit size.'
|
||||
)
|
||||
} else if (err.status === 429) {
|
||||
const secondsLeft = err.headers.get('retry-after')
|
||||
if (secondsLeft) {
|
||||
const minutesLeft = Math.floor(parseInt(secondsLeft, 10) / 60)
|
||||
errorMessage = 'Too many attempts, please try again after ' + minutesLeft + ' minutes.'
|
||||
errorMessage = this.i18n('Too many attempts, please try again after {{ minutesLeft }} minutes.', { minutesLeft })
|
||||
} else {
|
||||
errorMessage = 'Too many attempts, please try again later.'
|
||||
errorMessage = this.i18n('Too many attempts, please try again later.')
|
||||
}
|
||||
} else if (err.status === 500) {
|
||||
errorMessage = 'Server error. Please retry later.'
|
||||
errorMessage = this.i18n('Server error. Please retry later.')
|
||||
}
|
||||
|
||||
errorMessage = errorMessage ? errorMessage : 'Unknown error.'
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
</div>
|
||||
<my-video-feed [syndicationItems]="syndicationItems"></my-video-feed>
|
||||
|
||||
<div *ngIf="pagination.totalItems === 0">No results.</div>
|
||||
<div i18n *ngIf="pagination.totalItems === 0">No results.</div>
|
||||
<div
|
||||
myInfiniteScroller
|
||||
[pageHeight]="pageHeight"
|
||||
|
|
|
@ -10,6 +10,7 @@ import { AuthService } from '../../core/auth'
|
|||
import { ComponentPagination } from '../rest/component-pagination.model'
|
||||
import { VideoSortField } from './sort-field.type'
|
||||
import { Video } from './video.model'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
export abstract class AbstractVideoList implements OnInit, OnDestroy {
|
||||
private static LINES_PER_PAGE = 4
|
||||
|
@ -40,6 +41,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
|
|||
protected abstract authService: AuthService
|
||||
protected abstract router: Router
|
||||
protected abstract route: ActivatedRoute
|
||||
protected abstract i18n: I18n
|
||||
protected abstract location: Location
|
||||
protected abstract currentRoute: string
|
||||
abstract titlePage: string
|
||||
|
@ -124,7 +126,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
|
|||
},
|
||||
error => {
|
||||
this.loadingPage[page] = false
|
||||
this.notificationsService.error('Error', error.message)
|
||||
this.notificationsService.error(this.i18n('Error'), error.message)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
{{ video.name }}
|
||||
</a>
|
||||
|
||||
<span class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
|
||||
<span i18n class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
|
||||
<a class="video-miniature-account" [routerLink]="[ '/accounts', video.by ]">{{ video.by }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<a
|
||||
[routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name"
|
||||
class="video-thumbnail"
|
||||
class="video-thumbnail"
|
||||
>
|
||||
<img [attr.src]="getImageUrl()" [ngClass]="{ 'blur-filter': nsfw }" />
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<div class="margin-content">
|
||||
|
||||
<div class="title-page title-page-single">
|
||||
<div i18n class="title-page title-page-single">
|
||||
Create an account
|
||||
</div>
|
||||
|
||||
<div class="initial-user-quota">
|
||||
<span class="initial-user-quota-label">Initial video quota:</span>
|
||||
<span i18n class="initial-user-quota-label">Initial video quota:</span>
|
||||
|
||||
<span *ngIf="initialUserVideoQuota !== -1">
|
||||
{{ initialUserVideoQuota | bytes: 0 }}
|
||||
|
@ -13,18 +13,18 @@
|
|||
<my-help helpType="custom" [customHtml]="quotaHelpIndication"></my-help>
|
||||
</span>
|
||||
|
||||
<ng-template [ngIf]="initialUserVideoQuota === -1">
|
||||
<ng-container i18n *ngIf="initialUserVideoQuota === -1">
|
||||
Unlimited
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
|
||||
|
||||
<form role="form" (ngSubmit)="signup()" [formGroup]="form">
|
||||
<div class="form-group">
|
||||
<label for="username">Username</label>
|
||||
<label for="username" i18n>Username</label>
|
||||
<input
|
||||
type="text" id="username" placeholder="Username"
|
||||
type="text" id="username" i18n-placeholder placeholder="Username"
|
||||
formControlName="username" [ngClass]="{ 'input-error': formErrors['username'] }"
|
||||
>
|
||||
<div *ngIf="formErrors.username" class="form-error">
|
||||
|
@ -33,9 +33,9 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">Email</label>
|
||||
<label for="email" i18n>Email</label>
|
||||
<input
|
||||
type="text" id="email" placeholder="Email"
|
||||
type="text" id="email" i18n-placeholder placeholder="Email"
|
||||
formControlName="email" [ngClass]="{ 'input-error': formErrors['email'] }"
|
||||
>
|
||||
<div *ngIf="formErrors.email" class="form-error">
|
||||
|
@ -44,9 +44,9 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<label for="password" i18n>Password</label>
|
||||
<input
|
||||
type="password" id="password" placeholder="Password"
|
||||
type="password" id="password" i18n-placeholder placeholder="Password"
|
||||
formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }"
|
||||
>
|
||||
<div *ngIf="formErrors.password" class="form-error">
|
||||
|
@ -54,7 +54,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<input type="submit" value="Signup" [disabled]="!form.valid">
|
||||
<input type="submit" i18n-value value="Signup" [disabled]="!form.valid">
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -6,6 +6,8 @@ import { ServerService } from '@app/core/server'
|
|||
import { NotificationsService } from 'angular2-notifications'
|
||||
import { UserCreate } from '../../../../shared'
|
||||
import { FormReactive, USER_EMAIL, USER_PASSWORD, USER_USERNAME, UserService } from '../shared'
|
||||
import { RedirectService } from '@app/core'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-signup',
|
||||
|
@ -45,7 +47,9 @@ export class SignupComponent extends FormReactive implements OnInit {
|
|||
private router: Router,
|
||||
private notificationsService: NotificationsService,
|
||||
private userService: UserService,
|
||||
private serverService: ServerService
|
||||
private redirectService: RedirectService,
|
||||
private serverService: ServerService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -78,8 +82,11 @@ export class SignupComponent extends FormReactive implements OnInit {
|
|||
|
||||
this.userService.signup(userCreate).subscribe(
|
||||
() => {
|
||||
this.notificationsService.success('Success', `Registration for ${userCreate.username} complete.`)
|
||||
this.router.navigate([ '/videos/list' ])
|
||||
this.notificationsService.success(
|
||||
this.i18n('Success'),
|
||||
this.i18n('Registration for {{ username }} complete.', { username: userCreate.username})
|
||||
)
|
||||
this.redirectService.redirectToHomepage()
|
||||
},
|
||||
|
||||
err => this.error = err.message
|
||||
|
@ -99,9 +106,9 @@ export class SignupComponent extends FormReactive implements OnInit {
|
|||
const normalSeconds = initialUserVideoQuotaBit / (1.5 * 1000 * 1000)
|
||||
|
||||
const lines = [
|
||||
SignupComponent.getApproximateTime(fullHdSeconds) + ' of full HD videos',
|
||||
SignupComponent.getApproximateTime(hdSeconds) + ' of HD videos',
|
||||
SignupComponent.getApproximateTime(normalSeconds) + ' of average quality videos'
|
||||
this.i18n('{{ seconds }} of full HD videos', { seconds: SignupComponent.getApproximateTime(fullHdSeconds) }),
|
||||
this.i18n('{{ seconds }} of HD videos', { seconds: SignupComponent.getApproximateTime(hdSeconds) }),
|
||||
this.i18n('{{ seconds }} of average quality videos', { seconds: SignupComponent.getApproximateTime(normalSeconds) })
|
||||
]
|
||||
|
||||
this.quotaHelpIndication = lines.join('<br />')
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<tab heading="Basic info">
|
||||
<div class="col-md-8">
|
||||
<div class="form-group">
|
||||
<label for="name">Title</label>
|
||||
<label i18n for="name">Title</label>
|
||||
<input type="text" id="name" formControlName="name" />
|
||||
<div *ngIf="formErrors.name" class="form-error">
|
||||
{{ formErrors.name }}
|
||||
|
@ -12,7 +12,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="label-tags">Tags</label> <span>(press Enter to add)</span>
|
||||
<label i18n class="label-tags">Tags</label> <span i18n>(press Enter to add)</span>
|
||||
<tag-input
|
||||
[validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
|
||||
formControlName="tags" maxItems="5" modelAsStrings="true"
|
||||
|
@ -20,8 +20,8 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="description">Description</label>
|
||||
<my-help helpType="markdownText" preHtml="Video descriptions are truncated by default and require manual action to expand them."></my-help>
|
||||
<label i18n for="description">Description</label>
|
||||
<my-help helpType="markdownText" i18n-preHtml preHtml="Video descriptions are truncated by default and require manual action to expand them."></my-help>
|
||||
<my-markdown-textarea truncate="250" formControlName="description"></my-markdown-textarea>
|
||||
|
||||
<div *ngIf="formErrors.description" class="form-error">
|
||||
|
@ -32,7 +32,7 @@
|
|||
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label>Channel</label>
|
||||
<label i18n>Channel</label>
|
||||
<div class="peertube-select-container">
|
||||
<select formControlName="channelId">
|
||||
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
|
||||
|
@ -41,7 +41,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="category">Category</label>
|
||||
<label i18n for="category">Category</label>
|
||||
<div class="peertube-select-container">
|
||||
<select id="category" formControlName="category">
|
||||
<option></option>
|
||||
|
@ -55,7 +55,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="licence">Licence</label>
|
||||
<label i18n for="licence">Licence</label>
|
||||
<div class="peertube-select-container">
|
||||
<select id="licence" formControlName="licence">
|
||||
<option></option>
|
||||
|
@ -69,7 +69,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="language">Language</label>
|
||||
<label i18n for="language">Language</label>
|
||||
<div class="peertube-select-container">
|
||||
<select id="language" formControlName="language">
|
||||
<option></option>
|
||||
|
@ -83,7 +83,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="privacy">Privacy</label>
|
||||
<label i18n for="privacy">Privacy</label>
|
||||
<div class="peertube-select-container">
|
||||
<select id="privacy" formControlName="privacy">
|
||||
<option></option>
|
||||
|
@ -99,14 +99,14 @@
|
|||
<div class="form-group form-group-checkbox">
|
||||
<input type="checkbox" id="nsfw" formControlName="nsfw" />
|
||||
<label for="nsfw"></label>
|
||||
<label for="nsfw">This video contains mature or explicit content</label>
|
||||
<my-help tooltipPlacement="top" helpType="custom" customHtml="Some instances do not list NSFW videos by default."></my-help>
|
||||
<label i18n for="nsfw">This video contains mature or explicit content</label>
|
||||
<my-help tooltipPlacement="top" helpType="custom" i18n-customHtml customHtml="Some instances do not list NSFW videos by default."></my-help>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-checkbox">
|
||||
<input type="checkbox" id="commentsEnabled" formControlName="commentsEnabled" />
|
||||
<label for="commentsEnabled"></label>
|
||||
<label for="commentsEnabled">Enable video comments</label>
|
||||
<label i18n for="commentsEnabled">Enable video comments</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -116,24 +116,24 @@
|
|||
<div class="col-md-12 advanced-settings">
|
||||
<div class="form-group">
|
||||
<my-video-image
|
||||
inputLabel="Upload thumbnail" inputName="thumbnailfile" formControlName="thumbnailfile"
|
||||
i18n-inputLabel inputLabel="Upload thumbnail" inputName="thumbnailfile" formControlName="thumbnailfile"
|
||||
previewWidth="200px" previewHeight="110px"
|
||||
></my-video-image>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<my-video-image
|
||||
inputLabel="Upload preview" inputName="previewfile" formControlName="previewfile"
|
||||
i18n-inputLabel inputLabel="Upload preview" inputName="previewfile" formControlName="previewfile"
|
||||
previewWidth="360px" previewHeight="200px"
|
||||
></my-video-image>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="support">Support</label>
|
||||
<my-help helpType="markdownEnhanced" preHtml="Short text to tell people how they can support you (membership platform...)."></my-help>
|
||||
<label i18n for="support">Support</label>
|
||||
<my-help helpType="markdownEnhanced" i18n-preHtml preHtml="Short text to tell people how they can support you (membership platform...)."></my-help>
|
||||
<my-markdown-textarea
|
||||
id="support" formControlName="support" textareaWidth="500px" [previewColumn]="true" markdownType="enhanced"
|
||||
[classes]="{ 'input-error': formErrors['support'] }"
|
||||
id="support" formControlName="support" textareaWidth="500px" [previewColumn]="true" markdownType="enhanced"
|
||||
[classes]="{ 'input-error': formErrors['support'] }"
|
||||
></my-markdown-textarea>
|
||||
<div *ngIf="formErrors.support" class="form-error">
|
||||
{{ formErrors.support }}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(change)="fileChange($event)"
|
||||
/>
|
||||
</div>
|
||||
<div class="image-constraints">(extensions: {{ videoImageExtensions }}, max size: {{ maxVideoImageSize | bytes }})</div>
|
||||
<div i18n class="image-constraints">(extensions: {{ videoImageExtensions }}, max size: {{ maxVideoImageSize | bytes }})</div>
|
||||
</div>
|
||||
|
||||
<img *ngIf="imageSrc" [ngStyle]="{ width: previewWidth, height: previewHeight }" [src]="imageSrc" class="preview" />
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="margin-content">
|
||||
<div class="title-page title-page-single">
|
||||
<ng-template [ngIf]="!videoFileName">Upload your video</ng-template>
|
||||
<ng-template [ngIf]="videoFileName">Upload {{ videoFileName }}</ng-template>
|
||||
<ng-container *ngIf="!videoFileName" i18n>Upload your video</ng-container>
|
||||
<ng-container *ngIf="videoFileName" i18n>Upload {{ videoFileName }}</ng-container>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!isUploadingVideo" class="upload-video-container">
|
||||
|
@ -9,12 +9,12 @@
|
|||
<div class="icon icon-upload"></div>
|
||||
|
||||
<div class="button-file">
|
||||
<span>Select the file to upload</span>
|
||||
<span i18n>Select the file to upload</span>
|
||||
<input #videofileInput type="file" name="videofile" id="videofile" [accept]="videoExtensions" (change)="fileChange()" />
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-channel">
|
||||
<label for="first-step-channel">Channel</label>
|
||||
<label i18n for="first-step-channel">Channel</label>
|
||||
<div class="peertube-select-container">
|
||||
<select id="first-step-channel" [(ngModel)]="firstStepChannelId">
|
||||
<option *ngFor="let channel of userVideoChannels" [value]="channel.id">{{ channel.label }}</option>
|
||||
|
@ -23,7 +23,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="first-step-privacy">Privacy</label>
|
||||
<label i18n for="first-step-privacy">Privacy</label>
|
||||
<div class="peertube-select-container">
|
||||
<select id="first-step-privacy" [(ngModel)]="firstStepPrivacyId">
|
||||
<option *ngFor="let privacy of videoPrivacies" [value]="privacy.id">{{ privacy.label }}</option>
|
||||
|
@ -49,14 +49,14 @@
|
|||
></my-video-edit>
|
||||
|
||||
<div class="submit-container">
|
||||
<div *ngIf="videoUploaded === false" class="message-submit">Publish will be available when upload is finished</div>
|
||||
<div i18n *ngIf="videoUploaded === false" class="message-submit">Publish will be available when upload is finished</div>
|
||||
|
||||
<div class="submit-button"
|
||||
(click)="updateSecondStep()"
|
||||
[ngClass]="{ disabled: !form.valid || isUpdatingVideo === true || videoUploaded !== true }"
|
||||
>
|
||||
<span class="icon icon-validate"></span>
|
||||
<input type="button" value="Publish" />
|
||||
<input type="button" i18n-value value="Publish" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -15,6 +15,7 @@ import { ValidatorMessage } from '../../shared/forms/form-validators/validator-m
|
|||
import { populateAsyncUserVideoChannels } from '../../shared/misc/utils'
|
||||
import { VideoEdit } from '../../shared/video/video-edit.model'
|
||||
import { VideoService } from '../../shared/video/video.service'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-videos-add',
|
||||
|
@ -56,7 +57,8 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
|
|||
private userService: UserService,
|
||||
private serverService: ServerService,
|
||||
private videoService: VideoService,
|
||||
private loadingBar: LoadingBarService
|
||||
private loadingBar: LoadingBarService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -99,10 +101,11 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
|
|||
let text = ''
|
||||
|
||||
if (this.videoUploaded === true) {
|
||||
text = 'Your video was uploaded in your account and is private.' +
|
||||
' But associated data (tags, description...) will be lost, are you sure you want to leave this page?'
|
||||
// FIXME: cannot concatenate strings inside i18n service :/
|
||||
text = this.i18n('Your video was uploaded in your account and is private.') +
|
||||
this.i18n('But associated data (tags, description...) will be lost, are you sure you want to leave this page?')
|
||||
} else {
|
||||
text = 'Your video is not uploaded yet, are you sure you want to leave this page?'
|
||||
text = this.i18n('Your video is not uploaded yet, are you sure you want to leave this page?')
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -127,7 +130,7 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
|
|||
this.isUploadingVideo = false
|
||||
this.videoUploadPercents = 0
|
||||
this.videoUploadObservable = null
|
||||
this.notificationsService.info('Info', 'Upload cancelled')
|
||||
this.notificationsService.info(this.i18n('Info'), this.i18n('Upload cancelled'))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,7 +140,7 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
|
|||
|
||||
// Cannot upload videos > 4GB for now
|
||||
if (videofile.size > 4 * 1024 * 1024 * 1024) {
|
||||
this.notificationsService.error('Error', 'We are sorry but PeerTube cannot handle videos > 4GB')
|
||||
this.notificationsService.error(this.i18n('Error'), this.i18n('We are sorry but PeerTube cannot handle videos > 4GB'))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -145,11 +148,15 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
|
|||
if (videoQuota !== -1 && (this.userVideoQuotaUsed + videofile.size) > videoQuota) {
|
||||
const bytePipes = new BytesPipe()
|
||||
|
||||
const msg = 'Your video quota is exceeded with this video ' +
|
||||
`(video size: ${bytePipes.transform(videofile.size, 0)}, ` +
|
||||
`used: ${bytePipes.transform(this.userVideoQuotaUsed, 0)}, ` +
|
||||
`quota: ${bytePipes.transform(videoQuota, 0)})`
|
||||
this.notificationsService.error('Error', msg)
|
||||
const msg = this.i18n(
|
||||
'Your video quota is exceeded with this video (video size: {{ videoSize }}, used: {{ videoQuotaUsed }}, quota: {{ videoQuota }})',
|
||||
{
|
||||
videoSize: bytePipes.transform(videofile.size, 0),
|
||||
videoQuotaUsed: bytePipes.transform(this.userVideoQuotaUsed, 0),
|
||||
videoQuota: bytePipes.transform(videoQuota, 0)
|
||||
}
|
||||
)
|
||||
this.notificationsService.error(this.i18n('Error'), msg)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -192,8 +199,6 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
|
|||
if (event.type === HttpEventType.UploadProgress) {
|
||||
this.videoUploadPercents = Math.round(100 * event.loaded / event.total)
|
||||
} else if (event instanceof HttpResponse) {
|
||||
console.log('Video uploaded.')
|
||||
|
||||
this.videoUploaded = true
|
||||
|
||||
this.videoUploadedIds = event.body.video
|
||||
|
@ -207,7 +212,7 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
|
|||
this.isUploadingVideo = false
|
||||
this.videoUploadPercents = 0
|
||||
this.videoUploadObservable = null
|
||||
this.notificationsService.error('Error', err.message)
|
||||
this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -231,13 +236,13 @@ export class VideoAddComponent extends FormReactive implements OnInit, OnDestroy
|
|||
this.isUploadingVideo = false
|
||||
this.loadingBar.complete()
|
||||
|
||||
this.notificationsService.success('Success', 'Video published.')
|
||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Video published.'))
|
||||
this.router.navigate([ '/videos/watch', video.uuid ])
|
||||
},
|
||||
|
||||
err => {
|
||||
this.isUpdatingVideo = false
|
||||
this.notificationsService.error('Error', err.message)
|
||||
this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
console.error(err)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="margin-content">
|
||||
<div class="title-page title-page-single">
|
||||
<div i18n class="title-page title-page-single">
|
||||
Update {{ video?.name }}
|
||||
</div>
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
|||
<div class="submit-container">
|
||||
<div class="submit-button" (click)="update()" [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true }">
|
||||
<span class="icon icon-validate"></span>
|
||||
<input type="button" value="Update" />
|
||||
<input type="button" i18n-value value="Update" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -12,6 +12,7 @@ import { ValidatorMessage } from '../../shared/forms/form-validators/validator-m
|
|||
import { VideoEdit } from '../../shared/video/video-edit.model'
|
||||
import { VideoService } from '../../shared/video/video.service'
|
||||
import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-videos-update',
|
||||
|
@ -37,7 +38,8 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
|||
private videoService: VideoService,
|
||||
private authService: AuthService,
|
||||
private loadingBar: LoadingBarService,
|
||||
private videoChannelService: VideoChannelService
|
||||
private videoChannelService: VideoChannelService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -91,7 +93,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
|||
|
||||
err => {
|
||||
console.error(err)
|
||||
this.notificationsService.error('Error', err.message)
|
||||
this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -116,13 +118,13 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
|||
() => {
|
||||
this.isUpdatingVideo = false
|
||||
this.loadingBar.complete()
|
||||
this.notificationsService.success('Success', 'Video updated.')
|
||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Video updated.'))
|
||||
this.router.navigate([ '/videos/watch', this.video.uuid ])
|
||||
},
|
||||
|
||||
err => {
|
||||
this.isUpdatingVideo = false
|
||||
this.notificationsService.error('Error', err.message)
|
||||
this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
console.error(err)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<img [src]="user.accountAvatarUrl" alt="Avatar" />
|
||||
|
||||
<div class="form-group">
|
||||
<textarea placeholder="Add comment..." formControlName="text" [ngClass]="{ 'input-error': formErrors['text'] }"
|
||||
<textarea i18n-placeholder placeholder="Add comment..." formControlName="text" [ngClass]="{ 'input-error': formErrors['text'] }"
|
||||
(keyup.control.enter)="onValidKey()" (keyup.meta.enter)="onValidKey()" #textarea>
|
||||
|
||||
</textarea>
|
||||
|
@ -14,7 +14,7 @@
|
|||
</div>
|
||||
|
||||
<div class="submit-comment">
|
||||
<button *ngIf="isAddButtonDisplayed()" [ngClass]="{ disabled: !form.valid }">
|
||||
<button *ngIf="isAddButtonDisplayed()" [ngClass]="{ disabled: !form.valid }" i18n>
|
||||
Post comment
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -9,6 +9,7 @@ import { User } from '../../../shared/users'
|
|||
import { Video } from '../../../shared/video/video.model'
|
||||
import { VideoComment } from './video-comment.model'
|
||||
import { VideoCommentService } from './video-comment.service'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-comment-add',
|
||||
|
@ -37,7 +38,8 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
|
|||
constructor (
|
||||
private formBuilder: FormBuilder,
|
||||
private notificationsService: NotificationsService,
|
||||
private videoCommentService: VideoCommentService
|
||||
private videoCommentService: VideoCommentService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
@ -92,7 +94,7 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
|
|||
this.form.reset()
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.text)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.text)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<img [src]="comment.accountAvatarUrl" alt="Avatar" />
|
||||
|
||||
<div class="comment">
|
||||
<div *ngIf="highlightedComment === true" class="highlighted-comment">Highlighted comment</div>
|
||||
<div *ngIf="highlightedComment === true" class="highlighted-comment" i18n>Highlighted comment</div>
|
||||
|
||||
<div class="comment-account-date">
|
||||
<a [href]="comment.account.url" target="_blank" rel="noopener noreferrer" class="comment-account">{{ comment.by }}</a>
|
||||
|
@ -11,8 +11,8 @@
|
|||
<div class="comment-html" [innerHTML]="sanitizedCommentHTML"></div>
|
||||
|
||||
<div class="comment-actions">
|
||||
<div *ngIf="isUserLoggedIn()" (click)="onWantToReply()" class="comment-action-reply">Reply</div>
|
||||
<div *ngIf="isRemovableByUser()" (click)="onWantToDelete()" class="comment-action-delete">Delete</div>
|
||||
<div *ngIf="isUserLoggedIn()" (click)="onWantToReply()" class="comment-action-reply" i18n>Reply</div>
|
||||
<div *ngIf="isRemovableByUser()" (click)="onWantToDelete()" class="comment-action-delete" i18n>Delete</div>
|
||||
</div>
|
||||
|
||||
<my-video-comment-add
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
<div class="title-page title-page-single">
|
||||
Comments
|
||||
</div>
|
||||
<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>
|
||||
<my-help
|
||||
*ngIf="video.commentsEnabled === true" helpType="custom" i18n-customHtml
|
||||
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>
|
||||
</div>
|
||||
|
||||
<ng-template [ngIf]="video.commentsEnabled === true">
|
||||
|
@ -14,7 +17,7 @@
|
|||
(commentCreated)="onCommentThreadCreated($event)"
|
||||
></my-video-comment-add>
|
||||
|
||||
<div *ngIf="componentPagination.totalItems === 0 && comments.length === 0">No comments.</div>
|
||||
<div *ngIf="componentPagination.totalItems === 0 && comments.length === 0" i18n>No comments.</div>
|
||||
|
||||
<div
|
||||
class="comment-threads"
|
||||
|
@ -24,15 +27,15 @@
|
|||
>
|
||||
<div *ngIf="highlightedThread" id="highlighted-comment">
|
||||
<my-video-comment
|
||||
[comment]="highlightedThread"
|
||||
[video]="video"
|
||||
[inReplyToCommentId]="inReplyToCommentId"
|
||||
[commentTree]="threadComments[highlightedThread.id]"
|
||||
[highlightedComment]="true"
|
||||
(wantedToReply)="onWantedToReply($event)"
|
||||
(wantedToDelete)="onWantedToDelete($event)"
|
||||
(threadCreated)="onThreadCreated($event)"
|
||||
(resetReply)="onResetReply()"
|
||||
[comment]="highlightedThread"
|
||||
[video]="video"
|
||||
[inReplyToCommentId]="inReplyToCommentId"
|
||||
[commentTree]="threadComments[highlightedThread.id]"
|
||||
[highlightedComment]="true"
|
||||
(wantedToReply)="onWantedToReply($event)"
|
||||
(wantedToDelete)="onWantedToDelete($event)"
|
||||
(threadCreated)="onThreadCreated($event)"
|
||||
(resetReply)="onResetReply()"
|
||||
></my-video-comment>
|
||||
</div>
|
||||
|
||||
|
@ -50,7 +53,7 @@
|
|||
></my-video-comment>
|
||||
|
||||
<div *ngIf="comment.totalReplies !== 0 && !threadComments[comment.id]" (click)="viewReplies(comment.id)" class="view-replies">
|
||||
View all {{ comment.totalReplies }} replies
|
||||
<ng-container i18n>View all {{ comment.totalReplies }} replies</ng-container>
|
||||
|
||||
<span *ngIf="!threadLoading[comment.id]" class="glyphicon glyphicon-menu-down"></span>
|
||||
<my-loader class="comment-thread-loading" [loading]="threadLoading[comment.id]"></my-loader>
|
||||
|
@ -59,7 +62,7 @@
|
|||
</div>
|
||||
</ng-template>
|
||||
|
||||
<div *ngIf="video.commentsEnabled === false">
|
||||
<div *ngIf="video.commentsEnabled === false" i18n>
|
||||
Comments are disabled.
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -11,6 +11,7 @@ import { VideoSortField } from '../../../shared/video/sort-field.type'
|
|||
import { VideoDetails } from '../../../shared/video/video-details.model'
|
||||
import { VideoComment } from './video-comment.model'
|
||||
import { VideoCommentService } from './video-comment.service'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-comments',
|
||||
|
@ -40,7 +41,8 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
|
|||
private notificationsService: NotificationsService,
|
||||
private confirmService: ConfirmService,
|
||||
private videoCommentService: VideoCommentService,
|
||||
private activatedRoute: ActivatedRoute
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private i18n: I18n
|
||||
) {}
|
||||
|
||||
ngOnInit () {
|
||||
|
@ -77,7 +79,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
|
|||
if (highlightThread) this.highlightedThread = new VideoComment(res.comment)
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -89,7 +91,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
|
|||
this.componentPagination.totalItems = res.totalComments
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -111,9 +113,11 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
async onWantedToDelete (commentToDelete: VideoComment) {
|
||||
let message = 'Do you really want to delete this comment?'
|
||||
if (commentToDelete.totalReplies !== 0) message += `${commentToDelete.totalReplies} would be deleted too.`
|
||||
if (commentToDelete.totalReplies !== 0) {
|
||||
message += this.i18n(' {{ totalReplies }} replies will be deleted too.', { totalReplies: commentToDelete.totalReplies })
|
||||
}
|
||||
|
||||
const res = await this.confirmService.confirm(message, 'Delete')
|
||||
const res = await this.confirmService.confirm(message, this.i18n('Delete'))
|
||||
if (res === false) return
|
||||
|
||||
this.videoCommentService.deleteVideoComment(commentToDelete.videoId, commentToDelete.id)
|
||||
|
@ -136,7 +140,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
|
|||
this.componentPagination.totalItems--
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<div class="modal-header">
|
||||
<span class="close" aria-hidden="true" (click)="hide()"></span>
|
||||
<h4 class="modal-title">Download video</h4>
|
||||
<h4 i18n class="modal-title">Download video</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
|
@ -17,22 +17,22 @@
|
|||
<div class="download-type">
|
||||
<div class="peertube-radio-container">
|
||||
<input type="radio" name="download" id="download-torrent" [(ngModel)]="downloadType" value="torrent">
|
||||
<label for="download-torrent">Torrent</label>
|
||||
<label i18n for="download-torrent">Torrent</label>
|
||||
</div>
|
||||
|
||||
<div class="peertube-radio-container">
|
||||
<input type="radio" name="download" id="download-direct" [(ngModel)]="downloadType" value="direct">
|
||||
<label for="download-direct">Direct download</label>
|
||||
<label i18n for="download-direct">Direct download</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group inputs">
|
||||
<span class="action-button action-button-cancel" (click)="hide()">
|
||||
<span i18n class="action-button action-button-cancel" (click)="hide()">
|
||||
Cancel
|
||||
</span>
|
||||
|
||||
<input
|
||||
type="submit" value="Download" class="action-button-submit"
|
||||
type="submit" i18n-value value="Download" class="action-button-submit"
|
||||
(click)="download()"
|
||||
>
|
||||
</div>
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
<div class="modal-header">
|
||||
<span class="close" aria-hidden="true" (click)="hide()"></span>
|
||||
<h4 class="modal-title">Report video</h4>
|
||||
<h4 i18n class="modal-title">Report video</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<form novalidate [formGroup]="form" (ngSubmit)="report()">
|
||||
<div class="form-group">
|
||||
<textarea placeholder="Reason..." formControlName="reason" [ngClass]="{ 'input-error': formErrors['reason'] }">
|
||||
<textarea i18n-placeholder placeholder="Reason..." formControlName="reason" [ngClass]="{ 'input-error': formErrors['reason'] }">
|
||||
</textarea>
|
||||
<div *ngIf="formErrors.reason" class="form-error">
|
||||
{{ formErrors.reason }}
|
||||
|
@ -19,12 +19,12 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group inputs">
|
||||
<span class="action-button action-button-cancel" (click)="hide()">
|
||||
<span i18n class="action-button action-button-cancel" (click)="hide()">
|
||||
Cancel
|
||||
</span>
|
||||
|
||||
<input
|
||||
type="submit" value="Submit" class="action-button-submit"
|
||||
type="submit" i18n-value value="Submit" class="action-button-submit"
|
||||
[disabled]="!form.valid"
|
||||
>
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { NotificationsService } from 'angular2-notifications'
|
|||
import { ModalDirective } from 'ngx-bootstrap/modal'
|
||||
import { FormReactive, VIDEO_ABUSE_REASON, VideoAbuseService } from '../../../shared/index'
|
||||
import { VideoDetails } from '../../../shared/video/video-details.model'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-report',
|
||||
|
@ -27,8 +28,9 @@ export class VideoReportComponent extends FormReactive implements OnInit {
|
|||
constructor (
|
||||
private formBuilder: FormBuilder,
|
||||
private videoAbuseService: VideoAbuseService,
|
||||
private notificationsService: NotificationsService
|
||||
) {
|
||||
private notificationsService: NotificationsService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
|
@ -58,11 +60,11 @@ export class VideoReportComponent extends FormReactive implements OnInit {
|
|||
this.videoAbuseService.reportVideo(this.video.id, reason)
|
||||
.subscribe(
|
||||
() => {
|
||||
this.notificationsService.success('Success', 'Video reported.')
|
||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Video reported.'))
|
||||
this.hide()
|
||||
},
|
||||
|
||||
err => this.notificationsService.error('Error', err.message)
|
||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
<div class="modal-header">
|
||||
<span class="close" aria-hidden="true" (click)="hide()"></span>
|
||||
<h4 class="modal-title">Share</h4>
|
||||
<h4 i18n class="modal-title">Share</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>URL</label>
|
||||
<label i18n>URL</label>
|
||||
<div class="input-group input-group-sm">
|
||||
<input #urlInput (click)="urlInput.select()" type="text" class="form-control input-sm readonly" readonly [value]="getVideoUrl()" />
|
||||
<div class="input-group-btn" placement="bottom right">
|
||||
|
@ -21,7 +21,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Embed</label>
|
||||
<label i18n>Embed</label>
|
||||
<div class="input-group input-group-sm">
|
||||
<input #shareInput (click)="shareInput.select()" type="text" class="form-control input-sm readonly" readonly [value]="getVideoIframeCode()" />
|
||||
<div class="input-group-btn" placement="bottom right">
|
||||
|
@ -32,12 +32,12 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="notSecure()" class="alert alert-warning">
|
||||
<div i18n *ngIf="notSecure()" class="alert alert-warning">
|
||||
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).
|
||||
</div>
|
||||
|
||||
<div class="form-group inputs">
|
||||
<span class="action-button action-button-cancel" (click)="hide()">
|
||||
<span i18n class="action-button action-button-cancel" (click)="hide()">
|
||||
Cancel
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { NotificationsService } from 'angular2-notifications'
|
|||
import { ModalDirective } from 'ngx-bootstrap/modal'
|
||||
import { VideoDetails } from '../../../shared/video/video-details.model'
|
||||
import { buildVideoEmbed } from '../../../../assets/player/utils'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-share',
|
||||
|
@ -16,7 +17,10 @@ export class VideoShareComponent {
|
|||
|
||||
@ViewChild('modal') modal: ModalDirective
|
||||
|
||||
constructor (private notificationsService: NotificationsService) {
|
||||
constructor (
|
||||
private notificationsService: NotificationsService,
|
||||
private i18n: I18n
|
||||
) {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
@ -41,6 +45,6 @@ export class VideoShareComponent {
|
|||
}
|
||||
|
||||
activateCopiedMessage () {
|
||||
this.notificationsService.success('Success', 'Copied')
|
||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Copied'))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<div class="modal-header">
|
||||
<span class="close" aria-hidden="true" (click)="hide()"></span>
|
||||
<h4 class="modal-title">Support</h4>
|
||||
<h4 i18n class="modal-title">Support</h4>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
|
@ -12,7 +12,7 @@
|
|||
<div [innerHTML]="videoHTMLSupport"></div>
|
||||
|
||||
<div class="form-group inputs">
|
||||
<span class="action-button action-button-cancel" (click)="hide()">
|
||||
<span i18n class="action-button action-button-cancel" (click)="hide()">
|
||||
Cancel
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -27,8 +27,8 @@ export class VideoLocalComponent extends AbstractVideoList implements OnInit, On
|
|||
protected notificationsService: NotificationsService,
|
||||
protected authService: AuthService,
|
||||
protected location: Location,
|
||||
private videoService: VideoService,
|
||||
private i18n: I18n
|
||||
protected i18n: I18n,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
super()
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ export class VideoRecentlyAddedComponent extends AbstractVideoList implements On
|
|||
protected location: Location,
|
||||
protected notificationsService: NotificationsService,
|
||||
protected authService: AuthService,
|
||||
private videoService: VideoService,
|
||||
private i18n: I18n
|
||||
protected i18n: I18n,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
super()
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@ export class VideoSearchComponent extends AbstractVideoList implements OnInit, O
|
|||
protected notificationsService: NotificationsService,
|
||||
protected authService: AuthService,
|
||||
protected location: Location,
|
||||
protected i18n: I18n,
|
||||
private videoService: VideoService,
|
||||
private redirectService: RedirectService,
|
||||
private i18n: I18n
|
||||
private redirectService: RedirectService
|
||||
) {
|
||||
super()
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ export class VideoTrendingComponent extends AbstractVideoList implements OnInit,
|
|||
protected notificationsService: NotificationsService,
|
||||
protected authService: AuthService,
|
||||
protected location: Location,
|
||||
private videoService: VideoService,
|
||||
private i18n: I18n
|
||||
protected i18n: I18n,
|
||||
private videoService: VideoService
|
||||
) {
|
||||
super()
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue