From 66357162f8e1227495f09bd4f68446aad7071c6d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 12 Aug 2020 10:40:04 +0200 Subject: Migrate to $localize * Remove i18n polyfill to translate things in components * Reduce bundle sizes * Improve runtime perf * Reduce a lot the time to make a full client build * Reduce client build complexity * We don't need a service to translate things anymore (so we will be able to translate title pages etc) Unfortunately we may loose some translations in the migration process. I'll put a message on weblate to notify translators --- client/angular.json | 81 +-------- client/package.json | 23 ++- .../contact-admin-modal.component.ts | 8 +- .../account-about/account-about.component.ts | 4 +- .../account-videos/account-videos.component.ts | 4 +- client/src/app/+accounts/accounts.component.ts | 24 ++- client/src/app/+admin/admin.component.ts | 32 ++-- .../edit-custom-config.component.ts | 24 ++- .../src/app/+admin/config/shared/config.service.ts | 38 ++--- .../followers-list/followers-list.component.ts | 16 +- .../following-list/following-list.component.ts | 14 +- .../shared/redundancy-checkbox.component.ts | 10 +- .../video-redundancies-list.component.ts | 14 +- .../video-block-list/video-block-list.component.ts | 42 +++-- .../plugin-list-installed.component.ts | 16 +- .../plugin-search/plugin-search.component.ts | 13 +- .../plugin-show-installed.component.ts | 4 +- .../+admin/plugins/shared/plugin-api.service.ts | 10 +- .../src/app/+admin/system/jobs/jobs.component.ts | 6 +- .../src/app/+admin/system/logs/logs.component.ts | 24 ++- .../users/user-edit/user-create.component.ts | 10 +- .../users/user-edit/user-password.component.ts | 12 +- .../users/user-edit/user-update.component.ts | 14 +- .../+admin/users/user-list/user-list.component.ts | 40 ++--- client/src/app/+login/login.component.ts | 17 +- .../my-account-video-channel-create.component.ts | 14 +- .../my-account-video-channel-update.component.ts | 10 +- .../my-account-video-channels.component.ts | 48 +++--- .../my-account-history.component.ts | 14 +- .../my-account-accept-ownership.component.ts | 8 +- .../my-account-change-email.component.ts | 12 +- .../my-account-change-password.component.ts | 10 +- .../my-account-danger-zone.component.ts | 16 +- ...y-account-notification-preferences.component.ts | 32 ++-- .../my-account-profile.component.ts | 8 +- .../my-account-settings.component.ts | 8 +- .../my-account-video-playlist-create.component.ts | 14 +- ...my-account-video-playlist-elements.component.ts | 18 +- .../my-account-video-playlist-update.component.ts | 9 +- .../my-account-video-playlists.component.ts | 17 +- .../my-account-videos.component.ts | 17 +- .../video-change-ownership.component.ts | 8 +- client/src/app/+my-account/my-account.component.ts | 34 ++-- .../+reset-password/reset-password.component.ts | 10 +- client/src/app/+search/search-filters.component.ts | 28 ++- client/src/app/+search/search.component.ts | 8 +- .../app/+signup/+register/register.component.ts | 10 +- .../verify-account-ask-send-email.component.ts | 12 +- .../verify-account-email.component.ts | 8 +- .../video-channel-about.component.ts | 4 +- .../video-channel-videos.component.ts | 8 +- .../+video-channels/video-channels.component.ts | 12 +- .../shared/i18n-primeng-calendar.service.ts | 102 ++++++----- .../+video-edit/shared/video-edit.component.ts | 10 +- .../video-import-torrent.component.ts | 10 +- .../video-import-url.component.ts | 10 +- .../video-add-components/video-upload.component.ts | 48 +++--- .../+videos/+video-edit/video-update.component.ts | 10 +- .../comment/video-comment.component.ts | 4 +- .../comment/video-comments.component.ts | 8 +- .../recommended-videos.component.ts | 6 +- .../+video-watch/video-duration-formatter.pipe.ts | 11 +- .../+video-watch/video-watch-playlist.component.ts | 12 +- .../+videos/+video-watch/video-watch.component.ts | 55 +++--- .../+videos/video-list/video-local.component.ts | 4 +- .../video-list/video-most-liked.component.ts | 6 +- .../video-list/video-recently-added.component.ts | 4 +- .../+videos/video-list/video-trending.component.ts | 13 +- .../video-user-subscriptions.component.ts | 8 +- client/src/app/app.component.ts | 18 +- client/src/app/app.module.ts | 16 +- client/src/app/core/auth/auth.service.ts | 24 ++- client/src/app/core/hotkeys/hotkeys.component.ts | 12 +- .../src/app/core/notification/notifier.service.ts | 14 +- client/src/app/core/rest/rest-extractor.service.ts | 17 +- .../core/routing/can-deactivate-guard.service.ts | 11 +- client/src/app/core/users/user.service.ts | 12 +- client/src/app/menu/menu.component.ts | 16 +- client/src/app/modal/confirm.component.ts | 6 +- .../shared-abuse-list/abuse-details.component.ts | 21 +-- .../abuse-list-table.component.ts | 77 ++++----- .../abuse-message-modal.component.ts | 10 +- .../moderation-comment-modal.component.ts | 8 +- .../form-validators/abuse-validators.service.ts | 23 ++- .../batch-domains-validators.service.ts | 11 +- .../custom-config-validators.service.ts | 41 +++-- .../form-validators/instance-validators.service.ts | 27 ++- .../form-validators/login-validators.service.ts | 9 +- .../reset-password-validators.service.ts | 7 +- .../form-validators/user-validators.service.ts | 63 ++++--- .../video-accept-ownership-validators.service.ts | 7 +- .../video-block-validators.service.ts | 9 +- .../video-captions-validators.service.ts | 9 +- .../video-change-ownership-validators.service.ts | 9 +- .../video-channel-validators.service.ts | 27 ++- .../video-comment-validators.service.ts | 11 +- .../video-playlist-validators.service.ts | 21 ++- .../form-validators/video-validators.service.ts | 33 ++-- .../shared-forms/input-readonly-copy.component.ts | 8 +- .../shared-forms/preview-upload.component.ts | 6 +- .../shared/shared-forms/reactive-file.component.ts | 13 +- .../select/select-checkbox.component.ts | 11 +- .../instance-features-table.component.ts | 23 ++- .../account/actor-avatar-info.component.ts | 6 +- .../shared/shared-main/account/avatar.component.ts | 15 +- .../shared/shared-main/angular/from-now.pipe.ts | 27 ++- .../shared-main/buttons/delete-button.component.ts | 7 +- .../shared-main/buttons/edit-button.component.ts | 7 +- .../app/shared/shared-main/misc/help.component.ts | 15 +- .../app/shared/shared-main/shared-main.module.ts | 3 - .../shared-main/users/user-quota.component.ts | 10 +- .../app/shared/shared-main/video/video.service.ts | 16 +- .../app/shared/shared-moderation/abuse.service.ts | 34 ++-- .../account-blocklist.component.ts | 10 +- .../batch-domains-modal.component.ts | 6 +- .../report-modals/account-report.component.ts | 8 +- .../report-modals/comment-report.component.ts | 8 +- .../report-modals/video-report.component.ts | 8 +- .../server-blocklist.component.ts | 12 +- .../shared-moderation/user-ban-modal.component.ts | 8 +- .../user-moderation-dropdown.component.ts | 103 ++++++----- .../shared-moderation/video-block.component.ts | 6 +- .../shared-thumbnail/video-thumbnail.component.ts | 10 +- .../user-interface-settings.component.ts | 8 +- .../user-video-settings.component.ts | 24 +-- .../subscribe-button.component.ts | 26 +-- .../shared-video-miniature/abstract-video-list.ts | 14 +- .../video-actions-dropdown.component.ts | 53 +++--- .../video-download.component.ts | 36 ++-- .../video-miniature.component.ts | 17 +- .../videos-selection.component.ts | 2 - .../video-add-to-playlist.component.ts | 8 +- .../video-playlist-element-miniature.component.ts | 13 +- client/yarn.lock | 124 +++++--------- scripts/build/client.sh | 189 ++++++--------------- scripts/i18n/generate.sh | 8 +- 136 files changed, 1061 insertions(+), 1628 deletions(-) diff --git a/client/angular.json b/client/angular.json index 06223b837..c893cc1e9 100644 --- a/client/angular.json +++ b/client/angular.json @@ -124,6 +124,7 @@ "builder": "@angular-devkit/build-angular:browser", "options": { "aot": true, + "localize": true, "outputPath": "dist", "index": "src/index.html", "main": "src/main.ts", @@ -214,6 +215,7 @@ "budgets": [] }, "hmr": { + "localize": false, "budgets": [ { "type": "anyComponentStyle", @@ -228,6 +230,7 @@ ] }, "e2e": { + "localize": false, "budgets": [ { "type": "anyComponentStyle", @@ -240,84 +243,6 @@ "with": "src/environments/environment.e2e.ts" } ] - }, - "ar": { - "localize": [ "ar" ] - }, - "hu-HU": { - "localize": [ "hu" ] - }, - "th-TH": { - "localize": [ "th" ] - }, - "fi-FI": { - "localize": [ "fi" ] - }, - "nl-NL": { - "localize": [ "nl" ] - }, - "gd": { - "localize": [ "gd" ] - }, - "el-GR": { - "localize": [ "el" ] - }, - "es-ES": { - "localize": [ "es" ] - }, - "oc": { - "localize": [ "oc" ] - }, - "pt-BR": { - "localize": [ "pt" ] - }, - "pt-PT": { - "localize": [ "pt-PT" ] - }, - "sv-SE": { - "localize": [ "sv" ] - }, - "pl-PL": { - "localize": [ "pl" ] - }, - "ru-RU": { - "localize": [ "ru" ] - }, - "zh-Hans-CN": { - "localize": [ "zh-Hans" ] - }, - "zh-Hant-TW": { - "localize": [ "zh-Hant" ] - }, - "fr-FR": { - "localize": [ "fr" ] - }, - "ja-JP": { - "localize": [ "ja" ] - }, - "eu-ES": { - "localize": [ "eu" ] - }, - "ca-ES": { - "localize": [ "ca" ] - }, - "cs-CZ": { - "localize": [ "cs" ] - }, - "eo": { - "localize": [ "eo" ] - }, - "de-DE": { - "localize": [ "de" ] - }, - "it-IT": { - "localize": [ "it" ] - }, - "vi-VN": { - "localize": [ "vi" ] - }, - "kab": { - "localize": [ "kab" ] } } }, diff --git a/client/package.json b/client/package.json index 3c4b9ead4..9769cc813 100644 --- a/client/package.json +++ b/client/package.json @@ -28,19 +28,19 @@ "typings": "*.d.ts", "devDependencies": { "@angular-devkit/build-angular": "^0.1001.0-next.4", - "@angular/animations": "^10.1.0-next.4", + "@angular/animations": "^10.1.0-next.5", "@angular/cdk": "^10.0.0", "@angular/cli": "^10.1.0-next.4", - "@angular/common": "^10.1.0-next.4", - "@angular/compiler": "^10.1.0-next.4", - "@angular/compiler-cli": "^10.1.0-next.4", - "@angular/core": "^10.1.0-next.4", - "@angular/forms": "^10.1.0-next.4", - "@angular/localize": "^10.1.0-next.4", - "@angular/platform-browser": "^10.1.0-next.4", - "@angular/platform-browser-dynamic": "^10.1.0-next.4", - "@angular/router": "^10.1.0-next.4", - "@angular/service-worker": "^10.1.0-next.4", + "@angular/common": "^10.1.0-next.5", + "@angular/compiler": "^10.1.0-next.5", + "@angular/compiler-cli": "^10.1.0-next.5", + "@angular/core": "^10.1.0-next.5", + "@angular/forms": "^10.1.0-next.5", + "@angular/localize": "^10.1.0-next.5", + "@angular/platform-browser": "^10.1.0-next.5", + "@angular/platform-browser-dynamic": "^10.1.0-next.5", + "@angular/router": "^10.1.0-next.5", + "@angular/service-worker": "^10.1.0-next.5", "@angularclass/hmr": "^2.1.3", "@neos21/bootstrap3-glyphicons": "^1.0.1", "@ng-bootstrap/ng-bootstrap": "^7.0.0", @@ -51,7 +51,6 @@ "@ngx-loading-bar/http-client": "^5.0.0", "@ngx-loading-bar/router": "^5.0.0", "@ngx-meta/core": "^9.0.0", - "@ngx-translate/i18n-polyfill": "^1.0.0", "@types/chart.js": "^2.9.16", "@types/core-js": "^2.5.2", "@types/debug": "^4.1.5", diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.ts b/client/src/app/+about/about-instance/contact-admin-modal.component.ts index 5199402e6..215e281bb 100644 --- a/client/src/app/+about/about-instance/contact-admin-modal.component.ts +++ b/client/src/app/+about/about-instance/contact-admin-modal.component.ts @@ -4,7 +4,6 @@ import { FormReactive, FormValidatorService, InstanceValidatorsService } from '@ import { InstanceService } from '@app/shared/shared-instance' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig } from '@shared/models' @Component({ @@ -26,8 +25,7 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit { private instanceValidatorsService: InstanceValidatorsService, private instanceService: InstanceService, private serverService: ServerService, - private notifier: Notifier, - private i18n: I18n + private notifier: Notifier ) { super() } @@ -70,13 +68,13 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit { this.instanceService.contactAdministrator(fromEmail, fromName, subject, body) .subscribe( () => { - this.notifier.success(this.i18n('Your message has been sent.')) + this.notifier.success($localize`Your message has been sent.`) this.hide() }, err => { this.error = err.status === 403 - ? this.i18n('You already sent this form recently') + ? $localize`You already sent this form recently` : err.message } ) diff --git a/client/src/app/+accounts/account-about/account-about.component.ts b/client/src/app/+accounts/account-about/account-about.component.ts index 8c01e4007..6cf846d72 100644 --- a/client/src/app/+accounts/account-about/account-about.component.ts +++ b/client/src/app/+accounts/account-about/account-about.component.ts @@ -2,7 +2,6 @@ import { Subscription } from 'rxjs' import { Component, OnDestroy, OnInit } from '@angular/core' import { MarkdownService } from '@app/core' import { Account, AccountService } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-account-about', @@ -16,7 +15,6 @@ export class AccountAboutComponent implements OnInit, OnDestroy { private accountSub: Subscription constructor ( - private i18n: I18n, private accountService: AccountService, private markdownService: MarkdownService ) { } @@ -37,6 +35,6 @@ export class AccountAboutComponent implements OnInit, OnDestroy { getAccountDescription () { if (this.descriptionHTML) return this.descriptionHTML - return this.i18n('No description') + return $localize`No description` } } diff --git a/client/src/app/+accounts/account-videos/account-videos.component.ts b/client/src/app/+accounts/account-videos/account-videos.component.ts index 5a9241f8e..3134a8ee2 100644 --- a/client/src/app/+accounts/account-videos/account-videos.component.ts +++ b/client/src/app/+accounts/account-videos/account-videos.component.ts @@ -6,7 +6,6 @@ import { AuthService, ConfirmService, LocalStorageService, Notifier, ScreenServi import { immutableAssign } from '@app/helpers' import { Account, AccountService, VideoService } from '@app/shared/shared-main' import { AbstractVideoList } from '@app/shared/shared-video-miniature' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-account-videos', @@ -23,7 +22,6 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit, private accountSub: Subscription constructor ( - protected i18n: I18n, protected router: Router, protected serverService: ServerService, protected route: ActivatedRoute, @@ -66,7 +64,7 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit, .getAccountVideos(this.account, newPagination, this.sort) .pipe( tap(({ total }) => { - this.titlePage = this.i18n('Published {{total}} videos', { total }) + this.titlePage = $localize`Published ${total} videos` }) ) } diff --git a/client/src/app/+accounts/accounts.component.ts b/client/src/app/+accounts/accounts.component.ts index 9288fcb42..bbce62c35 100644 --- a/client/src/app/+accounts/accounts.component.ts +++ b/client/src/app/+accounts/accounts.component.ts @@ -5,7 +5,6 @@ import { ActivatedRoute } from '@angular/router' import { AuthService, Notifier, RedirectService, RestExtractor, ScreenService, UserService } from '@app/core' import { Account, AccountService, DropdownAction, ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main' import { AccountReportComponent } from '@app/shared/shared-moderation' -import { I18n } from '@ngx-translate/i18n-polyfill' import { User, UserRight } from '@shared/models' @Component({ @@ -36,8 +35,7 @@ export class AccountsComponent implements OnInit, OnDestroy { private restExtractor: RestExtractor, private redirectService: RedirectService, private authService: AuthService, - private screenService: ScreenService, - private i18n: I18n + private screenService: ScreenService ) { } @@ -58,9 +56,9 @@ export class AccountsComponent implements OnInit, OnDestroy { ) this.links = [ - { label: this.i18n('VIDEO CHANNELS'), routerLink: 'video-channels' }, - { label: this.i18n('VIDEOS'), routerLink: 'videos' }, - { label: this.i18n('ABOUT'), routerLink: 'about' } + { label: $localize`VIDEO CHANNELS`, routerLink: 'video-channels' }, + { label: $localize`VIDEOS`, routerLink: 'videos' }, + { label: $localize`ABOUT`, routerLink: 'about' } ] } @@ -88,11 +86,13 @@ export class AccountsComponent implements OnInit, OnDestroy { } activateCopiedMessage () { - this.notifier.success(this.i18n('Username copied')) + this.notifier.success($localize`Username copied`) } subscribersDisplayFor (count: number) { - return this.i18n('{count, plural, =1 {1 subscriber} other {{{count}} subscribers}}', { count }) + if (count === 1) return $localize`1 subscriber` + + return $localize`${count} subscribers` } private onAccount (account: Account) { @@ -105,16 +105,14 @@ export class AccountsComponent implements OnInit, OnDestroy { () => { this.isAccountManageable = this.account.userId && this.account.userId === this.authService.getUser().id - this.accountFollowerTitle = this.i18n( - '{{followers}} direct account followers', - { followers: this.subscribersDisplayFor(account.followersCount) } - ) + const followers = this.subscribersDisplayFor(account.followersCount) + this.accountFollowerTitle = $localize`${followers} direct account followers` // It's not our account, we can report it if (!this.isAccountManageable) { this.prependModerationActions = [ { - label: this.i18n('Report account'), + label: $localize`Report account`, handler: () => this.showReportModal() } ] diff --git a/client/src/app/+admin/admin.component.ts b/client/src/app/+admin/admin.component.ts index 66e068c4c..b661a5517 100644 --- a/client/src/app/+admin/admin.component.ts +++ b/client/src/app/+admin/admin.component.ts @@ -1,9 +1,8 @@ import { Component, OnInit } from '@angular/core' import { AuthService, ScreenService } from '@app/core' import { ListOverflowItem } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { UserRight } from '@shared/models' import { TopMenuDropdownParam } from '@app/shared/shared-main/misc/top-menu-dropdown.component' +import { UserRight } from '@shared/models' @Component({ templateUrl: './admin.component.html', @@ -15,8 +14,7 @@ export class AdminComponent implements OnInit { constructor ( private auth: AuthService, - private screen: ScreenService, - private i18n: I18n + private screen: ScreenService ) { } get isBroadcastMessageDisplayed () { @@ -25,20 +23,20 @@ export class AdminComponent implements OnInit { ngOnInit () { const federationItems: TopMenuDropdownParam = { - label: this.i18n('Federation'), + label: $localize`Federation`, children: [ { - label: this.i18n('Instances you follow'), + label: $localize`Instances you follow`, routerLink: '/admin/follows/following-list', iconName: 'following' }, { - label: this.i18n('Instances following you'), + label: $localize`Instances following you`, routerLink: '/admin/follows/followers-list', iconName: 'follower' }, { - label: this.i18n('Video redundancies'), + label: $localize`Video redundancies`, routerLink: '/admin/follows/video-redundancies-list', iconName: 'videos' } @@ -46,56 +44,56 @@ export class AdminComponent implements OnInit { } const moderationItems: TopMenuDropdownParam = { - label: this.i18n('Moderation'), + label: $localize`Moderation`, children: [] } if (this.hasAbusesRight()) { moderationItems.children.push({ - label: this.i18n('Reports'), + label: $localize`Reports`, routerLink: '/admin/moderation/abuses/list', iconName: 'flag' }) } if (this.hasVideoBlocklistRight()) { moderationItems.children.push({ - label: this.i18n('Video blocks'), + label: $localize`Video blocks`, routerLink: '/admin/moderation/video-blocks/list', iconName: 'cross' }) } if (this.hasAccountsBlocklistRight()) { moderationItems.children.push({ - label: this.i18n('Muted accounts'), + label: $localize`Muted accounts`, routerLink: '/admin/moderation/blocklist/accounts', iconName: 'user-x' }) } if (this.hasServersBlocklistRight()) { moderationItems.children.push({ - label: this.i18n('Muted servers'), + label: $localize`Muted servers`, routerLink: '/admin/moderation/blocklist/servers', iconName: 'peertube-x' }) } if (this.hasUsersRight()) { - this.menuEntries.push({ label: this.i18n('Users'), routerLink: '/admin/users' }) + this.menuEntries.push({ label: $localize`Users`, routerLink: '/admin/users' }) } if (this.hasServerFollowRight()) this.menuEntries.push(federationItems) if (this.hasAbusesRight() || this.hasVideoBlocklistRight()) this.menuEntries.push(moderationItems) if (this.hasConfigRight()) { - this.menuEntries.push({ label: this.i18n('Configuration'), routerLink: '/admin/config' }) + this.menuEntries.push({ label: $localize`Configuration`, routerLink: '/admin/config' }) } if (this.hasPluginsRight()) { - this.menuEntries.push({ label: this.i18n('Plugins/Themes'), routerLink: '/admin/plugins' }) + this.menuEntries.push({ label: $localize`Plugins/Themes`, routerLink: '/admin/plugins' }) } if (this.hasJobsRight() || this.hasLogsRight() || this.hasDebugRight()) { - this.menuEntries.push({ label: this.i18n('System'), routerLink: '/admin/system' }) + this.menuEntries.push({ label: $localize`System`, routerLink: '/admin/system' }) } } diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts index 00a0bfad2..3a60b144f 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts @@ -12,7 +12,6 @@ import { UserValidatorsService } from '@app/shared/shared-forms' import { NgbNav } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { CustomConfig, ServerConfig } from '@shared/models' @Component({ @@ -42,45 +41,44 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A private userValidatorsService: UserValidatorsService, private notifier: Notifier, private configService: ConfigService, - private serverService: ServerService, - private i18n: I18n + private serverService: ServerService ) { super() this.resolutions = [ { id: '0p', - label: this.i18n('Audio-only'), - description: this.i18n('A .mp4 that keeps the original audio track, with no video') + label: $localize`Audio-only`, + description: $localize`A .mp4 that keeps the original audio track, with no video` }, { id: '240p', - label: this.i18n('240p') + label: $localize`240p` }, { id: '360p', - label: this.i18n('360p') + label: $localize`360p` }, { id: '480p', - label: this.i18n('480p') + label: $localize`480p` }, { id: '720p', - label: this.i18n('720p') + label: $localize`720p` }, { id: '1080p', - label: this.i18n('1080p') + label: $localize`1080p` }, { id: '2160p', - label: this.i18n('2160p') + label: $localize`2160p` } ] this.transcodingThreadOptions = [ - { value: 0, label: this.i18n('Auto (via ffmpeg)') }, + { value: 0, label: $localize`Auto (via ffmpeg)` }, { value: 1, label: '1' }, { value: 2, label: '2' }, { value: 4, label: '4' }, @@ -288,7 +286,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A this.updateForm() - this.notifier.success(this.i18n('Configuration updated.')) + this.notifier.success($localize`Configuration updated.`) }, err => this.notifier.error(err.message) diff --git a/client/src/app/+admin/config/shared/config.service.ts b/client/src/app/+admin/config/shared/config.service.ts index f182946b8..5f98aa545 100644 --- a/client/src/app/+admin/config/shared/config.service.ts +++ b/client/src/app/+admin/config/shared/config.service.ts @@ -2,7 +2,6 @@ import { catchError } from 'rxjs/operators' import { HttpClient } from '@angular/common/http' import { Injectable } from '@angular/core' import { RestExtractor } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { CustomConfig } from '@shared/models' import { environment } from '../../../../environments/environment' @@ -15,33 +14,32 @@ export class ConfigService { constructor ( private authHttp: HttpClient, - private restExtractor: RestExtractor, - private i18n: I18n - ) { + private restExtractor: RestExtractor + ) { this.videoQuotaOptions = [ { value: undefined, label: 'Default quota', disabled: true }, - { value: -1, label: this.i18n('Unlimited') }, + { value: -1, label: $localize`Unlimited` }, { value: undefined, label: '─────', disabled: true }, - { value: 0, label: this.i18n('None - no upload possible') }, - { value: 100 * 1024 * 1024, label: this.i18n('100MB') }, - { value: 500 * 1024 * 1024, label: this.i18n('500MB') }, - { value: 1024 * 1024 * 1024, label: this.i18n('1GB') }, - { value: 5 * 1024 * 1024 * 1024, label: this.i18n('5GB') }, - { value: 20 * 1024 * 1024 * 1024, label: this.i18n('20GB') }, - { value: 50 * 1024 * 1024 * 1024, label: this.i18n('50GB') } + { value: 0, label: $localize`None - no upload possible` }, + { value: 100 * 1024 * 1024, label: $localize`100MB` }, + { value: 500 * 1024 * 1024, label: $localize`500MB` }, + { value: 1024 * 1024 * 1024, label: $localize`1GB` }, + { value: 5 * 1024 * 1024 * 1024, label: $localize`5GB` }, + { value: 20 * 1024 * 1024 * 1024, label: $localize`20GB` }, + { value: 50 * 1024 * 1024 * 1024, label: $localize`50GB` } ] this.videoQuotaDailyOptions = [ { value: undefined, label: 'Default daily upload limit', disabled: true }, - { value: -1, label: this.i18n('Unlimited') }, + { value: -1, label: $localize`Unlimited` }, { value: undefined, label: '─────', disabled: true }, - { value: 0, label: this.i18n('None - no upload possible') }, - { value: 10 * 1024 * 1024, label: this.i18n('10MB') }, - { value: 50 * 1024 * 1024, label: this.i18n('50MB') }, - { value: 100 * 1024 * 1024, label: this.i18n('100MB') }, - { value: 500 * 1024 * 1024, label: this.i18n('500MB') }, - { value: 2 * 1024 * 1024 * 1024, label: this.i18n('2GB') }, - { value: 5 * 1024 * 1024 * 1024, label: this.i18n('5GB') } + { value: 0, label: $localize`None - no upload possible` }, + { value: 10 * 1024 * 1024, label: $localize`10MB` }, + { value: 50 * 1024 * 1024, label: $localize`50MB` }, + { value: 100 * 1024 * 1024, label: $localize`100MB` }, + { value: 500 * 1024 * 1024, label: $localize`500MB` }, + { value: 2 * 1024 * 1024 * 1024, label: $localize`2GB` }, + { value: 5 * 1024 * 1024 * 1024, label: $localize`5GB` } ] } diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.ts b/client/src/app/+admin/follows/followers-list/followers-list.component.ts index 63135f898..904e3c338 100644 --- a/client/src/app/+admin/follows/followers-list/followers-list.component.ts +++ b/client/src/app/+admin/follows/followers-list/followers-list.component.ts @@ -2,7 +2,6 @@ import { SortMeta } from 'primeng/api' import { Component, OnInit } from '@angular/core' import { ConfirmService, Notifier, RestPagination, RestTable } from '@app/core' import { InstanceFollowService } from '@app/shared/shared-instance' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ActorFollow } from '@shared/models' @Component({ @@ -19,7 +18,6 @@ export class FollowersListComponent extends RestTable implements OnInit { constructor ( private confirmService: ConfirmService, private notifier: Notifier, - private i18n: I18n, private followService: InstanceFollowService ) { super() @@ -40,7 +38,7 @@ export class FollowersListComponent extends RestTable implements OnInit { .subscribe( () => { const handle = follow.follower.name + '@' + follow.follower.host - this.notifier.success(this.i18n('{{handle}} accepted in instance followers', { handle })) + this.notifier.success($localize`${handle} accepted in instance followers`) }, err => { @@ -51,15 +49,15 @@ export class FollowersListComponent extends RestTable implements OnInit { } async rejectFollower (follow: ActorFollow) { - const message = this.i18n('Do you really want to reject this follower?') - const res = await this.confirmService.confirm(message, this.i18n('Reject')) + const message = $localize`Do you really want to reject this follower?` + const res = await this.confirmService.confirm(message, $localize`Reject`) if (res === false) return this.followService.rejectFollower(follow) .subscribe( () => { const handle = follow.follower.name + '@' + follow.follower.host - this.notifier.success(this.i18n('{{handle}} rejected from instance followers', { handle })) + this.notifier.success($localize`${handle} rejected from instance followers`) this.loadData() }, @@ -72,15 +70,15 @@ export class FollowersListComponent extends RestTable implements OnInit { } async deleteFollower (follow: ActorFollow) { - const message = this.i18n('Do you really want to delete this follower?') - const res = await this.confirmService.confirm(message, this.i18n('Delete')) + const message = $localize`Do you really want to delete this follower?` + const res = await this.confirmService.confirm(message, $localize`Delete`) if (res === false) return this.followService.removeFollower(follow) .subscribe( () => { const handle = follow.follower.name + '@' + follow.follower.host - this.notifier.success(this.i18n('{{handle}} removed from instance followers', { handle })) + this.notifier.success($localize`${handle} removed from instance followers`) this.loadData() }, diff --git a/client/src/app/+admin/follows/following-list/following-list.component.ts b/client/src/app/+admin/follows/following-list/following-list.component.ts index dae8923b5..5f71f1238 100644 --- a/client/src/app/+admin/follows/following-list/following-list.component.ts +++ b/client/src/app/+admin/follows/following-list/following-list.component.ts @@ -3,7 +3,6 @@ import { Component, OnInit, ViewChild } from '@angular/core' import { ConfirmService, Notifier, RestPagination, RestTable } from '@app/core' import { InstanceFollowService } from '@app/shared/shared-instance' import { BatchDomainsModalComponent } from '@app/shared/shared-moderation' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ActorFollow } from '@shared/models' @Component({ @@ -22,9 +21,8 @@ export class FollowingListComponent extends RestTable implements OnInit { constructor ( private notifier: Notifier, private confirmService: ConfirmService, - private followService: InstanceFollowService, - private i18n: I18n - ) { + private followService: InstanceFollowService + ) { super() } @@ -47,7 +45,7 @@ export class FollowingListComponent extends RestTable implements OnInit { async addFollowing (hosts: string[]) { this.followService.follow(hosts).subscribe( () => { - this.notifier.success(this.i18n('Follow request(s) sent!')) + this.notifier.success($localize`Follow request(s) sent!`) this.loadData() }, @@ -57,14 +55,14 @@ export class FollowingListComponent extends RestTable implements OnInit { async removeFollowing (follow: ActorFollow) { const res = await this.confirmService.confirm( - this.i18n('Do you really want to unfollow {{host}}?', { host: follow.following.host }), - this.i18n('Unfollow') + $localize`Do you really want to unfollow ${follow.following.host}?`, + $localize`Unfollow` ) if (res === false) return this.followService.unfollow(follow).subscribe( () => { - this.notifier.success(this.i18n('You are not following {{host}} anymore.', { host: follow.following.host })) + this.notifier.success($localize`You are not following ${follow.following.host} anymore.`) this.loadData() }, diff --git a/client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts b/client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts index 662143abc..729b7f599 100644 --- a/client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts +++ b/client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts @@ -1,7 +1,6 @@ import { Component, Input } from '@angular/core' import { Notifier } from '@app/core' import { RedundancyService } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-redundancy-checkbox', @@ -14,17 +13,16 @@ export class RedundancyCheckboxComponent { constructor ( private notifier: Notifier, - private redundancyService: RedundancyService, - private i18n: I18n - ) { } + private redundancyService: RedundancyService + ) { } updateRedundancyState () { this.redundancyService.updateRedundancy(this.host, this.redundancyAllowed) .subscribe( () => { - const stateLabel = this.redundancyAllowed ? this.i18n('enabled') : this.i18n('disabled') + const stateLabel = this.redundancyAllowed ? $localize`enabled` : $localize`disabled` - this.notifier.success(this.i18n('Redundancy for {{host}} is {{stateLabel}}', { host: this.host, stateLabel })) + this.notifier.success($localize`Redundancy for ${this.host} is ${stateLabel}`) }, err => this.notifier.error(err.message) diff --git a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts index 07e2e0ff3..d6fd1a1ab 100644 --- a/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts +++ b/client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts @@ -2,7 +2,6 @@ import { SortMeta } from 'primeng/api' import { Component, OnInit } from '@angular/core' import { ConfirmService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' import { BytesPipe, RedundancyService } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage' import { VideoRedundanciesTarget, VideoRedundancy } from '@shared/models' import { VideosRedundancyStats } from '@shared/models/server' @@ -32,9 +31,8 @@ export class VideoRedundanciesListComponent extends RestTable implements OnInit private notifier: Notifier, private confirmService: ConfirmService, private redundancyService: RedundancyService, - private serverService: ServerService, - private i18n: I18n - ) { + private serverService: ServerService + ) { super() this.bytesPipe = new BytesPipe() @@ -100,7 +98,7 @@ export class VideoRedundanciesListComponent extends RestTable implements OnInit this.redundanciesGraphsData.push({ stats, graphData: { - labels: [ this.i18n('Used'), this.i18n('Available') ], + labels: [ $localize`Used`, $localize`Available` ], datasets: [ { data: [ stats.totalUsed, totalSize ], @@ -139,14 +137,14 @@ export class VideoRedundanciesListComponent extends RestTable implements OnInit } async removeRedundancy (redundancy: VideoRedundancy) { - const message = this.i18n('Do you really want to remove this video redundancy?') - const res = await this.confirmService.confirm(message, this.i18n('Remove redundancy')) + const message = $localize`Do you really want to remove this video redundancy?` + const res = await this.confirmService.confirm(message, $localize`Remove redundancy`) if (res === false) return this.redundancyService.removeVideoRedundancies(redundancy) .subscribe( () => { - this.notifier.success(this.i18n('Video redundancies removed!')) + this.notifier.success($localize`Video redundancies removed!`) this.loadData() }, diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts index 422d873c0..2b1ef663c 100644 --- a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts +++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts @@ -1,15 +1,14 @@ import { SortMeta } from 'primeng/api' import { filter, switchMap } from 'rxjs/operators' +import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils' +import { environment } from 'src/environments/environment' import { AfterViewInit, Component, OnInit } from '@angular/core' +import { DomSanitizer } from '@angular/platform-browser' import { ActivatedRoute, Params, Router } from '@angular/router' import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' import { DropdownAction, Video, VideoService } from '@app/shared/shared-main' import { VideoBlockService } from '@app/shared/shared-moderation' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoBlacklist, VideoBlacklistType } from '@shared/models' -import { buildVideoOrPlaylistEmbed, buildVideoLink } from 'src/assets/player/utils' -import { environment } from 'src/environments/environment' -import { DomSanitizer } from '@angular/platform-browser' @Component({ selector: 'my-video-block-list', @@ -34,26 +33,25 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV private sanitizer: DomSanitizer, private videoService: VideoService, private route: ActivatedRoute, - private router: Router, - private i18n: I18n - ) { + private router: Router + ) { super() this.videoBlocklistActions = [ [ { - label: this.i18n('Internal actions'), + label: $localize`Internal actions`, isHeader: true, isDisplayed: videoBlock => videoBlock.type === VideoBlacklistType.AUTO_BEFORE_PUBLISHED }, { - label: this.i18n('Switch video block to manual'), + label: $localize`Switch video block to manual`, handler: videoBlock => { this.videoBlocklistService.unblockVideo(videoBlock.video.id).pipe( switchMap(_ => this.videoBlocklistService.blockVideo(videoBlock.video.id, undefined, true)) ).subscribe( () => { - this.notifier.success(this.i18n('Video {{name}} switched to manual block.', { name: videoBlock.video.name })) + this.notifier.success($localize`Video ${videoBlock.video.name} switched to manual block.`) this.loadData() }, @@ -65,27 +63,27 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV ], [ { - label: this.i18n('Actions for the video'), + label: $localize`Actions for the video`, isHeader: true }, { - label: this.i18n('Unblock'), + label: $localize`Unblock`, handler: videoBlock => this.unblockVideo(videoBlock) }, { - label: this.i18n('Delete'), + label: $localize`Delete`, handler: async videoBlock => { const res = await this.confirmService.confirm( - this.i18n('Do you really want to delete this video?'), - this.i18n('Delete') + $localize`Do you really want to delete this video?`, + $localize`Delete` ) if (res === false) return this.videoService.removeVideo(videoBlock.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video deleted.')) + this.notifier.success($localize`Video deleted.`) }, err => this.notifier.error(err.message) @@ -148,9 +146,9 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV } booleanToText (value: boolean) { - if (value === true) return this.i18n('yes') + if (value === true) return $localize`yes` - return this.i18n('no') + return $localize`no` } toHtml (text: string) { @@ -158,16 +156,14 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV } async unblockVideo (entry: VideoBlacklist) { - const confirmMessage = this.i18n( - 'Do you really want to unblock this video? It will be available again in the videos list.' - ) + const confirmMessage = $localize`Do you really want to unblock this video? It will be available again in the videos list.` - const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblock')) + const res = await this.confirmService.confirm(confirmMessage, $localize`Unblock`) if (res === false) return this.videoBlocklistService.unblockVideo(entry.video.id).subscribe( () => { - this.notifier.success(this.i18n('Video {{name}} unblocked.', { name: entry.video.name })) + this.notifier.success($localize`Video ${entry.video.name} unblocked.`) this.loadData() }, diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts index af31f1144..1ffd001c6 100644 --- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts +++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts @@ -4,7 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router' import { PluginApiService } from '@app/+admin/plugins/shared/plugin-api.service' import { ComponentPagination, ConfirmService, hasMoreItems, Notifier } from '@app/core' import { PluginService } from '@app/core/plugins/plugin.service' -import { I18n } from '@ngx-translate/i18n-polyfill' import { compareSemVer } from '@shared/core-utils/miscs/miscs' import { PeerTubePlugin } from '@shared/models/plugins/peertube-plugin.model' import { PluginType } from '@shared/models/plugins/plugin.type' @@ -37,7 +36,6 @@ export class PluginListInstalledComponent implements OnInit { onDataSubject = new Subject() constructor ( - private i18n: I18n, private pluginService: PluginService, private pluginApiService: PluginApiService, private notifier: Notifier, @@ -88,10 +86,10 @@ export class PluginListInstalledComponent implements OnInit { getNoResultMessage () { if (this.pluginType === PluginType.PLUGIN) { - return this.i18n("You don't have plugins installed yet.") + return $localize`You don't have plugins installed yet.` } - return this.i18n("You don't have themes installed yet.") + return $localize`You don't have themes installed yet.` } isUpdateAvailable (plugin: PeerTubePlugin) { @@ -99,7 +97,7 @@ export class PluginListInstalledComponent implements OnInit { } getUpdateLabel (plugin: PeerTubePlugin) { - return this.i18n('Update to {{version}}', { version: plugin.latestVersion }) + return $localize`Update to ${plugin.latestVersion}` } isUpdating (plugin: PeerTubePlugin) { @@ -108,15 +106,15 @@ export class PluginListInstalledComponent implements OnInit { async uninstall (plugin: PeerTubePlugin) { const res = await this.confirmService.confirm( - this.i18n('Do you really want to uninstall {{pluginName}}?', { pluginName: plugin.name }), - this.i18n('Uninstall') + $localize`Do you really want to uninstall ${plugin.name}?`, + $localize`Uninstall` ) if (res === false) return this.pluginApiService.uninstall(plugin.name, plugin.type) .subscribe( () => { - this.notifier.success(this.i18n('{{pluginName}} uninstalled.', { pluginName: plugin.name })) + this.notifier.success($localize`${plugin.name} uninstalled.`) this.plugins = this.plugins.filter(p => p.name !== plugin.name) this.pagination.totalItems-- @@ -138,7 +136,7 @@ export class PluginListInstalledComponent implements OnInit { res => { this.updating[updatingKey] = false - this.notifier.success(this.i18n('{{pluginName}} updated.', { pluginName: plugin.name })) + this.notifier.success($localize`${plugin.name} updated.`) Object.assign(plugin, res) }, diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts index ccf9f1ed5..1a6b4eba3 100644 --- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts +++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts @@ -3,8 +3,7 @@ import { debounceTime, distinctUntilChanged } from 'rxjs/operators' import { Component, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { PluginApiService } from '@app/+admin/plugins/shared/plugin-api.service' -import { ComponentPagination, ConfirmService, hasMoreItems, Notifier, ServerService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' +import { ComponentPagination, ConfirmService, hasMoreItems, Notifier } from '@app/core' import { PeerTubePluginIndex } from '@shared/models/plugins/peertube-plugin-index.model' import { PluginType } from '@shared/models/plugins/plugin.type' @@ -40,8 +39,6 @@ export class PluginSearchComponent implements OnInit { private searchSubject = new Subject() constructor ( - private server: ServerService, - private i18n: I18n, private pluginService: PluginApiService, private notifier: Notifier, private confirmService: ConfirmService, @@ -100,7 +97,7 @@ export class PluginSearchComponent implements OnInit { err => { console.error(err) - const message = this.i18n('The plugin index is not available. Please retry later.') + const message = $localize`The plugin index is not available. Please retry later.` this.notifier.error(message) } ) @@ -122,8 +119,8 @@ export class PluginSearchComponent implements OnInit { if (this.installing[plugin.npmName]) return const res = await this.confirmService.confirm( - this.i18n('Please only install plugins or themes you trust, since they can execute any code on your instance.'), - this.i18n('Install {{pluginName}}?', { pluginName: plugin.name }) + $localize`Please only install plugins or themes you trust, since they can execute any code on your instance.`, + $localize`Install ${plugin.name}?` ) if (res === false) return @@ -135,7 +132,7 @@ export class PluginSearchComponent implements OnInit { this.installing[plugin.npmName] = false this.pluginInstalled = true - this.notifier.success(this.i18n('{{pluginName}} installed.', { pluginName: plugin.name })) + this.notifier.success($localize`${plugin.name} installed.`) plugin.installed = true }, diff --git a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts index dde03f1da..a33f01691 100644 --- a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts +++ b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts @@ -4,7 +4,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core' import { ActivatedRoute } from '@angular/router' import { Notifier } from '@app/core' import { BuildFormArgument, FormReactive, FormValidatorService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { PeerTubePlugin, RegisterServerSettingOptions } from '@shared/models' import { PluginApiService } from '../shared/plugin-api.service' @@ -22,7 +21,6 @@ export class PluginShowInstalledComponent extends FormReactive implements OnInit constructor ( protected formValidatorService: FormValidatorService, - private i18n: I18n, private pluginService: PluginApiService, private notifier: Notifier, private route: ActivatedRoute @@ -50,7 +48,7 @@ export class PluginShowInstalledComponent extends FormReactive implements OnInit this.pluginService.updatePluginSettings(this.plugin.name, this.plugin.type, settings) .subscribe( () => { - this.notifier.success(this.i18n('Settings updated.')) + this.notifier.success($localize`Settings updated.`) }, err => this.notifier.error(err.message) diff --git a/client/src/app/+admin/plugins/shared/plugin-api.service.ts b/client/src/app/+admin/plugins/shared/plugin-api.service.ts index 1fb827832..b28d46df4 100644 --- a/client/src/app/+admin/plugins/shared/plugin-api.service.ts +++ b/client/src/app/+admin/plugins/shared/plugin-api.service.ts @@ -4,7 +4,6 @@ import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { ComponentPagination, RestExtractor, RestService } from '@app/core' import { PluginService } from '@app/core/plugins/plugin.service' -import { I18n } from '@ngx-translate/i18n-polyfill' import { peertubeTranslate } from '@shared/core-utils/i18n' import { InstallOrUpdatePlugin, @@ -25,18 +24,17 @@ export class PluginApiService { private authHttp: HttpClient, private restExtractor: RestExtractor, private restService: RestService, - private i18n: I18n, private pluginService: PluginService ) { } getPluginTypeOptions () { return [ { - label: this.i18n('Plugins'), + label: $localize`Plugins`, value: PluginType.PLUGIN }, { - label: this.i18n('Themes'), + label: $localize`Themes`, value: PluginType.THEME } ] @@ -44,10 +42,10 @@ export class PluginApiService { getPluginTypeLabel (type: PluginType) { if (type === PluginType.PLUGIN) { - return this.i18n('plugin') + return $localize`plugin` } - return this.i18n('theme') + return $localize`theme` } getPlugins ( diff --git a/client/src/app/+admin/system/jobs/jobs.component.ts b/client/src/app/+admin/system/jobs/jobs.component.ts index ceb848976..96e0f25b0 100644 --- a/client/src/app/+admin/system/jobs/jobs.component.ts +++ b/client/src/app/+admin/system/jobs/jobs.component.ts @@ -2,7 +2,6 @@ import { SortMeta } from 'primeng/api' import { Component, OnInit } from '@angular/core' import { Notifier, RestPagination, RestTable } from '@app/core' import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage' -import { I18n } from '@ngx-translate/i18n-polyfill' import { Job, JobState, JobType } from '@shared/models' import { JobStateClient } from '../../../../types/job-state-client.type' import { JobTypeClient } from '../../../../types/job-type-client.type' @@ -43,9 +42,8 @@ export class JobsComponent extends RestTable implements OnInit { constructor ( private notifier: Notifier, - private jobsService: JobService, - private i18n: I18n - ) { + private jobsService: JobService + ) { super() } diff --git a/client/src/app/+admin/system/logs/logs.component.ts b/client/src/app/+admin/system/logs/logs.component.ts index 51f047188..c9c9dc3d1 100644 --- a/client/src/app/+admin/system/logs/logs.component.ts +++ b/client/src/app/+admin/system/logs/logs.component.ts @@ -1,6 +1,5 @@ import { Component, ElementRef, OnInit, ViewChild } from '@angular/core' import { Notifier } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { LogLevel } from '@shared/models' import { LogRow } from './log-row.model' import { LogsService } from './logs.service' @@ -25,9 +24,8 @@ export class LogsComponent implements OnInit { constructor ( private logsService: LogsService, - private notifier: Notifier, - private i18n: I18n - ) { } + private notifier: Notifier + ) { } ngOnInit (): void { this.buildTimeChoices() @@ -78,15 +76,15 @@ export class LogsComponent implements OnInit { this.timeChoices = [ { id: lastWeek.toISOString(), - label: this.i18n('Last week') + label: $localize`Last week` }, { id: lastDay.toISOString(), - label: this.i18n('Last day') + label: $localize`Last day` }, { id: lastHour.toISOString(), - label: this.i18n('Last hour') + label: $localize`Last hour` } ] @@ -97,19 +95,19 @@ export class LogsComponent implements OnInit { this.levelChoices = [ { id: 'debug', - label: this.i18n('Debug') + label: $localize`Debug` }, { id: 'info', - label: this.i18n('Info') + label: $localize`Info` }, { id: 'warn', - label: this.i18n('Warning') + label: $localize`Warning` }, { id: 'error', - label: this.i18n('Error') + label: $localize`Error` } ] @@ -120,11 +118,11 @@ export class LogsComponent implements OnInit { this.logTypeChoices = [ { id: 'standard', - label: this.i18n('Standard logs') + label: $localize`Standard logs` }, { id: 'audit', - label: this.i18n('Audit logs') + label: $localize`Audit logs` } ] diff --git a/client/src/app/+admin/users/user-edit/user-create.component.ts b/client/src/app/+admin/users/user-edit/user-create.component.ts index 3fddb9c09..36d71a927 100644 --- a/client/src/app/+admin/users/user-edit/user-create.component.ts +++ b/client/src/app/+admin/users/user-edit/user-create.component.ts @@ -3,7 +3,6 @@ import { ActivatedRoute, Router } from '@angular/router' import { ConfigService } from '@app/+admin/config/shared/config.service' import { AuthService, Notifier, ScreenService, ServerService, UserService } from '@app/core' import { FormValidatorService, UserValidatorsService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { UserCreate, UserRole } from '@shared/models' import { UserEdit } from './user-edit' @@ -25,9 +24,8 @@ export class UserCreateComponent extends UserEdit implements OnInit { private route: ActivatedRoute, private router: Router, private notifier: Notifier, - private userService: UserService, - private i18n: I18n - ) { + private userService: UserService + ) { super() this.buildQuotaOptions() @@ -67,7 +65,7 @@ export class UserCreateComponent extends UserEdit implements OnInit { this.userService.addUser(userCreate).subscribe( () => { - this.notifier.success(this.i18n('User {{username}} created.', { username: userCreate.username })) + this.notifier.success($localize`User ${userCreate.username} created.`) this.router.navigate([ '/admin/users/list' ]) }, @@ -85,6 +83,6 @@ export class UserCreateComponent extends UserEdit implements OnInit { } getFormButtonTitle () { - return this.i18n('Create user') + return $localize`Create user` } } diff --git a/client/src/app/+admin/users/user-edit/user-password.component.ts b/client/src/app/+admin/users/user-edit/user-password.component.ts index 33c7de31f..25f13495a 100644 --- a/client/src/app/+admin/users/user-edit/user-password.component.ts +++ b/client/src/app/+admin/users/user-edit/user-password.component.ts @@ -1,7 +1,6 @@ import { Component, Input, OnInit } from '@angular/core' import { Notifier, UserService } from '@app/core' import { FormReactive, FormValidatorService, UserValidatorsService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { UserUpdate } from '@shared/models' @Component({ @@ -20,9 +19,8 @@ export class UserPasswordComponent extends FormReactive implements OnInit { protected formValidatorService: FormValidatorService, private userValidatorsService: UserValidatorsService, private notifier: Notifier, - private userService: UserService, - private i18n: I18n - ) { + private userService: UserService + ) { super() } @@ -39,9 +37,7 @@ export class UserPasswordComponent extends FormReactive implements OnInit { this.userService.updateUser(this.userId, userUpdate).subscribe( () => { - this.notifier.success( - this.i18n('Password changed for user {{username}}.', { username: this.username }) - ) + this.notifier.success($localize`Password changed for user ${this.username}.`) }, err => this.error = err.message @@ -53,6 +49,6 @@ export class UserPasswordComponent extends FormReactive implements OnInit { } getFormButtonTitle () { - return this.i18n('Update user password') + return $localize`Update user password` } } diff --git a/client/src/app/+admin/users/user-edit/user-update.component.ts b/client/src/app/+admin/users/user-edit/user-update.component.ts index 870880fee..55bc7290e 100644 --- a/client/src/app/+admin/users/user-edit/user-update.component.ts +++ b/client/src/app/+admin/users/user-edit/user-update.component.ts @@ -4,7 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router' import { ConfigService } from '@app/+admin/config/shared/config.service' import { AuthService, Notifier, ScreenService, ServerService, User, UserService } from '@app/core' import { FormValidatorService, UserValidatorsService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { User as UserType, UserAdminFlag, UserRole, UserUpdate } from '@shared/models' import { UserEdit } from './user-edit' @@ -28,9 +27,8 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { private route: ActivatedRoute, private router: Router, private notifier: Notifier, - private userService: UserService, - private i18n: I18n - ) { + private userService: UserService + ) { super() this.buildQuotaOptions() @@ -79,7 +77,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { this.userService.updateUser(this.user.id, userUpdate).subscribe( () => { - this.notifier.success(this.i18n('User {{username}} updated.', { username: this.user.username })) + this.notifier.success($localize`User ${this.user.username} updated.`) this.router.navigate([ '/admin/users/list' ]) }, @@ -96,15 +94,13 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { } getFormButtonTitle () { - return this.i18n('Update user') + return $localize`Update user` } resetPassword () { this.userService.askResetPassword(this.user.email).subscribe( () => { - this.notifier.success( - this.i18n('An email asking for password reset has been sent to {{username}}.', { username: this.user.username }) - ) + this.notifier.success($localize`An email asking for password reset has been sent to ${this.user.username}.`) }, err => this.error = err.message diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts index 69d4e917d..86812f73d 100644 --- a/client/src/app/+admin/users/user-list/user-list.component.ts +++ b/client/src/app/+admin/users/user-list/user-list.component.ts @@ -1,11 +1,10 @@ import { SortMeta } from 'primeng/api' import { Component, OnInit, ViewChild } from '@angular/core' +import { ActivatedRoute, Params, Router } from '@angular/router' import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService, UserService } from '@app/core' import { Actor, DropdownAction } from '@app/shared/shared-main' import { UserBanModalComponent } from '@app/shared/shared-moderation' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig, User, UserRole } from '@shared/models' -import { Params, Router, ActivatedRoute } from '@angular/router' type UserForList = User & { rawVideoQuota: number @@ -42,9 +41,8 @@ export class UserListComponent extends RestTable implements OnInit { private userService: UserService, private auth: AuthService, private route: ActivatedRoute, - private router: Router, - private i18n: I18n - ) { + private router: Router + ) { super() } @@ -82,26 +80,26 @@ export class UserListComponent extends RestTable implements OnInit { this.bulkUserActions = [ [ { - label: this.i18n('Delete'), - description: this.i18n('Videos will be deleted, comments will be tombstoned.'), + label: $localize`Delete`, + description: $localize`Videos will be deleted, comments will be tombstoned.`, handler: users => this.removeUsers(users), isDisplayed: users => users.every(u => this.authUser.canManage(u)) }, { - label: this.i18n('Ban'), - description: this.i18n('User won\'t be able to login anymore, but videos and comments will be kept as is.'), + label: $localize`Ban`, + description: $localize`User won't be able to login anymore, but videos and comments will be kept as is.`, handler: users => this.openBanUserModal(users), isDisplayed: users => users.every(u => this.authUser.canManage(u) && u.blocked === false) }, { - label: this.i18n('Unban'), + label: $localize`Unban`, handler: users => this.unbanUsers(users), isDisplayed: users => users.every(u => this.authUser.canManage(u) && u.blocked === true) } ], [ { - label: this.i18n('Set Email as Verified'), + label: $localize`Set Email as Verified`, handler: users => this.setEmailsAsVerified(users), isDisplayed: users => { return this.requiresEmailVerification && @@ -160,7 +158,7 @@ export class UserListComponent extends RestTable implements OnInit { openBanUserModal (users: User[]) { for (const user of users) { if (user.username === 'root') { - this.notifier.error(this.i18n('You cannot ban root.')) + this.notifier.error($localize`You cannot ban root.`) return } } @@ -197,17 +195,13 @@ export class UserListComponent extends RestTable implements OnInit { } async unbanUsers (users: User[]) { - const message = this.i18n('Do you really want to unban {{num}} users?', { num: users.length }) - - const res = await this.confirmService.confirm(message, this.i18n('Unban')) + const res = await this.confirmService.confirm($localize`Do you really want to unban ${users.length} users?`, $localize`Unban`) if (res === false) return this.userService.unbanUsers(users) .subscribe( () => { - const message = this.i18n('{{num}} users unbanned.', { num: users.length }) - - this.notifier.success(message) + this.notifier.success($localize`${users.length} users unbanned.`) this.loadData() }, @@ -218,18 +212,18 @@ export class UserListComponent extends RestTable implements OnInit { async removeUsers (users: User[]) { for (const user of users) { if (user.username === 'root') { - this.notifier.error(this.i18n('You cannot delete root.')) + this.notifier.error($localize`You cannot delete root.`) return } } - const message = this.i18n('If you remove these users, you will not be able to create others with the same username!') - const res = await this.confirmService.confirm(message, this.i18n('Delete')) + const message = $localize`If you remove these users, you will not be able to create others with the same username!` + const res = await this.confirmService.confirm(message, $localize`Delete`) if (res === false) return this.userService.removeUser(users).subscribe( () => { - this.notifier.success(this.i18n('{{num}} users deleted.', { num: users.length })) + this.notifier.success($localize`${users.length} users deleted.`) this.loadData() }, @@ -240,7 +234,7 @@ export class UserListComponent extends RestTable implements OnInit { async setEmailsAsVerified (users: User[]) { this.userService.updateUsers(users, { emailVerified: true }).subscribe( () => { - this.notifier.success(this.i18n('{{num}} users email set as verified.', { num: users.length })) + this.notifier.success($localize`${users.length} users email set as verified.`) this.loadData() }, diff --git a/client/src/app/+login/login.component.ts b/client/src/app/+login/login.component.ts index e5a382218..e9336172e 100644 --- a/client/src/app/+login/login.component.ts +++ b/client/src/app/+login/login.component.ts @@ -5,7 +5,6 @@ import { AuthService, Notifier, RedirectService, UserService } from '@app/core' import { HooksService } from '@app/core/plugins/hooks.service' import { FormReactive, FormValidatorService, LoginValidatorsService } from '@app/shared/shared-forms' import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { RegisteredExternalAuthConfig, ServerConfig } from '@shared/models' @Component({ @@ -37,9 +36,8 @@ export class LoginComponent extends FormReactive implements OnInit, AfterViewIni private userService: UserService, private redirectService: RedirectService, private notifier: Notifier, - private hooks: HooksService, - private i18n: I18n - ) { + private hooks: HooksService + ) { super() } @@ -105,10 +103,9 @@ export class LoginComponent extends FormReactive implements OnInit, AfterViewIni this.userService.askResetPassword(this.forgotPasswordEmail) .subscribe( () => { - const message = this.i18n( - 'An email with the reset password instructions will be sent to {{email}}. The link will expire within 1 hour.', - { email: this.forgotPasswordEmail } - ) + const message = $localize`An email with the reset password instructions will be sent to ${this.forgotPasswordEmail}. +The link will expire within 1 hour.` + this.notifier.success(message) this.hideForgotPasswordModal() }, @@ -140,8 +137,8 @@ export class LoginComponent extends FormReactive implements OnInit, AfterViewIni } private handleError (err: any) { - if (err.message.indexOf('credentials are invalid') !== -1) this.error = this.i18n('Incorrect username or password.') - else if (err.message.indexOf('blocked') !== -1) this.error = this.i18n('Your account is blocked.') + if (err.message.indexOf('credentials are invalid') !== -1) this.error = $localize`Incorrect username or password.` + else if (err.message.indexOf('blocked') !== -1) this.error = $localize`Your account is blocked.` else this.error = err.message } } diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-create.component.ts b/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-create.component.ts index 039c389e4..5c438c3bf 100644 --- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-create.component.ts +++ b/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-create.component.ts @@ -3,7 +3,6 @@ import { Router } from '@angular/router' import { AuthService, Notifier } from '@app/core' import { FormValidatorService, VideoChannelValidatorsService } from '@app/shared/shared-forms' import { VideoChannelService } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoChannelCreate } from '@shared/models' import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' @@ -21,9 +20,8 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE private videoChannelValidatorsService: VideoChannelValidatorsService, private notifier: Notifier, private router: Router, - private videoChannelService: VideoChannelService, - private i18n: I18n - ) { + private videoChannelService: VideoChannelService + ) { super() } @@ -55,15 +53,13 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE () => { this.authService.refreshUserInformation() - this.notifier.success( - this.i18n('Video channel {{videoChannelName}} created.', { videoChannelName: videoChannelCreate.displayName }) - ) + this.notifier.success($localize`Video channel ${videoChannelCreate.displayName} created.`) this.router.navigate([ '/my-account', 'video-channels' ]) }, err => { if (err.status === 409) { - this.error = this.i18n('This name already exists on this instance.') + this.error = $localize`This name already exists on this instance.` return } @@ -77,6 +73,6 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE } getFormButtonTitle () { - return this.i18n('Create') + return $localize`Create` } } diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-update.component.ts b/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-update.component.ts index 489c437ea..485521dcc 100644 --- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-update.component.ts +++ b/client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-update.component.ts @@ -4,7 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router' import { AuthService, Notifier, ServerService } from '@app/core' import { FormValidatorService, VideoChannelValidatorsService } from '@app/shared/shared-forms' import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig, VideoChannelUpdate } from '@shared/models' import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' @@ -29,7 +28,6 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE private router: Router, private route: ActivatedRoute, private videoChannelService: VideoChannelService, - private i18n: I18n, private serverService: ServerService ) { super() @@ -87,9 +85,7 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE () => { this.authService.refreshUserInformation() - this.notifier.success( - this.i18n('Video channel {{videoChannelName}} updated.', { videoChannelName: videoChannelUpdate.displayName }) - ) + this.notifier.success($localize`Video channel ${videoChannelUpdate.displayName} updated.`) this.router.navigate([ '/my-account', 'video-channels' ]) }, @@ -102,7 +98,7 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE this.videoChannelService.changeVideoChannelAvatar(this.videoChannelToUpdate.name, formData) .subscribe( data => { - this.notifier.success(this.i18n('Avatar changed.')) + this.notifier.success($localize`Avatar changed.`) this.videoChannelToUpdate.updateAvatar(data.avatar) }, @@ -124,7 +120,7 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE } getFormButtonTitle () { - return this.i18n('Update') + return $localize`Update` } isBulkUpdateVideosDisplayed () { diff --git a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.ts b/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.ts index ad9368794..2aff09cd9 100644 --- a/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.ts +++ b/client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.ts @@ -1,11 +1,10 @@ import { ChartData } from 'chart.js' import { max, maxBy, min, minBy } from 'lodash-es' -import { flatMap, debounceTime } from 'rxjs/operators' +import { Subject } from 'rxjs' +import { debounceTime, mergeMap } from 'rxjs/operators' import { Component, OnInit } from '@angular/core' import { AuthService, ConfirmService, Notifier, ScreenService, User } from '@app/core' import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Subject } from 'rxjs' @Component({ selector: 'my-account-video-channels', @@ -30,9 +29,8 @@ export class MyAccountVideoChannelsComponent implements OnInit { private notifier: Notifier, private confirmService: ConfirmService, private videoChannelService: VideoChannelService, - private screenService: ScreenService, - private i18n: I18n - ) {} + private screenService: ScreenService + ) {} ngOnInit () { this.user = this.authService.getUser() @@ -110,17 +108,13 @@ export class MyAccountVideoChannelsComponent implements OnInit { async deleteVideoChannel (videoChannel: VideoChannel) { const res = await this.confirmService.confirmWithInput( - this.i18n( - // tslint:disable - 'Do you really want to delete {{channelDisplayName}}? It will delete {{videosCount}} videos uploaded in this channel, and you will not be able to create another channel with the same name ({{channelName}})!', - { channelDisplayName: videoChannel.displayName, videosCount: videoChannel.videosCount, channelName: videoChannel.name } - ), - this.i18n( - 'Please type the display name of the video channel ({{displayName}}) to confirm', - { displayName: videoChannel.displayName } - ), - videoChannel.displayName, - this.i18n('Delete') + $localize`Do you really want to delete ${videoChannel.displayName}? +It will delete ${videoChannel.videosCount} videos uploaded in this channel, and you will not be able to create another +channel with the same name (${videoChannel.name})!`, + + $localize`Please type the display name of the video channel (${videoChannel.displayName}) to confirm`, + + $localize`Delete` ) if (res === false) return @@ -128,9 +122,7 @@ export class MyAccountVideoChannelsComponent implements OnInit { .subscribe( () => { this.loadVideoChannels() - this.notifier.success( - this.i18n('Video channel {{videoChannelName}} deleted.', { videoChannelName: videoChannel.displayName }) - ) + this.notifier.success($localize`Video channel ${videoChannel.displayName} deleted.`) }, error => this.notifier.error(error.message) @@ -139,7 +131,7 @@ export class MyAccountVideoChannelsComponent implements OnInit { private loadVideoChannels () { this.authService.userInformationLoaded - .pipe(flatMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account, null, true, this.channelsSearch))) + .pipe(mergeMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account, null, true, this.channelsSearch))) .subscribe(res => { this.videoChannels = res.data this.totalItems = res.total @@ -149,10 +141,10 @@ export class MyAccountVideoChannelsComponent implements OnInit { labels: v.viewsPerDay.map(day => day.date.toLocaleDateString()), datasets: [ { - label: this.i18n('Views for the day'), - data: v.viewsPerDay.map(day => day.views), - fill: false, - borderColor: "#c6c6c6" + label: $localize`Views for the day`, + data: v.viewsPerDay.map(day => day.views), + fill: false, + borderColor: '#c6c6c6' } ] } as ChartData)) @@ -160,13 +152,15 @@ export class MyAccountVideoChannelsComponent implements OnInit { // chart options that depend on chart data: // we don't want to skew values and have min at 0, so we define what the floor/ceiling is here this.videoChannelsMinimumDailyViews = min( - this.videoChannels.map(v => minBy( // compute local minimum daily views for each channel, by their "views" attribute + // compute local minimum daily views for each channel, by their "views" attribute + this.videoChannels.map(v => minBy( v.viewsPerDay, day => day.views ).views) // the object returned is a ViewPerDate, so we still need to get the views attribute ) this.videoChannelsMaximumDailyViews = max( - this.videoChannels.map(v => maxBy( // compute local maximum daily views for each channel, by their "views" attribute + // compute local maximum daily views for each channel, by their "views" attribute + this.videoChannels.map(v => maxBy( v.viewsPerDay, day => day.views ).views) // the object returned is a ViewPerDate, so we still need to get the views attribute diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.ts b/client/src/app/+my-account/my-account-history/my-account-history.component.ts index dc78b3d6e..3298c56c7 100644 --- a/client/src/app/+my-account/my-account-history/my-account-history.component.ts +++ b/client/src/app/+my-account/my-account-history/my-account-history.component.ts @@ -13,7 +13,6 @@ import { import { immutableAssign } from '@app/helpers' import { UserHistoryService } from '@app/shared/shared-main' import { AbstractVideoList } from '@app/shared/shared-video-miniature' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-account-history', @@ -30,7 +29,6 @@ export class MyAccountHistoryComponent extends AbstractVideoList implements OnIn videosHistoryEnabled: boolean constructor ( - protected i18n: I18n, protected router: Router, protected serverService: ServerService, protected route: ActivatedRoute, @@ -44,7 +42,7 @@ export class MyAccountHistoryComponent extends AbstractVideoList implements OnIn ) { super() - this.titlePage = this.i18n('My videos history') + this.titlePage = $localize`My videos history` } ngOnInit () { @@ -72,8 +70,8 @@ export class MyAccountHistoryComponent extends AbstractVideoList implements OnIn .subscribe( () => { const message = this.videosHistoryEnabled === true ? - this.i18n('Videos history is enabled') : - this.i18n('Videos history is disabled') + $localize`Videos history is enabled` : + $localize`Videos history is disabled` this.notifier.success(message) @@ -85,8 +83,8 @@ export class MyAccountHistoryComponent extends AbstractVideoList implements OnIn } async deleteHistory () { - const title = this.i18n('Delete videos history') - const message = this.i18n('Are you sure you want to delete all your videos history?') + const title = $localize`Delete videos history` + const message = $localize`Are you sure you want to delete all your videos history?` const res = await this.confirmService.confirm(message, title) if (res !== true) return @@ -94,7 +92,7 @@ export class MyAccountHistoryComponent extends AbstractVideoList implements OnIn this.userHistoryService.deleteUserVideosHistory() .subscribe( () => { - this.notifier.success(this.i18n('Videos history deleted')) + this.notifier.success($localize`Videos history deleted`) this.reloadVideos() }, diff --git a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts b/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts index 0e62b5ca5..3bfffe2da 100644 --- a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts +++ b/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts @@ -3,7 +3,6 @@ import { AuthService, Notifier } from '@app/core' import { FormReactive, FormValidatorService, VideoAcceptOwnershipValidatorsService } from '@app/shared/shared-forms' import { VideoChannelService, VideoOwnershipService } from '@app/shared/shared-main' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoChangeOwnership, VideoChannel } from '@shared/models' @Component({ @@ -29,9 +28,8 @@ export class MyAccountAcceptOwnershipComponent extends FormReactive implements O private notifier: Notifier, private authService: AuthService, private videoChannelService: VideoChannelService, - private modalService: NgbModal, - private i18n: I18n - ) { + private modalService: NgbModal + ) { super() } @@ -63,7 +61,7 @@ export class MyAccountAcceptOwnershipComponent extends FormReactive implements O .acceptOwnership(videoChangeOwnership.id, { channelId: channel }) .subscribe( () => { - this.notifier.success(this.i18n('Ownership accepted')) + this.notifier.success($localize`Ownership accepted`) if (this.accepted) this.accepted.emit() this.videoChangeOwnership = undefined }, diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.ts b/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.ts index 5444b97ae..396936ef3 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.ts @@ -3,7 +3,6 @@ import { tap } from 'rxjs/operators' import { Component, OnInit } from '@angular/core' import { AuthService, ServerService, UserService } from '@app/core' import { FormReactive, FormValidatorService, UserValidatorsService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { User } from '@shared/models' @Component({ @@ -21,9 +20,8 @@ export class MyAccountChangeEmailComponent extends FormReactive implements OnIni private userValidatorsService: UserValidatorsService, private authService: AuthService, private userService: UserService, - private serverService: ServerService, - private i18n: I18n - ) { + private serverService: ServerService + ) { super() } @@ -52,15 +50,15 @@ export class MyAccountChangeEmailComponent extends FormReactive implements OnIni this.form.reset() if (config.signup.requiresEmailVerification) { - this.success = this.i18n('Please check your emails to verify your new email.') + this.success = $localize`Please check your emails to verify your new email.` } else { - this.success = this.i18n('Email updated.') + this.success = $localize`Email updated.` } }, err => { if (err.status === 401) { - this.error = this.i18n('You current password is invalid.') + this.error = $localize`You current password is invalid.` return } diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts index 6a16f8a2c..91fe4ec72 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts @@ -2,7 +2,6 @@ import { filter } from 'rxjs/operators' import { Component, OnInit } from '@angular/core' import { AuthService, Notifier, UserService } from '@app/core' import { FormReactive, FormValidatorService, UserValidatorsService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { User } from '@shared/models' @Component({ @@ -19,9 +18,8 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On private userValidatorsService: UserValidatorsService, private notifier: Notifier, private authService: AuthService, - private userService: UserService, - private i18n: I18n - ) { + private userService: UserService + ) { super() } @@ -47,7 +45,7 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On this.userService.changePassword(currentPassword, newPassword).subscribe( () => { - this.notifier.success(this.i18n('Password updated.')) + this.notifier.success($localize`Password updated.`) this.form.reset() this.error = null @@ -55,7 +53,7 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On err => { if (err.status === 401) { - this.error = this.i18n('You current password is invalid.') + this.error = $localize`You current password is invalid.` return } diff --git a/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts b/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts index ae6ac5387..387e9e7cd 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts @@ -1,6 +1,5 @@ import { Component, Input } from '@angular/core' import { AuthService, ConfirmService, Notifier, RedirectService, User, UserService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-account-danger-zone', @@ -15,23 +14,22 @@ export class MyAccountDangerZoneComponent { private notifier: Notifier, private userService: UserService, private confirmService: ConfirmService, - private redirectService: RedirectService, - private i18n: I18n - ) { } + private redirectService: RedirectService + ) { } async deleteMe () { const res = await this.confirmService.confirmWithInput( - this.i18n('Are you sure you want to delete your account? This will delete all your data, including channels, videos and comments. Content cached by other servers and other third-parties might make longer to be deleted.'), - this.i18n('Type your username to confirm'), + $localize`Are you sure you want to delete your account? This will delete all your data, including channels, videos and comments. Content cached by other servers and other third-parties might make longer to be deleted.`, + $localize`Type your username to confirm`, this.user.username, - this.i18n('Delete your account'), - this.i18n('Delete my account') + $localize`Delete your account`, + $localize`Delete my account` ) if (res === false) return this.userService.deleteMe().subscribe( () => { - this.notifier.success(this.i18n('Your account is deleted.')) + this.notifier.success($localize`Your account is deleted.`) this.authService.logout() this.redirectService.redirectToHomepage() diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts index b892ab479..bcbea7fad 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts @@ -3,7 +3,6 @@ import { Subject } from 'rxjs' import { Component, Input, OnInit } from '@angular/core' import { Notifier, ServerService, User } from '@app/core' import { UserNotificationService } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { UserNotificationSetting, UserNotificationSettingValue, UserRight } from '@shared/models' @Component({ @@ -25,26 +24,25 @@ export class MyAccountNotificationPreferencesComponent implements OnInit { private savePreferences = debounce(this.savePreferencesImpl.bind(this), 500) constructor ( - private i18n: I18n, private userNotificationService: UserNotificationService, private serverService: ServerService, private notifier: Notifier ) { this.labelNotifications = { - newVideoFromSubscription: this.i18n('New video from your subscriptions'), - newCommentOnMyVideo: this.i18n('New comment on your video'), - abuseAsModerator: this.i18n('New abuse'), - videoAutoBlacklistAsModerator: this.i18n('Video blocked automatically waiting review'), - blacklistOnMyVideo: this.i18n('One of your video is blocked/unblocked'), - myVideoPublished: this.i18n('Video published (after transcoding/scheduled update)'), - myVideoImportFinished: this.i18n('Video import finished'), - newUserRegistration: this.i18n('A new user registered on your instance'), - newFollow: this.i18n('You or your channel(s) has a new follower'), - commentMention: this.i18n('Someone mentioned you in video comments'), - newInstanceFollower: this.i18n('Your instance has a new follower'), - autoInstanceFollowing: this.i18n('Your instance automatically followed another instance'), - abuseNewMessage: this.i18n('An abuse report received a new message'), - abuseStateChange: this.i18n('One of your abuse reports has been accepted or rejected by moderators') + newVideoFromSubscription: $localize`New video from your subscriptions`, + newCommentOnMyVideo: $localize`New comment on your video`, + abuseAsModerator: $localize`New abuse`, + videoAutoBlacklistAsModerator: $localize`Video blocked automatically waiting review`, + blacklistOnMyVideo: $localize`One of your video is blocked/unblocked`, + myVideoPublished: $localize`Video published (after transcoding/scheduled update)`, + myVideoImportFinished: $localize`Video import finished`, + newUserRegistration: $localize`A new user registered on your instance`, + newFollow: $localize`You or your channel(s) has a new follower`, + commentMention: $localize`Someone mentioned you in video comments`, + newInstanceFollower: $localize`Your instance has a new follower`, + autoInstanceFollowing: $localize`Your instance automatically followed another instance`, + abuseNewMessage: $localize`An abuse report received a new message`, + abuseStateChange: $localize`One of your abuse reports has been accepted or rejected by moderators` } this.notificationSettingKeys = Object.keys(this.labelNotifications) as (keyof UserNotificationSetting)[] @@ -91,7 +89,7 @@ export class MyAccountNotificationPreferencesComponent implements OnInit { this.userNotificationService.updateNotificationSettings(this.user, this.user.notificationSettings) .subscribe( () => { - this.notifier.success(this.i18n('Preferences saved'), undefined, 2000) + this.notifier.success($localize`Preferences saved`, undefined, 2000) }, err => this.notifier.error(err.message) diff --git a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts index b0d8494e7..ed0984bf7 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts @@ -2,7 +2,6 @@ import { Subject } from 'rxjs' import { Component, Input, OnInit } from '@angular/core' import { Notifier, User, UserService } from '@app/core' import { FormReactive, FormValidatorService, UserValidatorsService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-account-profile', @@ -19,9 +18,8 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit { protected formValidatorService: FormValidatorService, private userValidatorsService: UserValidatorsService, private notifier: Notifier, - private userService: UserService, - private i18n: I18n - ) { + private userService: UserService + ) { super() } @@ -50,7 +48,7 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit { this.user.account.displayName = displayName this.user.account.description = description - this.notifier.success(this.i18n('Profile updated.')) + this.notifier.success($localize`Profile updated.`) }, err => this.error = err.message diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts index a3a8ff1f1..7ea4610d4 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts @@ -1,7 +1,6 @@ import { ViewportScroller } from '@angular/common' import { AfterViewChecked, Component, OnInit } from '@angular/core' import { AuthService, Notifier, User, UserService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-account-settings', @@ -17,9 +16,8 @@ export class MyAccountSettingsComponent implements OnInit, AfterViewChecked { private viewportScroller: ViewportScroller, private userService: UserService, private authService: AuthService, - private notifier: Notifier, - private i18n: I18n - ) {} + private notifier: Notifier + ) {} get userInformationLoaded () { return this.authService.userInformationLoaded @@ -41,7 +39,7 @@ export class MyAccountSettingsComponent implements OnInit, AfterViewChecked { this.userService.changeAvatar(formData) .subscribe( data => { - this.notifier.success(this.i18n('Avatar changed.')) + this.notifier.success($localize`Avatar changed.`) this.user.updateAccountAvatar(data.avatar) }, diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts index e72ae2366..5427dc3a0 100644 --- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts +++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts @@ -1,13 +1,12 @@ import { Component, OnInit } from '@angular/core' import { Router } from '@angular/router' import { AuthService, Notifier, ServerService } from '@app/core' +import { populateAsyncUserVideoChannels } from '@app/helpers' import { FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/shared-forms' import { VideoPlaylistService } from '@app/shared/shared-video-playlist' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoPlaylistCreate } from '@shared/models/videos/playlist/video-playlist-create.model' import { VideoPlaylistPrivacy } from '@shared/models/videos/playlist/video-playlist-privacy.model' import { MyAccountVideoPlaylistEdit } from './my-account-video-playlist-edit' -import { populateAsyncUserVideoChannels } from '@app/helpers' @Component({ selector: 'my-account-video-playlist-create', @@ -24,9 +23,8 @@ export class MyAccountVideoPlaylistCreateComponent extends MyAccountVideoPlaylis private notifier: Notifier, private router: Router, private videoPlaylistService: VideoPlaylistService, - private serverService: ServerService, - private i18n: I18n - ) { + private serverService: ServerService + ) { super() } @@ -70,9 +68,7 @@ export class MyAccountVideoPlaylistCreateComponent extends MyAccountVideoPlaylis this.videoPlaylistService.createVideoPlaylist(videoPlaylistCreate).subscribe( () => { - this.notifier.success( - this.i18n('Playlist {{playlistName}} created.', { playlistName: videoPlaylistCreate.displayName }) - ) + this.notifier.success($localize`Playlist ${videoPlaylistCreate.displayName} created.`) this.router.navigate([ '/my-account', 'video-playlists' ]) }, @@ -85,6 +81,6 @@ export class MyAccountVideoPlaylistCreateComponent extends MyAccountVideoPlaylis } getFormButtonTitle () { - return this.i18n('Create') + return $localize`Create` } } diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts index e278d9ed2..f6cdf1067 100644 --- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts +++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts @@ -6,7 +6,6 @@ import { ComponentPagination, ConfirmService, Notifier, ScreenService } from '@a import { DropdownAction } from '@app/shared/shared-main' import { VideoShareComponent } from '@app/shared/shared-share-modal' import { VideoPlaylist, VideoPlaylistElement, VideoPlaylistService } from '@app/shared/shared-video-playlist' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoPlaylistType } from '@shared/models' @Component({ @@ -35,7 +34,6 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro constructor ( private notifier: Notifier, - private i18n: I18n, private router: Router, private confirmService: ConfirmService, private route: ActivatedRoute, @@ -47,12 +45,12 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro this.playlistActions = [ [ { - label: this.i18n('Update playlist'), + label: $localize`Update playlist`, iconName: 'edit', linkBuilder: playlist => [ '/my-account', 'video-playlists', 'update', playlist.uuid ] }, { - label: this.i18n('Delete playlist'), + label: $localize`Delete playlist`, iconName: 'delete', handler: playlist => this.deleteVideoPlaylist(playlist) } @@ -126,11 +124,8 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro async deleteVideoPlaylist (videoPlaylist: VideoPlaylist) { const res = await this.confirmService.confirm( - this.i18n( - 'Do you really want to delete {{playlistDisplayName}}?', - { playlistDisplayName: videoPlaylist.displayName } - ), - this.i18n('Delete') + $localize`Do you really want to delete ${videoPlaylist.displayName}?`, + $localize`Delete` ) if (res === false) return @@ -138,10 +133,7 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro .subscribe( () => { this.router.navigate([ '/my-account', 'video-playlists' ]) - - this.notifier.success( - this.i18n('Playlist {{playlistDisplayName}} deleted.', { playlistDisplayName: videoPlaylist.displayName }) - ) + this.notifier.success($localize`Playlist ${videoPlaylist.displayName} deleted.`) }, error => this.notifier.error(error.message) diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts index 6787fb757..149d0d94f 100644 --- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts +++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts @@ -6,7 +6,6 @@ import { AuthService, Notifier, ServerService } from '@app/core' import { populateAsyncUserVideoChannels } from '@app/helpers' import { FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/shared-forms' import { VideoPlaylist, VideoPlaylistService } from '@app/shared/shared-video-playlist' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoPlaylistUpdate } from '@shared/models' import { MyAccountVideoPlaylistEdit } from './my-account-video-playlist-edit' @@ -29,7 +28,6 @@ export class MyAccountVideoPlaylistUpdateComponent extends MyAccountVideoPlaylis private router: Router, private route: ActivatedRoute, private videoPlaylistService: VideoPlaylistService, - private i18n: I18n, private serverService: ServerService ) { super() @@ -91,10 +89,7 @@ export class MyAccountVideoPlaylistUpdateComponent extends MyAccountVideoPlaylis this.videoPlaylistService.updateVideoPlaylist(this.videoPlaylistToUpdate, videoPlaylistUpdate).subscribe( () => { - this.notifier.success( - this.i18n('Playlist {{videoPlaylistName}} updated.', { videoPlaylistName: videoPlaylistUpdate.displayName }) - ) - + this.notifier.success($localize`Playlist ${videoPlaylistUpdate.displayName} updated.`) this.router.navigate([ '/my-account', 'video-playlists' ]) }, @@ -107,7 +102,7 @@ export class MyAccountVideoPlaylistUpdateComponent extends MyAccountVideoPlaylis } getFormButtonTitle () { - return this.i18n('Update') + return $localize`Update` } private hydrateFormFromPlaylist () { diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts index ba95b6c8b..1e569c0b6 100644 --- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts +++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts @@ -3,7 +3,6 @@ import { debounceTime, mergeMap } from 'rxjs/operators' import { Component, OnInit } from '@angular/core' import { AuthService, ComponentPagination, ConfirmService, Notifier, User } from '@app/core' import { VideoPlaylist, VideoPlaylistService } from '@app/shared/shared-video-playlist' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoPlaylistType } from '@shared/models' @Component({ @@ -30,9 +29,8 @@ export class MyAccountVideoPlaylistsComponent implements OnInit { private authService: AuthService, private notifier: Notifier, private confirmService: ConfirmService, - private videoPlaylistService: VideoPlaylistService, - private i18n: I18n - ) {} + private videoPlaylistService: VideoPlaylistService + ) {} ngOnInit () { this.user = this.authService.getUser() @@ -49,11 +47,8 @@ export class MyAccountVideoPlaylistsComponent implements OnInit { async deleteVideoPlaylist (videoPlaylist: VideoPlaylist) { const res = await this.confirmService.confirm( - this.i18n( - 'Do you really want to delete {{playlistDisplayName}}?', - { playlistDisplayName: videoPlaylist.displayName } - ), - this.i18n('Delete') + $localize`Do you really want to delete ${videoPlaylist.displayName}?`, + $localize`Delete` ) if (res === false) return @@ -63,9 +58,7 @@ export class MyAccountVideoPlaylistsComponent implements OnInit { this.videoPlaylists = this.videoPlaylists .filter(p => p.id !== videoPlaylist.id) - this.notifier.success( - this.i18n('Playlist {{playlistDisplayName}} deleted.', { playlistDisplayName: videoPlaylist.displayName }) - ) + this.notifier.success($localize`Playlist ${videoPlaylist.displayName}} deleted.`) }, error => this.notifier.error(error.message) diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts index 2274c6a7b..46a02a41a 100644 --- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts @@ -7,7 +7,6 @@ import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook' import { immutableAssign } from '@app/helpers' import { Video, VideoService } from '@app/shared/shared-main' import { MiniatureDisplayOptions, OwnerDisplayType, SelectionType, VideosSelectionComponent } from '@app/shared/shared-video-miniature' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoSortField } from '@shared/models' import { VideoChangeOwnershipComponent } from './video-change-ownership/video-change-ownership.component' @@ -50,11 +49,10 @@ export class MyAccountVideosComponent implements OnInit, DisableForReuseHook { protected authService: AuthService, protected notifier: Notifier, protected screenService: ScreenService, - private i18n: I18n, private confirmService: ConfirmService, private videoService: VideoService ) { - this.titlePage = this.i18n('My videos') + this.titlePage = $localize`My videos` } ngOnInit () { @@ -97,8 +95,8 @@ export class MyAccountVideosComponent implements OnInit, DisableForReuseHook { .map(k => parseInt(k, 10)) const res = await this.confirmService.confirm( - this.i18n('Do you really want to delete {{deleteLength}} videos?', { deleteLength: toDeleteVideosIds.length }), - this.i18n('Delete') + $localize`Do you really want to delete ${toDeleteVideosIds.length} videos?`, + $localize`Delete` ) if (res === false) return @@ -114,8 +112,7 @@ export class MyAccountVideosComponent implements OnInit, DisableForReuseHook { .pipe(toArray()) .subscribe( () => { - this.notifier.success(this.i18n('{{deleteLength}} videos deleted.', { deleteLength: toDeleteVideosIds.length })) - + this.notifier.success($localize`${toDeleteVideosIds.length} videos deleted.`) this.selection = {} }, @@ -125,15 +122,15 @@ export class MyAccountVideosComponent implements OnInit, DisableForReuseHook { async deleteVideo (video: Video) { const res = await this.confirmService.confirm( - this.i18n('Do you really want to delete {{videoName}}?', { videoName: video.name }), - this.i18n('Delete') + $localize`Do you really want to delete ${video.name}?`, + $localize`Delete` ) if (res === false) return this.videoService.removeVideo(video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video {{videoName}} deleted.', { videoName: video.name })) + this.notifier.success($localize`Video ${video.name} deleted.`) this.removeVideoFromArray(video.id) }, diff --git a/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts b/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts index 18e716a09..edd691694 100644 --- a/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts +++ b/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts @@ -3,7 +3,6 @@ import { Notifier, UserService } from '@app/core' import { FormReactive, FormValidatorService, VideoChangeOwnershipValidatorsService } from '@app/shared/shared-forms' import { Video, VideoOwnershipService } from '@app/shared/shared-main' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-video-change-ownership', @@ -25,9 +24,8 @@ export class VideoChangeOwnershipComponent extends FormReactive implements OnIni private videoOwnershipService: VideoOwnershipService, private notifier: Notifier, private userService: UserService, - private modalService: NgbModal, - private i18n: I18n - ) { + private modalService: NgbModal + ) { super() } @@ -63,7 +61,7 @@ export class VideoChangeOwnershipComponent extends FormReactive implements OnIni this.videoOwnershipService .changeOwnership(this.video.id, username) .subscribe( - () => this.notifier.success(this.i18n('Ownership change request sent.')), + () => this.notifier.success($localize`Ownership change request sent.`), err => this.notifier.error(err.message) ) diff --git a/client/src/app/+my-account/my-account.component.ts b/client/src/app/+my-account/my-account.component.ts index 56373e5f1..d3bf8d143 100644 --- a/client/src/app/+my-account/my-account.component.ts +++ b/client/src/app/+my-account/my-account.component.ts @@ -1,6 +1,5 @@ import { Component, OnInit } from '@angular/core' -import { AuthService, ScreenService, ServerService, AuthUser } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' +import { AuthService, AuthUser, ScreenService, ServerService } from '@app/core' import { ServerConfig } from '@shared/models' import { TopMenuDropdownParam } from '../shared/shared-main/misc/top-menu-dropdown.component' @@ -18,9 +17,8 @@ export class MyAccountComponent implements OnInit { constructor ( private serverService: ServerService, private authService: AuthService, - private screenService: ScreenService, - private i18n: I18n - ) { } + private screenService: ScreenService + ) { } get isBroadcastMessageDisplayed () { return this.screenService.isBroadcastMessageDisplayed @@ -46,31 +44,31 @@ export class MyAccountComponent implements OnInit { private buildMenu () { const libraryEntries: TopMenuDropdownParam = { - label: this.i18n('My library'), + label: $localize`My library`, children: [ { - label: this.i18n('My channels'), + label: $localize`My channels`, routerLink: '/my-account/video-channels', iconName: 'channel' }, { - label: this.i18n('My videos'), + label: $localize`My videos`, routerLink: '/my-account/videos', iconName: 'videos', isDisplayed: () => this.user.canSeeVideosLink }, { - label: this.i18n('My playlists'), + label: $localize`My playlists`, routerLink: '/my-account/video-playlists', iconName: 'playlists' }, { - label: this.i18n('My subscriptions'), + label: $localize`My subscriptions`, routerLink: '/my-account/subscriptions', iconName: 'subscriptions' }, { - label: this.i18n('My history'), + label: $localize`My history`, routerLink: '/my-account/history/videos', iconName: 'history' } @@ -87,25 +85,25 @@ export class MyAccountComponent implements OnInit { } const miscEntries: TopMenuDropdownParam = { - label: this.i18n('Misc'), + label: $localize`Misc`, children: [ { - label: this.i18n('Muted accounts'), + label: $localize`Muted accounts`, routerLink: '/my-account/blocklist/accounts', iconName: 'user-x' }, { - label: this.i18n('Muted servers'), + label: $localize`Muted servers`, routerLink: '/my-account/blocklist/servers', iconName: 'peertube-x' }, { - label: this.i18n('My abuse reports'), + label: $localize`My abuse reports`, routerLink: '/my-account/abuses', iconName: 'flag' }, { - label: this.i18n('Ownership changes'), + label: $localize`Ownership changes`, routerLink: '/my-account/ownership', iconName: 'download' } @@ -114,11 +112,11 @@ export class MyAccountComponent implements OnInit { this.menuEntries = [ { - label: this.i18n('My settings'), + label: $localize`My settings`, routerLink: '/my-account/settings' }, { - label: this.i18n('My notifications'), + label: $localize`My notifications`, routerLink: '/my-account/notifications' }, libraryEntries, diff --git a/client/src/app/+reset-password/reset-password.component.ts b/client/src/app/+reset-password/reset-password.component.ts index 8d50e9839..16e4f4090 100644 --- a/client/src/app/+reset-password/reset-password.component.ts +++ b/client/src/app/+reset-password/reset-password.component.ts @@ -2,7 +2,6 @@ import { Component, OnInit } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { Notifier, UserService } from '@app/core' import { FormReactive, FormValidatorService, ResetPasswordValidatorsService, UserValidatorsService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-login', @@ -21,9 +20,8 @@ export class ResetPasswordComponent extends FormReactive implements OnInit { private userService: UserService, private notifier: Notifier, private router: Router, - private route: ActivatedRoute, - private i18n: I18n - ) { + private route: ActivatedRoute + ) { super() } @@ -37,7 +35,7 @@ export class ResetPasswordComponent extends FormReactive implements OnInit { this.verificationString = this.route.snapshot.queryParams['verificationString'] if (!this.userId || !this.verificationString) { - this.notifier.error(this.i18n('Unable to find user id or verification string.')) + this.notifier.error($localize`Unable to find user id or verification string.`) this.router.navigate([ '/' ]) } } @@ -46,7 +44,7 @@ export class ResetPasswordComponent extends FormReactive implements OnInit { this.userService.resetPassword(this.userId, this.verificationString, this.form.value.password) .subscribe( () => { - this.notifier.success(this.i18n('Your password has been successfully reset!')) + this.notifier.success($localize`Your password has been successfully reset!`) this.router.navigate([ '/login' ]) }, diff --git a/client/src/app/+search/search-filters.component.ts b/client/src/app/+search/search-filters.component.ts index 13ad61647..a2af9a942 100644 --- a/client/src/app/+search/search-filters.component.ts +++ b/client/src/app/+search/search-filters.component.ts @@ -1,8 +1,6 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' import { ServerService } from '@app/core' -import { VideoValidatorsService } from '@app/shared/shared-forms' import { AdvancedSearch } from '@app/shared/shared-search' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig, VideoConstant } from '@shared/models' @Component({ @@ -32,64 +30,62 @@ export class SearchFiltersComponent implements OnInit { private serverConfig: ServerConfig constructor ( - private i18n: I18n, - private videoValidatorsService: VideoValidatorsService, private serverService: ServerService ) { this.publishedDateRanges = [ { id: 'any_published_date', - label: this.i18n('Any') + label: $localize`Any` }, { id: 'today', - label: this.i18n('Today') + label: $localize`Today` }, { id: 'last_7days', - label: this.i18n('Last 7 days') + label: $localize`Last 7 days` }, { id: 'last_30days', - label: this.i18n('Last 30 days') + label: $localize`Last 30 days` }, { id: 'last_365days', - label: this.i18n('Last 365 days') + label: $localize`Last 365 days` } ] this.durationRanges = [ { id: 'any_duration', - label: this.i18n('Any') + label: $localize`Any` }, { id: 'short', - label: this.i18n('Short (< 4 min)') + label: $localize`Short (< 4 min)` }, { id: 'medium', - label: this.i18n('Medium (4-10 min)') + label: $localize`Medium (4-10 min)` }, { id: 'long', - label: this.i18n('Long (> 10 min)') + label: $localize`Long (> 10 min)` } ] this.sorts = [ { id: '-match', - label: this.i18n('Relevance') + label: $localize`Relevance` }, { id: '-publishedAt', - label: this.i18n('Publish date') + label: $localize`Publish date` }, { id: '-views', - label: this.i18n('Views') + label: $localize`Views` } ] } diff --git a/client/src/app/+search/search.component.ts b/client/src/app/+search/search.component.ts index 70116fab3..2be952e16 100644 --- a/client/src/app/+search/search.component.ts +++ b/client/src/app/+search/search.component.ts @@ -7,7 +7,6 @@ import { Video, VideoChannel } from '@app/shared/shared-main' import { AdvancedSearch, SearchService } from '@app/shared/shared-search' import { MiniatureDisplayOptions, VideoLinkType } from '@app/shared/shared-video-miniature' import { MetaService } from '@ngx-meta/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { SearchTargetType, ServerConfig } from '@shared/models' @Component({ @@ -52,7 +51,6 @@ export class SearchComponent implements OnInit, OnDestroy { private lastSearchTarget: SearchTargetType constructor ( - private i18n: I18n, private route: ActivatedRoute, private router: Router, private metaService: MetaService, @@ -170,8 +168,8 @@ export class SearchComponent implements OnInit, OnDestroy { } this.notifier.error( - this.i18n('Search index is unavailable. Retrying with instance results instead.'), - this.i18n('Search error') + $localize`Search index is unavailable. Retrying with instance results instead.`, + $localize`Search error` ) this.advancedSearch.searchTarget = 'local' this.search() @@ -229,7 +227,7 @@ export class SearchComponent implements OnInit, OnDestroy { private updateTitle () { const suffix = this.currentSearch ? ' ' + this.currentSearch : '' - this.metaService.setTitle(this.i18n('Search') + suffix) + this.metaService.setTitle($localize`Search` + suffix) } private updateUrlFromAdvancedSearch () { diff --git a/client/src/app/+signup/+register/register.component.ts b/client/src/app/+signup/+register/register.component.ts index 3e8171b27..153a6d2b5 100644 --- a/client/src/app/+signup/+register/register.component.ts +++ b/client/src/app/+signup/+register/register.component.ts @@ -5,7 +5,6 @@ import { AuthService, Notifier, UserService } from '@app/core' import { HooksService } from '@app/core/plugins/hooks.service' import { InstanceService } from '@app/shared/shared-instance' import { NgbAccordion } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { UserRegister } from '@shared/models' import { About, ServerConfig } from '@shared/models/server' @@ -42,9 +41,8 @@ export class RegisterComponent implements OnInit { private notifier: Notifier, private userService: UserService, private instanceService: InstanceService, - private hooks: HooksService, - private i18n: I18n - ) { + private hooks: HooksService + ) { } get requiresEmailVerification () { @@ -114,7 +112,7 @@ export class RegisterComponent implements OnInit { this.signupDone = true if (this.requiresEmailVerification) { - this.info = this.i18n('Now please check your emails to verify your account and complete signup.') + this.info = $localize`Now please check your emails to verify your account and complete signup.` return } @@ -122,7 +120,7 @@ export class RegisterComponent implements OnInit { this.authService.login(body.username, body.password) .subscribe( () => { - this.success = this.i18n('You are now logged in as {{username}}!', { username: body.username }) + this.success = $localize`You are now logged in as ${body.username}!` }, err => this.error = err.message diff --git a/client/src/app/+signup/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts b/client/src/app/+signup/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts index 51910471b..b26581d2b 100644 --- a/client/src/app/+signup/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts +++ b/client/src/app/+signup/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts @@ -1,7 +1,6 @@ import { Component, OnInit } from '@angular/core' import { Notifier, RedirectService, ServerService, UserService } from '@app/core' import { FormReactive, FormValidatorService, UserValidatorsService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig } from '@shared/models' @Component({ @@ -19,9 +18,8 @@ export class VerifyAccountAskSendEmailComponent extends FormReactive implements private userService: UserService, private serverService: ServerService, private notifier: Notifier, - private redirectService: RedirectService, - private i18n: I18n - ) { + private redirectService: RedirectService + ) { super() } @@ -44,11 +42,7 @@ export class VerifyAccountAskSendEmailComponent extends FormReactive implements this.userService.askSendVerifyEmail(email) .subscribe( () => { - const message = this.i18n( - 'An email with verification link will be sent to {{email}}.', - { email } - ) - this.notifier.success(message) + this.notifier.success($localize`An email with verification link will be sent to ${email}.`) this.redirectService.redirectToHomepage() }, diff --git a/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.ts b/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.ts index 586f4e231..acc688ab3 100644 --- a/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.ts +++ b/client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.ts @@ -1,7 +1,6 @@ import { Component, OnInit } from '@angular/core' import { ActivatedRoute } from '@angular/router' import { AuthService, Notifier, UserService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-verify-account-email', @@ -20,9 +19,8 @@ export class VerifyAccountEmailComponent implements OnInit { private userService: UserService, private authService: AuthService, private notifier: Notifier, - private route: ActivatedRoute, - private i18n: I18n - ) { + private route: ActivatedRoute + ) { } ngOnInit () { @@ -32,7 +30,7 @@ export class VerifyAccountEmailComponent implements OnInit { this.isPendingEmail = queryParams['isPendingEmail'] === 'true' if (!this.userId || !this.verificationString) { - this.notifier.error(this.i18n('Unable to find user id or verification string.')) + this.notifier.error($localize`Unable to find user id or verification string.`) } else { this.verifyEmail() } diff --git a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts index 19e4bc1f4..537c7d08e 100644 --- a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts +++ b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts @@ -2,7 +2,6 @@ import { Subscription } from 'rxjs' import { Component, OnDestroy, OnInit } from '@angular/core' import { MarkdownService } from '@app/core' import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-video-channel-about', @@ -17,7 +16,6 @@ export class VideoChannelAboutComponent implements OnInit, OnDestroy { private videoChannelSub: Subscription constructor ( - private i18n: I18n, private videoChannelService: VideoChannelService, private markdownService: MarkdownService ) { } @@ -40,6 +38,6 @@ export class VideoChannelAboutComponent implements OnInit, OnDestroy { getVideoChannelDescription () { if (this.descriptionHTML) return this.descriptionHTML - return this.i18n('No description') + return $localize`No description` } } diff --git a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts index 599d38da9..e1ec6bbcb 100644 --- a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts +++ b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts @@ -6,7 +6,6 @@ import { AuthService, ConfirmService, LocalStorageService, Notifier, ScreenServi import { immutableAssign } from '@app/helpers' import { VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main' import { AbstractVideoList } from '@app/shared/shared-video-miniature' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-video-channel-videos', @@ -23,7 +22,6 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On private videoChannelSub: Subscription constructor ( - protected i18n: I18n, protected router: Router, protected serverService: ServerService, protected route: ActivatedRoute, @@ -38,7 +36,7 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On ) { super() - this.titlePage = this.i18n('Published videos') + this.titlePage = $localize`Published videos` this.displayOptions = { ...this.displayOptions, avatar: false @@ -72,7 +70,9 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On .getVideoChannelVideos(this.videoChannel, newPagination, this.sort, this.nsfwPolicy) .pipe( tap(({ total }) => { - this.titlePage = this.i18n(`{total, plural, =1 {Published 1 video} other {Published {{total}} videos}}`, { total }) + this.titlePage = total === 1 + ? $localize`Published 1 video` + : $localize`Published ${total} videos` }) ) } diff --git a/client/src/app/+video-channels/video-channels.component.ts b/client/src/app/+video-channels/video-channels.component.ts index cae442ee7..ea8bda1cf 100644 --- a/client/src/app/+video-channels/video-channels.component.ts +++ b/client/src/app/+video-channels/video-channels.component.ts @@ -6,7 +6,6 @@ import { ActivatedRoute } from '@angular/router' import { AuthService, Notifier, RestExtractor, ScreenService } from '@app/core' import { ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main' import { SubscribeButtonComponent } from '@app/shared/shared-user-subscription' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ templateUrl: './video-channels.component.html', @@ -23,7 +22,6 @@ export class VideoChannelsComponent implements OnInit, OnDestroy { private routeSub: Subscription constructor ( - private i18n: I18n, private route: ActivatedRoute, private notifier: Notifier, private authService: AuthService, @@ -59,14 +57,14 @@ export class VideoChannelsComponent implements OnInit, OnDestroy { this.subscribeButton.unsubscribe() : this.subscribeButton.subscribe() return false - }, undefined, this.i18n('Subscribe to the account')) + }, undefined, $localize`Subscribe to the account`) ] if (this.isUserLoggedIn()) this.hotkeysService.add(this.hotkeys) this.links = [ - { label: this.i18n('VIDEOS'), routerLink: 'videos' }, - { label: this.i18n('VIDEO PLAYLISTS'), routerLink: 'video-playlists' }, - { label: this.i18n('ABOUT'), routerLink: 'about' } + { label: $localize`VIDEOS`, routerLink: 'videos' }, + { label: $localize`VIDEO PLAYLISTS`, routerLink: 'video-playlists' }, + { label: $localize`ABOUT`, routerLink: 'about' } ] } @@ -91,6 +89,6 @@ export class VideoChannelsComponent implements OnInit, OnDestroy { } activateCopiedMessage () { - this.notifier.success(this.i18n('Username copied')) + this.notifier.success($localize`Username copied`) } } diff --git a/client/src/app/+videos/+video-edit/shared/i18n-primeng-calendar.service.ts b/client/src/app/+videos/+video-edit/shared/i18n-primeng-calendar.service.ts index b05852ff8..2acbace48 100644 --- a/client/src/app/+videos/+video-edit/shared/i18n-primeng-calendar.service.ts +++ b/client/src/app/+videos/+video-edit/shared/i18n-primeng-calendar.service.ts @@ -1,76 +1,75 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' import { Injectable } from '@angular/core' @Injectable() export class I18nPrimengCalendarService { private readonly calendarLocale: any = {} - constructor (private i18n: I18n) { + constructor () { this.calendarLocale = { firstDayOfWeek: 0, dayNames: [ - this.i18n('Sunday'), - this.i18n('Monday'), - this.i18n('Tuesday'), - this.i18n('Wednesday'), - this.i18n('Thursday'), - this.i18n('Friday'), - this.i18n('Saturday') + $localize`Sunday`, + $localize`Monday`, + $localize`Tuesday`, + $localize`Wednesday`, + $localize`Thursday`, + $localize`Friday`, + $localize`Saturday` ], dayNamesShort: [ - this.i18n({ value: 'Sun', description: 'Day name short' }), - this.i18n({ value: 'Mon', description: 'Day name short' }), - this.i18n({ value: 'Tue', description: 'Day name short' }), - this.i18n({ value: 'Wed', description: 'Day name short' }), - this.i18n({ value: 'Thu', description: 'Day name short' }), - this.i18n({ value: 'Fri', description: 'Day name short' }), - this.i18n({ value: 'Sat', description: 'Day name short' }) + $localize`:Day name short:Sun`, + $localize`:Day name short:Mon`, + $localize`:Day name short:Tue`, + $localize`:Day name short:Wed`, + $localize`:Day name short:Thu`, + $localize`:Day name short:Fri`, + $localize`:Day name short:Sat` ], dayNamesMin: [ - this.i18n({ value: 'Su', description: 'Day name min' }), - this.i18n({ value: 'Mo', description: 'Day name min' }), - this.i18n({ value: 'Tu', description: 'Day name min' }), - this.i18n({ value: 'We', description: 'Day name min' }), - this.i18n({ value: 'Th', description: 'Day name min' }), - this.i18n({ value: 'Fr', description: 'Day name min' }), - this.i18n({ value: 'Sa', description: 'Day name min' }) + $localize`:Day name min:Su`, + $localize`:Day name min:Mo`, + $localize`:Day name min:Tu`, + $localize`:Day name min:We`, + $localize`:Day name min:Th`, + $localize`:Day name min:Fr`, + $localize`:Day name min:Sa` ], monthNames: [ - this.i18n('January'), - this.i18n('February'), - this.i18n('March'), - this.i18n('April'), - this.i18n('May'), - this.i18n('June'), - this.i18n('July'), - this.i18n('August'), - this.i18n('September'), - this.i18n('October'), - this.i18n('November'), - this.i18n('December') + $localize`January`, + $localize`February`, + $localize`March`, + $localize`April`, + $localize`May`, + $localize`June`, + $localize`July`, + $localize`August`, + $localize`September`, + $localize`October`, + $localize`November`, + $localize`December` ], monthNamesShort: [ - this.i18n({ value: 'Jan', description: 'Month name short' }), - this.i18n({ value: 'Feb', description: 'Month name short' }), - this.i18n({ value: 'Mar', description: 'Month name short' }), - this.i18n({ value: 'Apr', description: 'Month name short' }), - this.i18n({ value: 'May', description: 'Month name short' }), - this.i18n({ value: 'Jun', description: 'Month name short' }), - this.i18n({ value: 'Jul', description: 'Month name short' }), - this.i18n({ value: 'Aug', description: 'Month name short' }), - this.i18n({ value: 'Sep', description: 'Month name short' }), - this.i18n({ value: 'Oct', description: 'Month name short' }), - this.i18n({ value: 'Nov', description: 'Month name short' }), - this.i18n({ value: 'Dec', description: 'Month name short' }) + $localize`:Month name short:Jan`, + $localize`:Month name short:Feb`, + $localize`:Month name short:Mar`, + $localize`:Month name short:Apr`, + $localize`:Month name short:May`, + $localize`:Month name short:Jun`, + $localize`:Month name short:Jul`, + $localize`:Month name short:Aug`, + $localize`:Month name short:Sep`, + $localize`:Month name short:Oct`, + $localize`:Month name short:Nov`, + $localize`:Month name short:Dec` ], - today: this.i18n('Today'), + today: $localize`Today`, - clear: this.i18n('Clear') + clear: $localize`Clear` } } @@ -86,9 +85,6 @@ export class I18nPrimengCalendarService { } getDateFormat () { - return this.i18n({ - value: 'yy-mm-dd ', - description: 'Date format in this locale.' - }) + return $localize`:Date format in this locale.:yy-mm-dd` } } diff --git a/client/src/app/+videos/+video-edit/shared/video-edit.component.ts b/client/src/app/+videos/+video-edit/shared/video-edit.component.ts index ba3b7c96a..050b6d931 100644 --- a/client/src/app/+videos/+video-edit/shared/video-edit.component.ts +++ b/client/src/app/+videos/+video-edit/shared/video-edit.component.ts @@ -7,7 +7,6 @@ import { removeElementFromArray } from '@app/helpers' import { FormReactiveValidationMessages, FormValidatorService, SelectChannelItem, VideoValidatorsService } from '@app/shared/shared-forms' import { InstanceService } from '@app/shared/shared-instance' import { VideoCaptionEdit, VideoEdit, VideoService } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig, VideoConstant, VideoPrivacy } from '@shared/models' import { I18nPrimengCalendarService } from './i18n-primeng-calendar.service' import { VideoCaptionAddModalComponent } from './video-caption-add-modal.component' @@ -63,7 +62,6 @@ export class VideoEditComponent implements OnInit, OnDestroy { private serverService: ServerService, private instanceService: InstanceService, private i18nPrimengCalendarService: I18nPrimengCalendarService, - private i18n: I18n, private ngZone: NgZone ) { this.calendarLocale = this.i18nPrimengCalendarService.getCalendarLocale() @@ -137,8 +135,8 @@ export class VideoEditComponent implements OnInit, OnDestroy { .subscribe(res => { this.videoLanguages = res.languages .map(l => res.about.instance.languages.includes(l.id) - ? { ...l, group: this.i18n('Instance languages'), groupOrder: 0 } - : { ...l, group: this.i18n('All languages'), groupOrder: 1 }) + ? { ...l, group: $localize`Instance languages`, groupOrder: 0 } + : { ...l, group: $localize`All languages`, groupOrder: 1 }) .sort((a, b) => a.groupOrder - b.groupOrder) }) @@ -148,8 +146,8 @@ export class VideoEditComponent implements OnInit, OnDestroy { if (this.schedulePublicationPossible) { this.videoPrivacies.push({ id: this.SPECIAL_SCHEDULED_PRIVACY, - label: this.i18n('Scheduled'), - description: this.i18n('Hide the video until a specific date') + label: $localize`Scheduled`, + description: $localize`Hide the video until a specific date` }) } }) diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts b/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts index 3a8e6eecc..e9ad8af7a 100644 --- a/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts +++ b/client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts @@ -4,10 +4,9 @@ import { AuthService, CanComponentDeactivate, Notifier, ServerService } from '@a import { scrollToTop } from '@app/helpers' import { FormValidatorService } from '@app/shared/shared-forms' import { VideoCaptionService, VideoEdit, VideoImportService, VideoService } from '@app/shared/shared-main' -import { VideoSend } from './video-send' import { LoadingBarService } from '@ngx-loading-bar/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoPrivacy, VideoUpdate } from '@shared/models' +import { VideoSend } from './video-send' @Component({ selector: 'my-video-import-torrent', @@ -43,9 +42,8 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca protected videoService: VideoService, protected videoCaptionService: VideoCaptionService, private router: Router, - private videoImportService: VideoImportService, - private i18n: I18n - ) { + private videoImportService: VideoImportService + ) { super() } @@ -127,7 +125,7 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca .subscribe( () => { this.isUpdatingVideo = false - this.notifier.success(this.i18n('Video to import updated.')) + this.notifier.success($localize`Video to import updated.`) this.router.navigate([ '/my-account', 'video-imports' ]) }, diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts b/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts index da25663d7..8bad81097 100644 --- a/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts +++ b/client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts @@ -5,10 +5,9 @@ import { AuthService, CanComponentDeactivate, Notifier, ServerService } from '@a import { getAbsoluteAPIUrl, scrollToTop } from '@app/helpers' import { FormValidatorService } from '@app/shared/shared-forms' import { VideoCaptionService, VideoEdit, VideoImportService, VideoService } from '@app/shared/shared-main' -import { VideoSend } from './video-send' import { LoadingBarService } from '@ngx-loading-bar/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoPrivacy, VideoUpdate } from '@shared/models' +import { VideoSend } from './video-send' @Component({ selector: 'my-video-import-url', @@ -42,9 +41,8 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom protected videoService: VideoService, protected videoCaptionService: VideoCaptionService, private router: Router, - private videoImportService: VideoImportService, - private i18n: I18n - ) { + private videoImportService: VideoImportService + ) { super() } @@ -137,7 +135,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom .subscribe( () => { this.isUpdatingVideo = false - this.notifier.success(this.i18n('Video to import updated.')) + this.notifier.success($localize`Video to import updated.`) this.router.navigate([ '/my-account', 'video-imports' ]) }, diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts b/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts index e18e3c9a7..416b655a4 100644 --- a/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts +++ b/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts @@ -7,7 +7,6 @@ import { scrollToTop } from '@app/helpers' import { FormValidatorService } from '@app/shared/shared-forms' import { BytesPipe, VideoCaptionService, VideoEdit, VideoService } from '@app/shared/shared-main' import { LoadingBarService } from '@ngx-loading-bar/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoPrivacy } from '@shared/models' import { VideoSend } from './video-send' @@ -59,9 +58,8 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy protected videoService: VideoService, protected videoCaptionService: VideoCaptionService, private userService: UserService, - private router: Router, - private i18n: I18n - ) { + private router: Router + ) { super() } @@ -88,10 +86,10 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy if (this.videoUploaded === true) { // FIXME: cannot concatenate strings inside i18n service :/ - text = this.i18n('Your video was uploaded to your account and is private.') + ' ' + - this.i18n('But associated data (tags, description...) will be lost, are you sure you want to leave this page?') + text = $localize`Your video was uploaded to your account and is private.` + ' ' + + $localize`But associated data (tags, description...) will be lost, are you sure you want to leave this page?` } else { - text = this.i18n('Your video is not uploaded yet, are you sure you want to leave this page?') + text = $localize`Your video is not uploaded yet, are you sure you want to leave this page?` } return { @@ -111,9 +109,9 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy getAudioUploadLabel () { const videofile = this.getVideoFile() - if (!videofile) return this.i18n('Upload') + if (!videofile) return $localize`Upload` - return this.i18n('Upload {{videofileName}}', { videofileName: videofile.name }) + return $localize`Upload ${videofile.name}` } fileChange () { @@ -130,7 +128,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy this.firstStepError.emit() - this.notifier.info(this.i18n('Upload cancelled')) + this.notifier.info($localize`Upload cancelled`) } } @@ -242,7 +240,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy this.isUpdatingVideo = false this.isUploadingVideo = false - this.notifier.success(this.i18n('Video published.')) + this.notifier.success($localize`Video published.`) this.router.navigate([ '/videos/watch', video.uuid ]) }, @@ -260,14 +258,12 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy // Check global user quota const videoQuota = this.authService.getUser().videoQuota if (videoQuota !== -1 && (this.userVideoQuotaUsed + videofile.size) > videoQuota) { - 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) - } - ) + const videoSizeBytes = bytePipes.transform(videofile.size, 0) + const videoQuotaUsedBytes = bytePipes.transform(this.userVideoQuotaUsed, 0) + const videoQuotaBytes = bytePipes.transform(videoQuota, 0) + + const msg = $localize`Your video quota is exceeded with this video ( +video size: ${videoSizeBytes}, used: ${videoQuotaUsedBytes}, quota: ${videoQuotaBytes})` this.notifier.error(msg) return false @@ -282,14 +278,12 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy // Check daily user quota const videoQuotaDaily = this.authService.getUser().videoQuotaDaily if (videoQuotaDaily !== -1 && (this.userVideoQuotaUsedDaily + videofile.size) > videoQuotaDaily) { - const msg = this.i18n( - 'Your daily video quota is exceeded with this video (video size: {{videoSize}}, used: {{quotaUsedDaily}}, quota: {{quotaDaily}})', - { - videoSize: bytePipes.transform(videofile.size, 0), - quotaUsedDaily: bytePipes.transform(this.userVideoQuotaUsedDaily, 0), - quotaDaily: bytePipes.transform(videoQuotaDaily, 0) - } - ) + const videoSizeBytes = bytePipes.transform(videofile.size, 0) + const quotaUsedDailyBytes = bytePipes.transform(this.userVideoQuotaUsedDaily, 0) + const quotaDailyBytes = bytePipes.transform(videoQuotaDaily, 0) + + const msg = $localize`Your daily video quota is exceeded with this video ( +video size: ${videoSizeBytes}, used: ${quotaUsedDailyBytes}, quota: ${quotaDailyBytes})` this.notifier.error(msg) return false diff --git a/client/src/app/+videos/+video-edit/video-update.component.ts b/client/src/app/+videos/+video-edit/video-update.component.ts index abd08f05c..2e1d0f89d 100644 --- a/client/src/app/+videos/+video-edit/video-update.component.ts +++ b/client/src/app/+videos/+video-edit/video-update.component.ts @@ -5,7 +5,6 @@ import { Notifier } from '@app/core' import { FormReactive, FormValidatorService, SelectChannelItem } from '@app/shared/shared-forms' import { VideoCaptionEdit, VideoCaptionService, VideoDetails, VideoEdit, VideoService } from '@app/shared/shared-main' import { LoadingBarService } from '@ngx-loading-bar/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoPrivacy } from '@shared/models' @Component({ @@ -31,9 +30,8 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { private notifier: Notifier, private videoService: VideoService, private loadingBar: LoadingBarService, - private videoCaptionService: VideoCaptionService, - private i18n: I18n - ) { + private videoCaptionService: VideoCaptionService + ) { super() } @@ -78,7 +76,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { canDeactivate (): { canDeactivate: boolean, text?: string } { if (this.updateDone === true) return { canDeactivate: true } - const text = this.i18n('You have unsaved changes! If you leave, your changes will be lost.') + const text = $localize`You have unsaved changes! If you leave, your changes will be lost.` for (const caption of this.videoCaptions) { if (caption.action) return { canDeactivate: false, text } @@ -115,7 +113,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { this.updateDone = true this.isUpdatingVideo = false this.loadingBar.useRef().complete() - this.notifier.success(this.i18n('Video updated.')) + this.notifier.success($localize`Video updated.`) this.router.navigate([ '/videos/watch', this.video.uuid ]) }, diff --git a/client/src/app/+videos/+video-watch/comment/video-comment.component.ts b/client/src/app/+videos/+video-watch/comment/video-comment.component.ts index 36ec6e9f9..a84e91fd3 100644 --- a/client/src/app/+videos/+video-watch/comment/video-comment.component.ts +++ b/client/src/app/+videos/+video-watch/comment/video-comment.component.ts @@ -5,7 +5,6 @@ import { AuthService } from '@app/core/auth' import { Account, Actor, DropdownAction, Video } from '@app/shared/shared-main' import { CommentReportComponent } from '@app/shared/shared-moderation/report-modals/comment-report.component' import { VideoComment, VideoCommentThreadTree } from '@app/shared/shared-video-comment' -import { I18n } from '@ngx-translate/i18n-polyfill' import { User, UserRight } from '@shared/models' @Component({ @@ -39,7 +38,6 @@ export class VideoCommentComponent implements OnInit, OnChanges { commentUser: User constructor ( - private i18n: I18n, private markdownService: MarkdownService, private authService: AuthService, private userService: UserService, @@ -138,7 +136,7 @@ export class VideoCommentComponent implements OnInit, OnChanges { if (this.isUserLoggedIn() && this.comment.isDeleted === false && this.authService.getUser().account.id !== this.comment.account.id) { this.prependModerationActions = [ { - label: this.i18n('Report comment'), + label: $localize`Report comment`, handler: () => this.showReportModal() } ] diff --git a/client/src/app/+videos/+video-watch/comment/video-comments.component.ts b/client/src/app/+videos/+video-watch/comment/video-comments.component.ts index 66494a20a..517844ab2 100644 --- a/client/src/app/+videos/+video-watch/comment/video-comments.component.ts +++ b/client/src/app/+videos/+video-watch/comment/video-comments.component.ts @@ -5,7 +5,6 @@ import { AuthService, ComponentPagination, ConfirmService, hasMoreItems, Notifie import { HooksService } from '@app/core/plugins/hooks.service' import { Syndication, VideoDetails } from '@app/shared/shared-main' import { VideoComment, VideoCommentService, VideoCommentThreadTree } from '@app/shared/shared-video-comment' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-video-comments', @@ -43,7 +42,6 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy { private confirmService: ConfirmService, private videoCommentService: VideoCommentService, private activatedRoute: ActivatedRoute, - private i18n: I18n, private hooks: HooksService ) {} @@ -162,12 +160,12 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy { let message = 'Do you really want to delete this comment?' if (commentToDelete.isLocal || this.video.isLocal) { - message += this.i18n(' The deletion will be sent to remote instances so they can reflect the change.') + message += $localize` The deletion will be sent to remote instances so they can reflect the change.` } else { - message += this.i18n(' It is a remote comment, so the deletion will only be effective on your instance.') + message += $localize` It is a remote comment, so the deletion will only be effective on your instance.` } - const res = await this.confirmService.confirm(message, this.i18n('Delete')) + const res = await this.confirmService.confirm(message, $localize`Delete`) if (res === false) return this.videoCommentService.deleteVideoComment(commentToDelete.videoId, commentToDelete.id) diff --git a/client/src/app/+videos/+video-watch/recommendations/recommended-videos.component.ts b/client/src/app/+videos/+video-watch/recommendations/recommended-videos.component.ts index d2372023f..a1c8e0661 100644 --- a/client/src/app/+videos/+video-watch/recommendations/recommended-videos.component.ts +++ b/client/src/app/+videos/+video-watch/recommendations/recommended-videos.component.ts @@ -4,10 +4,9 @@ import { AuthService, Notifier, SessionStorageService, User, UserService } from import { Video } from '@app/shared/shared-main' import { MiniatureDisplayOptions } from '@app/shared/shared-video-miniature' import { VideoPlaylist } from '@app/shared/shared-video-playlist' -import { I18n } from '@ngx-translate/i18n-polyfill' +import { UserLocalStorageKeys } from '@root-helpers/users' import { RecommendationInfo } from './recommendation-info.model' import { RecommendedVideosStore } from './recommended-videos.store' -import { UserLocalStorageKeys } from '@root-helpers/users' @Component({ selector: 'my-recommended-videos', @@ -38,7 +37,6 @@ export class RecommendedVideosComponent implements OnInit, OnChanges { private userService: UserService, private authService: AuthService, private notifier: Notifier, - private i18n: I18n, private store: RecommendedVideosStore, private sessionStorageService: SessionStorageService ) { @@ -58,7 +56,7 @@ export class RecommendedVideosComponent implements OnInit, OnChanges { ) } - this.autoPlayNextVideoTooltip = this.i18n('When active, the next video is automatically played after the current one.') + this.autoPlayNextVideoTooltip = $localize`When active, the next video is automatically played after the current one.` } ngOnInit () { diff --git a/client/src/app/+videos/+video-watch/video-duration-formatter.pipe.ts b/client/src/app/+videos/+video-watch/video-duration-formatter.pipe.ts index 4b6767415..19b34f984 100644 --- a/client/src/app/+videos/+video-watch/video-duration-formatter.pipe.ts +++ b/client/src/app/+videos/+video-watch/video-duration-formatter.pipe.ts @@ -1,28 +1,23 @@ import { Pipe, PipeTransform } from '@angular/core' -import { I18n } from '@ngx-translate/i18n-polyfill' @Pipe({ name: 'myVideoDurationFormatter' }) export class VideoDurationPipe implements PipeTransform { - constructor (private i18n: I18n) { - - } - transform (value: number): string { const hours = Math.floor(value / 3600) const minutes = Math.floor((value % 3600) / 60) const seconds = value % 60 if (hours > 0) { - return this.i18n('{{hours}} h {{minutes}} min {{seconds}} sec', { hours, minutes, seconds }) + return $localize`${hours} h ${minutes} min ${seconds} sec` } if (minutes > 0) { - return this.i18n('{{minutes}} min {{seconds}} sec', { minutes, seconds }) + return $localize`${minutes} min ${seconds} sec` } - return this.i18n('{{seconds}} sec', { seconds }) + return $localize`${seconds} sec` } } diff --git a/client/src/app/+videos/+video-watch/video-watch-playlist.component.ts b/client/src/app/+videos/+video-watch/video-watch-playlist.component.ts index 519ce2974..c60ca4671 100644 --- a/client/src/app/+videos/+video-watch/video-watch-playlist.component.ts +++ b/client/src/app/+videos/+video-watch/video-watch-playlist.component.ts @@ -1,9 +1,8 @@ import { Component, Input } from '@angular/core' import { Router } from '@angular/router' import { AuthService, ComponentPagination, LocalStorageService, Notifier, SessionStorageService, UserService } from '@app/core' -import { peertubeLocalStorage, peertubeSessionStorage } from '@root-helpers/peertube-web-storage' import { VideoPlaylist, VideoPlaylistElement, VideoPlaylistService } from '@app/shared/shared-video-playlist' -import { I18n } from '@ngx-translate/i18n-polyfill' +import { peertubeLocalStorage, peertubeSessionStorage } from '@root-helpers/peertube-web-storage' import { VideoDetails, VideoPlaylistPrivacy } from '@shared/models' @Component({ @@ -36,7 +35,6 @@ export class VideoWatchPlaylistComponent { private userService: UserService, private auth: AuthService, private notifier: Notifier, - private i18n: I18n, private videoPlaylist: VideoPlaylistService, private localStorageService: LocalStorageService, private sessionStorageService: SessionStorageService, @@ -189,13 +187,13 @@ export class VideoWatchPlaylistComponent { private setAutoPlayNextVideoPlaylistSwitchText () { this.autoPlayNextVideoPlaylistSwitchText = this.autoPlayNextVideoPlaylist - ? this.i18n('Stop autoplaying next video') - : this.i18n('Autoplay next video') + ? $localize`Stop autoplaying next video` + : $localize`Autoplay next video` } private setLoopPlaylistSwitchText () { this.loopPlaylistSwitchText = this.loopPlaylist - ? this.i18n('Stop looping playlist videos') - : this.i18n('Loop playlist videos') + ? $localize`Stop looping playlist videos` + : $localize`Loop playlist videos` } } diff --git a/client/src/app/+videos/+video-watch/video-watch.component.ts b/client/src/app/+videos/+video-watch/video-watch.component.ts index a53af210a..fb89bf6cd 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.ts +++ b/client/src/app/+videos/+video-watch/video-watch.component.ts @@ -14,7 +14,6 @@ import { SubscribeButtonComponent } from '@app/shared/shared-user-subscription' import { VideoDownloadComponent } from '@app/shared/shared-video-miniature' import { VideoPlaylist, VideoPlaylistService } from '@app/shared/shared-video-playlist' import { MetaService } from '@ngx-meta/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage' import { ServerConfig, UserVideoRateType, VideoCaption, VideoPrivacy, VideoState } from '@shared/models' import { getStoredP2PEnabled, getStoredTheater } from '../../../assets/player/peertube-player-local-storage' @@ -97,16 +96,15 @@ export class VideoWatchComponent implements OnInit, OnDestroy { private zone: NgZone, private redirectService: RedirectService, private videoCaptionService: VideoCaptionService, - private i18n: I18n, private hotkeysService: HotkeysService, private hooks: HooksService, private location: PlatformLocation, @Inject(LOCALE_ID) private localeId: string ) { - this.tooltipLike = this.i18n('Like this video') - this.tooltipDislike = this.i18n('Dislike this video') - this.tooltipSupport = this.i18n('Support options for this video') - this.tooltipSaveToPlaylist = this.i18n('Save to playlist') + this.tooltipLike = $localize`Like this video` + this.tooltipDislike = $localize`Dislike this video` + this.tooltipSupport = $localize`Support options for this video` + this.tooltipSaveToPlaylist = $localize`Save to playlist` } get user () { @@ -188,7 +186,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { getRatePopoverText () { if (this.isUserLoggedIn()) return undefined - return this.i18n('You need to be connected to rate this content.') + return $localize`You need to be connected to rate this content.` } showMoreDescription () { @@ -409,10 +407,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { } private setVideoLikesBarTooltipText () { - this.likesBarTooltipText = this.i18n('{{likesNumber}} likes / {{dislikesNumber}} dislikes', { - likesNumber: this.video.likes, - dislikesNumber: this.video.dislikes - }) + this.likesBarTooltipText = `${this.video.likes} likes / ${this.video.dislikes} dislikes` } private handleError (err: any) { @@ -465,8 +460,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy { if (this.isVideoBlur(this.video)) { const res = await this.confirmService.confirm( - this.i18n('This video contains mature or explicit content. Are you sure you want to watch it?'), - this.i18n('Mature or explicit content') + $localize`This video contains mature or explicit content. Are you sure you want to watch it?`, + $localize`Mature or explicit content` ) if (res === false) return this.location.back() } @@ -515,9 +510,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy { */ this.player.upnext({ timeout: 10000, // 10s - headText: this.i18n('Up Next'), - cancelText: this.i18n('Cancel'), - suspendedText: this.i18n('Autoplay is suspended'), + headText: $localize`Up Next`, + cancelText: $localize`Cancel`, + suspendedText: $localize`Autoplay is suspended`, getTitle: () => this.nextVideoTitle, next: () => this.zone.run(() => this.autoplayNext()), condition: () => { @@ -781,22 +776,22 @@ export class VideoWatchComponent implements OnInit, OnDestroy { private initHotkeys () { this.hotkeys = [ // These hotkeys are managed by the player - new Hotkey('f', e => e, undefined, this.i18n('Enter/exit fullscreen (requires player focus)')), - new Hotkey('space', e => e, undefined, this.i18n('Play/Pause the video (requires player focus)')), - new Hotkey('m', e => e, undefined, this.i18n('Mute/unmute the video (requires player focus)')), + new Hotkey('f', e => e, undefined, $localize`Enter/exit fullscreen (requires player focus)`), + new Hotkey('space', e => e, undefined, $localize`Play/Pause the video (requires player focus)`), + new Hotkey('m', e => e, undefined, $localize`Mute/unmute the video (requires player focus)`), - new Hotkey('0-9', e => e, undefined, this.i18n('Skip to a percentage of the video: 0 is 0% and 9 is 90% (requires player focus)')), + new Hotkey('0-9', e => e, undefined, $localize`Skip to a percentage of the video: 0 is 0% and 9 is 90% (requires player focus)`), - new Hotkey('up', e => e, undefined, this.i18n('Increase the volume (requires player focus)')), - new Hotkey('down', e => e, undefined, this.i18n('Decrease the volume (requires player focus)')), + new Hotkey('up', e => e, undefined, $localize`Increase the volume (requires player focus)`), + new Hotkey('down', e => e, undefined, $localize`Decrease the volume (requires player focus)`), - new Hotkey('right', e => e, undefined, this.i18n('Seek the video forward (requires player focus)')), - new Hotkey('left', e => e, undefined, this.i18n('Seek the video backward (requires player focus)')), + new Hotkey('right', e => e, undefined, $localize`Seek the video forward (requires player focus)`), + new Hotkey('left', e => e, undefined, $localize`Seek the video backward (requires player focus)`), - new Hotkey('>', e => e, undefined, this.i18n('Increase playback rate (requires player focus)')), - new Hotkey('<', e => e, undefined, this.i18n('Decrease playback rate (requires player focus)')), + new Hotkey('>', e => e, undefined, $localize`Increase playback rate (requires player focus)`), + new Hotkey('<', e => e, undefined, $localize`Decrease playback rate (requires player focus)`), - new Hotkey('.', e => e, undefined, this.i18n('Navigate in the video frame by frame (requires player focus)')) + new Hotkey('.', e => e, undefined, $localize`Navigate in the video frame by frame (requires player focus)`) ] if (this.isUserLoggedIn()) { @@ -804,17 +799,17 @@ export class VideoWatchComponent implements OnInit, OnDestroy { new Hotkey('shift+l', () => { this.setLike() return false - }, undefined, this.i18n('Like the video')), + }, undefined, $localize`Like the video`), new Hotkey('shift+d', () => { this.setDislike() return false - }, undefined, this.i18n('Dislike the video')), + }, undefined, $localize`Dislike the video`), new Hotkey('shift+s', () => { this.subscribeButton.subscribed ? this.subscribeButton.unsubscribe() : this.subscribeButton.subscribe() return false - }, undefined, this.i18n('Subscribe to the account')) + }, undefined, $localize`Subscribe to the account`) ]) } diff --git a/client/src/app/+videos/video-list/video-local.component.ts b/client/src/app/+videos/video-list/video-local.component.ts index b4c71ac49..07063d4d4 100644 --- a/client/src/app/+videos/video-list/video-local.component.ts +++ b/client/src/app/+videos/video-list/video-local.component.ts @@ -5,7 +5,6 @@ import { HooksService } from '@app/core/plugins/hooks.service' import { immutableAssign } from '@app/helpers' import { VideoService } from '@app/shared/shared-main' import { AbstractVideoList } from '@app/shared/shared-video-miniature' -import { I18n } from '@ngx-translate/i18n-polyfill' import { UserRight, VideoFilter, VideoSortField } from '@shared/models' @Component({ @@ -21,7 +20,6 @@ export class VideoLocalComponent extends AbstractVideoList implements OnInit, On useUserVideoPreferences = true constructor ( - protected i18n: I18n, protected router: Router, protected serverService: ServerService, protected route: ActivatedRoute, @@ -35,7 +33,7 @@ export class VideoLocalComponent extends AbstractVideoList implements OnInit, On ) { super() - this.titlePage = i18n('Local videos') + this.titlePage = $localize`Local videos` } ngOnInit () { diff --git a/client/src/app/+videos/video-list/video-most-liked.component.ts b/client/src/app/+videos/video-list/video-most-liked.component.ts index ca14851bb..e5f7bd152 100644 --- a/client/src/app/+videos/video-list/video-most-liked.component.ts +++ b/client/src/app/+videos/video-list/video-most-liked.component.ts @@ -5,7 +5,6 @@ import { HooksService } from '@app/core/plugins/hooks.service' import { immutableAssign } from '@app/helpers' import { VideoService } from '@app/shared/shared-main' import { AbstractVideoList } from '@app/shared/shared-video-miniature' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoSortField } from '@shared/models' @Component({ @@ -20,7 +19,6 @@ export class VideoMostLikedComponent extends AbstractVideoList implements OnInit useUserVideoPreferences = true constructor ( - protected i18n: I18n, protected router: Router, protected serverService: ServerService, protected route: ActivatedRoute, @@ -40,8 +38,8 @@ export class VideoMostLikedComponent extends AbstractVideoList implements OnInit this.generateSyndicationList() - this.titlePage = this.i18n('Most liked videos') - this.titleTooltip = this.i18n('Videos that have the higher number of likes.') + this.titlePage = $localize`Most liked videos` + this.titleTooltip = $localize`Videos that have the higher number of likes.` } getVideosObservable (page: number) { diff --git a/client/src/app/+videos/video-list/video-recently-added.component.ts b/client/src/app/+videos/video-list/video-recently-added.component.ts index c9395133f..34db6aabd 100644 --- a/client/src/app/+videos/video-list/video-recently-added.component.ts +++ b/client/src/app/+videos/video-list/video-recently-added.component.ts @@ -5,7 +5,6 @@ import { HooksService } from '@app/core/plugins/hooks.service' import { immutableAssign } from '@app/helpers' import { VideoService } from '@app/shared/shared-main' import { AbstractVideoList } from '@app/shared/shared-video-miniature' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoSortField } from '@shared/models' @Component({ @@ -21,7 +20,6 @@ export class VideoRecentlyAddedComponent extends AbstractVideoList implements On useUserVideoPreferences = true constructor ( - protected i18n: I18n, protected route: ActivatedRoute, protected serverService: ServerService, protected router: Router, @@ -35,7 +33,7 @@ export class VideoRecentlyAddedComponent extends AbstractVideoList implements On ) { super() - this.titlePage = i18n('Recently added') + this.titlePage = $localize`Recently added` } ngOnInit () { diff --git a/client/src/app/+videos/video-list/video-trending.component.ts b/client/src/app/+videos/video-list/video-trending.component.ts index 10eab18de..babcb9067 100644 --- a/client/src/app/+videos/video-list/video-trending.component.ts +++ b/client/src/app/+videos/video-list/video-trending.component.ts @@ -5,7 +5,6 @@ import { HooksService } from '@app/core/plugins/hooks.service' import { immutableAssign } from '@app/helpers' import { VideoService } from '@app/shared/shared-main' import { AbstractVideoList } from '@app/shared/shared-video-miniature' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoSortField } from '@shared/models' @Component({ @@ -20,7 +19,6 @@ export class VideoTrendingComponent extends AbstractVideoList implements OnInit, useUserVideoPreferences = true constructor ( - protected i18n: I18n, protected router: Router, protected serverService: ServerService, protected route: ActivatedRoute, @@ -45,14 +43,11 @@ export class VideoTrendingComponent extends AbstractVideoList implements OnInit, const trendingDays = config.trending.videos.intervalDays if (trendingDays === 1) { - this.titlePage = this.i18n('Trending for the last 24 hours') - this.titleTooltip = this.i18n('Trending videos are those totalizing the greatest number of views during the last 24 hours') + this.titlePage = $localize`Trending for the last 24 hours` + this.titleTooltip = $localize`Trending videos are those totalizing the greatest number of views during the last 24 hours` } else { - this.titlePage = this.i18n('Trending for the last {{days}} days', { days: trendingDays }) - this.titleTooltip = this.i18n( - 'Trending videos are those totalizing the greatest number of views during the last {{days}} days', - { days: trendingDays } - ) + this.titlePage = `Trending for the last ${trendingDays} days` + this.titleTooltip = `Trending videos are those totalizing the greatest number of views during the last ${trendingDays} days` } }) } diff --git a/client/src/app/+videos/video-list/video-user-subscriptions.component.ts b/client/src/app/+videos/video-list/video-user-subscriptions.component.ts index 41ad9b277..b02988169 100644 --- a/client/src/app/+videos/video-list/video-user-subscriptions.component.ts +++ b/client/src/app/+videos/video-list/video-user-subscriptions.component.ts @@ -3,10 +3,8 @@ import { ActivatedRoute, Router } from '@angular/router' import { AuthService, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' import { HooksService } from '@app/core/plugins/hooks.service' import { immutableAssign } from '@app/helpers' -import { VideoService } from '@app/shared/shared-main' import { UserSubscriptionService } from '@app/shared/shared-user-subscription' import { AbstractVideoList, OwnerDisplayType } from '@app/shared/shared-video-miniature' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoSortField } from '@shared/models' @Component({ @@ -21,7 +19,6 @@ export class VideoUserSubscriptionsComponent extends AbstractVideoList implement groupByDate = true constructor ( - protected i18n: I18n, protected router: Router, protected serverService: ServerService, protected route: ActivatedRoute, @@ -31,15 +28,14 @@ export class VideoUserSubscriptionsComponent extends AbstractVideoList implement protected screenService: ScreenService, protected storageService: LocalStorageService, private userSubscription: UserSubscriptionService, - private videoService: VideoService, private hooks: HooksService ) { super() - this.titlePage = i18n('Videos from your subscriptions') + this.titlePage = $localize`Videos from your subscriptions` this.actions.push({ routerLink: '/my-account/subscriptions', - label: i18n('Subscriptions'), + label: $localize`Subscriptions`, iconName: 'cog' }) } diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts index ee95d2cbb..ef0b1ae56 100644 --- a/client/src/app/app.component.ts +++ b/client/src/app/app.component.ts @@ -12,12 +12,11 @@ import { CustomModalComponent } from '@app/modal/custom-modal.component' import { InstanceConfigWarningModalComponent } from '@app/modal/instance-config-warning-modal.component' import { WelcomeModalComponent } from '@app/modal/welcome-modal.component' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' +import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage' import { getShortLocale, is18nPath } from '@shared/core-utils/i18n' import { BroadcastMessageLevel, ServerConfig, UserRole } from '@shared/models' import { MenuService } from './core/menu/menu.service' import { POP_STATE_MODAL_DISMISS } from './helpers' -import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage' import { InstanceService } from './shared/shared-instance' @Component({ @@ -40,7 +39,6 @@ export class AppComponent implements OnInit, AfterViewInit { constructor ( @Inject(DOCUMENT) private document: Document, @Inject(LOCALE_ID) private localeId: string, - private i18n: I18n, private viewportScroller: ViewportScroller, private router: Router, private authService: AuthService, @@ -288,37 +286,37 @@ export class AppComponent implements OnInit, AfterViewInit { new Hotkey(['/', 's'], (event: KeyboardEvent): boolean => { document.getElementById('search-video').focus() return false - }, undefined, this.i18n('Focus the search bar')), + }, undefined, $localize`Focus the search bar`), new Hotkey('b', (event: KeyboardEvent): boolean => { this.menu.toggleMenu() return false - }, undefined, this.i18n('Toggle the left menu')), + }, undefined, $localize`Toggle the left menu`), new Hotkey('g o', (event: KeyboardEvent): boolean => { this.router.navigate([ '/videos/overview' ]) return false - }, undefined, this.i18n('Go to the discover videos page')), + }, undefined, $localize`Go to the discover videos page`), new Hotkey('g t', (event: KeyboardEvent): boolean => { this.router.navigate([ '/videos/trending' ]) return false - }, undefined, this.i18n('Go to the trending videos page')), + }, undefined, $localize`Go to the trending videos page`), new Hotkey('g r', (event: KeyboardEvent): boolean => { this.router.navigate([ '/videos/recently-added' ]) return false - }, undefined, this.i18n('Go to the recently added videos page')), + }, undefined, $localize`Go to the recently added videos page`), new Hotkey('g l', (event: KeyboardEvent): boolean => { this.router.navigate([ '/videos/local' ]) return false - }, undefined, this.i18n('Go to the local videos page')), + }, undefined, $localize`Go to the local videos page`), new Hotkey('g u', (event: KeyboardEvent): boolean => { this.router.navigate([ '/videos/upload' ]) return false - }, undefined, this.i18n('Go to the videos upload page')) + }, undefined, $localize`Go to the videos upload page`) ]) } } diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts index b35cc1716..5c4616153 100644 --- a/client/src/app/app.module.ts +++ b/client/src/app/app.module.ts @@ -81,21 +81,7 @@ registerLocaleData(localeOc, 'oc') { provide: APP_BASE_HREF, useValue: '/' - }, - - { - provide: TRANSLATIONS, - useFactory: (locale: string) => { - // Default locale, nothing to translate - const completeLocale = getCompleteLocale(locale) - if (isDefaultLocale(completeLocale)) return '' - - const fileLocale = buildFileLocale(locale) - return require(`raw-loader!../locale/angular.${fileLocale}.xlf`).default - }, - deps: [ LOCALE_ID ] - }, - { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' } + } ] }) export class AppModule {} diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts index d3dc48267..10e2c2c58 100644 --- a/client/src/app/core/auth/auth.service.ts +++ b/client/src/app/core/auth/auth.service.ts @@ -6,7 +6,6 @@ import { Injectable } from '@angular/core' import { Router } from '@angular/router' import { Notifier } from '@app/core/notification/notifier.service' import { objectToUrlEncoded, peertubeLocalStorage } from '@root-helpers/index' -import { I18n } from '@ngx-translate/i18n-polyfill' import { MyUser as UserServerModel, OAuthClientLocal, User, UserLogin, UserRefreshToken } from '@shared/models' import { environment } from '../../../environments/environment' import { RestExtractor } from '../rest/rest-extractor.service' @@ -48,9 +47,8 @@ export class AuthService { private notifier: Notifier, private hotkeysService: HotkeysService, private restExtractor: RestExtractor, - private router: Router, - private i18n: I18n - ) { + private router: Router + ) { this.loginChanged = new Subject() this.loginChangedSource = this.loginChanged.asObservable() @@ -62,19 +60,19 @@ export class AuthService { new Hotkey('m s', (event: KeyboardEvent): boolean => { this.router.navigate([ '/videos/subscriptions' ]) return false - }, undefined, this.i18n('Go to my subscriptions')), + }, undefined, $localize`Go to my subscriptions`), new Hotkey('m v', (event: KeyboardEvent): boolean => { this.router.navigate([ '/my-account/videos' ]) return false - }, undefined, this.i18n('Go to my videos')), + }, undefined, $localize`Go to my videos`), new Hotkey('m i', (event: KeyboardEvent): boolean => { this.router.navigate([ '/my-account/video-imports' ]) return false - }, undefined, this.i18n('Go to my imports')), + }, undefined, $localize`Go to my imports`), new Hotkey('m c', (event: KeyboardEvent): boolean => { this.router.navigate([ '/my-account/video-channels' ]) return false - }, undefined, this.i18n('Go to my channels')) + }, undefined, $localize`Go to my channels`) ] } @@ -97,14 +95,12 @@ export class AuthService { let errorMessage = error.message if (error.status === 403) { - 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.' - ) + errorMessage = $localize`Cannot retrieve OAuth Client credentials: ${error.text}. +Ensure you have correctly configured PeerTube (config/ directory), in particular the "webserver" section.` } // We put a bigger timeout: this is an important message - this.notifier.error(errorMessage, this.i18n('Error'), 7000) + this.notifier.error(errorMessage, $localize`Error`, 7000) } ) } @@ -216,7 +212,7 @@ export class AuthService { this.router.navigate([ '/login' ]) return observableThrowError({ - error: this.i18n('You need to reconnect.') + error: $localize`You need to reconnect.` }) }), share() diff --git a/client/src/app/core/hotkeys/hotkeys.component.ts b/client/src/app/core/hotkeys/hotkeys.component.ts index 512a2399a..315e1a25e 100644 --- a/client/src/app/core/hotkeys/hotkeys.component.ts +++ b/client/src/app/core/hotkeys/hotkeys.component.ts @@ -1,7 +1,6 @@ -import { Component, OnInit, OnDestroy, Input } from '@angular/core' +import { Hotkey, HotkeysService } from 'angular2-hotkeys' import { Subscription } from 'rxjs' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { HotkeysService, Hotkey } from 'angular2-hotkeys' +import { Component, Input, OnDestroy, OnInit } from '@angular/core' @Component({ selector : 'my-hotkeys-cheatsheet', @@ -9,16 +8,15 @@ import { HotkeysService, Hotkey } from 'angular2-hotkeys' styleUrls: [ './hotkeys.component.scss' ] }) export class CheatSheetComponent implements OnInit, OnDestroy { - @Input() title = this.i18n('Keyboard Shortcuts:') + @Input() title = $localize`Keyboard Shortcuts:` helpVisible = false subscription: Subscription hotkeys: Hotkey[] constructor ( - private hotkeysService: HotkeysService, - private i18n: I18n - ) {} + private hotkeysService: HotkeysService + ) {} public ngOnInit (): void { this.subscription = this.hotkeysService.cheatSheetToggle.subscribe((isOpen) => { diff --git a/client/src/app/core/notification/notifier.service.ts b/client/src/app/core/notification/notifier.service.ts index 9833c65a0..f736672bb 100644 --- a/client/src/app/core/notification/notifier.service.ts +++ b/client/src/app/core/notification/notifier.service.ts @@ -1,30 +1,26 @@ -import { Injectable } from '@angular/core' import { MessageService } from 'primeng/api' -import { I18n } from '@ngx-translate/i18n-polyfill' +import { Injectable } from '@angular/core' @Injectable() export class Notifier { readonly TIMEOUT = 5000 - constructor ( - private i18n: I18n, - private messageService: MessageService) { - } + constructor (private messageService: MessageService) { } info (text: string, title?: string, timeout?: number) { - if (!title) title = this.i18n('Info') + if (!title) title = $localize`Info` return this.notify('info', text, title, timeout) } error (text: string, title?: string, timeout?: number) { - if (!title) title = this.i18n('Error') + if (!title) title = $localize`Error` return this.notify('error', text, title, timeout) } success (text: string, title?: string, timeout?: number) { - if (!title) title = this.i18n('Success') + if (!title) title = $localize`Success` return this.notify('success', text, title, timeout) } diff --git a/client/src/app/core/rest/rest-extractor.service.ts b/client/src/app/core/rest/rest-extractor.service.ts index 9de964f79..36702b371 100644 --- a/client/src/app/core/rest/rest-extractor.service.ts +++ b/client/src/app/core/rest/rest-extractor.service.ts @@ -2,16 +2,12 @@ import { throwError as observableThrowError } from 'rxjs' import { Injectable } from '@angular/core' import { Router } from '@angular/router' import { dateToHuman } from '@app/helpers' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ResultList } from '@shared/models' @Injectable() export class RestExtractor { - constructor ( - private router: Router, - private i18n: I18n - ) { } + constructor (private router: Router) { } extractDataBool () { return true @@ -62,19 +58,18 @@ export class RestExtractor { } else if (err.error && err.error.error) { errorMessage = err.error.error } else if (err.status === 413) { - errorMessage = this.i18n( - 'Request is too large for the server. Please contact you administrator if you want to increase the limit size.' - ) + errorMessage = $localize`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 = this.i18n('Too many attempts, please try again after {{minutesLeft}} minutes.', { minutesLeft }) + errorMessage = $localize`Too many attempts, please try again after ${minutesLeft} minutes.` } else { - errorMessage = this.i18n('Too many attempts, please try again later.') + errorMessage = $localize`Too many attempts, please try again later.` } } else if (err.status === 500) { - errorMessage = this.i18n('Server error. Please retry later.') + errorMessage = $localize`Server error. Please retry later.` } errorMessage = errorMessage ? errorMessage : 'Unknown error.' diff --git a/client/src/app/core/routing/can-deactivate-guard.service.ts b/client/src/app/core/routing/can-deactivate-guard.service.ts index e0405293a..8fce495e9 100644 --- a/client/src/app/core/routing/can-deactivate-guard.service.ts +++ b/client/src/app/core/routing/can-deactivate-guard.service.ts @@ -2,7 +2,6 @@ import { Observable } from 'rxjs' import { Injectable } from '@angular/core' import { CanDeactivate } from '@angular/router' import { ConfirmService } from '@app/core/confirm' -import { I18n } from '@ngx-translate/i18n-polyfill' export type CanComponentDeactivateResult = { text?: string, canDeactivate: Observable | boolean } @@ -12,18 +11,16 @@ export interface CanComponentDeactivate { @Injectable() export class CanDeactivateGuard implements CanDeactivate { - constructor ( - private confirmService: ConfirmService, - private i18n: I18n - ) { } + + constructor (private confirmService: ConfirmService) { } canDeactivate (component: CanComponentDeactivate) { const result = component.canDeactivate() - const text = result.text || this.i18n('All unsaved data will be lost, are you sure you want to leave this page?') + const text = result.text || $localize`All unsaved data will be lost, are you sure you want to leave this page?` return result.canDeactivate || this.confirmService.confirm( text, - this.i18n('Warning') + $localize`Warning` ) } diff --git a/client/src/app/core/users/user.service.ts b/client/src/app/core/users/user.service.ts index 6e7a48519..01c9be5bf 100644 --- a/client/src/app/core/users/user.service.ts +++ b/client/src/app/core/users/user.service.ts @@ -5,7 +5,6 @@ import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { AuthService } from '@app/core/auth' import { BytesPipe } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { UserLocalStorageKeys } from '@root-helpers/users' import { Avatar, @@ -38,9 +37,8 @@ export class UserService { private restExtractor: RestExtractor, private restService: RestService, private localStorageService: LocalStorageService, - private sessionStorageService: SessionStorageService, - private i18n: I18n - ) { } + private sessionStorageService: SessionStorageService + ) { } changePassword (currentPassword: string, newPassword: string) { const url = UserService.BASE_USERS_URL + 'me' @@ -383,9 +381,9 @@ export class UserService { } const roleLabels: { [ id in UserRole ]: string } = { - [UserRole.USER]: this.i18n('User'), - [UserRole.ADMINISTRATOR]: this.i18n('Administrator'), - [UserRole.MODERATOR]: this.i18n('Moderator') + [UserRole.USER]: $localize`User`, + [UserRole.ADMINISTRATOR]: $localize`Administrator`, + [UserRole.MODERATOR]: $localize`Moderator` } return Object.assign(user, { diff --git a/client/src/app/menu/menu.component.ts b/client/src/app/menu/menu.component.ts index 2c55b9a84..3d6cbda24 100644 --- a/client/src/app/menu/menu.component.ts +++ b/client/src/app/menu/menu.component.ts @@ -5,7 +5,6 @@ import { Component, OnInit, ViewChild } from '@angular/core' import { AuthService, AuthStatus, AuthUser, RedirectService, ScreenService, ServerService, UserService } from '@app/core' import { LanguageChooserComponent } from '@app/menu/language-chooser.component' import { QuickSettingsModalComponent } from '@app/modal/quick-settings-modal.component' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig, UserRight, VideoConstant } from '@shared/models' const logger = debug('peertube:menu:MenuComponent') @@ -44,9 +43,8 @@ export class MenuComponent implements OnInit { private serverService: ServerService, private redirectService: RedirectService, private hotkeysService: HotkeysService, - private screenService: ScreenService, - private i18n: I18n - ) { } + private screenService: ScreenService + ) { } get isInMobileView () { return this.screenService.isInMobileView() @@ -117,13 +115,13 @@ export class MenuComponent implements OnInit { switch (this.user.nsfwPolicy) { case 'do_not_list': - return this.i18n('hide') + return $localize`hide` case 'blur': - return this.i18n('blur') + return $localize`blur` case 'display': - return this.i18n('display') + return $localize`display` } } @@ -189,7 +187,7 @@ export class MenuComponent implements OnInit { } langForLocale (localeId: string) { - if (localeId === '_unknown') return this.i18n('Unknown') + if (localeId === '_unknown') return $localize`Unknown` return this.languages.find(lang => lang.id === localeId).label } @@ -201,7 +199,7 @@ export class MenuComponent implements OnInit { } if (!this.user.videoLanguages) { - this.videoLanguages = [this.i18n('any language')] + this.videoLanguages = [$localize`any language`] return } diff --git a/client/src/app/modal/confirm.component.ts b/client/src/app/modal/confirm.component.ts index 2c7ef46c4..457dd1f3f 100644 --- a/client/src/app/modal/confirm.component.ts +++ b/client/src/app/modal/confirm.component.ts @@ -3,7 +3,6 @@ import { ConfirmService } from '@app/core/confirm/confirm.service' import { POP_STATE_MODAL_DISMISS } from '@app/helpers' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-confirm', @@ -25,8 +24,7 @@ export class ConfirmComponent implements OnInit { constructor ( private modalService: NgbModal, - private confirmService: ConfirmService, - private i18n: I18n + private confirmService: ConfirmService ) { } ngOnInit () { @@ -38,7 +36,7 @@ export class ConfirmComponent implements OnInit { this.inputLabel = inputLabel this.expectedInputValue = expectedInputValue - this.confirmButtonText = confirmButtonText || this.i18n('Confirm') + this.confirmButtonText = confirmButtonText || $localize`Confirm` this.showModal() } diff --git a/client/src/app/shared/shared-abuse-list/abuse-details.component.ts b/client/src/app/shared/shared-abuse-list/abuse-details.component.ts index 0e872079a..282a6fe19 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-details.component.ts +++ b/client/src/app/shared/shared-abuse-list/abuse-details.component.ts @@ -1,7 +1,6 @@ import { Component, Input } from '@angular/core' import { durationToString } from '@app/helpers' import { Actor } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AbusePredefinedReasonsString } from '@shared/models' import { ProcessedAbuse } from './processed-abuse.model' @@ -17,18 +16,16 @@ export class AbuseDetailsComponent { private predefinedReasonsTranslations: { [key in AbusePredefinedReasonsString]: string } - constructor ( - private i18n: I18n - ) { + constructor () { this.predefinedReasonsTranslations = { - violentOrRepulsive: this.i18n('Violent or Repulsive'), - hatefulOrAbusive: this.i18n('Hateful or Abusive'), - spamOrMisleading: this.i18n('Spam or Misleading'), - privacy: this.i18n('Privacy'), - rights: this.i18n('Copyright'), - serverRules: this.i18n('Server rules'), - thumbnails: this.i18n('Thumbnails'), - captions: this.i18n('Captions') + violentOrRepulsive: $localize`Violent or Repulsive`, + hatefulOrAbusive: $localize`Hateful or Abusive`, + spamOrMisleading: $localize`Spam or Misleading`, + privacy: $localize`Privacy`, + rights: $localize`Copyright`, + serverRules: $localize`Server rules`, + thumbnails: $localize`Thumbnails`, + captions: $localize`Captions` } } diff --git a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts index c7dc5f4d2..cc933db0d 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts +++ b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts @@ -1,16 +1,15 @@ import * as debug from 'debug' import truncate from 'lodash-es/truncate' import { SortMeta } from 'primeng/api' -import { buildVideoOrPlaylistEmbed, buildVideoLink } from 'src/assets/player/utils' +import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils' import { environment } from 'src/environments/environment' -import { AfterViewInit, Component, OnInit, ViewChild, Input } from '@angular/core' +import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core' import { DomSanitizer } from '@angular/platform-browser' import { ActivatedRoute, Params, Router } from '@angular/router' import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core' import { Account, Actor, DropdownAction, Video, VideoService } from '@app/shared/shared-main' import { AbuseService, BlocklistService, VideoBlockService } from '@app/shared/shared-moderation' import { VideoCommentService } from '@app/shared/shared-video-comment' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AbuseState, AdminAbuse } from '@shared/models' import { AbuseMessageModalComponent } from './abuse-message-modal.component' import { ModerationCommentModalComponent } from './moderation-comment-modal.component' @@ -45,7 +44,6 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV private videoService: VideoService, private videoBlocklistService: VideoBlockService, private confirmService: ConfirmService, - private i18n: I18n, private markdownRenderer: MarkdownService, private sanitizer: DomSanitizer, private route: ActivatedRoute, @@ -157,12 +155,12 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV } async removeAbuse (abuse: AdminAbuse) { - const res = await this.confirmService.confirm(this.i18n('Do you really want to delete this abuse report?'), this.i18n('Delete')) + const res = await this.confirmService.confirm($localize`Do you really want to delete this abuse report?`, $localize`Delete`) if (res === false) return this.abuseService.removeAbuse(abuse).subscribe( () => { - this.notifier.success(this.i18n('Abuse deleted.')) + this.notifier.success($localize`Abuse deleted.`) this.loadData() }, @@ -238,7 +236,7 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV if (abuse.comment) { if (abuse.comment.deleted) { - abuse.truncatedCommentHtml = abuse.commentHtml = this.i18n('Deleted comment') + abuse.truncatedCommentHtml = abuse.commentHtml = $localize`Deleted comment` } else { const truncated = truncate(abuse.comment.text, { length: 100 }) abuse.truncatedCommentHtml = await this.markdownRenderer.textMarkdownToHTML(truncated, true) @@ -267,38 +265,38 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV private buildInternalActions (): DropdownAction[] { return [ { - label: this.i18n('Internal actions'), + label: $localize`Internal actions`, isHeader: true }, { label: this.isAdminView() - ? this.i18n('Messages with reporter') - : this.i18n('Messages with moderators'), + ? $localize`Messages with reporter` + : $localize`Messages with moderators`, handler: abuse => this.openAbuseMessagesModal(abuse), isDisplayed: abuse => this.isLocalAbuse(abuse) }, { - label: this.i18n('Update internal note'), + label: $localize`Update internal note`, handler: abuse => this.openModerationCommentModal(abuse), isDisplayed: abuse => this.isAdminView() && !!abuse.moderationComment }, { - label: this.i18n('Mark as accepted'), + label: $localize`Mark as accepted`, handler: abuse => this.updateAbuseState(abuse, AbuseState.ACCEPTED), isDisplayed: abuse => this.isAdminView() && !this.isAbuseAccepted(abuse) }, { - label: this.i18n('Mark as rejected'), + label: $localize`Mark as rejected`, handler: abuse => this.updateAbuseState(abuse, AbuseState.REJECTED), isDisplayed: abuse => this.isAdminView() && !this.isAbuseRejected(abuse) }, { - label: this.i18n('Add internal note'), + label: $localize`Add internal note`, handler: abuse => this.openModerationCommentModal(abuse), isDisplayed: abuse => this.isAdminView() && !abuse.moderationComment }, { - label: this.i18n('Delete report'), + label: $localize`Delete report`, handler: abuse => this.isAdminView() && this.removeAbuse(abuse) } ] @@ -309,19 +307,19 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV return [ { - label: this.i18n('Actions for the flagged account'), + label: $localize`Actions for the flagged account`, isHeader: true, isDisplayed: abuse => abuse.flaggedAccount && !abuse.comment && !abuse.video }, { - label: this.i18n('Mute account'), + label: $localize`Mute account`, isDisplayed: abuse => abuse.flaggedAccount && !abuse.comment && !abuse.video, handler: abuse => this.muteAccountHelper(abuse.flaggedAccount) }, { - label: this.i18n('Mute server account'), + label: $localize`Mute server account`, isDisplayed: abuse => abuse.flaggedAccount && !abuse.comment && !abuse.video, handler: abuse => this.muteServerHelper(abuse.flaggedAccount.host) } @@ -333,19 +331,19 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV return [ { - label: this.i18n('Actions for the reporter'), + label: $localize`Actions for the reporter`, isHeader: true, isDisplayed: abuse => !!abuse.reporterAccount }, { - label: this.i18n('Mute reporter'), + label: $localize`Mute reporter`, isDisplayed: abuse => !!abuse.reporterAccount, handler: abuse => this.muteAccountHelper(abuse.reporterAccount) }, { - label: this.i18n('Mute server'), + label: $localize`Mute server`, isDisplayed: abuse => abuse.reporterAccount && !abuse.reporterAccount.userId, handler: abuse => this.muteServerHelper(abuse.reporterAccount.host) } @@ -357,18 +355,18 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV return [ { - label: this.i18n('Actions for the video'), + label: $localize`Actions for the video`, isHeader: true, isDisplayed: abuse => abuse.video && !abuse.video.deleted }, { - label: this.i18n('Block video'), + label: $localize`Block video`, isDisplayed: abuse => abuse.video && !abuse.video.deleted && !abuse.video.blacklisted, handler: abuse => { this.videoBlocklistService.blockVideo(abuse.video.id, undefined, true) .subscribe( () => { - this.notifier.success(this.i18n('Video blocked.')) + this.notifier.success($localize`Video blocked.`) this.updateAbuseState(abuse, AbuseState.ACCEPTED) }, @@ -378,13 +376,13 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV } }, { - label: this.i18n('Unblock video'), + label: $localize`Unblock video`, isDisplayed: abuse => abuse.video && !abuse.video.deleted && abuse.video.blacklisted, handler: abuse => { this.videoBlocklistService.unblockVideo(abuse.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video unblocked.')) + this.notifier.success($localize`Video unblocked.`) this.updateAbuseState(abuse, AbuseState.ACCEPTED) }, @@ -394,19 +392,19 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV } }, { - label: this.i18n('Delete video'), + label: $localize`Delete video`, isDisplayed: abuse => abuse.video && !abuse.video.deleted, handler: async abuse => { const res = await this.confirmService.confirm( - this.i18n('Do you really want to delete this video?'), - this.i18n('Delete') + $localize`Do you really want to delete this video?`, + $localize`Delete` ) if (res === false) return this.videoService.removeVideo(abuse.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video deleted.')) + this.notifier.success($localize`Video deleted.`) this.updateAbuseState(abuse, AbuseState.ACCEPTED) }, @@ -423,25 +421,25 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV return [ { - label: this.i18n('Actions for the comment'), + label: $localize`Actions for the comment`, isHeader: true, isDisplayed: abuse => abuse.comment && !abuse.comment.deleted }, { - label: this.i18n('Delete comment'), + label: $localize`Delete comment`, isDisplayed: abuse => abuse.comment && !abuse.comment.deleted, handler: async abuse => { const res = await this.confirmService.confirm( - this.i18n('Do you really want to delete this comment?'), - this.i18n('Delete') + $localize`Do you really want to delete this comment?`, + $localize`Delete` ) if (res === false) return this.commentService.deleteVideoComment(abuse.comment.video.id, abuse.comment.id) .subscribe( () => { - this.notifier.success(this.i18n('Comment deleted.')) + this.notifier.success($localize`Comment deleted.`) this.updateAbuseState(abuse, AbuseState.ACCEPTED) }, @@ -457,10 +455,7 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV this.blocklistService.blockAccountByInstance(account) .subscribe( () => { - this.notifier.success( - this.i18n('Account {{nameWithHost}} muted by the instance.', { nameWithHost: account.nameWithHost }) - ) - + this.notifier.success($localize`Account ${account.nameWithHost} muted by the instance.`) account.mutedByInstance = true }, @@ -472,9 +467,7 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV this.blocklistService.blockServerByInstance(host) .subscribe( () => { - this.notifier.success( - this.i18n('Server {{host}} muted by the instance.', { host: host }) - ) + this.notifier.success($localize`Server ${host} muted by the instance.`) }, err => this.notifier.error(err.message) diff --git a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts index 6686d91f4..0c3c8ff48 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts +++ b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts @@ -1,9 +1,8 @@ -import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' -import { AuthService, Notifier, HtmlRendererService } from '@app/core' +import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' +import { AuthService, HtmlRendererService, Notifier } from '@app/core' import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AbuseMessage, UserAbuse } from '@shared/models' import { AbuseService } from '../shared-moderation' @@ -31,7 +30,6 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit { protected formValidatorService: FormValidatorService, private abuseValidatorsService: AbuseValidatorsService, private modalService: NgbModal, - private i18n: I18n, private htmlRenderer: HtmlRendererService, private auth: AuthService, private notifier: Notifier, @@ -99,10 +97,10 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit { getPlaceholderMessage () { if (this.isAdminView) { - return this.i18n('Add a message to communicate with the reporter') + return $localize`Add a message to communicate with the reporter` } - return this.i18n('Add a message to communicate with the moderation team') + return $localize`Add a message to communicate with the moderation team` } private loadMessages () { diff --git a/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts b/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts index ecb7966bf..fad7f888d 100644 --- a/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts +++ b/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts @@ -1,10 +1,9 @@ import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' import { Notifier } from '@app/core' -import { FormReactive, FormValidatorService, AbuseValidatorsService } from '@app/shared/shared-forms' +import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { AbuseService } from '@app/shared/shared-moderation' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AdminAbuse } from '@shared/models' @Component({ @@ -24,8 +23,7 @@ export class ModerationCommentModalComponent extends FormReactive implements OnI private modalService: NgbModal, private notifier: Notifier, private abuseService: AbuseService, - private abuseValidatorsService: AbuseValidatorsService, - private i18n: I18n + private abuseValidatorsService: AbuseValidatorsService ) { super() } @@ -57,7 +55,7 @@ export class ModerationCommentModalComponent extends FormReactive implements OnI this.abuseService.updateAbuse(this.abuseToComment, { moderationComment }) .subscribe( () => { - this.notifier.success(this.i18n('Comment updated.')) + this.notifier.success($localize`Comment updated.`) this.commentUpdated.emit(moderationComment) this.hide() diff --git a/client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts index 5f15963f3..56d30d6f9 100644 --- a/client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts @@ -1,6 +1,5 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() @@ -9,31 +8,31 @@ export class AbuseValidatorsService { readonly ABUSE_MODERATION_COMMENT: BuildFormValidator readonly ABUSE_MESSAGE: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.ABUSE_REASON = { VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], MESSAGES: { - 'required': this.i18n('Report reason is required.'), - 'minlength': this.i18n('Report reason must be at least 2 characters long.'), - 'maxlength': this.i18n('Report reason cannot be more than 3000 characters long.') + 'required': $localize`Report reason is required.`, + 'minlength': $localize`Report reason must be at least 2 characters long.`, + 'maxlength': $localize`Report reason cannot be more than 3000 characters long.` } } this.ABUSE_MODERATION_COMMENT = { VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], MESSAGES: { - 'required': this.i18n('Moderation comment is required.'), - 'minlength': this.i18n('Moderation comment must be at least 2 characters long.'), - 'maxlength': this.i18n('Moderation comment cannot be more than 3000 characters long.') + 'required': $localize`Moderation comment is required.`, + 'minlength': $localize`Moderation comment must be at least 2 characters long.`, + 'maxlength': $localize`Moderation comment cannot be more than 3000 characters long.` } } this.ABUSE_MESSAGE = { VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], MESSAGES: { - 'required': this.i18n('Abuse message is required.'), - 'minlength': this.i18n('Abuse message must be at least 2 characters long.'), - 'maxlength': this.i18n('Abuse message cannot be more than 3000 characters long.') + 'required': $localize`Abuse message is required.`, + 'minlength': $localize`Abuse message must be at least 2 characters long.`, + 'maxlength': $localize`Abuse message cannot be more than 3000 characters long.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts index f270b602b..6c7da833f 100644 --- a/client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@angular/core' import { ValidatorFn, Validators } from '@angular/forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { BuildFormValidator } from './form-validator.service' import { validateHost } from './host' @@ -8,13 +7,13 @@ import { validateHost } from './host' export class BatchDomainsValidatorsService { readonly DOMAINS: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.DOMAINS = { VALIDATORS: [ Validators.required, this.validDomains, this.isHostsUnique ], MESSAGES: { - 'required': this.i18n('Domain is required.'), - 'validDomains': this.i18n('Domains entered are invalid.'), - 'uniqueDomains': this.i18n('Domains entered contain duplicates.') + 'required': $localize`Domain is required.`, + 'validDomains': $localize`Domains entered are invalid.`, + 'uniqueDomains': $localize`Domains entered contain duplicates.` } } } @@ -33,7 +32,7 @@ export class BatchDomainsValidatorsService { for (const host of hosts) { if (validateHost(host) === false) { - newHostsErrors.push(this.i18n('{{host}} is not valid', { host })) + newHostsErrors.push($localize`${host} is not valid`) } } diff --git a/client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts index c77aba6a1..862ff5470 100644 --- a/client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts @@ -1,7 +1,6 @@ +import { Injectable } from '@angular/core' import { Validators } from '@angular/forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { BuildFormValidator } from './form-validator.service' -import { Injectable } from '@angular/core' @Injectable() export class CustomConfigValidatorsService { @@ -16,82 +15,82 @@ export class CustomConfigValidatorsService { readonly INDEX_URL: BuildFormValidator readonly SEARCH_INDEX_URL: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.INSTANCE_NAME = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Instance name is required.') + 'required': $localize`Instance name is required.` } } this.INSTANCE_SHORT_DESCRIPTION = { VALIDATORS: [ Validators.max(250) ], MESSAGES: { - 'max': this.i18n('Short description should not be longer than 250 characters.') + 'max': $localize`Short description should not be longer than 250 characters.` } } this.SERVICES_TWITTER_USERNAME = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Twitter username is required.') + 'required': $localize`Twitter username is required.` } } this.CACHE_PREVIEWS_SIZE = { VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ], MESSAGES: { - 'required': this.i18n('Previews cache size is required.'), - 'min': this.i18n('Previews cache size must be greater than 1.'), - 'pattern': this.i18n('Previews cache size must be a number.') + 'required': $localize`Previews cache size is required.`, + 'min': $localize`Previews cache size must be greater than 1.`, + 'pattern': $localize`Previews cache size must be a number.` } } this.CACHE_CAPTIONS_SIZE = { VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ], MESSAGES: { - 'required': this.i18n('Captions cache size is required.'), - 'min': this.i18n('Captions cache size must be greater than 1.'), - 'pattern': this.i18n('Captions cache size must be a number.') + 'required': $localize`Captions cache size is required.`, + 'min': $localize`Captions cache size must be greater than 1.`, + 'pattern': $localize`Captions cache size must be a number.` } } this.SIGNUP_LIMIT = { VALIDATORS: [ Validators.required, Validators.min(-1), Validators.pattern('-?[0-9]+') ], MESSAGES: { - 'required': this.i18n('Signup limit is required.'), - 'min': this.i18n('Signup limit must be greater than 1.'), - 'pattern': this.i18n('Signup limit must be a number.') + 'required': $localize`Signup limit is required.`, + 'min': $localize`Signup limit must be greater than 1.`, + 'pattern': $localize`Signup limit must be a number.` } } this.ADMIN_EMAIL = { VALIDATORS: [ Validators.required, Validators.email ], MESSAGES: { - 'required': this.i18n('Admin email is required.'), - 'email': this.i18n('Admin email must be valid.') + 'required': $localize`Admin email is required.`, + 'email': $localize`Admin email must be valid.` } } this.TRANSCODING_THREADS = { VALIDATORS: [ Validators.required, Validators.min(0) ], MESSAGES: { - 'required': this.i18n('Transcoding threads is required.'), - 'min': this.i18n('Transcoding threads must be greater or equal to 0.') + 'required': $localize`Transcoding threads is required.`, + 'min': $localize`Transcoding threads must be greater or equal to 0.` } } this.INDEX_URL = { VALIDATORS: [ Validators.pattern(/^https:\/\//) ], MESSAGES: { - 'pattern': this.i18n('Index URL should be a URL') + 'pattern': $localize`Index URL should be a URL` } } this.SEARCH_INDEX_URL = { VALIDATORS: [ Validators.pattern(/^https?:\/\//) ], MESSAGES: { - 'pattern': this.i18n('Search index URL should be a URL') + 'pattern': $localize`Search index URL should be a URL` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts index 96a35a48f..3628f0b60 100644 --- a/client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts @@ -1,7 +1,6 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' +import { Injectable } from '@angular/core' import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' -import { Injectable } from '@angular/core' @Injectable() export class InstanceValidatorsService { @@ -10,13 +9,13 @@ export class InstanceValidatorsService { readonly SUBJECT: BuildFormValidator readonly BODY: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.FROM_EMAIL = { VALIDATORS: [ Validators.required, Validators.email ], MESSAGES: { - 'required': this.i18n('Email is required.'), - 'email': this.i18n('Email must be valid.') + 'required': $localize`Email is required.`, + 'email': $localize`Email must be valid.` } } @@ -27,9 +26,9 @@ export class InstanceValidatorsService { Validators.maxLength(120) ], MESSAGES: { - 'required': this.i18n('Your name is required.'), - 'minlength': this.i18n('Your name must be at least 1 character long.'), - 'maxlength': this.i18n('Your name cannot be more than 120 characters long.') + 'required': $localize`Your name is required.`, + 'minlength': $localize`Your name must be at least 1 character long.`, + 'maxlength': $localize`Your name cannot be more than 120 characters long.` } } @@ -40,9 +39,9 @@ export class InstanceValidatorsService { Validators.maxLength(120) ], MESSAGES: { - 'required': this.i18n('A subject is required.'), - 'minlength': this.i18n('The subject must be at least 1 character long.'), - 'maxlength': this.i18n('The subject cannot be more than 120 characters long.') + 'required': $localize`A subject is required.`, + 'minlength': $localize`The subject must be at least 1 character long.`, + 'maxlength': $localize`The subject cannot be more than 120 characters long.` } } @@ -53,9 +52,9 @@ export class InstanceValidatorsService { Validators.maxLength(5000) ], MESSAGES: { - 'required': this.i18n('A message is required.'), - 'minlength': this.i18n('The message must be at least 3 characters long.'), - 'maxlength': this.i18n('The message cannot be more than 5000 characters long.') + 'required': $localize`A message is required.`, + 'minlength': $localize`The message must be at least 3 characters long.`, + 'maxlength': $localize`The message cannot be more than 5000 characters long.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/login-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/login-validators.service.ts index a5837357e..67ea11f20 100644 --- a/client/src/app/shared/shared-forms/form-validators/login-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/login-validators.service.ts @@ -1,6 +1,5 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() @@ -8,13 +7,13 @@ export class LoginValidatorsService { readonly LOGIN_USERNAME: BuildFormValidator readonly LOGIN_PASSWORD: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.LOGIN_USERNAME = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Username is required.') + 'required': $localize`Username is required.` } } @@ -23,7 +22,7 @@ export class LoginValidatorsService { Validators.required ], MESSAGES: { - 'required': this.i18n('Password is required.') + 'required': $localize`Password is required.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts index d2085a309..3d0b4dd64 100644 --- a/client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts @@ -1,19 +1,18 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() export class ResetPasswordValidatorsService { readonly RESET_PASSWORD_CONFIRM: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.RESET_PASSWORD_CONFIRM = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Confirmation of the password is required.') + 'required': $localize`Confirmation of the password is required.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/user-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/user-validators.service.ts index 61486bbab..312fc9b1e 100644 --- a/client/src/app/shared/shared-forms/form-validators/user-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/user-validators.service.ts @@ -1,7 +1,6 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' +import { Injectable } from '@angular/core' import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' -import { Injectable } from '@angular/core' @Injectable() export class UserValidatorsService { @@ -20,7 +19,7 @@ export class UserValidatorsService { readonly USER_BAN_REASON: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.USER_USERNAME = { VALIDATORS: [ @@ -30,10 +29,10 @@ export class UserValidatorsService { Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) ], MESSAGES: { - 'required': this.i18n('Username is required.'), - 'minlength': this.i18n('Username must be at least 1 character long.'), - 'maxlength': this.i18n('Username cannot be more than 50 characters long.'), - 'pattern': this.i18n('Username should be lowercase alphanumeric; dots and underscores are allowed.') + 'required': $localize`Username is required.`, + 'minlength': $localize`Username must be at least 1 character long.`, + 'maxlength': $localize`Username cannot be more than 50 characters long.`, + 'pattern': $localize`Username should be lowercase alphanumeric; dots and underscores are allowed.` } } @@ -45,18 +44,18 @@ export class UserValidatorsService { Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) ], MESSAGES: { - 'required': this.i18n('Channel name is required.'), - 'minlength': this.i18n('Channel name must be at least 1 character long.'), - 'maxlength': this.i18n('Channel name cannot be more than 50 characters long.'), - 'pattern': this.i18n('Channel name should be lowercase alphanumeric; dots and underscores are allowed.') + 'required': $localize`Channel name is required.`, + 'minlength': $localize`Channel name must be at least 1 character long.`, + 'maxlength': $localize`Channel name cannot be more than 50 characters long.`, + 'pattern': $localize`Channel name should be lowercase alphanumeric; dots and underscores are allowed.` } } this.USER_EMAIL = { VALIDATORS: [ Validators.required, Validators.email ], MESSAGES: { - 'required': this.i18n('Email is required.'), - 'email': this.i18n('Email must be valid.') + 'required': $localize`Email is required.`, + 'email': $localize`Email must be valid.` } } @@ -67,9 +66,9 @@ export class UserValidatorsService { Validators.maxLength(255) ], MESSAGES: { - 'required': this.i18n('Password is required.'), - 'minlength': this.i18n('Password must be at least 6 characters long.'), - 'maxlength': this.i18n('Password cannot be more than 255 characters long.') + 'required': $localize`Password is required.`, + 'minlength': $localize`Password must be at least 6 characters long.`, + 'maxlength': $localize`Password cannot be more than 255 characters long.` } } @@ -79,37 +78,37 @@ export class UserValidatorsService { Validators.maxLength(255) ], MESSAGES: { - 'minlength': this.i18n('Password must be at least 6 characters long.'), - 'maxlength': this.i18n('Password cannot be more than 255 characters long.') + 'minlength': $localize`Password must be at least 6 characters long.`, + 'maxlength': $localize`Password cannot be more than 255 characters long.` } } this.USER_CONFIRM_PASSWORD = { VALIDATORS: [], MESSAGES: { - 'matchPassword': this.i18n('The new password and the confirmed password do not correspond.') + 'matchPassword': $localize`The new password and the confirmed password do not correspond.` } } this.USER_VIDEO_QUOTA = { VALIDATORS: [ Validators.required, Validators.min(-1) ], MESSAGES: { - 'required': this.i18n('Video quota is required.'), - 'min': this.i18n('Quota must be greater than -1.') + 'required': $localize`Video quota is required.`, + 'min': $localize`Quota must be greater than -1.` } } this.USER_VIDEO_QUOTA_DAILY = { VALIDATORS: [ Validators.required, Validators.min(-1) ], MESSAGES: { - 'required': this.i18n('Daily upload limit is required.'), - 'min': this.i18n('Daily upload limit must be greater than -1.') + 'required': $localize`Daily upload limit is required.`, + 'min': $localize`Daily upload limit must be greater than -1.` } } this.USER_ROLE = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('User role is required.') + 'required': $localize`User role is required.` } } @@ -121,8 +120,8 @@ export class UserValidatorsService { Validators.maxLength(1000) ], MESSAGES: { - 'minlength': this.i18n('Description must be at least 3 characters long.'), - 'maxlength': this.i18n('Description cannot be more than 1000 characters long.') + 'minlength': $localize`Description must be at least 3 characters long.`, + 'maxlength': $localize`Description cannot be more than 1000 characters long.` } } @@ -131,7 +130,7 @@ export class UserValidatorsService { Validators.requiredTrue ], MESSAGES: { - 'required': this.i18n('You must agree with the instance terms in order to register on it.') + 'required': $localize`You must agree with the instance terms in order to register on it.` } } @@ -141,8 +140,8 @@ export class UserValidatorsService { Validators.maxLength(250) ], MESSAGES: { - 'minlength': this.i18n('Ban reason must be at least 3 characters long.'), - 'maxlength': this.i18n('Ban reason cannot be more than 250 characters long.') + 'minlength': $localize`Ban reason must be at least 3 characters long.`, + 'maxlength': $localize`Ban reason cannot be more than 250 characters long.` } } } @@ -154,9 +153,9 @@ export class UserValidatorsService { Validators.maxLength(120) ], MESSAGES: { - 'required': this.i18n('Display name is required.'), - 'minlength': this.i18n('Display name must be at least 1 character long.'), - 'maxlength': this.i18n('Display name cannot be more than 50 characters long.') + 'required': $localize`Display name is required.`, + 'minlength': $localize`Display name must be at least 1 character long.`, + 'maxlength': $localize`Display name cannot be more than 50 characters long.` } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts index 998d616ec..aed9e9cdd 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts @@ -1,17 +1,16 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() export class VideoAcceptOwnershipValidatorsService { readonly CHANNEL: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.CHANNEL = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('The channel is required.') + 'required': $localize`The channel is required.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts index ddf0ab5eb..bce1880dc 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts @@ -1,18 +1,17 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() export class VideoBlockValidatorsService { readonly VIDEO_BLOCK_REASON: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_BLOCK_REASON = { VALIDATORS: [ Validators.minLength(2), Validators.maxLength(300) ], MESSAGES: { - 'minlength': this.i18n('Block reason must be at least 2 characters long.'), - 'maxlength': this.i18n('Block reason cannot be more than 300 characters long.') + 'minlength': $localize`Block reason must be at least 2 characters long.`, + 'maxlength': $localize`Block reason cannot be more than 300 characters long.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts index 280d28414..7e90264e5 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts @@ -1,6 +1,5 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() @@ -8,19 +7,19 @@ export class VideoCaptionsValidatorsService { readonly VIDEO_CAPTION_LANGUAGE: BuildFormValidator readonly VIDEO_CAPTION_FILE: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_CAPTION_LANGUAGE = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Video caption language is required.') + 'required': $localize`Video caption language is required.` } } this.VIDEO_CAPTION_FILE = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Video caption file is required.') + 'required': $localize`Video caption file is required.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts index 59659defd..8c809a0d5 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts @@ -1,18 +1,17 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { AbstractControl, ValidationErrors, Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { AbstractControl, ValidationErrors, Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() export class VideoChangeOwnershipValidatorsService { readonly USERNAME: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.USERNAME = { VALIDATORS: [ Validators.required, this.localAccountValidator ], MESSAGES: { - 'required': this.i18n('The username is required.'), - 'localAccountOnly': this.i18n('You can only transfer ownership to a local account') + 'required': $localize`The username is required.`, + 'localAccountOnly': $localize`You can only transfer ownership to a local account` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts index bb650b149..3e7444196 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts @@ -1,6 +1,5 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() @@ -10,7 +9,7 @@ export class VideoChannelValidatorsService { readonly VIDEO_CHANNEL_DESCRIPTION: BuildFormValidator readonly VIDEO_CHANNEL_SUPPORT: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_CHANNEL_NAME = { VALIDATORS: [ Validators.required, @@ -19,10 +18,10 @@ export class VideoChannelValidatorsService { Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) ], MESSAGES: { - 'required': this.i18n('Name is required.'), - 'minlength': this.i18n('Name must be at least 1 character long.'), - 'maxlength': this.i18n('Name cannot be more than 50 characters long.'), - 'pattern': this.i18n('Name should be lowercase alphanumeric; dots and underscores are allowed.') + 'required': $localize`Name is required.`, + 'minlength': $localize`Name must be at least 1 character long.`, + 'maxlength': $localize`Name cannot be more than 50 characters long.`, + 'pattern': $localize`Name should be lowercase alphanumeric; dots and underscores are allowed.` } } @@ -33,9 +32,9 @@ export class VideoChannelValidatorsService { Validators.maxLength(50) ], MESSAGES: { - 'required': i18n('Display name is required.'), - 'minlength': i18n('Display name must be at least 1 character long.'), - 'maxlength': i18n('Display name cannot be more than 50 characters long.') + 'required': $localize`Display name is required.`, + 'minlength': $localize`Display name must be at least 1 character long.`, + 'maxlength': $localize`Display name cannot be more than 50 characters long.` } } @@ -45,8 +44,8 @@ export class VideoChannelValidatorsService { Validators.maxLength(1000) ], MESSAGES: { - 'minlength': i18n('Description must be at least 3 characters long.'), - 'maxlength': i18n('Description cannot be more than 1000 characters long.') + 'minlength': $localize`Description must be at least 3 characters long.`, + 'maxlength': $localize`Description cannot be more than 1000 characters long.` } } @@ -56,8 +55,8 @@ export class VideoChannelValidatorsService { Validators.maxLength(1000) ], MESSAGES: { - 'minlength': i18n('Support text must be at least 3 characters long.'), - 'maxlength': i18n('Support text cannot be more than 1000 characters long.') + 'minlength': $localize`Support text must be at least 3 characters long.`, + 'maxlength': $localize`Support text cannot be more than 1000 characters long` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts index 97c8e967e..18e7ae264 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts @@ -1,19 +1,18 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() export class VideoCommentValidatorsService { readonly VIDEO_COMMENT_TEXT: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_COMMENT_TEXT = { VALIDATORS: [ Validators.required, Validators.minLength(1), Validators.maxLength(3000) ], MESSAGES: { - 'required': this.i18n('Comment is required.'), - 'minlength': this.i18n('Comment must be at least 2 characters long.'), - 'maxlength': this.i18n('Comment cannot be more than 3000 characters long.') + 'required': $localize`Comment is required.`, + 'minlength': $localize`Comment must be at least 2 characters long.`, + 'maxlength': $localize`Comment cannot be more than 3000 characters long.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts index ab9c43625..3b45a40fd 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts @@ -1,8 +1,7 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { AbstractControl, FormControl, Validators } from '@angular/forms' import { Injectable } from '@angular/core' -import { BuildFormValidator } from './form-validator.service' +import { AbstractControl, Validators } from '@angular/forms' import { VideoPlaylistPrivacy } from '@shared/models' +import { BuildFormValidator } from './form-validator.service' @Injectable() export class VideoPlaylistValidatorsService { @@ -11,7 +10,7 @@ export class VideoPlaylistValidatorsService { readonly VIDEO_PLAYLIST_DESCRIPTION: BuildFormValidator readonly VIDEO_PLAYLIST_CHANNEL_ID: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_PLAYLIST_DISPLAY_NAME = { VALIDATORS: [ Validators.required, @@ -19,9 +18,9 @@ export class VideoPlaylistValidatorsService { Validators.maxLength(120) ], MESSAGES: { - 'required': this.i18n('Display name is required.'), - 'minlength': this.i18n('Display name must be at least 1 character long.'), - 'maxlength': this.i18n('Display name cannot be more than 120 characters long.') + 'required': $localize`Display name is required.`, + 'minlength': $localize`Display name must be at least 1 character long.`, + 'maxlength': $localize`Display name cannot be more than 120 characters long.` } } @@ -30,7 +29,7 @@ export class VideoPlaylistValidatorsService { Validators.required ], MESSAGES: { - 'required': this.i18n('Privacy is required.') + 'required': $localize`Privacy is required.` } } @@ -40,15 +39,15 @@ export class VideoPlaylistValidatorsService { Validators.maxLength(1000) ], MESSAGES: { - 'minlength': i18n('Description must be at least 3 characters long.'), - 'maxlength': i18n('Description cannot be more than 1000 characters long.') + 'minlength': $localize`Description must be at least 3 characters long.`, + 'maxlength': $localize`Description cannot be more than 1000 characters long.` } } this.VIDEO_PLAYLIST_CHANNEL_ID = { VALIDATORS: [ ], MESSAGES: { - 'required': this.i18n('The channel is required when the playlist is public.') + 'required': $localize`The channel is required when the playlist is public.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-validators.service.ts index c96e4ef66..8119c1ae7 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-validators.service.ts @@ -1,6 +1,5 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators, ValidatorFn, ValidationErrors, AbstractControl } from '@angular/forms' import { Injectable } from '@angular/core' +import { AbstractControl, ValidationErrors, ValidatorFn, Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() @@ -19,21 +18,21 @@ export class VideoValidatorsService { readonly VIDEO_SCHEDULE_PUBLICATION_AT: BuildFormValidator readonly VIDEO_ORIGINALLY_PUBLISHED_AT: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_NAME = { VALIDATORS: [ Validators.required, Validators.minLength(3), Validators.maxLength(120) ], MESSAGES: { - 'required': this.i18n('Video name is required.'), - 'minlength': this.i18n('Video name must be at least 3 characters long.'), - 'maxlength': this.i18n('Video name cannot be more than 120 characters long.') + 'required': $localize`Video name is required.`, + 'minlength': $localize`Video name must be at least 3 characters long.`, + 'maxlength': $localize`Video name cannot be more than 120 characters long.` } } this.VIDEO_PRIVACY = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Video privacy is required.') + 'required': $localize`Video privacy is required.` } } @@ -60,46 +59,46 @@ export class VideoValidatorsService { this.VIDEO_CHANNEL = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Video channel is required.') + 'required': $localize`Video channel is required.` } } this.VIDEO_DESCRIPTION = { VALIDATORS: [ Validators.minLength(3), Validators.maxLength(10000) ], MESSAGES: { - 'minlength': this.i18n('Video description must be at least 3 characters long.'), - 'maxlength': this.i18n('Video description cannot be more than 10000 characters long.') + 'minlength': $localize`Video description must be at least 3 characters long.`, + 'maxlength': $localize`Video description cannot be more than 10000 characters long.` } } this.VIDEO_TAG = { VALIDATORS: [ Validators.minLength(2), Validators.maxLength(30) ], MESSAGES: { - 'minlength': this.i18n('A tag should be more than 2 characters long.'), - 'maxlength': this.i18n('A tag should be less than 30 characters long.') + 'minlength': $localize`A tag should be more than 2 characters long.`, + 'maxlength': $localize`A tag should be less than 30 characters long.` } } this.VIDEO_TAGS_ARRAY = { VALIDATORS: [ Validators.maxLength(5), this.arrayTagLengthValidator() ], MESSAGES: { - 'maxlength': this.i18n('A maximum of 5 tags can be used on a video.'), - 'arrayTagLength': this.i18n('A tag should be more than 2, and less than 30 characters long.') + 'maxlength': $localize`A maximum of 5 tags can be used on a video.`, + 'arrayTagLength': $localize`A tag should be more than 2, and less than 30 characters long.` } } this.VIDEO_SUPPORT = { VALIDATORS: [ Validators.minLength(3), Validators.maxLength(1000) ], MESSAGES: { - 'minlength': this.i18n('Video support must be at least 3 characters long.'), - 'maxlength': this.i18n('Video support cannot be more than 1000 characters long.') + 'minlength': $localize`Video support must be at least 3 characters long.`, + 'maxlength': $localize`Video support cannot be more than 1000 characters long.` } } this.VIDEO_SCHEDULE_PUBLICATION_AT = { VALIDATORS: [ ], MESSAGES: { - 'required': this.i18n('A date is required to schedule video update.') + 'required': $localize`A date is required to schedule video update.` } } diff --git a/client/src/app/shared/shared-forms/input-readonly-copy.component.ts b/client/src/app/shared/shared-forms/input-readonly-copy.component.ts index 7528fb7a1..a67b0c691 100644 --- a/client/src/app/shared/shared-forms/input-readonly-copy.component.ts +++ b/client/src/app/shared/shared-forms/input-readonly-copy.component.ts @@ -1,6 +1,5 @@ import { Component, Input } from '@angular/core' import { Notifier } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-input-readonly-copy', @@ -10,12 +9,9 @@ import { I18n } from '@ngx-translate/i18n-polyfill' export class InputReadonlyCopyComponent { @Input() value = '' - constructor ( - private notifier: Notifier, - private i18n: I18n - ) { } + constructor (private notifier: Notifier) { } activateCopiedMessage () { - this.notifier.success(this.i18n('Copied')) + this.notifier.success($localize`Copied`) } } diff --git a/client/src/app/shared/shared-forms/preview-upload.component.ts b/client/src/app/shared/shared-forms/preview-upload.component.ts index 7afff0b31..a55dcdd9a 100644 --- a/client/src/app/shared/shared-forms/preview-upload.component.ts +++ b/client/src/app/shared/shared-forms/preview-upload.component.ts @@ -2,7 +2,6 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core' import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser' import { ServerService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig } from '@shared/models' import { BytesPipe } from '../shared-main' @@ -34,11 +33,10 @@ export class PreviewUploadComponent implements OnInit, ControlValueAccessor { constructor ( private sanitizer: DomSanitizer, - private serverService: ServerService, - private i18n: I18n + private serverService: ServerService ) { this.bytesPipe = new BytesPipe() - this.maxSizeText = this.i18n('max size') + this.maxSizeText = $localize`max size` } get videoImageExtensions () { diff --git a/client/src/app/shared/shared-forms/reactive-file.component.ts b/client/src/app/shared/shared-forms/reactive-file.component.ts index 9ebf487ce..eeb2a3fd8 100644 --- a/client/src/app/shared/shared-forms/reactive-file.component.ts +++ b/client/src/app/shared/shared-forms/reactive-file.component.ts @@ -2,7 +2,6 @@ import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@ang import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' import { Notifier } from '@app/core' import { GlobalIconName } from '@app/shared/shared-icons' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-reactive-file', @@ -31,10 +30,7 @@ export class ReactiveFileComponent implements OnInit, ControlValueAccessor { private file: File - constructor ( - private notifier: Notifier, - private i18n: I18n - ) {} + constructor (private notifier: Notifier) { } get filename () { if (!this.file) return '' @@ -51,16 +47,13 @@ export class ReactiveFileComponent implements OnInit, ControlValueAccessor { const [ file ] = event.target.files if (file.size > this.maxFileSize) { - this.notifier.error(this.i18n('This file is too large.')) + this.notifier.error($localize`This file is too large.`) return } const extension = '.' + file.name.split('.').pop() if (this.extensions.includes(extension) === false) { - const message = this.i18n( - 'PeerTube cannot handle this kind of file. Accepted extensions are {{extensions}}.', - { extensions: this.allowedExtensionsMessage } - ) + const message = $localize`PeerTube cannot handle this kind of file. Accepted extensions are ${this.allowedExtensionsMessage}}.` this.notifier.error(message) return diff --git a/client/src/app/shared/shared-forms/select/select-checkbox.component.ts b/client/src/app/shared/shared-forms/select/select-checkbox.component.ts index fd683ae5d..eb0c49034 100644 --- a/client/src/app/shared/shared-forms/select/select-checkbox.component.ts +++ b/client/src/app/shared/shared-forms/select/select-checkbox.component.ts @@ -1,7 +1,6 @@ -import { Component, Input, forwardRef, OnInit } from '@angular/core' -import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms' +import { Component, forwardRef, Input, OnInit } from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' import { SelectOptionsItem } from './select-options.component' -import { I18n } from '@ngx-translate/i18n-polyfill' export type ItemSelectCheckboxValue = { id?: string | number, group?: string } | string @@ -25,12 +24,8 @@ export class SelectCheckboxComponent implements OnInit, ControlValueAccessor { @Input() maxSelectedItems: number @Input() placeholder: string - constructor ( - private i18n: I18n - ) {} - ngOnInit () { - if (!this.placeholder) this.placeholder = this.i18n('Add a new option') + if (!this.placeholder) this.placeholder = $localize`Add a new option` } propagateChange = (_: any) => { /* empty */ } diff --git a/client/src/app/shared/shared-instance/instance-features-table.component.ts b/client/src/app/shared/shared-instance/instance-features-table.component.ts index 8fd15ebad..76b595c20 100644 --- a/client/src/app/shared/shared-instance/instance-features-table.component.ts +++ b/client/src/app/shared/shared-instance/instance-features-table.component.ts @@ -1,6 +1,5 @@ import { Component, OnInit } from '@angular/core' import { ServerService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig } from '@shared/models' @Component({ @@ -12,11 +11,7 @@ export class InstanceFeaturesTableComponent implements OnInit { quotaHelpIndication = '' serverConfig: ServerConfig - constructor ( - private i18n: I18n, - private serverService: ServerService - ) { - } + constructor (private serverService: ServerService) { } get initialUserVideoQuota () { return this.serverConfig.user.videoQuota @@ -38,9 +33,9 @@ export class InstanceFeaturesTableComponent implements OnInit { buildNSFWLabel () { const policy = this.serverConfig.instance.defaultNSFWPolicy - if (policy === 'do_not_list') return this.i18n('Hidden') - if (policy === 'blur') return this.i18n('Blurred with confirmation request') - if (policy === 'display') return this.i18n('Displayed') + if (policy === 'do_not_list') return $localize`Hidden` + if (policy === 'blur') return $localize`Blurred with confirmation request` + if (policy === 'display') return $localize`Displayed` } getServerVersionAndCommit () { @@ -55,7 +50,9 @@ export class InstanceFeaturesTableComponent implements OnInit { const minutes = Math.floor(seconds % 3600 / 60) - return this.i18n('~ {{minutes}} {minutes, plural, =1 {minute} other {minutes}}', { minutes }) + if (minutes === 1) return $localize`~ 1 minute` + + return $localize`~ ${minutes} minutes` } private buildQuotaHelpIndication () { @@ -71,9 +68,9 @@ export class InstanceFeaturesTableComponent implements OnInit { const normalSeconds = initialUserVideoQuotaBit / (1.5 * 1000 * 1000) const lines = [ - this.i18n('{{seconds}} of full HD videos', { seconds: this.getApproximateTime(fullHdSeconds) }), - this.i18n('{{seconds}} of HD videos', { seconds: this.getApproximateTime(hdSeconds) }), - this.i18n('{{seconds}} of average quality videos', { seconds: this.getApproximateTime(normalSeconds) }) + $localize`${this.getApproximateTime(fullHdSeconds)} of full HD videos`, + $localize`${this.getApproximateTime(hdSeconds)} of HD videos`, + $localize`${this.getApproximateTime(normalSeconds)} of average quality videos` ] this.quotaHelpIndication = lines.join('
') diff --git a/client/src/app/shared/shared-main/account/actor-avatar-info.component.ts b/client/src/app/shared/shared-main/account/actor-avatar-info.component.ts index 1389218cc..3a86e5b21 100644 --- a/client/src/app/shared/shared-main/account/actor-avatar-info.component.ts +++ b/client/src/app/shared/shared-main/account/actor-avatar-info.component.ts @@ -1,7 +1,6 @@ import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' import { Notifier, ServerService } from '@app/core' import { Account, BytesPipe, VideoChannel } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig } from '@shared/models' @Component({ @@ -23,11 +22,10 @@ export class ActorAvatarInfoComponent implements OnInit { constructor ( private serverService: ServerService, - private notifier: Notifier, - private i18n: I18n + private notifier: Notifier ) { this.bytesPipe = new BytesPipe() - this.maxSizeText = this.i18n('max size') + this.maxSizeText = $localize`max size` } ngOnInit (): void { diff --git a/client/src/app/shared/shared-main/account/avatar.component.ts b/client/src/app/shared/shared-main/account/avatar.component.ts index 73c145ef9..2967828a0 100644 --- a/client/src/app/shared/shared-main/account/avatar.component.ts +++ b/client/src/app/shared/shared-main/account/avatar.component.ts @@ -1,6 +1,5 @@ import { Component, Input, OnInit } from '@angular/core' import { Video } from '../video/video.model' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'avatar-channel', @@ -15,19 +14,9 @@ export class AvatarComponent implements OnInit { channelLinkTitle = '' accountLinkTitle = '' - constructor ( - private i18n: I18n - ) {} - ngOnInit () { - this.channelLinkTitle = this.i18n( - '{{name}} (channel page)', - { name: this.video.channel.name, handle: this.video.byVideoChannel } - ) - this.accountLinkTitle = this.i18n( - '{{name}} (account page)', - { name: this.video.account.name, handle: this.video.byAccount } - ) + this.channelLinkTitle = $localize`${this.video.account.name} (channel page)` + this.accountLinkTitle = $localize`${this.video.byAccount} (account page)` } isChannelAvatarNull () { diff --git a/client/src/app/shared/shared-main/angular/from-now.pipe.ts b/client/src/app/shared/shared-main/angular/from-now.pipe.ts index 9851468ee..5d85590bb 100644 --- a/client/src/app/shared/shared-main/angular/from-now.pipe.ts +++ b/client/src/app/shared/shared-main/angular/from-now.pipe.ts @@ -1,39 +1,36 @@ 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 (arg: number | Date | string) { const argDate = new Date(arg) const seconds = Math.floor((Date.now() - argDate.getTime()) / 1000) let interval = Math.floor(seconds / 31536000) - if (interval > 1) return this.i18n('{{interval}} years ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} year ago', { interval }) + if (interval > 1) return $localize`${interval} years ago` + if (interval === 1) return $localize`${interval} year ago` interval = Math.floor(seconds / 2592000) - if (interval > 1) return this.i18n('{{interval}} months ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} month ago', { interval }) + if (interval > 1) return $localize`${interval} months ago` + if (interval === 1) return $localize`${interval} month ago` interval = Math.floor(seconds / 604800) - if (interval > 1) return this.i18n('{{interval}} weeks ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} week ago', { interval }) + if (interval > 1) return $localize`${interval} weeks ago` + if (interval === 1) return $localize`${interval} week ago` interval = Math.floor(seconds / 86400) - if (interval > 1) return this.i18n('{{interval}} days ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} day ago', { interval }) + if (interval > 1) return $localize`${interval} days ago` + if (interval === 1) return $localize`${interval} day ago` interval = Math.floor(seconds / 3600) - if (interval > 1) return this.i18n('{{interval}} hours ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} hour ago', { interval }) + if (interval > 1) return $localize`${interval} hours ago` + if (interval === 1) return $localize`${interval} hour ago` interval = Math.floor(seconds / 60) - if (interval >= 1) return this.i18n('{{interval}} min ago', { interval }) + if (interval >= 1) return $localize`${interval} min ago` - return this.i18n('just now') + return $localize`just now` } } diff --git a/client/src/app/shared/shared-main/buttons/delete-button.component.ts b/client/src/app/shared/shared-main/buttons/delete-button.component.ts index aced0f881..18995422a 100644 --- a/client/src/app/shared/shared-main/buttons/delete-button.component.ts +++ b/client/src/app/shared/shared-main/buttons/delete-button.component.ts @@ -1,5 +1,4 @@ import { Component, Input, OnInit } from '@angular/core' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-delete-button', @@ -11,17 +10,15 @@ export class DeleteButtonComponent implements OnInit { @Input() label: string @Input() title: string - constructor (private i18n: I18n) { } - ngOnInit () { // No label if (this.label === undefined && !this.title) { - this.title = this.i18n('Delete') + this.title = $localize`Delete` } // Use default label if (this.label === '') { - this.label = this.i18n('Delete') + this.label = $localize`Delete` if (!this.title) { this.title = this.label diff --git a/client/src/app/shared/shared-main/buttons/edit-button.component.ts b/client/src/app/shared/shared-main/buttons/edit-button.component.ts index d8ae39b84..4b76551ca 100644 --- a/client/src/app/shared/shared-main/buttons/edit-button.component.ts +++ b/client/src/app/shared/shared-main/buttons/edit-button.component.ts @@ -1,5 +1,4 @@ import { Component, Input, OnInit } from '@angular/core' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-edit-button', @@ -12,17 +11,15 @@ export class EditButtonComponent implements OnInit { @Input() title: string @Input() routerLink: string[] | string = [] - constructor (private i18n: I18n) { } - ngOnInit () { // No label if (this.label === undefined && !this.title) { - this.title = this.i18n('Update') + this.title = $localize`Update` } // Use default label if (this.label === '') { - this.label = this.i18n('Update') + this.label = $localize`Update` if (!this.title) { this.title = this.label diff --git a/client/src/app/shared/shared-main/misc/help.component.ts b/client/src/app/shared/shared-main/misc/help.component.ts index 0825b96de..ebc965a88 100644 --- a/client/src/app/shared/shared-main/misc/help.component.ts +++ b/client/src/app/shared/shared-main/misc/help.component.ts @@ -1,6 +1,5 @@ import { AfterContentInit, Component, ContentChildren, Input, OnChanges, OnInit, QueryList, TemplateRef } from '@angular/core' import { MarkdownService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { PeerTubeTemplateDirective } from '../angular' @Component({ @@ -22,8 +21,6 @@ export class HelpComponent implements OnInit, OnChanges, AfterContentInit { customHtmlTemplate: TemplateRef postHtmlTemplate: TemplateRef - constructor (private i18n: I18n) { } - ngOnInit () { this.init() } @@ -71,17 +68,17 @@ export class HelpComponent implements OnInit, OnChanges, AfterContentInit { private formatMarkdownSupport (rules: string[]) { // tslint:disable:max-line-length - return this.i18n('Markdown compatible that supports:') + + return $localize`Markdown compatible that supports:` + this.createMarkdownList(rules) } private createMarkdownList (rules: string[]) { const rulesToText = { - 'emphasis': this.i18n('Emphasis'), - 'link': this.i18n('Links'), - 'newline': this.i18n('New lines'), - 'list': this.i18n('Lists'), - 'image': this.i18n('Images') + 'emphasis': $localize`Emphasis`, + 'link': $localize`Links`, + 'newline': $localize`New lines`, + 'list': $localize`Lists`, + 'image': $localize`Images` } const bullets = rules.map(r => rulesToText[r]) diff --git a/client/src/app/shared/shared-main/shared-main.module.ts b/client/src/app/shared/shared-main/shared-main.module.ts index 6186db4d6..7f4676dd1 100644 --- a/client/src/app/shared/shared-main/shared-main.module.ts +++ b/client/src/app/shared/shared-main/shared-main.module.ts @@ -13,7 +13,6 @@ import { NgbPopoverModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { SharedGlobalIconModule } from '../shared-icons' import { AccountService, ActorAvatarInfoComponent, AvatarComponent } from './account' import { FromNowPipe, InfiniteScrollerDirective, NumberFormatterPipe, PeerTubeTemplateDirective, BytesPipe } from './angular' @@ -129,8 +128,6 @@ import { VideoChannelService } from './video-channel' ], providers: [ - I18n, - DatePipe, FromNowPipe, diff --git a/client/src/app/shared/shared-main/users/user-quota.component.ts b/client/src/app/shared/shared-main/users/user-quota.component.ts index 6830ad8fe..b38619186 100644 --- a/client/src/app/shared/shared-main/users/user-quota.component.ts +++ b/client/src/app/shared/shared-main/users/user-quota.component.ts @@ -1,7 +1,6 @@ import { Subject } from 'rxjs' import { Component, Input, OnInit } from '@angular/core' import { User, UserService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { BytesPipe } from '../angular' @Component({ @@ -22,10 +21,7 @@ export class UserQuotaComponent implements OnInit { userVideoQuotaUsedDaily = 0 userVideoQuotaDailyPercentage = 15 - constructor ( - private userService: UserService, - private i18n: I18n - ) { } + constructor (private userService: UserService) { } ngOnInit () { this.userInformationLoaded.subscribe( @@ -33,13 +29,13 @@ export class UserQuotaComponent implements OnInit { if (this.user.videoQuota !== -1) { this.userVideoQuota = new BytesPipe().transform(this.user.videoQuota, 0).toString() } else { - this.userVideoQuota = this.i18n('Unlimited') + this.userVideoQuota = $localize`Unlimited` } if (this.user.videoQuotaDaily !== -1) { this.userVideoQuotaDaily = new BytesPipe().transform(this.user.videoQuotaDaily, 0).toString() } else { - this.userVideoQuotaDaily = this.i18n('Unlimited') + this.userVideoQuotaDaily = $localize`Unlimited` } } ) diff --git a/client/src/app/shared/shared-main/video/video.service.ts b/client/src/app/shared/shared-main/video/video.service.ts index 978f775bf..b01e919aa 100644 --- a/client/src/app/shared/shared-main/video/video.service.ts +++ b/client/src/app/shared/shared-main/video/video.service.ts @@ -4,7 +4,6 @@ import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http' import { Injectable } from '@angular/core' import { ComponentPaginationLight, RestExtractor, RestService, ServerService, UserService } from '@app/core' import { objectToFormData } from '@app/helpers' -import { I18n } from '@ngx-translate/i18n-polyfill' import { FeedFormat, NSFWPolicyType, @@ -15,11 +14,11 @@ import { Video as VideoServerModel, VideoConstant, VideoDetails as VideoDetailsServerModel, + VideoFileMetadata, VideoFilter, VideoPrivacy, VideoSortField, - VideoUpdate, - VideoFileMetadata + VideoUpdate } from '@shared/models' import { environment } from '../../../../environments/environment' import { Account, AccountService } from '../account' @@ -48,8 +47,7 @@ export class VideoService implements VideosProvider { private authHttp: HttpClient, private restExtractor: RestExtractor, private restService: RestService, - private serverService: ServerService, - private i18n: I18n + private serverService: ServerService ) {} getVideoViewUrl (uuid: string) { @@ -339,19 +337,19 @@ export class VideoService implements VideosProvider { const base = [ { id: VideoPrivacy.PRIVATE, - description: this.i18n('Only I can see this video') + description: $localize`Only I can see this video` }, { id: VideoPrivacy.UNLISTED, - description: this.i18n('Only shareable via a private link') + description: $localize`Only shareable via a private link` }, { id: VideoPrivacy.PUBLIC, - description: this.i18n('Anyone can see this video') + description: $localize`Anyone can see this video` }, { id: VideoPrivacy.INTERNAL, - description: this.i18n('Only users of this instance can see this video') + description: $localize`Only users of this instance can see this video` } ] diff --git a/client/src/app/shared/shared-moderation/abuse.service.ts b/client/src/app/shared/shared-moderation/abuse.service.ts index 06b236d1e..bf98d4b36 100644 --- a/client/src/app/shared/shared-moderation/abuse.service.ts +++ b/client/src/app/shared/shared-moderation/abuse.service.ts @@ -5,7 +5,6 @@ import { catchError, map } from 'rxjs/operators' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { RestExtractor, RestPagination, RestService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AbuseCreate, AbuseFilter, @@ -25,7 +24,6 @@ export class AbuseService { private static BASE_MY_ABUSE_URL = environment.apiUrl + '/api/v1/users/me/abuses' constructor ( - private i18n: I18n, private authHttp: HttpClient, private restService: RestService, private restExtractor: RestExtractor @@ -138,33 +136,33 @@ export class AbuseService { let reasons: { id: AbusePredefinedReasonsString, label: string, description?: string, help?: string }[] = [ { id: 'violentOrRepulsive', - label: this.i18n('Violent or repulsive'), - help: this.i18n('Contains offensive, violent, or coarse language or iconography.') + label: $localize`Violent or repulsive`, + help: $localize`Contains offensive, violent, or coarse language or iconography.` }, { id: 'hatefulOrAbusive', - label: this.i18n('Hateful or abusive'), - help: this.i18n('Contains abusive, racist or sexist language or iconography.') + label: $localize`Hateful or abusive`, + help: $localize`Contains abusive, racist or sexist language or iconography.` }, { id: 'spamOrMisleading', - label: this.i18n('Spam, ad or false news'), - help: this.i18n('Contains marketing, spam, purposefully deceitful news, or otherwise misleading thumbnail/text/tags. Please provide reputable sources to report hoaxes.') + label: $localize`Spam, ad or false news`, + help: $localize`Contains marketing, spam, purposefully deceitful news, or otherwise misleading thumbnail/text/tags. Please provide reputable sources to report hoaxes.` }, { id: 'privacy', - label: this.i18n('Privacy breach or doxxing'), - help: this.i18n('Contains personal information that could be used to track, identify, contact or impersonate someone (e.g. name, address, phone number, email, or credit card details).') + label: $localize`Privacy breach or doxxing`, + help: $localize`Contains personal information that could be used to track, identify, contact or impersonate someone (e.g. name, address, phone number, email, or credit card details).` }, { id: 'rights', - label: this.i18n('Copyright'), - help: this.i18n('Infringes your copyright wrt. the regional laws with which the server must comply.') + label: $localize`Copyright`, + help: $localize`Infringes your copyright wrt. the regional laws with which the server must comply.` }, { id: 'serverRules', - label: this.i18n('Breaks server rules'), - description: this.i18n('Anything not included in the above that breaks the terms of service, code of conduct, or general rules in place on the server.') + label: $localize`Breaks server rules`, + description: $localize`Anything not included in the above that breaks the terms of service, code of conduct, or general rules in place on the server.` } ] @@ -172,13 +170,13 @@ export class AbuseService { reasons = reasons.concat([ { id: 'thumbnails', - label: this.i18n('Thumbnails'), - help: this.i18n('The above can only be seen in thumbnails.') + label: $localize`Thumbnails`, + help: $localize`The above can only be seen in thumbnails.` }, { id: 'captions', - label: this.i18n('Captions'), - help: this.i18n('The above can only be seen in captions (please describe which).') + label: $localize`Captions`, + help: $localize`The above can only be seen in captions (please describe which).` } ]) } diff --git a/client/src/app/shared/shared-moderation/account-blocklist.component.ts b/client/src/app/shared/shared-moderation/account-blocklist.component.ts index a5a3c27cd..68928a2c2 100644 --- a/client/src/app/shared/shared-moderation/account-blocklist.component.ts +++ b/client/src/app/shared/shared-moderation/account-blocklist.component.ts @@ -1,8 +1,7 @@ import { SortMeta } from 'primeng/api' -import { OnInit, Directive } from '@angular/core' +import { Directive, OnInit } from '@angular/core' import { Notifier, RestPagination, RestTable } from '@app/core' import { Actor } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AccountBlock } from './account-block.model' import { BlocklistComponentType, BlocklistService } from './blocklist.service' @@ -19,8 +18,7 @@ export class GenericAccountBlocklistComponent extends RestTable implements OnIni constructor ( private notifier: Notifier, - private blocklistService: BlocklistService, - private i18n: I18n + private blocklistService: BlocklistService ) { super() } @@ -46,8 +44,8 @@ export class GenericAccountBlocklistComponent extends RestTable implements OnIni () => { this.notifier.success( this.mode === BlocklistComponentType.Account - ? this.i18n('Account {{nameWithHost}} unmuted.', { nameWithHost: blockedAccount.nameWithHost }) - : this.i18n('Account {{nameWithHost}} unmuted by your instance.', { nameWithHost: blockedAccount.nameWithHost }) + ? $localize`Account ${blockedAccount.nameWithHost} unmuted.` + : $localize`Account ${blockedAccount.nameWithHost} unmuted by your instance.` ) this.loadData() diff --git a/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts b/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts index fdd4a79a9..7193ccb1b 100644 --- a/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts +++ b/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts @@ -2,7 +2,6 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angu import { BatchDomainsValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-batch-domains-modal', @@ -20,14 +19,13 @@ export class BatchDomainsModalComponent extends FormReactive implements OnInit { constructor ( protected formValidatorService: FormValidatorService, private modalService: NgbModal, - private batchDomainsValidatorsService: BatchDomainsValidatorsService, - private i18n: I18n + private batchDomainsValidatorsService: BatchDomainsValidatorsService ) { super() } ngOnInit () { - if (!this.action) this.action = this.i18n('Process domains') + if (!this.action) this.action = $localize`Process domains` this.buildForm({ domains: this.batchDomainsValidatorsService.DOMAINS diff --git a/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts b/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts index 08dbe9538..8ab2fe940 100644 --- a/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts +++ b/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts @@ -5,7 +5,6 @@ import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app import { Account } from '@app/shared/shared-main' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { abusePredefinedReasonsMap } from '@shared/core-utils/abuse' import { AbusePredefinedReasonsString } from '@shared/models' import { AbuseService } from '../abuse.service' @@ -31,8 +30,7 @@ export class AccountReportComponent extends FormReactive implements OnInit { private modalService: NgbModal, private abuseValidatorsService: AbuseValidatorsService, private abuseService: AbuseService, - private notifier: Notifier, - private i18n: I18n + private notifier: Notifier ) { super() } @@ -50,7 +48,7 @@ export class AccountReportComponent extends FormReactive implements OnInit { } ngOnInit () { - this.modalTitle = this.i18n('Report {{displayName}}', { displayName: this.account.displayName }) + this.modalTitle = $localize`Report ${this.account.displayName}` this.buildForm({ reason: this.abuseValidatorsService.ABUSE_REASON, @@ -81,7 +79,7 @@ export class AccountReportComponent extends FormReactive implements OnInit { } }).subscribe( () => { - this.notifier.success(this.i18n('Account reported.')) + this.notifier.success($localize`Account reported.`) this.hide() }, diff --git a/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts b/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts index 2769874d9..d75f4d717 100644 --- a/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts +++ b/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts @@ -5,7 +5,6 @@ import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app import { VideoComment } from '@app/shared/shared-video-comment' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { abusePredefinedReasonsMap } from '@shared/core-utils/abuse' import { AbusePredefinedReasonsString } from '@shared/models' import { AbuseService } from '../abuse.service' @@ -31,8 +30,7 @@ export class CommentReportComponent extends FormReactive implements OnInit { private modalService: NgbModal, private abuseValidatorsService: AbuseValidatorsService, private abuseService: AbuseService, - private notifier: Notifier, - private i18n: I18n + private notifier: Notifier ) { super() } @@ -50,7 +48,7 @@ export class CommentReportComponent extends FormReactive implements OnInit { } ngOnInit () { - this.modalTitle = this.i18n('Report comment') + this.modalTitle = $localize`Report comment` this.buildForm({ reason: this.abuseValidatorsService.ABUSE_REASON, @@ -81,7 +79,7 @@ export class CommentReportComponent extends FormReactive implements OnInit { } }).subscribe( () => { - this.notifier.success(this.i18n('Comment reported.')) + this.notifier.success($localize`Comment reported.`) this.hide() }, diff --git a/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts b/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts index 794dd54bb..edff6d325 100644 --- a/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts +++ b/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts @@ -1,12 +1,11 @@ import { mapValues, pickBy } from 'lodash-es' -import { buildVideoOrPlaylistEmbed, buildVideoLink } from 'src/assets/player/utils' +import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils' import { Component, Input, OnInit, ViewChild } from '@angular/core' import { DomSanitizer, SafeHtml } from '@angular/platform-browser' import { Notifier } from '@app/core' import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { abusePredefinedReasonsMap } from '@shared/core-utils/abuse' import { AbusePredefinedReasonsString } from '@shared/models' import { Video } from '../../shared-main' @@ -34,8 +33,7 @@ export class VideoReportComponent extends FormReactive implements OnInit { private abuseValidatorsService: AbuseValidatorsService, private abuseService: AbuseService, private notifier: Notifier, - private sanitizer: DomSanitizer, - private i18n: I18n + private sanitizer: DomSanitizer ) { super() } @@ -109,7 +107,7 @@ export class VideoReportComponent extends FormReactive implements OnInit { } }).subscribe( () => { - this.notifier.success(this.i18n('Video reported.')) + this.notifier.success($localize`Video reported.`) this.hide() }, diff --git a/client/src/app/shared/shared-moderation/server-blocklist.component.ts b/client/src/app/shared/shared-moderation/server-blocklist.component.ts index 8f65cdb71..546fd53c3 100644 --- a/client/src/app/shared/shared-moderation/server-blocklist.component.ts +++ b/client/src/app/shared/shared-moderation/server-blocklist.component.ts @@ -2,7 +2,6 @@ import { SortMeta } from 'primeng/api' import { Directive, OnInit, ViewChild } from '@angular/core' import { Notifier, RestPagination, RestTable } from '@app/core' import { BatchDomainsModalComponent } from '@app/shared/shared-moderation/batch-domains-modal.component' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerBlock } from '@shared/models' import { BlocklistComponentType, BlocklistService } from './blocklist.service' @@ -21,8 +20,7 @@ export class GenericServerBlocklistComponent extends RestTable implements OnInit constructor ( protected notifier: Notifier, - protected blocklistService: BlocklistService, - protected i18n: I18n + protected blocklistService: BlocklistService ) { super() } @@ -44,8 +42,8 @@ export class GenericServerBlocklistComponent extends RestTable implements OnInit () => { this.notifier.success( this.mode === BlocklistComponentType.Account - ? this.i18n('Instance {{host}} unmuted.', { host }) - : this.i18n('Instance {{host}} unmuted by your instance.', { host }) + ? $localize`Instance ${host} unmuted.` + : $localize`Instance ${host} unmuted by your instance.` ) this.loadData() @@ -67,8 +65,8 @@ export class GenericServerBlocklistComponent extends RestTable implements OnInit () => { this.notifier.success( this.mode === BlocklistComponentType.Account - ? this.i18n('Instance {{domain}} muted.', { domain }) - : this.i18n('Instance {{domain}} muted by your instance.', { domain }) + ? $localize`Instance ${domain} muted.` + : $localize`Instance ${domain} muted by your instance.` ) this.loadData() diff --git a/client/src/app/shared/shared-moderation/user-ban-modal.component.ts b/client/src/app/shared/shared-moderation/user-ban-modal.component.ts index 124e58669..f9a0381c5 100644 --- a/client/src/app/shared/shared-moderation/user-ban-modal.component.ts +++ b/client/src/app/shared/shared-moderation/user-ban-modal.component.ts @@ -3,7 +3,6 @@ import { Notifier, UserService } from '@app/core' import { FormReactive, FormValidatorService, UserValidatorsService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { User } from '@shared/models' @Component({ @@ -23,8 +22,7 @@ export class UserBanModalComponent extends FormReactive implements OnInit { private modalService: NgbModal, private notifier: Notifier, private userService: UserService, - private userValidatorsService: UserValidatorsService, - private i18n: I18n + private userValidatorsService: UserValidatorsService ) { super() } @@ -52,8 +50,8 @@ export class UserBanModalComponent extends FormReactive implements OnInit { .subscribe( () => { const message = Array.isArray(this.usersToBan) - ? this.i18n('{{num}} users banned.', { num: this.usersToBan.length }) - : this.i18n('User {{username}} banned.', { username: this.usersToBan.username }) + ? $localize`${this.usersToBan.length} users banned.` + : $localize`User ${this.usersToBan.username} banned.` this.notifier.success(message) diff --git a/client/src/app/shared/shared-moderation/user-moderation-dropdown.component.ts b/client/src/app/shared/shared-moderation/user-moderation-dropdown.component.ts index 34fa7366c..44aefa853 100644 --- a/client/src/app/shared/shared-moderation/user-moderation-dropdown.component.ts +++ b/client/src/app/shared/shared-moderation/user-moderation-dropdown.component.ts @@ -1,7 +1,6 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output, ViewChild } from '@angular/core' import { AuthService, ConfirmService, Notifier, ServerService, UserService } from '@app/core' import { Account, DropdownAction } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { BulkRemoveCommentsOfBody, ServerConfig, User, UserRight } from '@shared/models' import { BlocklistService } from './blocklist.service' import { BulkService } from './bulk.service' @@ -37,8 +36,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { private serverService: ServerService, private userService: UserService, private blocklistService: BlocklistService, - private bulkService: BulkService, - private i18n: I18n + private bulkService: BulkService ) { } get requiresEmailVerification () { @@ -57,7 +55,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { openBanUserModal (user: User) { if (user.username === 'root') { - this.notifier.error(this.i18n('You cannot ban root.')) + this.notifier.error($localize`You cannot ban root.`) return } @@ -69,15 +67,13 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { } async unbanUser (user: User) { - const message = this.i18n('Do you really want to unban {{username}}?', { username: user.username }) - const res = await this.confirmService.confirm(message, this.i18n('Unban')) + const res = await this.confirmService.confirm($localize`Do you really want to unban ${user.username}?`, $localize`Unban`) if (res === false) return this.userService.unbanUsers(user) .subscribe( () => { - this.notifier.success(this.i18n('User {{username}} unbanned.', { username: user.username })) - + this.notifier.success($localize`User ${user.username} unbanned.`) this.userChanged.emit() }, @@ -87,17 +83,17 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { async removeUser (user: User) { if (user.username === 'root') { - this.notifier.error(this.i18n('You cannot delete root.')) + this.notifier.error($localize`You cannot delete root.`) return } - const message = this.i18n('If you remove this user, you will not be able to create another with the same username!') - const res = await this.confirmService.confirm(message, this.i18n('Delete')) + const message = $localize`If you remove this user, you will not be able to create another with the same username!` + const res = await this.confirmService.confirm(message, $localize`Delete`) if (res === false) return this.userService.removeUser(user).subscribe( () => { - this.notifier.success(this.i18n('User {{username}} deleted.', { username: user.username })) + this.notifier.success($localize`User ${user.username} deleted.`) this.userDeleted.emit() }, @@ -108,8 +104,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { setEmailAsVerified (user: User) { this.userService.updateUser(user.id, { emailVerified: true }).subscribe( () => { - this.notifier.success(this.i18n('User {{username}} email set as verified', { username: user.username })) - + this.notifier.success($localize`User ${user.username} email set as verified`) this.userChanged.emit() }, @@ -121,7 +116,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.blockAccountByUser(account) .subscribe( () => { - this.notifier.success(this.i18n('Account {{nameWithHost}} muted.', { nameWithHost: account.nameWithHost })) + this.notifier.success($localize`Account ${account.nameWithHost} muted.`) this.account.mutedByUser = true this.userChanged.emit() @@ -135,7 +130,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.unblockAccountByUser(account) .subscribe( () => { - this.notifier.success(this.i18n('Account {{nameWithHost}} unmuted.', { nameWithHost: account.nameWithHost })) + this.notifier.success($localize`Account ${account.nameWithHost} unmuted.`) this.account.mutedByUser = false this.userChanged.emit() @@ -149,7 +144,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.blockServerByUser(host) .subscribe( () => { - this.notifier.success(this.i18n('Instance {{host}} muted.', { host })) + this.notifier.success($localize`Instance ${host} muted.`) this.account.mutedServerByUser = true this.userChanged.emit() @@ -163,7 +158,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.unblockServerByUser(host) .subscribe( () => { - this.notifier.success(this.i18n('Instance {{host}} unmuted.', { host })) + this.notifier.success($localize`Instance ${host} unmuted.`) this.account.mutedServerByUser = false this.userChanged.emit() @@ -177,7 +172,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.blockAccountByInstance(account) .subscribe( () => { - this.notifier.success(this.i18n('Account {{nameWithHost}} muted by the instance.', { nameWithHost: account.nameWithHost })) + this.notifier.success($localize`Account ${account.nameWithHost} muted by the instance.`) this.account.mutedByInstance = true this.userChanged.emit() @@ -191,7 +186,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.unblockAccountByInstance(account) .subscribe( () => { - this.notifier.success(this.i18n('Account {{nameWithHost}} unmuted by the instance.', { nameWithHost: account.nameWithHost })) + this.notifier.success($localize`Account ${account.nameWithHost} unmuted by the instance.`) this.account.mutedByInstance = false this.userChanged.emit() @@ -205,7 +200,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.blockServerByInstance(host) .subscribe( () => { - this.notifier.success(this.i18n('Instance {{host}} muted by the instance.', { host })) + this.notifier.success($localize`Instance ${host} muted by the instance.`) this.account.mutedServerByInstance = true this.userChanged.emit() @@ -219,7 +214,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.unblockServerByInstance(host) .subscribe( () => { - this.notifier.success(this.i18n('Instance {{host}} unmuted by the instance.', { host })) + this.notifier.success($localize`Instance ${host} unmuted by the instance.`) this.account.mutedServerByInstance = false this.userChanged.emit() @@ -230,14 +225,14 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { } async bulkRemoveCommentsOf (body: BulkRemoveCommentsOfBody) { - const message = this.i18n('Are you sure you want to remove all the comments of this account?') - const res = await this.confirmService.confirm(message, this.i18n('Delete account comments')) + const message = $localize`Are you sure you want to remove all the comments of this account?` + const res = await this.confirmService.confirm(message, $localize`Delete account comments`) if (res === false) return this.bulkService.removeCommentsOf(body) .subscribe( () => { - this.notifier.success(this.i18n('Will remove comments of this account (may take several minutes).')) + this.notifier.success($localize`Will remove comments of this account (may take several minutes).`) }, err => this.notifier.error(err.message) @@ -265,29 +260,29 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { if (this.user && authUser.hasRight(UserRight.MANAGE_USERS) && authUser.canManage(this.user)) { this.userActions.push([ { - label: this.i18n('Edit user'), - description: this.i18n('Change quota, role, and more.'), + label: $localize`Edit user`, + description: $localize`Change quota, role, and more.`, linkBuilder: ({ user }) => this.getRouterUserEditLink(user) }, { - label: this.i18n('Delete user'), - description: this.i18n('Videos will be deleted, comments will be tombstoned.'), + label: $localize`Delete user`, + description: $localize`Videos will be deleted, comments will be tombstoned.`, handler: ({ user }) => this.removeUser(user) }, { - label: this.i18n('Ban'), - description: this.i18n('User won\'t be able to login anymore, but videos and comments will be kept as is.'), + label: $localize`Ban`, + description: $localize`User won't be able to login anymore, but videos and comments will be kept as is.`, handler: ({ user }) => this.openBanUserModal(user), isDisplayed: ({ user }) => !user.blocked }, { - label: this.i18n('Unban user'), - description: this.i18n('Allow the user to login and create videos/comments again'), + label: $localize`Unban user`, + description: $localize`Allow the user to login and create videos/comments again`, handler: ({ user }) => this.unbanUser(user), isDisplayed: ({ user }) => user.blocked }, { - label: this.i18n('Set Email as Verified'), + label: $localize`Set Email as Verified`, handler: ({ user }) => this.setEmailAsVerified(user), isDisplayed: ({ user }) => this.requiresEmailVerification && !user.blocked && user.emailVerified === false } @@ -299,32 +294,32 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { // User actions this.userActions.push([ { - label: this.i18n('Mute this account'), - description: this.i18n('Hide any content from that user for you.'), + label: $localize`Mute this account`, + description: $localize`Hide any content from that user for you.`, isDisplayed: ({ account }) => account.mutedByUser === false, handler: ({ account }) => this.blockAccountByUser(account) }, { - label: this.i18n('Unmute this account'), - description: this.i18n('Show back content from that user for you.'), + label: $localize`Unmute this account`, + description: $localize`Show back content from that user for you.`, isDisplayed: ({ account }) => account.mutedByUser === true, handler: ({ account }) => this.unblockAccountByUser(account) }, { - label: this.i18n('Mute the instance'), - description: this.i18n('Hide any content from that instance for you.'), + label: $localize`Mute the instance`, + description: $localize`Hide any content from that instance for you.`, isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === false, handler: ({ account }) => this.blockServerByUser(account.host) }, { - label: this.i18n('Unmute the instance'), - description: this.i18n('Show back content from that instance for you.'), + label: $localize`Unmute the instance`, + description: $localize`Show back content from that instance for you.`, isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === true, handler: ({ account }) => this.unblockServerByUser(account.host) }, { - label: this.i18n('Remove comments from your videos'), - description: this.i18n('Remove comments of this account from your videos.'), + label: $localize`Remove comments from your videos`, + description: $localize`Remove comments of this account from your videos.`, handler: ({ account }) => this.bulkRemoveCommentsOf({ accountName: account.nameWithHost, scope: 'my-videos' }) } ]) @@ -335,14 +330,14 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { if (authUser.hasRight(UserRight.MANAGE_ACCOUNTS_BLOCKLIST)) { instanceActions = instanceActions.concat([ { - label: this.i18n('Mute this account by your instance'), - description: this.i18n('Hide any content from that user for you, your instance and its users.'), + label: $localize`Mute this account by your instance`, + description: $localize`Hide any content from that user for you, your instance and its users.`, isDisplayed: ({ account }) => account.mutedByInstance === false, handler: ({ account }) => this.blockAccountByInstance(account) }, { - label: this.i18n('Unmute this account by your instance'), - description: this.i18n('Show back content from that user for you, your instance and its users.'), + label: $localize`Unmute this account by your instance`, + description: $localize`Show back content from that user for you, your instance and its users.`, isDisplayed: ({ account }) => account.mutedByInstance === true, handler: ({ account }) => this.unblockAccountByInstance(account) } @@ -353,14 +348,14 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { if (authUser.hasRight(UserRight.MANAGE_SERVERS_BLOCKLIST)) { instanceActions = instanceActions.concat([ { - label: this.i18n('Mute the instance by your instance'), - description: this.i18n('Hide any content from that instance for you, your instance and its users.'), + label: $localize`Mute the instance by your instance`, + description: $localize`Hide any content from that instance for you, your instance and its users.`, isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === false, handler: ({ account }) => this.blockServerByInstance(account.host) }, { - label: this.i18n('Unmute the instance by your instance'), - description: this.i18n('Show back content from that instance for you, your instance and its users.'), + label: $localize`Unmute the instance by your instance`, + description: $localize`Show back content from that instance for you, your instance and its users.`, isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === true, handler: ({ account }) => this.unblockServerByInstance(account.host) } @@ -370,8 +365,8 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { if (authUser.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT)) { instanceActions = instanceActions.concat([ { - label: this.i18n('Remove comments from your instance'), - description: this.i18n('Remove comments of this account from your instance.'), + label: $localize`Remove comments from your instance`, + description: $localize`Remove comments of this account from your instance.`, handler: ({ account }) => this.bulkRemoveCommentsOf({ accountName: account.nameWithHost, scope: 'instance' }) } ]) diff --git a/client/src/app/shared/shared-moderation/video-block.component.ts b/client/src/app/shared/shared-moderation/video-block.component.ts index 054651e71..2bef9efdd 100644 --- a/client/src/app/shared/shared-moderation/video-block.component.ts +++ b/client/src/app/shared/shared-moderation/video-block.component.ts @@ -4,7 +4,6 @@ import { FormReactive, FormValidatorService, VideoBlockValidatorsService } from import { Video } from '@app/shared/shared-main' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoBlockService } from './video-block.service' @Component({ @@ -28,8 +27,7 @@ export class VideoBlockComponent extends FormReactive implements OnInit { private modalService: NgbModal, private videoBlockValidatorsService: VideoBlockValidatorsService, private videoBlocklistService: VideoBlockService, - private notifier: Notifier, - private i18n: I18n + private notifier: Notifier ) { super() } @@ -59,7 +57,7 @@ export class VideoBlockComponent extends FormReactive implements OnInit { this.videoBlocklistService.blockVideo(this.video.id, reason, unfederate) .subscribe( () => { - this.notifier.success(this.i18n('Video blocked.')) + this.notifier.success($localize`Video blocked.`) this.hide() this.video.blacklisted = true diff --git a/client/src/app/shared/shared-thumbnail/video-thumbnail.component.ts b/client/src/app/shared/shared-thumbnail/video-thumbnail.component.ts index 812c7a508..b2a2cf240 100644 --- a/client/src/app/shared/shared-thumbnail/video-thumbnail.component.ts +++ b/client/src/app/shared/shared-thumbnail/video-thumbnail.component.ts @@ -1,6 +1,5 @@ import { Component, EventEmitter, Input, Output } from '@angular/core' import { ScreenService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { Video } from '../shared-main' @Component({ @@ -25,12 +24,9 @@ export class VideoThumbnailComponent { addToWatchLaterText: string addedToWatchLaterText: string - constructor ( - private screenService: ScreenService, - private i18n: I18n - ) { - this.addToWatchLaterText = this.i18n('Add to watch later') - this.addedToWatchLaterText = this.i18n('Remove from watch later') + constructor (private screenService: ScreenService) { + this.addToWatchLaterText = $localize`Add to watch later` + this.addedToWatchLaterText = $localize`Remove from watch later` } getImageUrl () { diff --git a/client/src/app/shared/shared-user-settings/user-interface-settings.component.ts b/client/src/app/shared/shared-user-settings/user-interface-settings.component.ts index 875ffa3f1..80b88c129 100644 --- a/client/src/app/shared/shared-user-settings/user-interface-settings.component.ts +++ b/client/src/app/shared/shared-user-settings/user-interface-settings.component.ts @@ -2,7 +2,6 @@ import { Subject, Subscription } from 'rxjs' import { Component, Input, OnDestroy, OnInit } from '@angular/core' import { AuthService, Notifier, ServerService, UserService } from '@app/core' import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig, User, UserUpdateMe } from '@shared/models' @Component({ @@ -25,8 +24,7 @@ export class UserInterfaceSettingsComponent extends FormReactive implements OnIn private authService: AuthService, private notifier: Notifier, private userService: UserService, - private serverService: ServerService, - private i18n: I18n + private serverService: ServerService ) { super() } @@ -73,14 +71,14 @@ export class UserInterfaceSettingsComponent extends FormReactive implements OnIn () => { this.authService.refreshUserInformation() - if (this.notifyOnUpdate) this.notifier.success(this.i18n('Interface settings updated.')) + if (this.notifyOnUpdate) this.notifier.success($localize`Interface settings updated.`) }, err => this.notifier.error(err.message) ) } else { this.userService.updateMyAnonymousProfile(details) - if (this.notifyOnUpdate) this.notifier.success(this.i18n('Interface settings updated.')) + if (this.notifyOnUpdate) this.notifier.success($localize`Interface settings updated.`) } } } diff --git a/client/src/app/shared/shared-user-settings/user-video-settings.component.ts b/client/src/app/shared/shared-user-settings/user-video-settings.component.ts index eb340e24d..ab77f6f9c 100644 --- a/client/src/app/shared/shared-user-settings/user-video-settings.component.ts +++ b/client/src/app/shared/shared-user-settings/user-video-settings.component.ts @@ -4,7 +4,6 @@ import { first } from 'rxjs/operators' import { Component, Input, OnDestroy, OnInit } from '@angular/core' import { AuthService, Notifier, ServerService, User, UserService } from '@app/core' import { FormReactive, FormValidatorService, ItemSelectCheckboxValue, SelectOptionsItem } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { UserUpdateMe } from '@shared/models' import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type' @@ -30,14 +29,13 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, private authService: AuthService, private notifier: Notifier, private userService: UserService, - private serverService: ServerService, - private i18n: I18n + private serverService: ServerService ) { super() } ngOnInit () { - this.allLanguagesGroup = this.i18n('All languages') + this.allLanguagesGroup = $localize`All languages` let oldForm: any @@ -56,7 +54,7 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, ]).subscribe(([ languages, config ]) => { const group = this.allLanguagesGroup - this.languageItems = [ { label: this.i18n('Unknown language'), id: '_unknown', group } ] + this.languageItems = [ { label: $localize`Unknown language`, id: '_unknown', group } ] this.languageItems = this.languageItems .concat(languages.map(l => ({ label: l.label, id: l.id, group }))) @@ -101,12 +99,12 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, if (Array.isArray(videoLanguages)) { if (videoLanguages.length > 20) { - this.notifier.error(this.i18n('Too many languages are enabled. Please enable them all or stay below 20 enabled languages.')) + this.notifier.error($localize`Too many languages are enabled. Please enable them all or stay below 20 enabled languages.`) return } if (videoLanguages.length === 0) { - this.notifier.error(this.i18n('You need to enable at least 1 video language.')) + this.notifier.error($localize`You need to enable at least 1 video language.`) return } @@ -133,22 +131,14 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, () => { this.authService.refreshUserInformation() - if (this.notifyOnUpdate) this.notifier.success(this.i18n('Video settings updated.')) + if (this.notifyOnUpdate) this.notifier.success($localize`Video settings updated.`) }, err => this.notifier.error(err.message) ) } else { this.userService.updateMyAnonymousProfile(details) - if (this.notifyOnUpdate) this.notifier.success(this.i18n('Display/Video settings updated.')) + if (this.notifyOnUpdate) this.notifier.success($localize`Display/Video settings updated.`) } } - - getDefaultVideoLanguageLabel () { - return this.i18n('No language') - } - - getSelectedVideoLanguageLabel () { - return this.i18n('{{\'{0} languages selected') - } } diff --git a/client/src/app/shared/shared-user-subscription/subscribe-button.component.ts b/client/src/app/shared/shared-user-subscription/subscribe-button.component.ts index 72fa3f4fd..b918fda06 100644 --- a/client/src/app/shared/shared-user-subscription/subscribe-button.component.ts +++ b/client/src/app/shared/shared-user-subscription/subscribe-button.component.ts @@ -3,7 +3,6 @@ import { Component, Input, OnChanges, OnInit } from '@angular/core' import { Router } from '@angular/router' import { AuthService, Notifier } from '@app/core' import { Account, VideoChannel, VideoService } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { FeedFormat } from '@shared/models' import { UserSubscriptionService } from './user-subscription.service' @@ -31,7 +30,6 @@ export class SubscribeButtonComponent implements OnInit, OnChanges { private router: Router, private notifier: Notifier, private userSubscriptionService: UserSubscriptionService, - private i18n: I18n, private videoService: VideoService ) { } @@ -108,20 +106,14 @@ export class SubscribeButtonComponent implements OnInit, OnChanges { () => { this.notifier.success( this.account - ? this.i18n( - 'Subscribed to all current channels of {{nameWithHost}}. You will be notified of all their new videos.', - { nameWithHost: this.account.displayName } - ) - : this.i18n( - 'Subscribed to {{nameWithHost}}. You will be notified of all their new videos.', - { nameWithHost: this.videoChannels[0].displayName } - ) - , - this.i18n('Subscribed') + ? $localize`Subscribed to all current channels of ${this.account.displayName}. You will be notified of all their new videos.` + : $localize`Subscribed to ${this.videoChannels[0].displayName}. You will be notified of all their new videos.`, + + $localize`Subscribed` ) }, - err => this.notifier.error(err.message) + err => this.notifier.error(err.message) ) } @@ -144,10 +136,10 @@ export class SubscribeButtonComponent implements OnInit, OnChanges { complete: () => { this.notifier.success( this.account - ? this.i18n('Unsubscribed from all channels of {{nameWithHost}}', { nameWithHost: this.account.nameWithHost }) - : this.i18n('Unsubscribed from {{nameWithHost}}', { nameWithHost: this.videoChannels[ 0 ].nameWithHost }) - , - this.i18n('Unsubscribed') + ? $localize`Unsubscribed from all channels of ${this.account.nameWithHost}` + : $localize`Unsubscribed from ${this.videoChannels[ 0 ].nameWithHost}`, + + $localize`Unsubscribed` ) }, diff --git a/client/src/app/shared/shared-video-miniature/abstract-video-list.ts b/client/src/app/shared/shared-video-miniature/abstract-video-list.ts index e18002b74..1b5b8a64b 100644 --- a/client/src/app/shared/shared-video-miniature/abstract-video-list.ts +++ b/client/src/app/shared/shared-video-miniature/abstract-video-list.ts @@ -14,7 +14,6 @@ import { } from '@app/core' import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook' import { GlobalIconName } from '@app/shared/shared-icons' -import { I18n } from '@ngx-translate/i18n-polyfill' import { isLastMonth, isLastWeek, isToday, isYesterday } from '@shared/core-utils/miscs/date' import { ServerConfig, VideoSortField } from '@shared/models' import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type' @@ -89,7 +88,6 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor protected abstract screenService: ScreenService protected abstract storageService: LocalStorageService protected abstract router: Router - protected abstract i18n: I18n abstract titlePage: string private resizeSubscription: Subscription @@ -111,11 +109,11 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor this.groupedDateLabels = { [GroupDate.UNKNOWN]: null, - [GroupDate.TODAY]: this.i18n('Today'), - [GroupDate.YESTERDAY]: this.i18n('Yesterday'), - [GroupDate.LAST_WEEK]: this.i18n('Last week'), - [GroupDate.LAST_MONTH]: this.i18n('Last month'), - [GroupDate.OLDER]: this.i18n('Older') + [GroupDate.TODAY]: $localize`Today`, + [GroupDate.YESTERDAY]: $localize`Yesterday`, + [GroupDate.LAST_WEEK]: $localize`Last week`, + [GroupDate.LAST_MONTH]: $localize`Last month`, + [GroupDate.OLDER]: $localize`Older` } // Subscribe to route changes @@ -192,7 +190,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor }, error => { - const message = this.i18n('Cannot load more videos. Try again later.') + const message = $localize`Cannot load more videos. Try again later.` console.error(message, { error }) this.notifier.error(message) diff --git a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts index 3d1fc8690..39358e08b 100644 --- a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts +++ b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts @@ -1,10 +1,18 @@ import { Component, EventEmitter, Input, OnChanges, Output, ViewChild } from '@angular/core' import { AuthService, ConfirmService, Notifier, ScreenService } from '@app/core' -import { VideoBlockComponent, VideoBlockService, VideoReportComponent, BlocklistService } from '@app/shared/shared-moderation' +import { BlocklistService, VideoBlockComponent, VideoBlockService, VideoReportComponent } from '@app/shared/shared-moderation' import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoCaption } from '@shared/models' -import { DropdownAction, DropdownButtonSize, DropdownDirection, RedundancyService, Video, VideoDetails, VideoService, Actor } from '../shared-main' +import { + Actor, + DropdownAction, + DropdownButtonSize, + DropdownDirection, + RedundancyService, + Video, + VideoDetails, + VideoService +} from '../shared-main' import { VideoAddToPlaylistComponent } from '../shared-video-playlist' import { VideoDownloadComponent } from './video-download.component' @@ -71,8 +79,7 @@ export class VideoActionsDropdownComponent implements OnChanges { private videoBlocklistService: VideoBlockService, private screenService: ScreenService, private videoService: VideoService, - private redundancyService: RedundancyService, - private i18n: I18n + private redundancyService: RedundancyService ) { } get user () { @@ -153,17 +160,15 @@ export class VideoActionsDropdownComponent implements OnChanges { /* Action handlers */ async unblockVideo () { - const confirmMessage = this.i18n( - 'Do you really want to unblock this video? It will be available again in the videos list.' - ) + const confirmMessage = $localize`Do you really want to unblock this video? It will be available again in the videos list.` - const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblock')) + const res = await this.confirmService.confirm(confirmMessage, $localize`Unblock`) if (res === false) return this.videoBlocklistService.unblockVideo(this.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video {{name}} unblocked.', { name: this.video.name })) + this.notifier.success($localize`Video ${this.video.name} unblocked.`) this.video.blacklisted = false this.video.blockedReason = null @@ -178,14 +183,13 @@ export class VideoActionsDropdownComponent implements OnChanges { async removeVideo () { this.modalOpened.emit() - const res = await this.confirmService.confirm(this.i18n('Do you really want to delete this video?'), this.i18n('Delete')) + const res = await this.confirmService.confirm($localize`Do you really want to delete this video?`, $localize`Delete`) if (res === false) return this.videoService.removeVideo(this.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video {{videoName}} deleted.', { videoName: this.video.name })) - + this.notifier.success($localize`Video ${this.video.name} deleted.`) this.videoRemoved.emit() }, @@ -197,7 +201,7 @@ export class VideoActionsDropdownComponent implements OnChanges { this.redundancyService.addVideoRedundancy(this.video) .subscribe( () => { - const message = this.i18n('This video will be duplicated by your instance.') + const message = $localize`This video will be duplicated by your instance.` this.notifier.success(message) }, @@ -211,8 +215,7 @@ export class VideoActionsDropdownComponent implements OnChanges { this.blocklistService.blockAccountByUser(params) .subscribe( () => { - this.notifier.success(this.i18n('Account {{nameWithHost}} muted.', params)) - + this.notifier.success($localize`Account ${params.nameWithHost} muted.`) this.videoAccountMuted.emit() }, @@ -236,7 +239,7 @@ export class VideoActionsDropdownComponent implements OnChanges { this.videoActions = [ [ { - label: this.i18n('Save to playlist'), + label: $localize`Save to playlist`, handler: () => this.playlistDropdown.toggle(), isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.playlist, iconName: 'playlist-add' @@ -244,43 +247,43 @@ export class VideoActionsDropdownComponent implements OnChanges { ], [ // actions regarding the video { - label: this.i18n('Download'), + label: $localize`Download`, handler: () => this.showDownloadModal(), isDisplayed: () => this.displayOptions.download && this.isVideoDownloadable(), iconName: 'download' }, { - label: this.i18n('Update'), + label: $localize`Update`, linkBuilder: ({ video }) => [ '/videos/update', video.uuid ], iconName: 'edit', isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.update && this.isVideoUpdatable() }, { - label: this.i18n('Block'), + label: $localize`Block`, handler: () => this.showBlockModal(), iconName: 'no', isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoBlockable() }, { - label: this.i18n('Unblock'), + label: $localize`Unblock`, handler: () => this.unblockVideo(), iconName: 'undo', isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoUnblockable() }, { - label: this.i18n('Mirror'), + label: $localize`Mirror`, handler: () => this.duplicateVideo(), isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.duplicate && this.canVideoBeDuplicated(), iconName: 'cloud-download' }, { - label: this.i18n('Delete'), + label: $localize`Delete`, handler: () => this.removeVideo(), isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.delete && this.isVideoRemovable(), iconName: 'delete' }, { - label: this.i18n('Report'), + label: $localize`Report`, handler: () => this.showReportModal(), isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.report, iconName: 'flag' @@ -288,7 +291,7 @@ export class VideoActionsDropdownComponent implements OnChanges { ], [ // actions regarding the account/its server { - label: this.i18n('Mute account'), + label: $localize`Mute account`, handler: () => this.muteVideoAccount(), isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.mute && this.isVideoAccountMutable(), iconName: 'no' diff --git a/client/src/app/shared/shared-video-miniature/video-download.component.ts b/client/src/app/shared/shared-video-miniature/video-download.component.ts index e3d6a1969..99838f712 100644 --- a/client/src/app/shared/shared-video-miniature/video-download.component.ts +++ b/client/src/app/shared/shared-video-miniature/video-download.component.ts @@ -2,7 +2,6 @@ import { mapValues, pick } from 'lodash-es' import { Component, ElementRef, ViewChild } from '@angular/core' import { AuthService, Notifier } from '@app/core' import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoCaption, VideoFile, VideoPrivacy } from '@shared/models' import { BytesPipe, NumberFormatterPipe, VideoDetails, VideoService } from '../shared-main' @@ -38,8 +37,7 @@ export class VideoDownloadComponent { private notifier: Notifier, private modalService: NgbModal, private videoService: VideoService, - private auth: AuthService, - private i18n: I18n + private auth: AuthService ) { this.bytesPipe = new BytesPipe() this.numbersPipe = new NumberFormatterPipe() @@ -47,8 +45,8 @@ export class VideoDownloadComponent { get typeText () { return this.type === 'video' - ? this.i18n('video') - : this.i18n('subtitles') + ? $localize`video` + : $localize`subtitles` } getVideoFiles () { @@ -135,7 +133,7 @@ export class VideoDownloadComponent { } activateCopiedMessage () { - this.notifier.success(this.i18n('Copied')) + this.notifier.success($localize`Copied`) } switchToType (type: DownloadType) { @@ -144,11 +142,11 @@ export class VideoDownloadComponent { getMetadataFormat (format: any) { const keyToTranslateFunction = { - 'encoder': (value: string) => ({ label: this.i18n('Encoder'), value }), - 'format_long_name': (value: string) => ({ label: this.i18n('Format name'), value }), - 'size': (value: number) => ({ label: this.i18n('Size'), value: this.bytesPipe.transform(value, 2) }), + 'encoder': (value: string) => ({ label: $localize`Encoder`, value }), + 'format_long_name': (value: string) => ({ label: $localize`Format name`, value }), + 'size': (value: number) => ({ label: $localize`Size`, value: this.bytesPipe.transform(value, 2) }), 'bit_rate': (value: number) => ({ - label: this.i18n('Bitrate'), + label: $localize`Bitrate`, value: `${this.numbersPipe.transform(value)}bps` }) } @@ -168,25 +166,25 @@ export class VideoDownloadComponent { if (!stream) return undefined let keyToTranslateFunction = { - 'codec_long_name': (value: string) => ({ label: this.i18n('Codec'), value }), - 'profile': (value: string) => ({ label: this.i18n('Profile'), value }), + 'codec_long_name': (value: string) => ({ label: $localize`Codec`, value }), + 'profile': (value: string) => ({ label: $localize`Profile`, value }), 'bit_rate': (value: number) => ({ - label: this.i18n('Bitrate'), + label: $localize`Bitrate`, value: `${this.numbersPipe.transform(value)}bps` }) } if (type === 'video') { keyToTranslateFunction = Object.assign(keyToTranslateFunction, { - 'width': (value: number) => ({ label: this.i18n('Resolution'), value: `${value}x${stream.height}` }), - 'display_aspect_ratio': (value: string) => ({ label: this.i18n('Aspect ratio'), value }), - 'avg_frame_rate': (value: string) => ({ label: this.i18n('Average frame rate'), value }), - 'pix_fmt': (value: string) => ({ label: this.i18n('Pixel format'), value }) + 'width': (value: number) => ({ label: $localize`Resolution`, value: `${value}x${stream.height}` }), + 'display_aspect_ratio': (value: string) => ({ label: $localize`Aspect ratio`, value }), + 'avg_frame_rate': (value: string) => ({ label: $localize`Average frame rate`, value }), + 'pix_fmt': (value: string) => ({ label: $localize`Pixel format`, value }) }) } else { keyToTranslateFunction = Object.assign(keyToTranslateFunction, { - 'sample_rate': (value: number) => ({ label: this.i18n('Sample rate'), value }), - 'channel_layout': (value: number) => ({ label: this.i18n('Channel Layout'), value }) + 'sample_rate': (value: number) => ({ label: $localize`Sample rate`, value }), + 'channel_layout': (value: number) => ({ label: $localize`Channel Layout`, value }) }) } diff --git a/client/src/app/shared/shared-video-miniature/video-miniature.component.ts b/client/src/app/shared/shared-video-miniature/video-miniature.component.ts index 3c7046de5..cc5665ab1 100644 --- a/client/src/app/shared/shared-video-miniature/video-miniature.component.ts +++ b/client/src/app/shared/shared-video-miniature/video-miniature.component.ts @@ -11,7 +11,6 @@ import { Output } from '@angular/core' import { AuthService, ScreenService, ServerService, User } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig, VideoPlaylistType, VideoPrivacy, VideoState } from '@shared/models' import { Video } from '../shared-main' import { VideoPlaylistService } from '../shared-video-playlist' @@ -95,7 +94,6 @@ export class VideoMiniatureComponent implements OnInit { constructor ( private screenService: ScreenService, private serverService: ServerService, - private i18n: I18n, private authService: AuthService, private videoPlaylistService: VideoPlaylistService, private cd: ChangeDetectorRef, @@ -116,10 +114,7 @@ export class VideoMiniatureComponent implements OnInit { this.setUpBy() - this.channelLinkTitle = this.i18n( - '{{name}} (channel page)', - { name: this.video.channel.name, handle: this.video.byVideoChannel } - ) + this.channelLinkTitle = $localize`${this.video.channel.name} (channel page)` // We rely on mouseenter to lazy load actions if (this.screenService.isInTouchScreen()) { @@ -164,24 +159,24 @@ export class VideoMiniatureComponent implements OnInit { if (!video.state) return '' if (video.privacy.id !== VideoPrivacy.PRIVATE && video.state.id === VideoState.PUBLISHED) { - return this.i18n('Published') + return $localize`Published` } if (video.scheduledUpdate) { const updateAt = new Date(video.scheduledUpdate.updateAt.toString()).toLocaleString(this.localeId) - return this.i18n('Publication scheduled on ') + updateAt + return $localize`Publication scheduled on ` + updateAt } if (video.state.id === VideoState.TO_TRANSCODE && video.waitTranscoding === true) { - return this.i18n('Waiting transcoding') + return $localize`Waiting transcoding` } if (video.state.id === VideoState.TO_TRANSCODE) { - return this.i18n('To transcode') + return $localize`To transcode` } if (video.state.id === VideoState.TO_IMPORT) { - return this.i18n('To import') + return $localize`To import` } return '' diff --git a/client/src/app/shared/shared-video-miniature/videos-selection.component.ts b/client/src/app/shared/shared-video-miniature/videos-selection.component.ts index 3e0e3b983..2b060b130 100644 --- a/client/src/app/shared/shared-video-miniature/videos-selection.component.ts +++ b/client/src/app/shared/shared-video-miniature/videos-selection.component.ts @@ -13,7 +13,6 @@ import { } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { AuthService, ComponentPagination, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ResultList, VideoSortField } from '@shared/models' import { PeerTubeTemplateDirective, Video } from '../shared-main' import { AbstractVideoList } from './abstract-video-list' @@ -45,7 +44,6 @@ export class VideosSelectionComponent extends AbstractVideoList implements OnIni globalButtonsTemplate: TemplateRef constructor ( - protected i18n: I18n, protected router: Router, protected route: ActivatedRoute, protected notifier: Notifier, diff --git a/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts b/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts index f611fc46b..757ffa099 100644 --- a/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts +++ b/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts @@ -4,7 +4,6 @@ import { debounceTime, filter } from 'rxjs/operators' import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core' import { AuthService, DisableForReuseHook, Notifier } from '@app/core' import { FormReactive, FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { Video, VideoExistInPlaylist, VideoPlaylistCreate, VideoPlaylistElementCreate, VideoPlaylistPrivacy } from '@shared/models' import { secondsToTime } from '../../../assets/player/utils' import { CachedPlaylist, VideoPlaylistService } from './video-playlist.service' @@ -53,7 +52,6 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, protected formValidatorService: FormValidatorService, private authService: AuthService, private notifier: Notifier, - private i18n: I18n, private videoPlaylistService: VideoPlaylistService, private videoPlaylistValidatorsService: VideoPlaylistValidatorsService, private cd: ChangeDetectorRef @@ -204,7 +202,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, playlist.playlistElementId, this.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video removed from {{name}}', { name: playlist.displayName })) + this.notifier.success($localize`Video removed from ${playlist.displayName}`) }, err => { @@ -262,8 +260,8 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, .subscribe( () => { const message = body.startTimestamp || body.stopTimestamp - ? this.i18n('Video added in {{n}} at timestamps {{t}}', { n: playlist.displayName, t: this.formatTimestamp(playlist) }) - : this.i18n('Video added in {{n}}', { n: playlist.displayName }) + ? $localize`Video added in ${playlist.displayName} at timestamps ${this.formatTimestamp(playlist)}` + : $localize`Video added in ${playlist.displayName}` this.notifier.success(message) }, diff --git a/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts b/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts index 57a5fbe61..5879c4978 100644 --- a/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts +++ b/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts @@ -2,7 +2,6 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, In import { AuthService, Notifier, ServerService } from '@app/core' import { Video } from '@app/shared/shared-main' import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig, VideoPlaylistElementType, VideoPlaylistElementUpdate } from '@shared/models' import { secondsToTime } from '../../../assets/player/utils' import { VideoPlaylistElement } from './video-playlist-element.model' @@ -44,7 +43,6 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit { private authService: AuthService, private serverService: ServerService, private notifier: Notifier, - private i18n: I18n, private videoPlaylistService: VideoPlaylistService, private cdr: ChangeDetectorRef ) {} @@ -97,8 +95,7 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit { this.videoPlaylistService.removeVideoFromPlaylist(this.playlist.id, playlistElement.id, videoId) .subscribe( () => { - this.notifier.success(this.i18n('Video removed from {{name}}', { name: this.playlist.displayName })) - + this.notifier.success($localize`Video removed from ${this.playlist.displayName}`) this.elementRemoved.emit(playlistElement) }, @@ -117,7 +114,7 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit { this.videoPlaylistService.updateVideoOfPlaylist(this.playlist.id, playlistElement.id, body, this.playlistElement.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Timestamps updated')) + this.notifier.success($localize`Timestamps updated`) playlistElement.startTimestamp = body.startTimestamp playlistElement.stopTimestamp = body.stopTimestamp @@ -140,10 +137,10 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit { if (start === null && stop === null) return '' - if (start !== null && stop === null) return this.i18n('Starts at ') + startFormatted - if (start === null && stop !== null) return this.i18n('Stops at ') + stopFormatted + if (start !== null && stop === null) return $localize`Starts at ` + startFormatted + if (start === null && stop !== null) return $localize`Stops at ` + stopFormatted - return this.i18n('Starts at ') + startFormatted + this.i18n(' and stops at ') + stopFormatted + return $localize`Starts at ` + startFormatted + $localize` and stops at ` + stopFormatted } onDropdownOpenChange () { diff --git a/client/yarn.lock b/client/yarn.lock index 4fe21c1a5..db52a4a54 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -120,10 +120,10 @@ ora "4.0.5" rxjs "6.6.2" -"@angular/animations@^10.1.0-next.4": - version "10.1.0-next.4" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-10.1.0-next.4.tgz#e2e46e23f4aa02d6b04b1db795f85d51e2fcc62b" - integrity sha512-3PWWtORaHjspKFbff+NdB2/DdgsNMNDz02/oCylK5+UAAtRzci885EAuk0oC5wn6pkzU4WrBbUYkVWikbQEy9Q== +"@angular/animations@^10.1.0-next.5": + version "10.1.0-next.5" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-10.1.0-next.5.tgz#af5c9365ef5473d430797eb1b2f08a8ed4e75b96" + integrity sha512-1ssVuf4in1nLqiC7ZOXQyjbk4KMj9g4jTB5LkhPgXmkMr5cdHckIgeSSk0sF0I7F1+Xo0P0Dz4CL7AZY/IlxQw== dependencies: tslib "^2.0.0" @@ -162,17 +162,17 @@ universal-analytics "0.4.23" uuid "8.3.0" -"@angular/common@^10.1.0-next.4": - version "10.1.0-next.4" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-10.1.0-next.4.tgz#712850da191bcd41e9d8fe0da9484d30b3b8e248" - integrity sha512-iiVUqc+ManJHak3HPhZ9ajp5f3IZmm8f9ev8Bu8bVRDjk/76hSeCRln6fykbZPwpbAOlVgVWjjTf2bgf6QMpQQ== +"@angular/common@^10.1.0-next.5": + version "10.1.0-next.5" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-10.1.0-next.5.tgz#9c8e43e6a319e9d65e4d6c8e000ee1ca9775eaf8" + integrity sha512-vK7btoMtC3hE6BfNY3QLlDipW9sd8CGdOfHyl8smNtRyw7qAMSxgvIkQSaclN4K7h3uD7QMppqPAjZMgeUxfzw== dependencies: tslib "^2.0.0" -"@angular/compiler-cli@^10.1.0-next.4": - version "10.1.0-next.4" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-10.1.0-next.4.tgz#b9edfe7c04ef5faeaecdab095e58137fdbe14f3d" - integrity sha512-yKv0bCr+vdb34uBiv18iHC+V83gWQt4AuEvUF/WYVqnmE7gKa1PO0LjMyWB8lHrur/3k5uBug1NAqOqAQGcyTw== +"@angular/compiler-cli@^10.1.0-next.5": + version "10.1.0-next.5" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-10.1.0-next.5.tgz#4ef0ae92ecee8b1de003a82180c5813f2c507cdb" + integrity sha512-+MI4enl5N0xyjzvL9vfqVaDqDm6RkuX/jydvaFr8yTESBRXCu8g4UvTcxnOwLcQehl7ZD45WmOeOnRXdwcI3kA== dependencies: canonical-path "1.0.0" chokidar "^3.0.0" @@ -188,61 +188,61 @@ tslib "^2.0.0" yargs "15.3.0" -"@angular/compiler@^10.1.0-next.4": - version "10.1.0-next.4" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-10.1.0-next.4.tgz#b86b51492e59edcc507d13ef1842bae9b36ae855" - integrity sha512-TT4kh41AkU4oatHnKwfQ5A10RPg+A7xSBPxSsqKBC8bphel0HL4Lf4hn5shIK4G8aZaieBfntkC9Nf7WoWgqaQ== +"@angular/compiler@^10.1.0-next.5": + version "10.1.0-next.5" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-10.1.0-next.5.tgz#3b638e8708d24310b81003271bee5006ea9c7d9e" + integrity sha512-pDUTIerTs6A9yDBGeKiSFzu0CsG3l0ct4UkIWE1PsW9ui63ar+UytGpiLBBJ8pXfktMOZle8NVmlKAzhXG2g/g== dependencies: tslib "^2.0.0" -"@angular/core@^10.1.0-next.4": - version "10.1.0-next.4" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-10.1.0-next.4.tgz#622cd9245c178422b896149e9d9aa387109142b3" - integrity sha512-buAMY+gTeX6jXfXSxnLnwLHeJnQ7obLr27JZo8FNt3JTI6nYAdLEf2Jw2jsqwJ8H6fSNjOHmm+tLRqSVHSyeRg== +"@angular/core@^10.1.0-next.5": + version "10.1.0-next.5" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-10.1.0-next.5.tgz#70269efc5ede9553bac231f4d61e2a99bb5b69bb" + integrity sha512-bLV1sSaEZqda+cmYwfYKvy4KX0xtoAoLwtNQi6/TGVBj4c+6NsUp5oN2SwSEQKTo7vi0qaP1/Q/XUGSX4ZYHQw== dependencies: tslib "^2.0.0" -"@angular/forms@^10.1.0-next.4": - version "10.1.0-next.4" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-10.1.0-next.4.tgz#15798595ffb50ad924f4be89d0de38a76a367a6f" - integrity sha512-6fINEZoxj4vRmgfDUG7ICt381hCizMp6wzYPUd55+fQjNGRy/BwkbmzZI0tf3QoiRjqiTZIq/L+sQxQMfKFZhg== +"@angular/forms@^10.1.0-next.5": + version "10.1.0-next.5" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-10.1.0-next.5.tgz#02b0a361cda71fbd6ed7c45e707db7ab98abd950" + integrity sha512-aE/Q0VT4k1AtUzC/2YL7//mXBZQDENwtFUVnMjv8Krbvlka9EylZHN0MdFNhzW2zuNmELnv2Eud4O+vEF9vJ6Q== dependencies: tslib "^2.0.0" -"@angular/localize@^10.1.0-next.4": - version "10.1.0-next.4" - resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-10.1.0-next.4.tgz#a2dbe3c6c4d72421baca87ec1e59f6a4dbc1d547" - integrity sha512-q/RiyZvMzhXabXVwYqjljS30mKsUL06CZAsrS1EvXC+dcA2qTpVoHUFLr5DHiqcNlxENXtJ/+56O7N+V85nH1w== +"@angular/localize@^10.1.0-next.5": + version "10.1.0-next.5" + resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-10.1.0-next.5.tgz#f2722ac407d34ac7f0c6b748f58b8966c08f797b" + integrity sha512-EBTsMw66snjNOl1FZJB/bhPJC19E5K5TImS4+Pf1lEbHBLuvfEwZLQnrFoyPWwU98ozFCxYtNZvNJUOHFpM5hQ== dependencies: "@babel/core" "7.8.3" glob "7.1.2" yargs "15.3.0" -"@angular/platform-browser-dynamic@^10.1.0-next.4": - version "10.1.0-next.4" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-10.1.0-next.4.tgz#664f48844152785b1af79a906766661bfbd8e030" - integrity sha512-amy8aLpE2Hjq5D4cwY8oDPFW963jXJPaMuXWwQsJUqKgmYwUOS4PU86x1BceTb6wOl4Gf4+sJREx3dMjh1AaAQ== +"@angular/platform-browser-dynamic@^10.1.0-next.5": + version "10.1.0-next.5" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-10.1.0-next.5.tgz#bc348ed36dc4f97cc90bb6817191e15d3f1b6f23" + integrity sha512-dgxGMyz5wwVegFEaE3RS4XSurlrqK1RMvFKpIpb/EbJVP7ZBYMhtX6Wqw0p81MYo0GIssaSaKJd+j4rjjxWR2g== dependencies: tslib "^2.0.0" -"@angular/platform-browser@^10.1.0-next.4": - version "10.1.0-next.4" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-10.1.0-next.4.tgz#533411a5a2c2fd5ec43198297a032a67c324e59c" - integrity sha512-DOEL1RDCEd/xttZNyf3VlWC639/3MSlYsDKpdn9FzgLNnu/CXerilSGQQlzaR0b3V8f64csUtuejH9YB/jp0HQ== +"@angular/platform-browser@^10.1.0-next.5": + version "10.1.0-next.5" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-10.1.0-next.5.tgz#205c99c3edb11b7a83bfa2f967d1e4617a4671ee" + integrity sha512-RDgLlDYqWYDdNEPYHJIoG5JsO6m81xxfJNsDVI4DE9z6iCqUxnWappRoDNs/yXFXbdF8p+WbjtL2pru50TWFEA== dependencies: tslib "^2.0.0" -"@angular/router@^10.1.0-next.4": - version "10.1.0-next.4" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-10.1.0-next.4.tgz#341951c3db2c206bf85bedfa496c5d75e41ac46c" - integrity sha512-KjvLIMZcxrDtXVYsWpizq91p50C8JQ4i7wsgxD9O7r0bvMJPn/LngUpaNz+9zKmk4UUwpxZ65sd8sfw+mOR26g== +"@angular/router@^10.1.0-next.5": + version "10.1.0-next.5" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-10.1.0-next.5.tgz#3882a2ed1ea5b7f2efca67af4fa3fd28b9e25762" + integrity sha512-Jyh62a0zP1gX/R3hV5ILnd/t3AwBLTvRetXfDuOB5c5vImjgwpl84gX3+aJsSvc1cZ0Rs31zqV8JR9M9yEAAbQ== dependencies: tslib "^2.0.0" -"@angular/service-worker@^10.1.0-next.4": - version "10.1.0-next.4" - resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-10.1.0-next.4.tgz#ae240fdc2957b27e71a738fe8a01d31dfbae2ee6" - integrity sha512-xF9J+bPGRPAxeC07cOKHoXxJ32skNPDj9bEpymrfJaRxzmQ41gN4+IlwmiFJjoHUwYVX3x4OZyb18HTJPhWqXw== +"@angular/service-worker@^10.1.0-next.5": + version "10.1.0-next.5" + resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-10.1.0-next.5.tgz#699bfd88e7b02c9e30fa9103c1fd508b86725e60" + integrity sha512-lXne4/88dre8NXY/jHEm+bONdG4EswzBGln2PnaHGZ1i3ALATcSwzrCEAqh29eeP9/OGXRMc7iBdAj2N24WxUw== dependencies: tslib "^2.0.0" @@ -1412,15 +1412,6 @@ resolved "https://registry.yarnpkg.com/@ngx-meta/core/-/core-9.0.0.tgz#2c3b27bd32d41f7aaf0712d4007e0afed8e5dd3f" integrity sha512-WL/HyKM+4gJPS3TNTO0M+46LlIvGTSyofL//8hxoozAyRPsiMyR0xrwUvPBJkVqFyD6j0iI5FaNcQ9d0JCVJhg== -"@ngx-translate/i18n-polyfill@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@ngx-translate/i18n-polyfill/-/i18n-polyfill-1.0.0.tgz#145edb28bcfc1332e1bc25279eadf9d4ed0a20f8" - integrity sha512-+UKmSr6cWBJiMDex6w2FwVjEeVnlEsINDGYvTgRaFRI3/IKZrsSVcfISDcBX2wWr6m4jumfOyCcimIl2TxcaoA== - dependencies: - glob "7.1.2" - tslib "^1.9.0" - yargs "10.0.3" - "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -5149,7 +5140,7 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^2.0.0, find-up@^2.1.0: +find-up@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= @@ -12355,31 +12346,6 @@ yargs-parser@^7.0.0: dependencies: camelcase "^4.1.0" -yargs-parser@^8.0.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" - integrity sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ== - dependencies: - camelcase "^4.1.0" - -yargs@10.0.3: - version "10.0.3" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae" - integrity sha512-DqBpQ8NAUX4GyPP/ijDGHsJya4tYqLQrjPr95HNsr1YwL3+daCfvBwg7+gIC6IdJhR2kATh3hb61vjzMWEtjdw== - dependencies: - cliui "^3.2.0" - decamelize "^1.1.1" - find-up "^2.1.0" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^8.0.0" - yargs@15.3.0: version "15.3.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.0.tgz#403af6edc75b3ae04bf66c94202228ba119f0976" diff --git a/scripts/build/client.sh b/scripts/build/client.sh index 644a0807f..9cd8d8cce 100755 --- a/scripts/build/client.sh +++ b/scripts/build/client.sh @@ -3,160 +3,75 @@ set -eu declare -A languages +defaultLanguage="en-US" -pre_build_hook () { - mkdir "./src/pending_locale" > /dev/null || true - mv ./src/locale/angular.*.xlf "./src/pending_locale" - - if [ ! -z ${1+x} ]; then - mv "./src/pending_locale/angular.$1.xlf" "./src/locale" - fi -} - -post_build_hook () { - mv ./src/pending_locale/* "./src/locale" - rmdir "./src/pending_locale/" -} - -# Previous build failed -if [ ! -f "client/src/locale/angular.fr-FR.xlf" ]; then - git checkout -- client/src/locale/ - rm -r client/src/pending_locale -fi +# Supported languages +languages=( + ["ar"]="ar" + ["en"]="en-US" + ["vi"]="vi-VN" + ["hu"]="hu-HU" + ["th"]="th-TH" + ["fi"]="fi-FI" + ["nl"]="nl-NL" + ["gd"]="gd" + ["el"]="el-GR" + ["es"]="es-ES" + ["oc"]="oc" + ["pt"]="pt-BR" + ["pt-PT"]="pt-PT" + ["sv"]="sv-SE" + ["pl"]="pl-PL" + ["ru"]="ru-RU" + ["zh-Hans"]="zh-Hans-CN" + ["zh-Hant"]="zh-Hant-TW" + ["fr"]="fr-FR" + ["ja"]="ja-JP" + ["eu"]="eu-ES" + ["ca"]="ca-ES" + ["cs"]="cs-CZ" + ["eo"]="eo" + ["de"]="de-DE" + ["it"]="it-IT" + ["kab"]="kab" +) cd client rm -rf ./dist ./compiled -pre_build_hook - -additionalParams="" -if [ ! -z ${1+x} ] && [ "$1" == "--analyze-bundle" ]; then - additionalParams="--namedChunks=true --outputHashing=none" - export ANALYZE_BUNDLE=true -fi - -if [ ! -z ${1+x} ] && [ "$1" == "--i18n" ]; then - additionalParams="--configuration=i18n" - export ANALYZE_BUNDLE=true -fi - -defaultLanguage="en-US" -npm run ng build -- --output-path "dist/$defaultLanguage/" --deploy-url "/client/$defaultLanguage/" --prod --stats-json $additionalParams -mv "./dist/$defaultLanguage/assets" "./dist" -mv "./dist/$defaultLanguage/manifest.webmanifest" "./dist/manifest.webmanifest" - -post_build_hook - # Don't build other languages if --light arg is provided if [ -z ${1+x} ] || ([ "$1" != "--light" ] && [ "$1" != "--analyze-bundle" ] && [ "$1" != "--i18n" ]); then - if [ ! -z ${1+x} ] && [ "$1" == "--light-hu" ]; then - languages=(["hu"]="hu-HU") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-ar" ]; then - languages=(["ar"]="ar") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-vi" ]; then - languages=(["vi"]="vi-VN") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-kab" ]; then - languages=(["kab"]="kab") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-th" ]; then - languages=(["th"]="th-TH") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-fi" ]; then - languages=(["fi"]="fi-FI") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-nl" ]; then - languages=(["nl"]="nl-NL") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-gd" ]; then - languages=(["gd"]="gd") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-el" ]; then - languages=(["el"]="el-GR") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-es" ]; then - languages=(["es"]="es-ES") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-oc" ]; then - languages=(["oc"]="oc") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-pt" ]; then - languages=(["pt"]="pt-BR") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-pt-PT" ]; then - languages=(["pt-PT"]="pt-PT") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-sv" ]; then - languages=(["sv"]="sv-SE") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-pl" ]; then - languages=(["pl"]="pl-PL") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-ru" ]; then - languages=(["ru"]="ru-RU") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-zh-Hans" ]; then - languages=(["zh-Hans"]="zh-Hans-CN") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-zh-Hant" ]; then - languages=(["zh-Hant"]="zh-Hant-TW") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-fr" ]; then - languages=(["fr"]="fr-FR") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-ja" ]; then - languages=(["ja"]="ja-JP") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-eu" ]; then - languages=(["eu"]="eu-ES") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-ca" ]; then - languages=(["ca"]="ca-ES") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-cs" ]; then - languages=(["cs"]="cs-CZ") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-eo" ]; then - languages=(["eo"]="eo") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-de" ]; then - languages=(["de"]="de-DE") - elif [ ! -z ${1+x} ] && [ "$1" == "--light-it" ]; then - languages=(["it"]="it-IT") - else - # Supported languages - languages=( - ["ar"]="ar" - ["vi"]="vi-VN" - ["hu"]="hu-HU" - ["th"]="th-TH" - ["fi"]="fi-FI" - ["nl"]="nl-NL" - ["gd"]="gd" - ["el"]="el-GR" - ["es"]="es-ES" - ["oc"]="oc" - ["pt"]="pt-BR" - ["pt-PT"]="pt-PT" - ["sv"]="sv-SE" - ["pl"]="pl-PL" - ["ru"]="ru-RU" - ["zh-Hans"]="zh-Hans-CN" - ["zh-Hant"]="zh-Hant-TW" - ["fr"]="fr-FR" - ["ja"]="ja-JP" - ["eu"]="eu-ES" - ["ca"]="ca-ES" - ["cs"]="cs-CZ" - ["eo"]="eo" - ["de"]="de-DE" - ["it"]="it-IT" - ["kab"]="kab" - ) - fi + npm run ng build -- --prod --output-path "dist/build" for key in "${!languages[@]}"; do lang=${languages[$key]} - # TODO: remove when the project will use runtime translations - pre_build_hook "$lang" + mv "dist/build/$key" "dist/$lang" - npm run ng build -- --prod --configuration="$lang" --output-path "dist/build" + if [ "$lang" != "en-US" ]; then + # Do not duplicate assets + rm -r "./dist/$lang/assets" + fi + done - # If --localize is not used - mv "dist/build/$key" "dist/$lang" - rmdir "dist/build" + mv "./dist/$defaultLanguage/assets" "./dist" + mv "./dist/$defaultLanguage/manifest.webmanifest" "./dist/manifest.webmanifest" - # If --localize is used - # if [ ! "$lang" = "$key" ]; then - # mv "dist/$key" "dist/$lang" - # fi + rmdir "dist/build" +else + additionalParams="" + if [ ! -z ${1+x} ] && [ "$1" == "--analyze-bundle" ]; then + additionalParams="--namedChunks=true --outputHashing=none" + export ANALYZE_BUNDLE=true + fi - # Do not duplicate assets - rm -r "./dist/$lang/assets" + if [ ! -z ${1+x} ] && [ "$1" == "--i18n" ]; then + additionalParams="--configuration=i18n" + export ANALYZE_BUNDLE=true + fi - # TODO: remove when the project will use runtime translations - post_build_hook - done + npm run ng build -- --localize=false --output-path "dist/$defaultLanguage/" --deploy-url "/client/$defaultLanguage/" --prod --stats-json $additionalParams fi cd ../ && npm run build:embed && cd client/ diff --git a/scripts/i18n/generate.sh b/scripts/i18n/generate.sh index f9c2f0613..0d1cd35c0 100755 --- a/scripts/i18n/generate.sh +++ b/scripts/i18n/generate.sh @@ -2,9 +2,13 @@ set -eu +npm run build -- --i18n + cd client -npm run ng -- xi18n --i18n-locale "en-US" --output-path src/locale --out-file angular.xlf -npm run ngx-extractor -- --locale "en-US" -i 'src/**/*.ts' -f xlf -o src/locale/angular.xlf +./node_modules/.bin/localize-extract -r . -f xliff --locale "en-US" -s 'dist/en-US/*.js' -o src/locale/angular.xlf + +# Workaround of https://github.com/angular/angular/issues/38437 +sed -i 's/other {{INTERPOLATION}/other {/g' src/locale/angular.xlf # Merge new translations in other language files npm run ng run -- PeerTube:xliffmerge -- cgit v1.2.3