]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Migrate to $localize
authorChocobozzz <me@florianbigard.com>
Wed, 12 Aug 2020 08:40:04 +0000 (10:40 +0200)
committerChocobozzz <me@florianbigard.com>
Fri, 14 Aug 2020 08:28:30 +0000 (10:28 +0200)
 * 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

136 files changed:
client/angular.json
client/package.json
client/src/app/+about/about-instance/contact-admin-modal.component.ts
client/src/app/+accounts/account-about/account-about.component.ts
client/src/app/+accounts/account-videos/account-videos.component.ts
client/src/app/+accounts/accounts.component.ts
client/src/app/+admin/admin.component.ts
client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
client/src/app/+admin/config/shared/config.service.ts
client/src/app/+admin/follows/followers-list/followers-list.component.ts
client/src/app/+admin/follows/following-list/following-list.component.ts
client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts
client/src/app/+admin/follows/video-redundancies-list/video-redundancies-list.component.ts
client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts
client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts
client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts
client/src/app/+admin/plugins/shared/plugin-api.service.ts
client/src/app/+admin/system/jobs/jobs.component.ts
client/src/app/+admin/system/logs/logs.component.ts
client/src/app/+admin/users/user-edit/user-create.component.ts
client/src/app/+admin/users/user-edit/user-password.component.ts
client/src/app/+admin/users/user-edit/user-update.component.ts
client/src/app/+admin/users/user-list/user-list.component.ts
client/src/app/+login/login.component.ts
client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-create.component.ts
client/src/app/+my-account/+my-account-video-channels/my-account-video-channel-update.component.ts
client/src/app/+my-account/+my-account-video-channels/my-account-video-channels.component.ts
client/src/app/+my-account/my-account-history/my-account-history.component.ts
client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts
client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.ts
client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts
client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts
client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts
client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts
client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts
client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts
client/src/app/+my-account/my-account-videos/my-account-videos.component.ts
client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts
client/src/app/+my-account/my-account.component.ts
client/src/app/+reset-password/reset-password.component.ts
client/src/app/+search/search-filters.component.ts
client/src/app/+search/search.component.ts
client/src/app/+signup/+register/register.component.ts
client/src/app/+signup/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts
client/src/app/+signup/+verify-account/verify-account-email/verify-account-email.component.ts
client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts
client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts
client/src/app/+video-channels/video-channels.component.ts
client/src/app/+videos/+video-edit/shared/i18n-primeng-calendar.service.ts
client/src/app/+videos/+video-edit/shared/video-edit.component.ts
client/src/app/+videos/+video-edit/video-add-components/video-import-torrent.component.ts
client/src/app/+videos/+video-edit/video-add-components/video-import-url.component.ts
client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts
client/src/app/+videos/+video-edit/video-update.component.ts
client/src/app/+videos/+video-watch/comment/video-comment.component.ts
client/src/app/+videos/+video-watch/comment/video-comments.component.ts
client/src/app/+videos/+video-watch/recommendations/recommended-videos.component.ts
client/src/app/+videos/+video-watch/video-duration-formatter.pipe.ts
client/src/app/+videos/+video-watch/video-watch-playlist.component.ts
client/src/app/+videos/+video-watch/video-watch.component.ts
client/src/app/+videos/video-list/video-local.component.ts
client/src/app/+videos/video-list/video-most-liked.component.ts
client/src/app/+videos/video-list/video-recently-added.component.ts
client/src/app/+videos/video-list/video-trending.component.ts
client/src/app/+videos/video-list/video-user-subscriptions.component.ts
client/src/app/app.component.ts
client/src/app/app.module.ts
client/src/app/core/auth/auth.service.ts
client/src/app/core/hotkeys/hotkeys.component.ts
client/src/app/core/notification/notifier.service.ts
client/src/app/core/rest/rest-extractor.service.ts
client/src/app/core/routing/can-deactivate-guard.service.ts
client/src/app/core/users/user.service.ts
client/src/app/menu/menu.component.ts
client/src/app/modal/confirm.component.ts
client/src/app/shared/shared-abuse-list/abuse-details.component.ts
client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts
client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts
client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts
client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts
client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts
client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts
client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts
client/src/app/shared/shared-forms/form-validators/login-validators.service.ts
client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts
client/src/app/shared/shared-forms/form-validators/user-validators.service.ts
client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts
client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts
client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts
client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts
client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts
client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts
client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts
client/src/app/shared/shared-forms/form-validators/video-validators.service.ts
client/src/app/shared/shared-forms/input-readonly-copy.component.ts
client/src/app/shared/shared-forms/preview-upload.component.ts
client/src/app/shared/shared-forms/reactive-file.component.ts
client/src/app/shared/shared-forms/select/select-checkbox.component.ts
client/src/app/shared/shared-instance/instance-features-table.component.ts
client/src/app/shared/shared-main/account/actor-avatar-info.component.ts
client/src/app/shared/shared-main/account/avatar.component.ts
client/src/app/shared/shared-main/angular/from-now.pipe.ts
client/src/app/shared/shared-main/buttons/delete-button.component.ts
client/src/app/shared/shared-main/buttons/edit-button.component.ts
client/src/app/shared/shared-main/misc/help.component.ts
client/src/app/shared/shared-main/shared-main.module.ts
client/src/app/shared/shared-main/users/user-quota.component.ts
client/src/app/shared/shared-main/video/video.service.ts
client/src/app/shared/shared-moderation/abuse.service.ts
client/src/app/shared/shared-moderation/account-blocklist.component.ts
client/src/app/shared/shared-moderation/batch-domains-modal.component.ts
client/src/app/shared/shared-moderation/report-modals/account-report.component.ts
client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts
client/src/app/shared/shared-moderation/report-modals/video-report.component.ts
client/src/app/shared/shared-moderation/server-blocklist.component.ts
client/src/app/shared/shared-moderation/user-ban-modal.component.ts
client/src/app/shared/shared-moderation/user-moderation-dropdown.component.ts
client/src/app/shared/shared-moderation/video-block.component.ts
client/src/app/shared/shared-thumbnail/video-thumbnail.component.ts
client/src/app/shared/shared-user-settings/user-interface-settings.component.ts
client/src/app/shared/shared-user-settings/user-video-settings.component.ts
client/src/app/shared/shared-user-subscription/subscribe-button.component.ts
client/src/app/shared/shared-video-miniature/abstract-video-list.ts
client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts
client/src/app/shared/shared-video-miniature/video-download.component.ts
client/src/app/shared/shared-video-miniature/video-miniature.component.ts
client/src/app/shared/shared-video-miniature/videos-selection.component.ts
client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts
client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts
client/yarn.lock
scripts/build/client.sh
scripts/i18n/generate.sh

index 06223b837f55f7b5134a81941c4df465d2455705..c893cc1e9d3829941e2a7ee4993241182194ce8c 100644 (file)
           "builder": "@angular-devkit/build-angular:browser",
           "options": {
             "aot": true,
+            "localize": true,
             "outputPath": "dist",
             "index": "src/index.html",
             "main": "src/main.ts",
               "budgets": []
             },
             "hmr": {
+              "localize": false,
               "budgets": [
                 {
                   "type": "anyComponentStyle",
               ]
             },
             "e2e": {
+              "localize": false,
               "budgets": [
                 {
                   "type": "anyComponentStyle",
                   "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" ]
             }
           }
         },
index 3c4b9ead4bc3a5cd3da147ccf88a52ef4f235503..9769cc813af27845ba44b7d7d3df234215bf08a7 100644 (file)
   "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",
index 5199402e6f636be6dcae9b77a135d46050bc92db..215e281bb5fcf5ee352bb3d6715782236f7fa43b 100644 (file)
@@ -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
           }
         )
index 8c01e4007d270018a5011409375d69f72bdd295e..6cf846d72bf45f438e11795f101a7cd3c7438f93 100644 (file)
@@ -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`
   }
 }
index 5a9241f8ee1e94f4d1ed6b339759dcd0d6876866..3134a8ee2d7197e40209668f3ffb986ba83e5cb7 100644 (file)
@@ -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`
                  })
                )
   }
index 9288fcb42bfbe0fcc0415705b5d7da47e1031450..bbce62c35389442c0e23aa65c4fd17d6eee1697d 100644 (file)
@@ -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()
               }
             ]
index 66e068c4ccaeb718b6940a16a53559e53be7d8b3..b661a5517e1f61130f1202b29f6ea3fad58b3f72 100644 (file)
@@ -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' })
     }
   }
 
index 00a0bfad201c47633630a8f31657ae52ab4a9423..3a60b144f7f738bdf78e30b449973da2f4a56875 100644 (file)
@@ -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 <code>.mp4</code> that keeps the original audio track, with no video')
+        label: $localize`Audio-only`,
+        description: $localize`A <code>.mp4</code> 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)
index f182946b86ced6e42112150d53681cfc63b0fc02..5f98aa5450e77f96db9a6d012577b8b1a5b8b471 100644 (file)
@@ -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` }
     ]
   }
 
index 63135f898212a9dbb6b5eaa1b8dd57223da2cc52..904e3c338a90d06aab05a810c851daf8b0e525fd 100644 (file)
@@ -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()
           },
index dae8923b5e5e2918a301384e71a6ca68ece347e2..5f71f123880f30387b0987f6ebf7c7c3a4aee304 100644 (file)
@@ -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()
       },
 
index 662143abcf0713ba784eef8ae50a68fb6d19970e..729b7f5991350876e186bc0fd00efb6a93a592d3 100644 (file)
@@ -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)
index 07e2e0ff3363056102c00c8497b54ece2ee9acd2..d6fd1a1ab62e020237832ccc18848e6a5a65a67f 100644 (file)
@@ -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()
         },
 
index 422d873c054c291dbb8ead3a4d4d541f0cb7568b..2b1ef663c88095b84033ff4b80062f13efbaeb63 100644 (file)
@@ -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()
       },
 
index af31f114444888f6e6c5d888ebcd0c69fde1d5ac..1ffd001c6e52a7c24f093d8ebc33374c75b10f2b 100644 (file)
@@ -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<any[]>()
 
   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)
           },
index ccf9f1ed50775f3f78a163f395b82537aff010a7..1a6b4eba3ecf50c88aa7fdcc254c3ebf2291c096 100644 (file)
@@ -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<string>()
 
   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
           },
index dde03f1da71b3ff1b182c5ff29e794e8f277b367..a33f0169106ae99a50475aebcfa530eac13857f5 100644 (file)
@@ -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)
index 1fb8278320a2633a57bada9779a89b950cb67e36..b28d46df4a199e7407a384cb1a6eb20318b2906b 100644 (file)
@@ -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 (
index ceb848976a9e919b2241dfa6a4164ee40167f1b5..96e0f25b00b41e1511487c45714ab7d459567af8 100644 (file)
@@ -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()
   }
 
index 51f04718817eb9b3331770b1ed9807ba84787542..c9c9dc3d147c0e81492a55829bb2b85fb7e2c46e 100644 (file)
@@ -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`
       }
     ]
 
index 3fddb9c09f24fa0cc3a7e8fa4f7612a38531ed6e..36d71a9273248634349c22013a6c325fb658115d 100644 (file)
@@ -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`
   }
 }
index 33c7de31f23172b26f9ac39c967f478a776aebbc..25f13495aa830730db9c505112eff83d3933cbf3 100644 (file)
@@ -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`
   }
 }
index 870880feeb25ad7432de307ee6a2800f8e6133de..55bc7290e5930472d32ad16b5fa9cfc774d9306c 100644 (file)
@@ -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
index 69d4e917dfbc1e01acf4fb70a8df140efeb88746..86812f73d1b48126682129f42b13e113fb77038d 100644 (file)
@@ -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()
       },
 
index e5a38221859dfe4ffd22fa0bbaf199e4c994d9bc..e9336172e8b8e5f904d80479999ed745d3b27bd4 100644 (file)
@@ -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
   }
 }
index 039c389e4ebb72d21192471a770a4555429beaae..5c438c3bf537a7de1b00c3455ddd0f127cda2820 100644 (file)
@@ -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`
   }
 }
index 489c437ead10eb8b5a777783b6eaed566d955005..485521dcc2b43c2e1baef938ba6cb251739212c4 100644 (file)
@@ -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 () {
index ad9368794da674c9233f7b9331a5c21673e24a70..2aff09cd9659adf96edd14b8c1cc2d4edd3c436e 100644 (file)
@@ -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
index dc78b3d6ef90845cd41cfbd408ff8afa27da7690..3298c56c737da60debf6b08e01b3cf8e32f5b4ff 100644 (file)
@@ -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()
           },
index 0e62b5ca545c2e9c146e6d0ad23f4cf60936c3eb..3bfffe2da61770dc56f1822df774041e68f1d293 100644 (file)
@@ -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
         },
index 5444b97ae74f241cee1f8b217c81f110e9f6d014..396936ef3927b248c44ab16557a9674c8f109c2a 100644 (file)
@@ -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
           }
 
index 6a16f8a2c6d05db374b55f54e92aea293e38c111..91fe4ec72472beec3d2fc414ba66f479ed9291ef 100644 (file)
@@ -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
         }
 
index ae6ac538720fb4c9266b31134bd732cc28953179..387e9e7cd6aa251025416461982792402808ddfd 100644 (file)
@@ -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()
index b892ab4792b7199b67e95bb823e32398ce7d926e..bcbea7fad1e608bacdf49089d7156d3373cca8d5 100644 (file)
@@ -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)
index b0d8494e711709c72ca815563ea09f25d76d3226..ed0984bf7d780250af74690944d2f3e02d506d1a 100644 (file)
@@ -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
index a3a8ff1f19020555159b8671cdd493e32123f8a1..7ea4610d47bba6a40992bcd79070ec95082821ee 100644 (file)
@@ -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)
         },
index e72ae236634b5c178a475e022f82916977605814..5427dc3a01ff81f324d7c42feefafffadf33b5a6 100644 (file)
@@ -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`
   }
 }
index e278d9ed2f69526c729dd1e15d422d95118f5a77..f6cdf10674edcbe36414abe6c74e3efddce18afa 100644 (file)
@@ -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)
index 6787fb757a9941a3807bdfdc9cdaa6171cf1726b..149d0d94f6af0436f11dd04ebf79ab40dce83168 100644 (file)
@@ -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 () {
index ba95b6c8b4deae060cc0fa3cd64d5ef52eb362eb..1e569c0b68789852c6016063416c3a3a7e33b49c 100644 (file)
@@ -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)
index 2274c6a7b0f2a9e50c6b902be70c2d7944f84d03..46a02a41a4e0631a0590547daba7ed995859b24e 100644 (file)
@@ -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)
           },
 
index 18e716a098eef29f80135d955dc482010387a57e..edd6916940f9d83c7e7fc5484e442f704980b282 100644 (file)
@@ -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)
       )
index 56373e5f18efd08080eaeb17c8c5476f5b26c734..d3bf8d143ac40f3f40e65aec40d515461789dc5f 100644 (file)
@@ -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,
index 8d50e983934713370e0d829330081219e5f4c3ad..16e4f4090c84c62e3170f051d4a13cadbfd47680 100644 (file)
@@ -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' ])
         },
 
index 13ad61647412d449e64a54450fdd07b474c14060..a2af9a9427a3b3ab3a2ef0fed56a1c5628421475 100644 (file)
@@ -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`
       }
     ]
   }
index 70116fab387bc890441e9f0adcdbe457257f55c0..2be952e161b9306b9afafaa1ba651dc3e4123d85 100644 (file)
@@ -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 () {
index 3e8171b27ce52ff24a81bda2e54100cdee9f750f..153a6d2b580ea57f0fd7811783038729b9b6810e 100644 (file)
@@ -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
index 51910471be9e5abc0143bfcab4c5439203668ad1..b26581d2bae5cb59ec23e00df5e726a604e850ae 100644 (file)
@@ -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()
         },
 
index 586f4e2315443a19b42b26422a3ee18fd5a69d28..acc688ab3f34ae7a3ef48b870ae74b2c6a2a4841 100644 (file)
@@ -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()
     }
index 19e4bc1f45be9ef3da170d8ec997ca83bb674dad..537c7d08e385fc825bf5aba523a41a53fb7f3cb9 100644 (file)
@@ -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`
   }
 }
index 599d38da9572c61851031d43a9bd933685e0fc9c..e1ec6bbcbc469091e540b8e4b645f83510464b6d 100644 (file)
@@ -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`
                  })
                )
   }
index cae442ee7d82e739547741e7dab911d241887bca..ea8bda1cf7df5c22653d24e44438e338132d462f 100644 (file)
@@ -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`)
   }
 }
index b05852ff8f74699cd90e659e65d74bb2ae8618ce..2acbace48d30e7dd7c60c51c295e053ff6299b21 100644 (file)
@@ -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`
   }
 }
index ba3b7c96a1cd0700fa4b2c559dd1e194dbf97d41..050b6d931b38f7ed90338ae11b7ff562960563b8 100644 (file)
@@ -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`
           })
         }
       })
index 3a8e6eeccc5d1132cb9c97f653fe27457793028c..e9ad8af7a4be01ded86812ed302fd88772008950 100644 (file)
@@ -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' ])
           },
index da25663d75eaae43d954ae20685ac5f22ac341e3..8bad810977e1197ee62e1d7db6e9ed8df883774c 100644 (file)
@@ -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' ])
           },
index e18e3c9a775342cef28498b28a8daad72971992e..416b655a45ead9310e0822731d5a6c206722ed0d 100644 (file)
@@ -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
index abd08f05c17c8819bc152397d7dd98e02f824dbc..2e1d0f89d59f8d8ea644e45f289c08463f966581 100644 (file)
@@ -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 ])
           },
 
index 36ec6e9f9d63521a26271b66b520278d97ce04d0..a84e91fd323171a4286d7e5ad76533a51de32400 100644 (file)
@@ -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()
         }
       ]
index 66494a20abbf12e6d8dbb4ea7b687cb09aedf268..517844ab2fc95ac34fcf24f589a078cd41d08c22 100644 (file)
@@ -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)
index d2372023f323f2c9de6141a6c9e43a1f02284e02..a1c8e0661c19c55aec0f7c819d89a20922268951 100644 (file)
@@ -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 () {
index 4b6767415796286cad69ff764aaf91e2cf97d25e..19b34f98483123ccf25077b05f1bcbf708e5e80b 100644 (file)
@@ -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`
   }
 }
index 519ce29741921048470b18e423f2e30e451e714b..c60ca46713907f48367d4631a25e29645b4cccb8 100644 (file)
@@ -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`
   }
 }
index a53af210a991bd5750c5b6873d388c4b3bd729f1..fb89bf6cd0be9a0023a0cb431fb7334cafa7496f 100644 (file)
@@ -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`)
       ])
     }
 
index b4c71ac4984e99954fe735b73cceaeb6521f6ea2..07063d4d4b1bed36e0783e36f7dc1c7349d80bfb 100644 (file)
@@ -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 () {
index ca14851bbd39e174cccae0724852a108dcc08382..e5f7bd15226a1a2b0ac9f04a8ef514cdf99e0d51 100644 (file)
@@ -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) {
index c9395133f61da8a4de8dc537bc6a2bb86cfc8f71..34db6aabd0eade8dc214e891bb10a69693e20411 100644 (file)
@@ -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 () {
index 10eab18de0b2d6eac97ebf09a49db3ad61c22f29..babcb9067b42d522cdcae5a33778613350ffd0ef 100644 (file)
@@ -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`
         }
       })
   }
index 41ad9b27791d082012ae1fedef72cbc74d42c4ce..b02988169c84d9fc8ba94be1e297f916755175bf 100644 (file)
@@ -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'
     })
   }
index ee95d2cbb47c589eb2d43c14f56bcec6a666d932..ef0b1ae56efff122389b63638169bd570b238491 100644 (file)
@@ -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`)
     ])
   }
 }
index b35cc1716c635ee6a901c1cd21119687e10ed838..5c46161532442980ea9cb48d67cd4a66324e55f6 100644 (file)
@@ -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 {}
index d3dc48267d9be6440df42420125189fe14aa7842..10e2c2c58a6c026786730ecf588901a10b5da3c0 100644 (file)
@@ -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<AuthStatus>()
     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()
index 512a2399a545677f5a991fd0a06665b02192bcfc..315e1a25e26782b18e034159bc6004b1b995cd3e 100644 (file)
@@ -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) => {
index 9833c65a02b1a7591f1ee4011dd186c3643299bb..f736672bb5ce0a468135269df9cc91c739284a4a 100644 (file)
@@ -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)
   }
index 9de964f79b01a847c741eba14f3a112aec736d44..36702b3712e28d21adf12148bd779f1d6b9f05f3 100644 (file)
@@ -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.'
index e0405293ae95884cf0d08fc153922bda42f0b2a7..8fce495e984f98bd3ffe5cb6f56c828ea736011a 100644 (file)
@@ -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> | boolean }
 
@@ -12,18 +11,16 @@ export interface CanComponentDeactivate {
 
 @Injectable()
 export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
-  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`
     )
   }
 
index 6e7a485192d76946b585bdb7b0a07cd58b463982..01c9be5bf6ff099a8ee59aae02b9591e25588ae2 100644 (file)
@@ -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, {
index 2c55b9a8482f8cfaecf6bf7ed56117a93527fe3c..3d6cbda24a991492c791e2f3c61a9be102b7308f 100644 (file)
@@ -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
     }
 
index 2c7ef46c4d4686422fec06d5202c7341271d99b8..457dd1f3f5eaae74671f7d513d4dc6f7e7ad7c7e 100644 (file)
@@ -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()
       }
index 0e872079a58124e5fc83ee80514f3c093eda5488..282a6fe1945c60af2dffd92a7d501ab298be4e19 100644 (file)
@@ -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`
     }
   }
 
index c7dc5f4d24ab3ab1e590e7050cee50e720f761e7..cc933db0db1b0f1b49a111f51fa87ad3d357c9c1 100644 (file)
@@ -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<ProcessedAbuse>[] {
     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)
index 6686d91f4ea3de8c0794956cc54fd2604c2d6fc2..0c3c8ff48a7218d5930a719b3853a7c112895a3f 100644 (file)
@@ -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 () {
index ecb7966bfc636f784dedf7f93a109876a164d27a..fad7f888da5c71788c3182745c7e4894dd2104f6 100644 (file)
@@ -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()
index 5f15963f326f6e79fe25aa0c11056621b745dee3..56d30d6f98944a7aaa23cffc85c5c93f999d4d63 100644 (file)
@@ -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.`
       }
     }
   }
index f270b602b373bb108eb6dae7942c98dc93b1ce5b..6c7da833fc7364eaaf124e81f78835511e574c85 100644 (file)
@@ -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`)
       }
     }
 
index c77aba6a1050c5e43be2e066a001d44b2ffa236d..862ff54709662f14b4e2c9880b328b4967b9346e 100644 (file)
@@ -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`
       }
     }
   }
index 96a35a48f6a69e3bae22f116b952eab35e00d96d..3628f0b60e8d69532ec6325fb3e2f19d1cd8a8a1 100644 (file)
@@ -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.`
       }
     }
   }
index a5837357e2120893483ea41d4b4a7b4cf80a609b..67ea11f20b75bf0124e3f420b5954ddc8aa58113 100644 (file)
@@ -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.`
       }
     }
   }
index d2085a309e90968b0243d82517063608049d5063..3d0b4dd6479b27767ca02e6f8fdf8d4aee5ecd40 100644 (file)
@@ -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.`
       }
     }
   }
index 61486bbab85540171e9021c3e286de9b51a2c7de..312fc9b1e3bf873443a3d9c5f027e341d08aef20 100644 (file)
@@ -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.`
       }
     }
 
index 998d616eceb862b49bef44ef9c4577d936f79542..aed9e9cdd2a97804fdbf32b5a0d5992a313b311a 100644 (file)
@@ -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.`
       }
     }
   }
index ddf0ab5ebaa3271539da95ef72560dd149be342a..bce1880dc9fbf204c4e9dd1a347fbe151d9f6a44 100644 (file)
@@ -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.`
       }
     }
   }
index 280d28414927b915d709ffb9cddfa08d322f1f21..7e90264e5e68f3459cd99528c726e1c0789fbd6a 100644 (file)
@@ -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.`
       }
     }
   }
index 59659defdb33e62aa4e06f40b8f87d0720896f1f..8c809a0d57b25d08e0fe72d401397d84a55b2919 100644 (file)
@@ -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`
       }
     }
   }
index bb650b149eedec8e5232519068913a3de80f7bcf..3e74441967785a37e87c1923bd2f26bcd05f470b 100644 (file)
@@ -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`
       }
     }
   }
index 97c8e967e8982ae838d7774904e2b5e24c039a6f..18e7ae2648f9ef21bae6b762b2cf9ceb1bb74963 100644 (file)
@@ -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.`
       }
     }
   }
index ab9c43625b253be0aff3374ccfdbf3e0564485d7..3b45a40fd2e41642907caa24e647721f30117274 100644 (file)
@@ -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.`
       }
     }
   }
index c96e4ef66b37243871a0a60250493ad42b6e71e3..8119c1ae72652b2cd6385b242f3ca63360722572 100644 (file)
@@ -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.`
       }
     }
 
index 7528fb7a1cd46ba657bfd2beec6d10ad73a72128..a67b0c6910f9ccd330b6768c85c3589038b2d7a7 100644 (file)
@@ -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`)
   }
 }
index 7afff0b314ede5753d2567def337691d72294040..a55dcdd9a636671ab80ead85383173ccfa79d13a 100644 (file)
@@ -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 () {
index 9ebf487ce24396de691d8758801098c01ab898a1..eeb2a3fd8fb869c06f9143434e6070ea8b221eb6 100644 (file)
@@ -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
index fd683ae5d1a382d789bedbeca53e6f75323d0ef5..eb0c49034c126dbe4e0f7416d48c3fc68bf16bf4 100644 (file)
@@ -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 */ }
index 8fd15ebadad2bed015c4727630cee165bd75f3eb..76b595c20e3bf2c95433e5bd6b8cc49dd7aed06c 100644 (file)
@@ -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('<br />')
index 1389218ccc392fca316648090547fb218048219e..3a86e5b21a482fd239fd75a1d80fbdd161e9bd2c 100644 (file)
@@ -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 {
index 73c145ef9e5cfc5ea524101c42b65586f9a2fd7c..2967828a05396a404a3aec1f68905070e5c190a1 100644 (file)
@@ -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 () {
index 9851468ee993538cb23f2e25302d1ad2d581f9e5..5d85590bb11194a94c590948213c52f48dca06d4 100644 (file)
@@ -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`
   }
 }
index aced0f881308b788bbe2d3448b8af4c81505e794..18995422a4cfc425fac044744c99abf4fd0fac54 100644 (file)
@@ -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 () {
     // <my-delete-button /> No label
     if (this.label === undefined && !this.title) {
-      this.title = this.i18n('Delete')
+      this.title = $localize`Delete`
     }
 
     // <my-delete-button label /> Use default label
     if (this.label === '') {
-      this.label = this.i18n('Delete')
+      this.label = $localize`Delete`
 
       if (!this.title) {
         this.title = this.label
index d8ae39b84c58c290a206aa7a97bb54bd9a60c6bb..4b76551ca93c84b73aeafdf9669b7713fcd1eb60 100644 (file)
@@ -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 () {
     // <my-edit-button /> No label
     if (this.label === undefined && !this.title) {
-      this.title = this.i18n('Update')
+      this.title = $localize`Update`
     }
 
     // <my-edit-button label /> Use default label
     if (this.label === '') {
-      this.label = this.i18n('Update')
+      this.label = $localize`Update`
 
       if (!this.title) {
         this.title = this.label
index 0825b96de3acea29eafa14e969b3c8332e6c571e..ebc965a889787a127c6ba214984c360a0afb950c 100644 (file)
@@ -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<any>
   postHtmlTemplate: TemplateRef<any>
 
-  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('<a href="https://en.wikipedia.org/wiki/Markdown#Example" target="_blank" rel="noopener noreferrer">Markdown</a> compatible that supports:') +
+    return $localize`<a href="https://en.wikipedia.org/wiki/Markdown#Example" target="_blank" rel="noopener noreferrer">Markdown</a> 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])
index 6186db4d6dc2c4538491f6c47278330f76bfdd06..7f4676dd14807225a830a571c0fdd24ef01df095 100644 (file)
@@ -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,
index 6830ad8fec46a1b97c5d5f66200e21c0c579e0f8..b38619186016d89fb4156edc0a6057f9b3772fd1 100644 (file)
@@ -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`
         }
       }
     )
index 978f775bf9af426c127609dcaecf55de7b75e8ff..b01e919aaed9b2cac852392b05ddf2e5d50a8ec3 100644 (file)
@@ -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`
       }
     ]
 
index 06b236d1e6a542c3de1e6d8957ec1eebdf41efbc..bf98d4b36d6b294ba0aa7de041372f6595e844ab 100644 (file)
@@ -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).`
         }
       ])
     }
index a5a3c27cd0cb279c9d916425425165701831dc00..68928a2c27af677f2e975874458d1c82b6db8db5 100644 (file)
@@ -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()
index fdd4a79a9eeed33f9738b33fb7c289c371117d82..7193ccb1b12e189e78b5401504e6672258db3137 100644 (file)
@@ -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
index 08dbe95381b30971017ae2564cd21e8ebac98cbb..8ab2fe940af8734b77dd198cbec4bc3b94e0a28d 100644 (file)
@@ -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()
       },
 
index 2769874d9ad18345ad4a7e1f4fe641522ed24d7e..d75f4d7173293f05d410dff3a5d1e2dc34b268b0 100644 (file)
@@ -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()
       },
 
index 794dd54bb6947f2a73002c22cf2338b2768cdd3d..edff6d325fd6575ab67e55b4c1a2a26b41f8ac9a 100644 (file)
@@ -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()
       },
 
index 8f65cdb715e3c1b0d1071df6688ceebcbb3f5338..546fd53c395eebf6ee913d2eb9e1491357fc5931 100644 (file)
@@ -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()
index 124e5866904cf1a49682f58ce900d12ace273955..f9a0381c5b0383db1aeeb8df0288fb23ff2c5e70 100644 (file)
@@ -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)
 
index 34fa7366cc4fd257223fabf80a44b1f200a9dd97..44aefa853b2b4428ddb145865303ef906c31d9df 100644 (file)
@@ -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' })
             }
           ])
index 054651e717b894b875989f5debeb1cc80c74208d..2bef9efdd770b5a11a41fdc9ff9e085b412c0625 100644 (file)
@@ -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
index 812c7a50880110dbdcf02533c88781e0befcec4c..b2a2cf240e11c24a57b26873b81acffb2db6b7f4 100644 (file)
@@ -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 () {
index 875ffa3f1b20540918f7b8f9647487fd3285614f..80b88c12978079cdc9f6ceccd8a3a01acca0c84f 100644 (file)
@@ -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.`)
     }
   }
 }
index eb340e24dfcb904638723f12079a9ccaf96b4631..ab77f6f9c3c9ba0eabd519d2e34d4e1113996830 100644 (file)
@@ -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')
-  }
 }
index 72fa3f4fd4240cef2435992d0110be8f42a8b3c2..b918fda06afa5cea836bc0cfe24ecd9b04d735b4 100644 (file)
@@ -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`
           )
         },
 
index e18002b74199d637b96bb5890f39edeb55f7da5f..1b5b8a64b00e00600d41d24fb506e6987756a3a5 100644 (file)
@@ -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)
index 3d1fc8690e85fc9e1ef695d8e8d9ff61e84d0e08..39358e08b7817ef81bc192f9cf165457a41141eb 100644 (file)
@@ -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'
index e3d6a1969ee62a82f7287f49fe8bec82944c97d6..99838f712b22f4501598d54a97e2c522c90406c7 100644 (file)
@@ -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 })
       })
     }
 
index 3c7046de5b2becc74bf57eb8bc627466ff35541b..cc5665ab1483cb0a0f8cd3324ad369124e64e056 100644 (file)
@@ -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 ''
index 3e0e3b98309ead370e94299d2c8a832be500e852..2b060b1300dd195b9cee466200f49d69258dced9 100644 (file)
@@ -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<any>
 
   constructor (
-    protected i18n: I18n,
     protected router: Router,
     protected route: ActivatedRoute,
     protected notifier: Notifier,
index f611fc46b4c11512a00364ce386ead23b16a2355..757ffa099791eafe62ac735cb0c49ee16cfb31e5 100644 (file)
@@ -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)
         },
index 57a5fbe619caca89a7c015e9011b1f6658cbfb25..5879c49781354541ffa143be8c9a0f9b00c5280d 100644 (file)
@@ -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 () {
index 4fe21c1a563e392167cfaf8a48cfc42c180970f7..db52a4a544ee6b0295f7676b861d4b4709e8ad03 100644 (file)
     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"
 
     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"
     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"
 
   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"
index 644a0807f2f7026baa5ee09480aa510cf051cb25..9cd8d8cce92229aa1c46c795472c76fb74980527 100755 (executable)
 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/
index f9c2f0613e21aaa99a10af3fc8c66a49bc766764..0d1cd35c0ea15d5b13ee339c55cc9d7ff93f4220 100755 (executable)
@@ -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 {<x id="INTERPOLATION"\/>/g' src/locale/angular.xlf
 
 # Merge new translations in other language files
 npm run ng run -- PeerTube:xliffmerge