From 66357162f8e1227495f09bd4f68446aad7071c6d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 12 Aug 2020 10:40:04 +0200 Subject: Migrate to $localize * Remove i18n polyfill to translate things in components * Reduce bundle sizes * Improve runtime perf * Reduce a lot the time to make a full client build * Reduce client build complexity * We don't need a service to translate things anymore (so we will be able to translate title pages etc) Unfortunately we may loose some translations in the migration process. I'll put a message on weblate to notify translators --- .../shared-abuse-list/abuse-details.component.ts | 21 ++--- .../abuse-list-table.component.ts | 77 +++++++-------- .../abuse-message-modal.component.ts | 10 +- .../moderation-comment-modal.component.ts | 8 +- .../form-validators/abuse-validators.service.ts | 23 +++-- .../batch-domains-validators.service.ts | 11 +-- .../custom-config-validators.service.ts | 41 ++++---- .../form-validators/instance-validators.service.ts | 27 +++--- .../form-validators/login-validators.service.ts | 9 +- .../reset-password-validators.service.ts | 7 +- .../form-validators/user-validators.service.ts | 63 +++++++------ .../video-accept-ownership-validators.service.ts | 7 +- .../video-block-validators.service.ts | 9 +- .../video-captions-validators.service.ts | 9 +- .../video-change-ownership-validators.service.ts | 9 +- .../video-channel-validators.service.ts | 27 +++--- .../video-comment-validators.service.ts | 11 +-- .../video-playlist-validators.service.ts | 21 ++--- .../form-validators/video-validators.service.ts | 33 ++++--- .../shared-forms/input-readonly-copy.component.ts | 8 +- .../shared-forms/preview-upload.component.ts | 6 +- .../shared/shared-forms/reactive-file.component.ts | 13 +-- .../select/select-checkbox.component.ts | 11 +-- .../instance-features-table.component.ts | 23 ++--- .../account/actor-avatar-info.component.ts | 6 +- .../shared/shared-main/account/avatar.component.ts | 15 +-- .../shared/shared-main/angular/from-now.pipe.ts | 27 +++--- .../shared-main/buttons/delete-button.component.ts | 7 +- .../shared-main/buttons/edit-button.component.ts | 7 +- .../app/shared/shared-main/misc/help.component.ts | 15 ++- .../app/shared/shared-main/shared-main.module.ts | 3 - .../shared-main/users/user-quota.component.ts | 10 +- .../app/shared/shared-main/video/video.service.ts | 16 ++-- .../app/shared/shared-moderation/abuse.service.ts | 34 ++++--- .../account-blocklist.component.ts | 10 +- .../batch-domains-modal.component.ts | 6 +- .../report-modals/account-report.component.ts | 8 +- .../report-modals/comment-report.component.ts | 8 +- .../report-modals/video-report.component.ts | 8 +- .../server-blocklist.component.ts | 12 +-- .../shared-moderation/user-ban-modal.component.ts | 8 +- .../user-moderation-dropdown.component.ts | 103 ++++++++++----------- .../shared-moderation/video-block.component.ts | 6 +- .../shared-thumbnail/video-thumbnail.component.ts | 10 +- .../user-interface-settings.component.ts | 8 +- .../user-video-settings.component.ts | 24 ++--- .../subscribe-button.component.ts | 26 ++---- .../shared-video-miniature/abstract-video-list.ts | 14 ++- .../video-actions-dropdown.component.ts | 53 ++++++----- .../video-download.component.ts | 36 ++++--- .../video-miniature.component.ts | 17 ++-- .../videos-selection.component.ts | 2 - .../video-add-to-playlist.component.ts | 8 +- .../video-playlist-element-miniature.component.ts | 13 +-- 54 files changed, 430 insertions(+), 574 deletions(-) (limited to 'client/src/app/shared') diff --git a/client/src/app/shared/shared-abuse-list/abuse-details.component.ts b/client/src/app/shared/shared-abuse-list/abuse-details.component.ts index 0e872079a..282a6fe19 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-details.component.ts +++ b/client/src/app/shared/shared-abuse-list/abuse-details.component.ts @@ -1,7 +1,6 @@ import { Component, Input } from '@angular/core' import { durationToString } from '@app/helpers' import { Actor } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AbusePredefinedReasonsString } from '@shared/models' import { ProcessedAbuse } from './processed-abuse.model' @@ -17,18 +16,16 @@ export class AbuseDetailsComponent { private predefinedReasonsTranslations: { [key in AbusePredefinedReasonsString]: string } - constructor ( - private i18n: I18n - ) { + constructor () { this.predefinedReasonsTranslations = { - violentOrRepulsive: this.i18n('Violent or Repulsive'), - hatefulOrAbusive: this.i18n('Hateful or Abusive'), - spamOrMisleading: this.i18n('Spam or Misleading'), - privacy: this.i18n('Privacy'), - rights: this.i18n('Copyright'), - serverRules: this.i18n('Server rules'), - thumbnails: this.i18n('Thumbnails'), - captions: this.i18n('Captions') + violentOrRepulsive: $localize`Violent or Repulsive`, + hatefulOrAbusive: $localize`Hateful or Abusive`, + spamOrMisleading: $localize`Spam or Misleading`, + privacy: $localize`Privacy`, + rights: $localize`Copyright`, + serverRules: $localize`Server rules`, + thumbnails: $localize`Thumbnails`, + captions: $localize`Captions` } } diff --git a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts index c7dc5f4d2..cc933db0d 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts +++ b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts @@ -1,16 +1,15 @@ import * as debug from 'debug' import truncate from 'lodash-es/truncate' import { SortMeta } from 'primeng/api' -import { buildVideoOrPlaylistEmbed, buildVideoLink } from 'src/assets/player/utils' +import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils' import { environment } from 'src/environments/environment' -import { AfterViewInit, Component, OnInit, ViewChild, Input } from '@angular/core' +import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core' import { DomSanitizer } from '@angular/platform-browser' import { ActivatedRoute, Params, Router } from '@angular/router' import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core' import { Account, Actor, DropdownAction, Video, VideoService } from '@app/shared/shared-main' import { AbuseService, BlocklistService, VideoBlockService } from '@app/shared/shared-moderation' import { VideoCommentService } from '@app/shared/shared-video-comment' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AbuseState, AdminAbuse } from '@shared/models' import { AbuseMessageModalComponent } from './abuse-message-modal.component' import { ModerationCommentModalComponent } from './moderation-comment-modal.component' @@ -45,7 +44,6 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV private videoService: VideoService, private videoBlocklistService: VideoBlockService, private confirmService: ConfirmService, - private i18n: I18n, private markdownRenderer: MarkdownService, private sanitizer: DomSanitizer, private route: ActivatedRoute, @@ -157,12 +155,12 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV } async removeAbuse (abuse: AdminAbuse) { - const res = await this.confirmService.confirm(this.i18n('Do you really want to delete this abuse report?'), this.i18n('Delete')) + const res = await this.confirmService.confirm($localize`Do you really want to delete this abuse report?`, $localize`Delete`) if (res === false) return this.abuseService.removeAbuse(abuse).subscribe( () => { - this.notifier.success(this.i18n('Abuse deleted.')) + this.notifier.success($localize`Abuse deleted.`) this.loadData() }, @@ -238,7 +236,7 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV if (abuse.comment) { if (abuse.comment.deleted) { - abuse.truncatedCommentHtml = abuse.commentHtml = this.i18n('Deleted comment') + abuse.truncatedCommentHtml = abuse.commentHtml = $localize`Deleted comment` } else { const truncated = truncate(abuse.comment.text, { length: 100 }) abuse.truncatedCommentHtml = await this.markdownRenderer.textMarkdownToHTML(truncated, true) @@ -267,38 +265,38 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV private buildInternalActions (): DropdownAction[] { return [ { - label: this.i18n('Internal actions'), + label: $localize`Internal actions`, isHeader: true }, { label: this.isAdminView() - ? this.i18n('Messages with reporter') - : this.i18n('Messages with moderators'), + ? $localize`Messages with reporter` + : $localize`Messages with moderators`, handler: abuse => this.openAbuseMessagesModal(abuse), isDisplayed: abuse => this.isLocalAbuse(abuse) }, { - label: this.i18n('Update internal note'), + label: $localize`Update internal note`, handler: abuse => this.openModerationCommentModal(abuse), isDisplayed: abuse => this.isAdminView() && !!abuse.moderationComment }, { - label: this.i18n('Mark as accepted'), + label: $localize`Mark as accepted`, handler: abuse => this.updateAbuseState(abuse, AbuseState.ACCEPTED), isDisplayed: abuse => this.isAdminView() && !this.isAbuseAccepted(abuse) }, { - label: this.i18n('Mark as rejected'), + label: $localize`Mark as rejected`, handler: abuse => this.updateAbuseState(abuse, AbuseState.REJECTED), isDisplayed: abuse => this.isAdminView() && !this.isAbuseRejected(abuse) }, { - label: this.i18n('Add internal note'), + label: $localize`Add internal note`, handler: abuse => this.openModerationCommentModal(abuse), isDisplayed: abuse => this.isAdminView() && !abuse.moderationComment }, { - label: this.i18n('Delete report'), + label: $localize`Delete report`, handler: abuse => this.isAdminView() && this.removeAbuse(abuse) } ] @@ -309,19 +307,19 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV return [ { - label: this.i18n('Actions for the flagged account'), + label: $localize`Actions for the flagged account`, isHeader: true, isDisplayed: abuse => abuse.flaggedAccount && !abuse.comment && !abuse.video }, { - label: this.i18n('Mute account'), + label: $localize`Mute account`, isDisplayed: abuse => abuse.flaggedAccount && !abuse.comment && !abuse.video, handler: abuse => this.muteAccountHelper(abuse.flaggedAccount) }, { - label: this.i18n('Mute server account'), + label: $localize`Mute server account`, isDisplayed: abuse => abuse.flaggedAccount && !abuse.comment && !abuse.video, handler: abuse => this.muteServerHelper(abuse.flaggedAccount.host) } @@ -333,19 +331,19 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV return [ { - label: this.i18n('Actions for the reporter'), + label: $localize`Actions for the reporter`, isHeader: true, isDisplayed: abuse => !!abuse.reporterAccount }, { - label: this.i18n('Mute reporter'), + label: $localize`Mute reporter`, isDisplayed: abuse => !!abuse.reporterAccount, handler: abuse => this.muteAccountHelper(abuse.reporterAccount) }, { - label: this.i18n('Mute server'), + label: $localize`Mute server`, isDisplayed: abuse => abuse.reporterAccount && !abuse.reporterAccount.userId, handler: abuse => this.muteServerHelper(abuse.reporterAccount.host) } @@ -357,18 +355,18 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV return [ { - label: this.i18n('Actions for the video'), + label: $localize`Actions for the video`, isHeader: true, isDisplayed: abuse => abuse.video && !abuse.video.deleted }, { - label: this.i18n('Block video'), + label: $localize`Block video`, isDisplayed: abuse => abuse.video && !abuse.video.deleted && !abuse.video.blacklisted, handler: abuse => { this.videoBlocklistService.blockVideo(abuse.video.id, undefined, true) .subscribe( () => { - this.notifier.success(this.i18n('Video blocked.')) + this.notifier.success($localize`Video blocked.`) this.updateAbuseState(abuse, AbuseState.ACCEPTED) }, @@ -378,13 +376,13 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV } }, { - label: this.i18n('Unblock video'), + label: $localize`Unblock video`, isDisplayed: abuse => abuse.video && !abuse.video.deleted && abuse.video.blacklisted, handler: abuse => { this.videoBlocklistService.unblockVideo(abuse.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video unblocked.')) + this.notifier.success($localize`Video unblocked.`) this.updateAbuseState(abuse, AbuseState.ACCEPTED) }, @@ -394,19 +392,19 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV } }, { - label: this.i18n('Delete video'), + label: $localize`Delete video`, isDisplayed: abuse => abuse.video && !abuse.video.deleted, handler: async abuse => { const res = await this.confirmService.confirm( - this.i18n('Do you really want to delete this video?'), - this.i18n('Delete') + $localize`Do you really want to delete this video?`, + $localize`Delete` ) if (res === false) return this.videoService.removeVideo(abuse.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video deleted.')) + this.notifier.success($localize`Video deleted.`) this.updateAbuseState(abuse, AbuseState.ACCEPTED) }, @@ -423,25 +421,25 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV return [ { - label: this.i18n('Actions for the comment'), + label: $localize`Actions for the comment`, isHeader: true, isDisplayed: abuse => abuse.comment && !abuse.comment.deleted }, { - label: this.i18n('Delete comment'), + label: $localize`Delete comment`, isDisplayed: abuse => abuse.comment && !abuse.comment.deleted, handler: async abuse => { const res = await this.confirmService.confirm( - this.i18n('Do you really want to delete this comment?'), - this.i18n('Delete') + $localize`Do you really want to delete this comment?`, + $localize`Delete` ) if (res === false) return this.commentService.deleteVideoComment(abuse.comment.video.id, abuse.comment.id) .subscribe( () => { - this.notifier.success(this.i18n('Comment deleted.')) + this.notifier.success($localize`Comment deleted.`) this.updateAbuseState(abuse, AbuseState.ACCEPTED) }, @@ -457,10 +455,7 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV this.blocklistService.blockAccountByInstance(account) .subscribe( () => { - this.notifier.success( - this.i18n('Account {{nameWithHost}} muted by the instance.', { nameWithHost: account.nameWithHost }) - ) - + this.notifier.success($localize`Account ${account.nameWithHost} muted by the instance.`) account.mutedByInstance = true }, @@ -472,9 +467,7 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV this.blocklistService.blockServerByInstance(host) .subscribe( () => { - this.notifier.success( - this.i18n('Server {{host}} muted by the instance.', { host: host }) - ) + this.notifier.success($localize`Server ${host} muted by the instance.`) }, err => this.notifier.error(err.message) diff --git a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts index 6686d91f4..0c3c8ff48 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts +++ b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts @@ -1,9 +1,8 @@ -import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' -import { AuthService, Notifier, HtmlRendererService } from '@app/core' +import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' +import { AuthService, HtmlRendererService, Notifier } from '@app/core' import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AbuseMessage, UserAbuse } from '@shared/models' import { AbuseService } from '../shared-moderation' @@ -31,7 +30,6 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit { protected formValidatorService: FormValidatorService, private abuseValidatorsService: AbuseValidatorsService, private modalService: NgbModal, - private i18n: I18n, private htmlRenderer: HtmlRendererService, private auth: AuthService, private notifier: Notifier, @@ -99,10 +97,10 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit { getPlaceholderMessage () { if (this.isAdminView) { - return this.i18n('Add a message to communicate with the reporter') + return $localize`Add a message to communicate with the reporter` } - return this.i18n('Add a message to communicate with the moderation team') + return $localize`Add a message to communicate with the moderation team` } private loadMessages () { diff --git a/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts b/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts index ecb7966bf..fad7f888d 100644 --- a/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts +++ b/client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts @@ -1,10 +1,9 @@ import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' import { Notifier } from '@app/core' -import { FormReactive, FormValidatorService, AbuseValidatorsService } from '@app/shared/shared-forms' +import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { AbuseService } from '@app/shared/shared-moderation' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AdminAbuse } from '@shared/models' @Component({ @@ -24,8 +23,7 @@ export class ModerationCommentModalComponent extends FormReactive implements OnI private modalService: NgbModal, private notifier: Notifier, private abuseService: AbuseService, - private abuseValidatorsService: AbuseValidatorsService, - private i18n: I18n + private abuseValidatorsService: AbuseValidatorsService ) { super() } @@ -57,7 +55,7 @@ export class ModerationCommentModalComponent extends FormReactive implements OnI this.abuseService.updateAbuse(this.abuseToComment, { moderationComment }) .subscribe( () => { - this.notifier.success(this.i18n('Comment updated.')) + this.notifier.success($localize`Comment updated.`) this.commentUpdated.emit(moderationComment) this.hide() diff --git a/client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts index 5f15963f3..56d30d6f9 100644 --- a/client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/abuse-validators.service.ts @@ -1,6 +1,5 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() @@ -9,31 +8,31 @@ export class AbuseValidatorsService { readonly ABUSE_MODERATION_COMMENT: BuildFormValidator readonly ABUSE_MESSAGE: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.ABUSE_REASON = { VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], MESSAGES: { - 'required': this.i18n('Report reason is required.'), - 'minlength': this.i18n('Report reason must be at least 2 characters long.'), - 'maxlength': this.i18n('Report reason cannot be more than 3000 characters long.') + 'required': $localize`Report reason is required.`, + 'minlength': $localize`Report reason must be at least 2 characters long.`, + 'maxlength': $localize`Report reason cannot be more than 3000 characters long.` } } this.ABUSE_MODERATION_COMMENT = { VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], MESSAGES: { - 'required': this.i18n('Moderation comment is required.'), - 'minlength': this.i18n('Moderation comment must be at least 2 characters long.'), - 'maxlength': this.i18n('Moderation comment cannot be more than 3000 characters long.') + 'required': $localize`Moderation comment is required.`, + 'minlength': $localize`Moderation comment must be at least 2 characters long.`, + 'maxlength': $localize`Moderation comment cannot be more than 3000 characters long.` } } this.ABUSE_MESSAGE = { VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ], MESSAGES: { - 'required': this.i18n('Abuse message is required.'), - 'minlength': this.i18n('Abuse message must be at least 2 characters long.'), - 'maxlength': this.i18n('Abuse message cannot be more than 3000 characters long.') + 'required': $localize`Abuse message is required.`, + 'minlength': $localize`Abuse message must be at least 2 characters long.`, + 'maxlength': $localize`Abuse message cannot be more than 3000 characters long.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts index f270b602b..6c7da833f 100644 --- a/client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/batch-domains-validators.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@angular/core' import { ValidatorFn, Validators } from '@angular/forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { BuildFormValidator } from './form-validator.service' import { validateHost } from './host' @@ -8,13 +7,13 @@ import { validateHost } from './host' export class BatchDomainsValidatorsService { readonly DOMAINS: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.DOMAINS = { VALIDATORS: [ Validators.required, this.validDomains, this.isHostsUnique ], MESSAGES: { - 'required': this.i18n('Domain is required.'), - 'validDomains': this.i18n('Domains entered are invalid.'), - 'uniqueDomains': this.i18n('Domains entered contain duplicates.') + 'required': $localize`Domain is required.`, + 'validDomains': $localize`Domains entered are invalid.`, + 'uniqueDomains': $localize`Domains entered contain duplicates.` } } } @@ -33,7 +32,7 @@ export class BatchDomainsValidatorsService { for (const host of hosts) { if (validateHost(host) === false) { - newHostsErrors.push(this.i18n('{{host}} is not valid', { host })) + newHostsErrors.push($localize`${host} is not valid`) } } diff --git a/client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts index c77aba6a1..862ff5470 100644 --- a/client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/custom-config-validators.service.ts @@ -1,7 +1,6 @@ +import { Injectable } from '@angular/core' import { Validators } from '@angular/forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { BuildFormValidator } from './form-validator.service' -import { Injectable } from '@angular/core' @Injectable() export class CustomConfigValidatorsService { @@ -16,82 +15,82 @@ export class CustomConfigValidatorsService { readonly INDEX_URL: BuildFormValidator readonly SEARCH_INDEX_URL: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.INSTANCE_NAME = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Instance name is required.') + 'required': $localize`Instance name is required.` } } this.INSTANCE_SHORT_DESCRIPTION = { VALIDATORS: [ Validators.max(250) ], MESSAGES: { - 'max': this.i18n('Short description should not be longer than 250 characters.') + 'max': $localize`Short description should not be longer than 250 characters.` } } this.SERVICES_TWITTER_USERNAME = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Twitter username is required.') + 'required': $localize`Twitter username is required.` } } this.CACHE_PREVIEWS_SIZE = { VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ], MESSAGES: { - 'required': this.i18n('Previews cache size is required.'), - 'min': this.i18n('Previews cache size must be greater than 1.'), - 'pattern': this.i18n('Previews cache size must be a number.') + 'required': $localize`Previews cache size is required.`, + 'min': $localize`Previews cache size must be greater than 1.`, + 'pattern': $localize`Previews cache size must be a number.` } } this.CACHE_CAPTIONS_SIZE = { VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ], MESSAGES: { - 'required': this.i18n('Captions cache size is required.'), - 'min': this.i18n('Captions cache size must be greater than 1.'), - 'pattern': this.i18n('Captions cache size must be a number.') + 'required': $localize`Captions cache size is required.`, + 'min': $localize`Captions cache size must be greater than 1.`, + 'pattern': $localize`Captions cache size must be a number.` } } this.SIGNUP_LIMIT = { VALIDATORS: [ Validators.required, Validators.min(-1), Validators.pattern('-?[0-9]+') ], MESSAGES: { - 'required': this.i18n('Signup limit is required.'), - 'min': this.i18n('Signup limit must be greater than 1.'), - 'pattern': this.i18n('Signup limit must be a number.') + 'required': $localize`Signup limit is required.`, + 'min': $localize`Signup limit must be greater than 1.`, + 'pattern': $localize`Signup limit must be a number.` } } this.ADMIN_EMAIL = { VALIDATORS: [ Validators.required, Validators.email ], MESSAGES: { - 'required': this.i18n('Admin email is required.'), - 'email': this.i18n('Admin email must be valid.') + 'required': $localize`Admin email is required.`, + 'email': $localize`Admin email must be valid.` } } this.TRANSCODING_THREADS = { VALIDATORS: [ Validators.required, Validators.min(0) ], MESSAGES: { - 'required': this.i18n('Transcoding threads is required.'), - 'min': this.i18n('Transcoding threads must be greater or equal to 0.') + 'required': $localize`Transcoding threads is required.`, + 'min': $localize`Transcoding threads must be greater or equal to 0.` } } this.INDEX_URL = { VALIDATORS: [ Validators.pattern(/^https:\/\//) ], MESSAGES: { - 'pattern': this.i18n('Index URL should be a URL') + 'pattern': $localize`Index URL should be a URL` } } this.SEARCH_INDEX_URL = { VALIDATORS: [ Validators.pattern(/^https?:\/\//) ], MESSAGES: { - 'pattern': this.i18n('Search index URL should be a URL') + 'pattern': $localize`Search index URL should be a URL` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts index 96a35a48f..3628f0b60 100644 --- a/client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/instance-validators.service.ts @@ -1,7 +1,6 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' +import { Injectable } from '@angular/core' import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' -import { Injectable } from '@angular/core' @Injectable() export class InstanceValidatorsService { @@ -10,13 +9,13 @@ export class InstanceValidatorsService { readonly SUBJECT: BuildFormValidator readonly BODY: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.FROM_EMAIL = { VALIDATORS: [ Validators.required, Validators.email ], MESSAGES: { - 'required': this.i18n('Email is required.'), - 'email': this.i18n('Email must be valid.') + 'required': $localize`Email is required.`, + 'email': $localize`Email must be valid.` } } @@ -27,9 +26,9 @@ export class InstanceValidatorsService { Validators.maxLength(120) ], MESSAGES: { - 'required': this.i18n('Your name is required.'), - 'minlength': this.i18n('Your name must be at least 1 character long.'), - 'maxlength': this.i18n('Your name cannot be more than 120 characters long.') + 'required': $localize`Your name is required.`, + 'minlength': $localize`Your name must be at least 1 character long.`, + 'maxlength': $localize`Your name cannot be more than 120 characters long.` } } @@ -40,9 +39,9 @@ export class InstanceValidatorsService { Validators.maxLength(120) ], MESSAGES: { - 'required': this.i18n('A subject is required.'), - 'minlength': this.i18n('The subject must be at least 1 character long.'), - 'maxlength': this.i18n('The subject cannot be more than 120 characters long.') + 'required': $localize`A subject is required.`, + 'minlength': $localize`The subject must be at least 1 character long.`, + 'maxlength': $localize`The subject cannot be more than 120 characters long.` } } @@ -53,9 +52,9 @@ export class InstanceValidatorsService { Validators.maxLength(5000) ], MESSAGES: { - 'required': this.i18n('A message is required.'), - 'minlength': this.i18n('The message must be at least 3 characters long.'), - 'maxlength': this.i18n('The message cannot be more than 5000 characters long.') + 'required': $localize`A message is required.`, + 'minlength': $localize`The message must be at least 3 characters long.`, + 'maxlength': $localize`The message cannot be more than 5000 characters long.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/login-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/login-validators.service.ts index a5837357e..67ea11f20 100644 --- a/client/src/app/shared/shared-forms/form-validators/login-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/login-validators.service.ts @@ -1,6 +1,5 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() @@ -8,13 +7,13 @@ export class LoginValidatorsService { readonly LOGIN_USERNAME: BuildFormValidator readonly LOGIN_PASSWORD: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.LOGIN_USERNAME = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Username is required.') + 'required': $localize`Username is required.` } } @@ -23,7 +22,7 @@ export class LoginValidatorsService { Validators.required ], MESSAGES: { - 'required': this.i18n('Password is required.') + 'required': $localize`Password is required.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts index d2085a309..3d0b4dd64 100644 --- a/client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/reset-password-validators.service.ts @@ -1,19 +1,18 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() export class ResetPasswordValidatorsService { readonly RESET_PASSWORD_CONFIRM: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.RESET_PASSWORD_CONFIRM = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Confirmation of the password is required.') + 'required': $localize`Confirmation of the password is required.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/user-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/user-validators.service.ts index 61486bbab..312fc9b1e 100644 --- a/client/src/app/shared/shared-forms/form-validators/user-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/user-validators.service.ts @@ -1,7 +1,6 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' +import { Injectable } from '@angular/core' import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' -import { Injectable } from '@angular/core' @Injectable() export class UserValidatorsService { @@ -20,7 +19,7 @@ export class UserValidatorsService { readonly USER_BAN_REASON: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.USER_USERNAME = { VALIDATORS: [ @@ -30,10 +29,10 @@ export class UserValidatorsService { Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) ], MESSAGES: { - 'required': this.i18n('Username is required.'), - 'minlength': this.i18n('Username must be at least 1 character long.'), - 'maxlength': this.i18n('Username cannot be more than 50 characters long.'), - 'pattern': this.i18n('Username should be lowercase alphanumeric; dots and underscores are allowed.') + 'required': $localize`Username is required.`, + 'minlength': $localize`Username must be at least 1 character long.`, + 'maxlength': $localize`Username cannot be more than 50 characters long.`, + 'pattern': $localize`Username should be lowercase alphanumeric; dots and underscores are allowed.` } } @@ -45,18 +44,18 @@ export class UserValidatorsService { Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) ], MESSAGES: { - 'required': this.i18n('Channel name is required.'), - 'minlength': this.i18n('Channel name must be at least 1 character long.'), - 'maxlength': this.i18n('Channel name cannot be more than 50 characters long.'), - 'pattern': this.i18n('Channel name should be lowercase alphanumeric; dots and underscores are allowed.') + 'required': $localize`Channel name is required.`, + 'minlength': $localize`Channel name must be at least 1 character long.`, + 'maxlength': $localize`Channel name cannot be more than 50 characters long.`, + 'pattern': $localize`Channel name should be lowercase alphanumeric; dots and underscores are allowed.` } } this.USER_EMAIL = { VALIDATORS: [ Validators.required, Validators.email ], MESSAGES: { - 'required': this.i18n('Email is required.'), - 'email': this.i18n('Email must be valid.') + 'required': $localize`Email is required.`, + 'email': $localize`Email must be valid.` } } @@ -67,9 +66,9 @@ export class UserValidatorsService { Validators.maxLength(255) ], MESSAGES: { - 'required': this.i18n('Password is required.'), - 'minlength': this.i18n('Password must be at least 6 characters long.'), - 'maxlength': this.i18n('Password cannot be more than 255 characters long.') + 'required': $localize`Password is required.`, + 'minlength': $localize`Password must be at least 6 characters long.`, + 'maxlength': $localize`Password cannot be more than 255 characters long.` } } @@ -79,37 +78,37 @@ export class UserValidatorsService { Validators.maxLength(255) ], MESSAGES: { - 'minlength': this.i18n('Password must be at least 6 characters long.'), - 'maxlength': this.i18n('Password cannot be more than 255 characters long.') + 'minlength': $localize`Password must be at least 6 characters long.`, + 'maxlength': $localize`Password cannot be more than 255 characters long.` } } this.USER_CONFIRM_PASSWORD = { VALIDATORS: [], MESSAGES: { - 'matchPassword': this.i18n('The new password and the confirmed password do not correspond.') + 'matchPassword': $localize`The new password and the confirmed password do not correspond.` } } this.USER_VIDEO_QUOTA = { VALIDATORS: [ Validators.required, Validators.min(-1) ], MESSAGES: { - 'required': this.i18n('Video quota is required.'), - 'min': this.i18n('Quota must be greater than -1.') + 'required': $localize`Video quota is required.`, + 'min': $localize`Quota must be greater than -1.` } } this.USER_VIDEO_QUOTA_DAILY = { VALIDATORS: [ Validators.required, Validators.min(-1) ], MESSAGES: { - 'required': this.i18n('Daily upload limit is required.'), - 'min': this.i18n('Daily upload limit must be greater than -1.') + 'required': $localize`Daily upload limit is required.`, + 'min': $localize`Daily upload limit must be greater than -1.` } } this.USER_ROLE = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('User role is required.') + 'required': $localize`User role is required.` } } @@ -121,8 +120,8 @@ export class UserValidatorsService { Validators.maxLength(1000) ], MESSAGES: { - 'minlength': this.i18n('Description must be at least 3 characters long.'), - 'maxlength': this.i18n('Description cannot be more than 1000 characters long.') + 'minlength': $localize`Description must be at least 3 characters long.`, + 'maxlength': $localize`Description cannot be more than 1000 characters long.` } } @@ -131,7 +130,7 @@ export class UserValidatorsService { Validators.requiredTrue ], MESSAGES: { - 'required': this.i18n('You must agree with the instance terms in order to register on it.') + 'required': $localize`You must agree with the instance terms in order to register on it.` } } @@ -141,8 +140,8 @@ export class UserValidatorsService { Validators.maxLength(250) ], MESSAGES: { - 'minlength': this.i18n('Ban reason must be at least 3 characters long.'), - 'maxlength': this.i18n('Ban reason cannot be more than 250 characters long.') + 'minlength': $localize`Ban reason must be at least 3 characters long.`, + 'maxlength': $localize`Ban reason cannot be more than 250 characters long.` } } } @@ -154,9 +153,9 @@ export class UserValidatorsService { Validators.maxLength(120) ], MESSAGES: { - 'required': this.i18n('Display name is required.'), - 'minlength': this.i18n('Display name must be at least 1 character long.'), - 'maxlength': this.i18n('Display name cannot be more than 50 characters long.') + 'required': $localize`Display name is required.`, + 'minlength': $localize`Display name must be at least 1 character long.`, + 'maxlength': $localize`Display name cannot be more than 50 characters long.` } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts index 998d616ec..aed9e9cdd 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-accept-ownership-validators.service.ts @@ -1,17 +1,16 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() export class VideoAcceptOwnershipValidatorsService { readonly CHANNEL: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.CHANNEL = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('The channel is required.') + 'required': $localize`The channel is required.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts index ddf0ab5eb..bce1880dc 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-block-validators.service.ts @@ -1,18 +1,17 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() export class VideoBlockValidatorsService { readonly VIDEO_BLOCK_REASON: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_BLOCK_REASON = { VALIDATORS: [ Validators.minLength(2), Validators.maxLength(300) ], MESSAGES: { - 'minlength': this.i18n('Block reason must be at least 2 characters long.'), - 'maxlength': this.i18n('Block reason cannot be more than 300 characters long.') + 'minlength': $localize`Block reason must be at least 2 characters long.`, + 'maxlength': $localize`Block reason cannot be more than 300 characters long.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts index 280d28414..7e90264e5 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-captions-validators.service.ts @@ -1,6 +1,5 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() @@ -8,19 +7,19 @@ export class VideoCaptionsValidatorsService { readonly VIDEO_CAPTION_LANGUAGE: BuildFormValidator readonly VIDEO_CAPTION_FILE: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_CAPTION_LANGUAGE = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Video caption language is required.') + 'required': $localize`Video caption language is required.` } } this.VIDEO_CAPTION_FILE = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Video caption file is required.') + 'required': $localize`Video caption file is required.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts index 59659defd..8c809a0d5 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-change-ownership-validators.service.ts @@ -1,18 +1,17 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { AbstractControl, ValidationErrors, Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { AbstractControl, ValidationErrors, Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() export class VideoChangeOwnershipValidatorsService { readonly USERNAME: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.USERNAME = { VALIDATORS: [ Validators.required, this.localAccountValidator ], MESSAGES: { - 'required': this.i18n('The username is required.'), - 'localAccountOnly': this.i18n('You can only transfer ownership to a local account') + 'required': $localize`The username is required.`, + 'localAccountOnly': $localize`You can only transfer ownership to a local account` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts index bb650b149..3e7444196 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-channel-validators.service.ts @@ -1,6 +1,5 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() @@ -10,7 +9,7 @@ export class VideoChannelValidatorsService { readonly VIDEO_CHANNEL_DESCRIPTION: BuildFormValidator readonly VIDEO_CHANNEL_SUPPORT: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_CHANNEL_NAME = { VALIDATORS: [ Validators.required, @@ -19,10 +18,10 @@ export class VideoChannelValidatorsService { Validators.pattern(/^[a-z0-9][a-z0-9._]*$/) ], MESSAGES: { - 'required': this.i18n('Name is required.'), - 'minlength': this.i18n('Name must be at least 1 character long.'), - 'maxlength': this.i18n('Name cannot be more than 50 characters long.'), - 'pattern': this.i18n('Name should be lowercase alphanumeric; dots and underscores are allowed.') + 'required': $localize`Name is required.`, + 'minlength': $localize`Name must be at least 1 character long.`, + 'maxlength': $localize`Name cannot be more than 50 characters long.`, + 'pattern': $localize`Name should be lowercase alphanumeric; dots and underscores are allowed.` } } @@ -33,9 +32,9 @@ export class VideoChannelValidatorsService { Validators.maxLength(50) ], MESSAGES: { - 'required': i18n('Display name is required.'), - 'minlength': i18n('Display name must be at least 1 character long.'), - 'maxlength': i18n('Display name cannot be more than 50 characters long.') + 'required': $localize`Display name is required.`, + 'minlength': $localize`Display name must be at least 1 character long.`, + 'maxlength': $localize`Display name cannot be more than 50 characters long.` } } @@ -45,8 +44,8 @@ export class VideoChannelValidatorsService { Validators.maxLength(1000) ], MESSAGES: { - 'minlength': i18n('Description must be at least 3 characters long.'), - 'maxlength': i18n('Description cannot be more than 1000 characters long.') + 'minlength': $localize`Description must be at least 3 characters long.`, + 'maxlength': $localize`Description cannot be more than 1000 characters long.` } } @@ -56,8 +55,8 @@ export class VideoChannelValidatorsService { Validators.maxLength(1000) ], MESSAGES: { - 'minlength': i18n('Support text must be at least 3 characters long.'), - 'maxlength': i18n('Support text cannot be more than 1000 characters long.') + 'minlength': $localize`Support text must be at least 3 characters long.`, + 'maxlength': $localize`Support text cannot be more than 1000 characters long` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts index 97c8e967e..18e7ae264 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-comment-validators.service.ts @@ -1,19 +1,18 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators } from '@angular/forms' import { Injectable } from '@angular/core' +import { Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() export class VideoCommentValidatorsService { readonly VIDEO_COMMENT_TEXT: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_COMMENT_TEXT = { VALIDATORS: [ Validators.required, Validators.minLength(1), Validators.maxLength(3000) ], MESSAGES: { - 'required': this.i18n('Comment is required.'), - 'minlength': this.i18n('Comment must be at least 2 characters long.'), - 'maxlength': this.i18n('Comment cannot be more than 3000 characters long.') + 'required': $localize`Comment is required.`, + 'minlength': $localize`Comment must be at least 2 characters long.`, + 'maxlength': $localize`Comment cannot be more than 3000 characters long.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts index ab9c43625..3b45a40fd 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-playlist-validators.service.ts @@ -1,8 +1,7 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { AbstractControl, FormControl, Validators } from '@angular/forms' import { Injectable } from '@angular/core' -import { BuildFormValidator } from './form-validator.service' +import { AbstractControl, Validators } from '@angular/forms' import { VideoPlaylistPrivacy } from '@shared/models' +import { BuildFormValidator } from './form-validator.service' @Injectable() export class VideoPlaylistValidatorsService { @@ -11,7 +10,7 @@ export class VideoPlaylistValidatorsService { readonly VIDEO_PLAYLIST_DESCRIPTION: BuildFormValidator readonly VIDEO_PLAYLIST_CHANNEL_ID: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_PLAYLIST_DISPLAY_NAME = { VALIDATORS: [ Validators.required, @@ -19,9 +18,9 @@ export class VideoPlaylistValidatorsService { Validators.maxLength(120) ], MESSAGES: { - 'required': this.i18n('Display name is required.'), - 'minlength': this.i18n('Display name must be at least 1 character long.'), - 'maxlength': this.i18n('Display name cannot be more than 120 characters long.') + 'required': $localize`Display name is required.`, + 'minlength': $localize`Display name must be at least 1 character long.`, + 'maxlength': $localize`Display name cannot be more than 120 characters long.` } } @@ -30,7 +29,7 @@ export class VideoPlaylistValidatorsService { Validators.required ], MESSAGES: { - 'required': this.i18n('Privacy is required.') + 'required': $localize`Privacy is required.` } } @@ -40,15 +39,15 @@ export class VideoPlaylistValidatorsService { Validators.maxLength(1000) ], MESSAGES: { - 'minlength': i18n('Description must be at least 3 characters long.'), - 'maxlength': i18n('Description cannot be more than 1000 characters long.') + 'minlength': $localize`Description must be at least 3 characters long.`, + 'maxlength': $localize`Description cannot be more than 1000 characters long.` } } this.VIDEO_PLAYLIST_CHANNEL_ID = { VALIDATORS: [ ], MESSAGES: { - 'required': this.i18n('The channel is required when the playlist is public.') + 'required': $localize`The channel is required when the playlist is public.` } } } diff --git a/client/src/app/shared/shared-forms/form-validators/video-validators.service.ts b/client/src/app/shared/shared-forms/form-validators/video-validators.service.ts index c96e4ef66..8119c1ae7 100644 --- a/client/src/app/shared/shared-forms/form-validators/video-validators.service.ts +++ b/client/src/app/shared/shared-forms/form-validators/video-validators.service.ts @@ -1,6 +1,5 @@ -import { I18n } from '@ngx-translate/i18n-polyfill' -import { Validators, ValidatorFn, ValidationErrors, AbstractControl } from '@angular/forms' import { Injectable } from '@angular/core' +import { AbstractControl, ValidationErrors, ValidatorFn, Validators } from '@angular/forms' import { BuildFormValidator } from './form-validator.service' @Injectable() @@ -19,21 +18,21 @@ export class VideoValidatorsService { readonly VIDEO_SCHEDULE_PUBLICATION_AT: BuildFormValidator readonly VIDEO_ORIGINALLY_PUBLISHED_AT: BuildFormValidator - constructor (private i18n: I18n) { + constructor () { this.VIDEO_NAME = { VALIDATORS: [ Validators.required, Validators.minLength(3), Validators.maxLength(120) ], MESSAGES: { - 'required': this.i18n('Video name is required.'), - 'minlength': this.i18n('Video name must be at least 3 characters long.'), - 'maxlength': this.i18n('Video name cannot be more than 120 characters long.') + 'required': $localize`Video name is required.`, + 'minlength': $localize`Video name must be at least 3 characters long.`, + 'maxlength': $localize`Video name cannot be more than 120 characters long.` } } this.VIDEO_PRIVACY = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Video privacy is required.') + 'required': $localize`Video privacy is required.` } } @@ -60,46 +59,46 @@ export class VideoValidatorsService { this.VIDEO_CHANNEL = { VALIDATORS: [ Validators.required ], MESSAGES: { - 'required': this.i18n('Video channel is required.') + 'required': $localize`Video channel is required.` } } this.VIDEO_DESCRIPTION = { VALIDATORS: [ Validators.minLength(3), Validators.maxLength(10000) ], MESSAGES: { - 'minlength': this.i18n('Video description must be at least 3 characters long.'), - 'maxlength': this.i18n('Video description cannot be more than 10000 characters long.') + 'minlength': $localize`Video description must be at least 3 characters long.`, + 'maxlength': $localize`Video description cannot be more than 10000 characters long.` } } this.VIDEO_TAG = { VALIDATORS: [ Validators.minLength(2), Validators.maxLength(30) ], MESSAGES: { - 'minlength': this.i18n('A tag should be more than 2 characters long.'), - 'maxlength': this.i18n('A tag should be less than 30 characters long.') + 'minlength': $localize`A tag should be more than 2 characters long.`, + 'maxlength': $localize`A tag should be less than 30 characters long.` } } this.VIDEO_TAGS_ARRAY = { VALIDATORS: [ Validators.maxLength(5), this.arrayTagLengthValidator() ], MESSAGES: { - 'maxlength': this.i18n('A maximum of 5 tags can be used on a video.'), - 'arrayTagLength': this.i18n('A tag should be more than 2, and less than 30 characters long.') + 'maxlength': $localize`A maximum of 5 tags can be used on a video.`, + 'arrayTagLength': $localize`A tag should be more than 2, and less than 30 characters long.` } } this.VIDEO_SUPPORT = { VALIDATORS: [ Validators.minLength(3), Validators.maxLength(1000) ], MESSAGES: { - 'minlength': this.i18n('Video support must be at least 3 characters long.'), - 'maxlength': this.i18n('Video support cannot be more than 1000 characters long.') + 'minlength': $localize`Video support must be at least 3 characters long.`, + 'maxlength': $localize`Video support cannot be more than 1000 characters long.` } } this.VIDEO_SCHEDULE_PUBLICATION_AT = { VALIDATORS: [ ], MESSAGES: { - 'required': this.i18n('A date is required to schedule video update.') + 'required': $localize`A date is required to schedule video update.` } } diff --git a/client/src/app/shared/shared-forms/input-readonly-copy.component.ts b/client/src/app/shared/shared-forms/input-readonly-copy.component.ts index 7528fb7a1..a67b0c691 100644 --- a/client/src/app/shared/shared-forms/input-readonly-copy.component.ts +++ b/client/src/app/shared/shared-forms/input-readonly-copy.component.ts @@ -1,6 +1,5 @@ import { Component, Input } from '@angular/core' import { Notifier } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-input-readonly-copy', @@ -10,12 +9,9 @@ import { I18n } from '@ngx-translate/i18n-polyfill' export class InputReadonlyCopyComponent { @Input() value = '' - constructor ( - private notifier: Notifier, - private i18n: I18n - ) { } + constructor (private notifier: Notifier) { } activateCopiedMessage () { - this.notifier.success(this.i18n('Copied')) + this.notifier.success($localize`Copied`) } } diff --git a/client/src/app/shared/shared-forms/preview-upload.component.ts b/client/src/app/shared/shared-forms/preview-upload.component.ts index 7afff0b31..a55dcdd9a 100644 --- a/client/src/app/shared/shared-forms/preview-upload.component.ts +++ b/client/src/app/shared/shared-forms/preview-upload.component.ts @@ -2,7 +2,6 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core' import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser' import { ServerService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig } from '@shared/models' import { BytesPipe } from '../shared-main' @@ -34,11 +33,10 @@ export class PreviewUploadComponent implements OnInit, ControlValueAccessor { constructor ( private sanitizer: DomSanitizer, - private serverService: ServerService, - private i18n: I18n + private serverService: ServerService ) { this.bytesPipe = new BytesPipe() - this.maxSizeText = this.i18n('max size') + this.maxSizeText = $localize`max size` } get videoImageExtensions () { diff --git a/client/src/app/shared/shared-forms/reactive-file.component.ts b/client/src/app/shared/shared-forms/reactive-file.component.ts index 9ebf487ce..eeb2a3fd8 100644 --- a/client/src/app/shared/shared-forms/reactive-file.component.ts +++ b/client/src/app/shared/shared-forms/reactive-file.component.ts @@ -2,7 +2,6 @@ import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@ang import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' import { Notifier } from '@app/core' import { GlobalIconName } from '@app/shared/shared-icons' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-reactive-file', @@ -31,10 +30,7 @@ export class ReactiveFileComponent implements OnInit, ControlValueAccessor { private file: File - constructor ( - private notifier: Notifier, - private i18n: I18n - ) {} + constructor (private notifier: Notifier) { } get filename () { if (!this.file) return '' @@ -51,16 +47,13 @@ export class ReactiveFileComponent implements OnInit, ControlValueAccessor { const [ file ] = event.target.files if (file.size > this.maxFileSize) { - this.notifier.error(this.i18n('This file is too large.')) + this.notifier.error($localize`This file is too large.`) return } const extension = '.' + file.name.split('.').pop() if (this.extensions.includes(extension) === false) { - const message = this.i18n( - 'PeerTube cannot handle this kind of file. Accepted extensions are {{extensions}}.', - { extensions: this.allowedExtensionsMessage } - ) + const message = $localize`PeerTube cannot handle this kind of file. Accepted extensions are ${this.allowedExtensionsMessage}}.` this.notifier.error(message) return diff --git a/client/src/app/shared/shared-forms/select/select-checkbox.component.ts b/client/src/app/shared/shared-forms/select/select-checkbox.component.ts index fd683ae5d..eb0c49034 100644 --- a/client/src/app/shared/shared-forms/select/select-checkbox.component.ts +++ b/client/src/app/shared/shared-forms/select/select-checkbox.component.ts @@ -1,7 +1,6 @@ -import { Component, Input, forwardRef, OnInit } from '@angular/core' -import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms' +import { Component, forwardRef, Input, OnInit } from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' import { SelectOptionsItem } from './select-options.component' -import { I18n } from '@ngx-translate/i18n-polyfill' export type ItemSelectCheckboxValue = { id?: string | number, group?: string } | string @@ -25,12 +24,8 @@ export class SelectCheckboxComponent implements OnInit, ControlValueAccessor { @Input() maxSelectedItems: number @Input() placeholder: string - constructor ( - private i18n: I18n - ) {} - ngOnInit () { - if (!this.placeholder) this.placeholder = this.i18n('Add a new option') + if (!this.placeholder) this.placeholder = $localize`Add a new option` } propagateChange = (_: any) => { /* empty */ } diff --git a/client/src/app/shared/shared-instance/instance-features-table.component.ts b/client/src/app/shared/shared-instance/instance-features-table.component.ts index 8fd15ebad..76b595c20 100644 --- a/client/src/app/shared/shared-instance/instance-features-table.component.ts +++ b/client/src/app/shared/shared-instance/instance-features-table.component.ts @@ -1,6 +1,5 @@ import { Component, OnInit } from '@angular/core' import { ServerService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig } from '@shared/models' @Component({ @@ -12,11 +11,7 @@ export class InstanceFeaturesTableComponent implements OnInit { quotaHelpIndication = '' serverConfig: ServerConfig - constructor ( - private i18n: I18n, - private serverService: ServerService - ) { - } + constructor (private serverService: ServerService) { } get initialUserVideoQuota () { return this.serverConfig.user.videoQuota @@ -38,9 +33,9 @@ export class InstanceFeaturesTableComponent implements OnInit { buildNSFWLabel () { const policy = this.serverConfig.instance.defaultNSFWPolicy - if (policy === 'do_not_list') return this.i18n('Hidden') - if (policy === 'blur') return this.i18n('Blurred with confirmation request') - if (policy === 'display') return this.i18n('Displayed') + if (policy === 'do_not_list') return $localize`Hidden` + if (policy === 'blur') return $localize`Blurred with confirmation request` + if (policy === 'display') return $localize`Displayed` } getServerVersionAndCommit () { @@ -55,7 +50,9 @@ export class InstanceFeaturesTableComponent implements OnInit { const minutes = Math.floor(seconds % 3600 / 60) - return this.i18n('~ {{minutes}} {minutes, plural, =1 {minute} other {minutes}}', { minutes }) + if (minutes === 1) return $localize`~ 1 minute` + + return $localize`~ ${minutes} minutes` } private buildQuotaHelpIndication () { @@ -71,9 +68,9 @@ export class InstanceFeaturesTableComponent implements OnInit { const normalSeconds = initialUserVideoQuotaBit / (1.5 * 1000 * 1000) const lines = [ - this.i18n('{{seconds}} of full HD videos', { seconds: this.getApproximateTime(fullHdSeconds) }), - this.i18n('{{seconds}} of HD videos', { seconds: this.getApproximateTime(hdSeconds) }), - this.i18n('{{seconds}} of average quality videos', { seconds: this.getApproximateTime(normalSeconds) }) + $localize`${this.getApproximateTime(fullHdSeconds)} of full HD videos`, + $localize`${this.getApproximateTime(hdSeconds)} of HD videos`, + $localize`${this.getApproximateTime(normalSeconds)} of average quality videos` ] this.quotaHelpIndication = lines.join('
') diff --git a/client/src/app/shared/shared-main/account/actor-avatar-info.component.ts b/client/src/app/shared/shared-main/account/actor-avatar-info.component.ts index 1389218cc..3a86e5b21 100644 --- a/client/src/app/shared/shared-main/account/actor-avatar-info.component.ts +++ b/client/src/app/shared/shared-main/account/actor-avatar-info.component.ts @@ -1,7 +1,6 @@ import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' import { Notifier, ServerService } from '@app/core' import { Account, BytesPipe, VideoChannel } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig } from '@shared/models' @Component({ @@ -23,11 +22,10 @@ export class ActorAvatarInfoComponent implements OnInit { constructor ( private serverService: ServerService, - private notifier: Notifier, - private i18n: I18n + private notifier: Notifier ) { this.bytesPipe = new BytesPipe() - this.maxSizeText = this.i18n('max size') + this.maxSizeText = $localize`max size` } ngOnInit (): void { diff --git a/client/src/app/shared/shared-main/account/avatar.component.ts b/client/src/app/shared/shared-main/account/avatar.component.ts index 73c145ef9..2967828a0 100644 --- a/client/src/app/shared/shared-main/account/avatar.component.ts +++ b/client/src/app/shared/shared-main/account/avatar.component.ts @@ -1,6 +1,5 @@ import { Component, Input, OnInit } from '@angular/core' import { Video } from '../video/video.model' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'avatar-channel', @@ -15,19 +14,9 @@ export class AvatarComponent implements OnInit { channelLinkTitle = '' accountLinkTitle = '' - constructor ( - private i18n: I18n - ) {} - ngOnInit () { - this.channelLinkTitle = this.i18n( - '{{name}} (channel page)', - { name: this.video.channel.name, handle: this.video.byVideoChannel } - ) - this.accountLinkTitle = this.i18n( - '{{name}} (account page)', - { name: this.video.account.name, handle: this.video.byAccount } - ) + this.channelLinkTitle = $localize`${this.video.account.name} (channel page)` + this.accountLinkTitle = $localize`${this.video.byAccount} (account page)` } isChannelAvatarNull () { diff --git a/client/src/app/shared/shared-main/angular/from-now.pipe.ts b/client/src/app/shared/shared-main/angular/from-now.pipe.ts index 9851468ee..5d85590bb 100644 --- a/client/src/app/shared/shared-main/angular/from-now.pipe.ts +++ b/client/src/app/shared/shared-main/angular/from-now.pipe.ts @@ -1,39 +1,36 @@ import { Pipe, PipeTransform } from '@angular/core' -import { I18n } from '@ngx-translate/i18n-polyfill' // Thanks: https://stackoverflow.com/questions/3177836/how-to-format-time-since-xxx-e-g-4-minutes-ago-similar-to-stack-exchange-site @Pipe({ name: 'myFromNow' }) export class FromNowPipe implements PipeTransform { - constructor (private i18n: I18n) { } - transform (arg: number | Date | string) { const argDate = new Date(arg) const seconds = Math.floor((Date.now() - argDate.getTime()) / 1000) let interval = Math.floor(seconds / 31536000) - if (interval > 1) return this.i18n('{{interval}} years ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} year ago', { interval }) + if (interval > 1) return $localize`${interval} years ago` + if (interval === 1) return $localize`${interval} year ago` interval = Math.floor(seconds / 2592000) - if (interval > 1) return this.i18n('{{interval}} months ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} month ago', { interval }) + if (interval > 1) return $localize`${interval} months ago` + if (interval === 1) return $localize`${interval} month ago` interval = Math.floor(seconds / 604800) - if (interval > 1) return this.i18n('{{interval}} weeks ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} week ago', { interval }) + if (interval > 1) return $localize`${interval} weeks ago` + if (interval === 1) return $localize`${interval} week ago` interval = Math.floor(seconds / 86400) - if (interval > 1) return this.i18n('{{interval}} days ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} day ago', { interval }) + if (interval > 1) return $localize`${interval} days ago` + if (interval === 1) return $localize`${interval} day ago` interval = Math.floor(seconds / 3600) - if (interval > 1) return this.i18n('{{interval}} hours ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} hour ago', { interval }) + if (interval > 1) return $localize`${interval} hours ago` + if (interval === 1) return $localize`${interval} hour ago` interval = Math.floor(seconds / 60) - if (interval >= 1) return this.i18n('{{interval}} min ago', { interval }) + if (interval >= 1) return $localize`${interval} min ago` - return this.i18n('just now') + return $localize`just now` } } diff --git a/client/src/app/shared/shared-main/buttons/delete-button.component.ts b/client/src/app/shared/shared-main/buttons/delete-button.component.ts index aced0f881..18995422a 100644 --- a/client/src/app/shared/shared-main/buttons/delete-button.component.ts +++ b/client/src/app/shared/shared-main/buttons/delete-button.component.ts @@ -1,5 +1,4 @@ import { Component, Input, OnInit } from '@angular/core' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-delete-button', @@ -11,17 +10,15 @@ export class DeleteButtonComponent implements OnInit { @Input() label: string @Input() title: string - constructor (private i18n: I18n) { } - ngOnInit () { // No label if (this.label === undefined && !this.title) { - this.title = this.i18n('Delete') + this.title = $localize`Delete` } // Use default label if (this.label === '') { - this.label = this.i18n('Delete') + this.label = $localize`Delete` if (!this.title) { this.title = this.label diff --git a/client/src/app/shared/shared-main/buttons/edit-button.component.ts b/client/src/app/shared/shared-main/buttons/edit-button.component.ts index d8ae39b84..4b76551ca 100644 --- a/client/src/app/shared/shared-main/buttons/edit-button.component.ts +++ b/client/src/app/shared/shared-main/buttons/edit-button.component.ts @@ -1,5 +1,4 @@ import { Component, Input, OnInit } from '@angular/core' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-edit-button', @@ -12,17 +11,15 @@ export class EditButtonComponent implements OnInit { @Input() title: string @Input() routerLink: string[] | string = [] - constructor (private i18n: I18n) { } - ngOnInit () { // No label if (this.label === undefined && !this.title) { - this.title = this.i18n('Update') + this.title = $localize`Update` } // Use default label if (this.label === '') { - this.label = this.i18n('Update') + this.label = $localize`Update` if (!this.title) { this.title = this.label diff --git a/client/src/app/shared/shared-main/misc/help.component.ts b/client/src/app/shared/shared-main/misc/help.component.ts index 0825b96de..ebc965a88 100644 --- a/client/src/app/shared/shared-main/misc/help.component.ts +++ b/client/src/app/shared/shared-main/misc/help.component.ts @@ -1,6 +1,5 @@ import { AfterContentInit, Component, ContentChildren, Input, OnChanges, OnInit, QueryList, TemplateRef } from '@angular/core' import { MarkdownService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { PeerTubeTemplateDirective } from '../angular' @Component({ @@ -22,8 +21,6 @@ export class HelpComponent implements OnInit, OnChanges, AfterContentInit { customHtmlTemplate: TemplateRef postHtmlTemplate: TemplateRef - constructor (private i18n: I18n) { } - ngOnInit () { this.init() } @@ -71,17 +68,17 @@ export class HelpComponent implements OnInit, OnChanges, AfterContentInit { private formatMarkdownSupport (rules: string[]) { // tslint:disable:max-line-length - return this.i18n('Markdown compatible that supports:') + + return $localize`Markdown compatible that supports:` + this.createMarkdownList(rules) } private createMarkdownList (rules: string[]) { const rulesToText = { - 'emphasis': this.i18n('Emphasis'), - 'link': this.i18n('Links'), - 'newline': this.i18n('New lines'), - 'list': this.i18n('Lists'), - 'image': this.i18n('Images') + 'emphasis': $localize`Emphasis`, + 'link': $localize`Links`, + 'newline': $localize`New lines`, + 'list': $localize`Lists`, + 'image': $localize`Images` } const bullets = rules.map(r => rulesToText[r]) diff --git a/client/src/app/shared/shared-main/shared-main.module.ts b/client/src/app/shared/shared-main/shared-main.module.ts index 6186db4d6..7f4676dd1 100644 --- a/client/src/app/shared/shared-main/shared-main.module.ts +++ b/client/src/app/shared/shared-main/shared-main.module.ts @@ -13,7 +13,6 @@ import { NgbPopoverModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { SharedGlobalIconModule } from '../shared-icons' import { AccountService, ActorAvatarInfoComponent, AvatarComponent } from './account' import { FromNowPipe, InfiniteScrollerDirective, NumberFormatterPipe, PeerTubeTemplateDirective, BytesPipe } from './angular' @@ -129,8 +128,6 @@ import { VideoChannelService } from './video-channel' ], providers: [ - I18n, - DatePipe, FromNowPipe, diff --git a/client/src/app/shared/shared-main/users/user-quota.component.ts b/client/src/app/shared/shared-main/users/user-quota.component.ts index 6830ad8fe..b38619186 100644 --- a/client/src/app/shared/shared-main/users/user-quota.component.ts +++ b/client/src/app/shared/shared-main/users/user-quota.component.ts @@ -1,7 +1,6 @@ import { Subject } from 'rxjs' import { Component, Input, OnInit } from '@angular/core' import { User, UserService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { BytesPipe } from '../angular' @Component({ @@ -22,10 +21,7 @@ export class UserQuotaComponent implements OnInit { userVideoQuotaUsedDaily = 0 userVideoQuotaDailyPercentage = 15 - constructor ( - private userService: UserService, - private i18n: I18n - ) { } + constructor (private userService: UserService) { } ngOnInit () { this.userInformationLoaded.subscribe( @@ -33,13 +29,13 @@ export class UserQuotaComponent implements OnInit { if (this.user.videoQuota !== -1) { this.userVideoQuota = new BytesPipe().transform(this.user.videoQuota, 0).toString() } else { - this.userVideoQuota = this.i18n('Unlimited') + this.userVideoQuota = $localize`Unlimited` } if (this.user.videoQuotaDaily !== -1) { this.userVideoQuotaDaily = new BytesPipe().transform(this.user.videoQuotaDaily, 0).toString() } else { - this.userVideoQuotaDaily = this.i18n('Unlimited') + this.userVideoQuotaDaily = $localize`Unlimited` } } ) diff --git a/client/src/app/shared/shared-main/video/video.service.ts b/client/src/app/shared/shared-main/video/video.service.ts index 978f775bf..b01e919aa 100644 --- a/client/src/app/shared/shared-main/video/video.service.ts +++ b/client/src/app/shared/shared-main/video/video.service.ts @@ -4,7 +4,6 @@ import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http' import { Injectable } from '@angular/core' import { ComponentPaginationLight, RestExtractor, RestService, ServerService, UserService } from '@app/core' import { objectToFormData } from '@app/helpers' -import { I18n } from '@ngx-translate/i18n-polyfill' import { FeedFormat, NSFWPolicyType, @@ -15,11 +14,11 @@ import { Video as VideoServerModel, VideoConstant, VideoDetails as VideoDetailsServerModel, + VideoFileMetadata, VideoFilter, VideoPrivacy, VideoSortField, - VideoUpdate, - VideoFileMetadata + VideoUpdate } from '@shared/models' import { environment } from '../../../../environments/environment' import { Account, AccountService } from '../account' @@ -48,8 +47,7 @@ export class VideoService implements VideosProvider { private authHttp: HttpClient, private restExtractor: RestExtractor, private restService: RestService, - private serverService: ServerService, - private i18n: I18n + private serverService: ServerService ) {} getVideoViewUrl (uuid: string) { @@ -339,19 +337,19 @@ export class VideoService implements VideosProvider { const base = [ { id: VideoPrivacy.PRIVATE, - description: this.i18n('Only I can see this video') + description: $localize`Only I can see this video` }, { id: VideoPrivacy.UNLISTED, - description: this.i18n('Only shareable via a private link') + description: $localize`Only shareable via a private link` }, { id: VideoPrivacy.PUBLIC, - description: this.i18n('Anyone can see this video') + description: $localize`Anyone can see this video` }, { id: VideoPrivacy.INTERNAL, - description: this.i18n('Only users of this instance can see this video') + description: $localize`Only users of this instance can see this video` } ] diff --git a/client/src/app/shared/shared-moderation/abuse.service.ts b/client/src/app/shared/shared-moderation/abuse.service.ts index 06b236d1e..bf98d4b36 100644 --- a/client/src/app/shared/shared-moderation/abuse.service.ts +++ b/client/src/app/shared/shared-moderation/abuse.service.ts @@ -5,7 +5,6 @@ import { catchError, map } from 'rxjs/operators' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { RestExtractor, RestPagination, RestService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AbuseCreate, AbuseFilter, @@ -25,7 +24,6 @@ export class AbuseService { private static BASE_MY_ABUSE_URL = environment.apiUrl + '/api/v1/users/me/abuses' constructor ( - private i18n: I18n, private authHttp: HttpClient, private restService: RestService, private restExtractor: RestExtractor @@ -138,33 +136,33 @@ export class AbuseService { let reasons: { id: AbusePredefinedReasonsString, label: string, description?: string, help?: string }[] = [ { id: 'violentOrRepulsive', - label: this.i18n('Violent or repulsive'), - help: this.i18n('Contains offensive, violent, or coarse language or iconography.') + label: $localize`Violent or repulsive`, + help: $localize`Contains offensive, violent, or coarse language or iconography.` }, { id: 'hatefulOrAbusive', - label: this.i18n('Hateful or abusive'), - help: this.i18n('Contains abusive, racist or sexist language or iconography.') + label: $localize`Hateful or abusive`, + help: $localize`Contains abusive, racist or sexist language or iconography.` }, { id: 'spamOrMisleading', - label: this.i18n('Spam, ad or false news'), - help: this.i18n('Contains marketing, spam, purposefully deceitful news, or otherwise misleading thumbnail/text/tags. Please provide reputable sources to report hoaxes.') + label: $localize`Spam, ad or false news`, + help: $localize`Contains marketing, spam, purposefully deceitful news, or otherwise misleading thumbnail/text/tags. Please provide reputable sources to report hoaxes.` }, { id: 'privacy', - label: this.i18n('Privacy breach or doxxing'), - help: this.i18n('Contains personal information that could be used to track, identify, contact or impersonate someone (e.g. name, address, phone number, email, or credit card details).') + label: $localize`Privacy breach or doxxing`, + help: $localize`Contains personal information that could be used to track, identify, contact or impersonate someone (e.g. name, address, phone number, email, or credit card details).` }, { id: 'rights', - label: this.i18n('Copyright'), - help: this.i18n('Infringes your copyright wrt. the regional laws with which the server must comply.') + label: $localize`Copyright`, + help: $localize`Infringes your copyright wrt. the regional laws with which the server must comply.` }, { id: 'serverRules', - label: this.i18n('Breaks server rules'), - description: this.i18n('Anything not included in the above that breaks the terms of service, code of conduct, or general rules in place on the server.') + label: $localize`Breaks server rules`, + description: $localize`Anything not included in the above that breaks the terms of service, code of conduct, or general rules in place on the server.` } ] @@ -172,13 +170,13 @@ export class AbuseService { reasons = reasons.concat([ { id: 'thumbnails', - label: this.i18n('Thumbnails'), - help: this.i18n('The above can only be seen in thumbnails.') + label: $localize`Thumbnails`, + help: $localize`The above can only be seen in thumbnails.` }, { id: 'captions', - label: this.i18n('Captions'), - help: this.i18n('The above can only be seen in captions (please describe which).') + label: $localize`Captions`, + help: $localize`The above can only be seen in captions (please describe which).` } ]) } diff --git a/client/src/app/shared/shared-moderation/account-blocklist.component.ts b/client/src/app/shared/shared-moderation/account-blocklist.component.ts index a5a3c27cd..68928a2c2 100644 --- a/client/src/app/shared/shared-moderation/account-blocklist.component.ts +++ b/client/src/app/shared/shared-moderation/account-blocklist.component.ts @@ -1,8 +1,7 @@ import { SortMeta } from 'primeng/api' -import { OnInit, Directive } from '@angular/core' +import { Directive, OnInit } from '@angular/core' import { Notifier, RestPagination, RestTable } from '@app/core' import { Actor } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { AccountBlock } from './account-block.model' import { BlocklistComponentType, BlocklistService } from './blocklist.service' @@ -19,8 +18,7 @@ export class GenericAccountBlocklistComponent extends RestTable implements OnIni constructor ( private notifier: Notifier, - private blocklistService: BlocklistService, - private i18n: I18n + private blocklistService: BlocklistService ) { super() } @@ -46,8 +44,8 @@ export class GenericAccountBlocklistComponent extends RestTable implements OnIni () => { this.notifier.success( this.mode === BlocklistComponentType.Account - ? this.i18n('Account {{nameWithHost}} unmuted.', { nameWithHost: blockedAccount.nameWithHost }) - : this.i18n('Account {{nameWithHost}} unmuted by your instance.', { nameWithHost: blockedAccount.nameWithHost }) + ? $localize`Account ${blockedAccount.nameWithHost} unmuted.` + : $localize`Account ${blockedAccount.nameWithHost} unmuted by your instance.` ) this.loadData() diff --git a/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts b/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts index fdd4a79a9..7193ccb1b 100644 --- a/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts +++ b/client/src/app/shared/shared-moderation/batch-domains-modal.component.ts @@ -2,7 +2,6 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angu import { BatchDomainsValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' @Component({ selector: 'my-batch-domains-modal', @@ -20,14 +19,13 @@ export class BatchDomainsModalComponent extends FormReactive implements OnInit { constructor ( protected formValidatorService: FormValidatorService, private modalService: NgbModal, - private batchDomainsValidatorsService: BatchDomainsValidatorsService, - private i18n: I18n + private batchDomainsValidatorsService: BatchDomainsValidatorsService ) { super() } ngOnInit () { - if (!this.action) this.action = this.i18n('Process domains') + if (!this.action) this.action = $localize`Process domains` this.buildForm({ domains: this.batchDomainsValidatorsService.DOMAINS diff --git a/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts b/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts index 08dbe9538..8ab2fe940 100644 --- a/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts +++ b/client/src/app/shared/shared-moderation/report-modals/account-report.component.ts @@ -5,7 +5,6 @@ import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app import { Account } from '@app/shared/shared-main' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { abusePredefinedReasonsMap } from '@shared/core-utils/abuse' import { AbusePredefinedReasonsString } from '@shared/models' import { AbuseService } from '../abuse.service' @@ -31,8 +30,7 @@ export class AccountReportComponent extends FormReactive implements OnInit { private modalService: NgbModal, private abuseValidatorsService: AbuseValidatorsService, private abuseService: AbuseService, - private notifier: Notifier, - private i18n: I18n + private notifier: Notifier ) { super() } @@ -50,7 +48,7 @@ export class AccountReportComponent extends FormReactive implements OnInit { } ngOnInit () { - this.modalTitle = this.i18n('Report {{displayName}}', { displayName: this.account.displayName }) + this.modalTitle = $localize`Report ${this.account.displayName}` this.buildForm({ reason: this.abuseValidatorsService.ABUSE_REASON, @@ -81,7 +79,7 @@ export class AccountReportComponent extends FormReactive implements OnInit { } }).subscribe( () => { - this.notifier.success(this.i18n('Account reported.')) + this.notifier.success($localize`Account reported.`) this.hide() }, diff --git a/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts b/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts index 2769874d9..d75f4d717 100644 --- a/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts +++ b/client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts @@ -5,7 +5,6 @@ import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app import { VideoComment } from '@app/shared/shared-video-comment' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { abusePredefinedReasonsMap } from '@shared/core-utils/abuse' import { AbusePredefinedReasonsString } from '@shared/models' import { AbuseService } from '../abuse.service' @@ -31,8 +30,7 @@ export class CommentReportComponent extends FormReactive implements OnInit { private modalService: NgbModal, private abuseValidatorsService: AbuseValidatorsService, private abuseService: AbuseService, - private notifier: Notifier, - private i18n: I18n + private notifier: Notifier ) { super() } @@ -50,7 +48,7 @@ export class CommentReportComponent extends FormReactive implements OnInit { } ngOnInit () { - this.modalTitle = this.i18n('Report comment') + this.modalTitle = $localize`Report comment` this.buildForm({ reason: this.abuseValidatorsService.ABUSE_REASON, @@ -81,7 +79,7 @@ export class CommentReportComponent extends FormReactive implements OnInit { } }).subscribe( () => { - this.notifier.success(this.i18n('Comment reported.')) + this.notifier.success($localize`Comment reported.`) this.hide() }, diff --git a/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts b/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts index 794dd54bb..edff6d325 100644 --- a/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts +++ b/client/src/app/shared/shared-moderation/report-modals/video-report.component.ts @@ -1,12 +1,11 @@ import { mapValues, pickBy } from 'lodash-es' -import { buildVideoOrPlaylistEmbed, buildVideoLink } from 'src/assets/player/utils' +import { buildVideoLink, buildVideoOrPlaylistEmbed } from 'src/assets/player/utils' import { Component, Input, OnInit, ViewChild } from '@angular/core' import { DomSanitizer, SafeHtml } from '@angular/platform-browser' import { Notifier } from '@app/core' import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { abusePredefinedReasonsMap } from '@shared/core-utils/abuse' import { AbusePredefinedReasonsString } from '@shared/models' import { Video } from '../../shared-main' @@ -34,8 +33,7 @@ export class VideoReportComponent extends FormReactive implements OnInit { private abuseValidatorsService: AbuseValidatorsService, private abuseService: AbuseService, private notifier: Notifier, - private sanitizer: DomSanitizer, - private i18n: I18n + private sanitizer: DomSanitizer ) { super() } @@ -109,7 +107,7 @@ export class VideoReportComponent extends FormReactive implements OnInit { } }).subscribe( () => { - this.notifier.success(this.i18n('Video reported.')) + this.notifier.success($localize`Video reported.`) this.hide() }, diff --git a/client/src/app/shared/shared-moderation/server-blocklist.component.ts b/client/src/app/shared/shared-moderation/server-blocklist.component.ts index 8f65cdb71..546fd53c3 100644 --- a/client/src/app/shared/shared-moderation/server-blocklist.component.ts +++ b/client/src/app/shared/shared-moderation/server-blocklist.component.ts @@ -2,7 +2,6 @@ import { SortMeta } from 'primeng/api' import { Directive, OnInit, ViewChild } from '@angular/core' import { Notifier, RestPagination, RestTable } from '@app/core' import { BatchDomainsModalComponent } from '@app/shared/shared-moderation/batch-domains-modal.component' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerBlock } from '@shared/models' import { BlocklistComponentType, BlocklistService } from './blocklist.service' @@ -21,8 +20,7 @@ export class GenericServerBlocklistComponent extends RestTable implements OnInit constructor ( protected notifier: Notifier, - protected blocklistService: BlocklistService, - protected i18n: I18n + protected blocklistService: BlocklistService ) { super() } @@ -44,8 +42,8 @@ export class GenericServerBlocklistComponent extends RestTable implements OnInit () => { this.notifier.success( this.mode === BlocklistComponentType.Account - ? this.i18n('Instance {{host}} unmuted.', { host }) - : this.i18n('Instance {{host}} unmuted by your instance.', { host }) + ? $localize`Instance ${host} unmuted.` + : $localize`Instance ${host} unmuted by your instance.` ) this.loadData() @@ -67,8 +65,8 @@ export class GenericServerBlocklistComponent extends RestTable implements OnInit () => { this.notifier.success( this.mode === BlocklistComponentType.Account - ? this.i18n('Instance {{domain}} muted.', { domain }) - : this.i18n('Instance {{domain}} muted by your instance.', { domain }) + ? $localize`Instance ${domain} muted.` + : $localize`Instance ${domain} muted by your instance.` ) this.loadData() diff --git a/client/src/app/shared/shared-moderation/user-ban-modal.component.ts b/client/src/app/shared/shared-moderation/user-ban-modal.component.ts index 124e58669..f9a0381c5 100644 --- a/client/src/app/shared/shared-moderation/user-ban-modal.component.ts +++ b/client/src/app/shared/shared-moderation/user-ban-modal.component.ts @@ -3,7 +3,6 @@ import { Notifier, UserService } from '@app/core' import { FormReactive, FormValidatorService, UserValidatorsService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { User } from '@shared/models' @Component({ @@ -23,8 +22,7 @@ export class UserBanModalComponent extends FormReactive implements OnInit { private modalService: NgbModal, private notifier: Notifier, private userService: UserService, - private userValidatorsService: UserValidatorsService, - private i18n: I18n + private userValidatorsService: UserValidatorsService ) { super() } @@ -52,8 +50,8 @@ export class UserBanModalComponent extends FormReactive implements OnInit { .subscribe( () => { const message = Array.isArray(this.usersToBan) - ? this.i18n('{{num}} users banned.', { num: this.usersToBan.length }) - : this.i18n('User {{username}} banned.', { username: this.usersToBan.username }) + ? $localize`${this.usersToBan.length} users banned.` + : $localize`User ${this.usersToBan.username} banned.` this.notifier.success(message) diff --git a/client/src/app/shared/shared-moderation/user-moderation-dropdown.component.ts b/client/src/app/shared/shared-moderation/user-moderation-dropdown.component.ts index 34fa7366c..44aefa853 100644 --- a/client/src/app/shared/shared-moderation/user-moderation-dropdown.component.ts +++ b/client/src/app/shared/shared-moderation/user-moderation-dropdown.component.ts @@ -1,7 +1,6 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output, ViewChild } from '@angular/core' import { AuthService, ConfirmService, Notifier, ServerService, UserService } from '@app/core' import { Account, DropdownAction } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { BulkRemoveCommentsOfBody, ServerConfig, User, UserRight } from '@shared/models' import { BlocklistService } from './blocklist.service' import { BulkService } from './bulk.service' @@ -37,8 +36,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { private serverService: ServerService, private userService: UserService, private blocklistService: BlocklistService, - private bulkService: BulkService, - private i18n: I18n + private bulkService: BulkService ) { } get requiresEmailVerification () { @@ -57,7 +55,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { openBanUserModal (user: User) { if (user.username === 'root') { - this.notifier.error(this.i18n('You cannot ban root.')) + this.notifier.error($localize`You cannot ban root.`) return } @@ -69,15 +67,13 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { } async unbanUser (user: User) { - const message = this.i18n('Do you really want to unban {{username}}?', { username: user.username }) - const res = await this.confirmService.confirm(message, this.i18n('Unban')) + const res = await this.confirmService.confirm($localize`Do you really want to unban ${user.username}?`, $localize`Unban`) if (res === false) return this.userService.unbanUsers(user) .subscribe( () => { - this.notifier.success(this.i18n('User {{username}} unbanned.', { username: user.username })) - + this.notifier.success($localize`User ${user.username} unbanned.`) this.userChanged.emit() }, @@ -87,17 +83,17 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { async removeUser (user: User) { if (user.username === 'root') { - this.notifier.error(this.i18n('You cannot delete root.')) + this.notifier.error($localize`You cannot delete root.`) return } - const message = this.i18n('If you remove this user, you will not be able to create another with the same username!') - const res = await this.confirmService.confirm(message, this.i18n('Delete')) + const message = $localize`If you remove this user, you will not be able to create another with the same username!` + const res = await this.confirmService.confirm(message, $localize`Delete`) if (res === false) return this.userService.removeUser(user).subscribe( () => { - this.notifier.success(this.i18n('User {{username}} deleted.', { username: user.username })) + this.notifier.success($localize`User ${user.username} deleted.`) this.userDeleted.emit() }, @@ -108,8 +104,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { setEmailAsVerified (user: User) { this.userService.updateUser(user.id, { emailVerified: true }).subscribe( () => { - this.notifier.success(this.i18n('User {{username}} email set as verified', { username: user.username })) - + this.notifier.success($localize`User ${user.username} email set as verified`) this.userChanged.emit() }, @@ -121,7 +116,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.blockAccountByUser(account) .subscribe( () => { - this.notifier.success(this.i18n('Account {{nameWithHost}} muted.', { nameWithHost: account.nameWithHost })) + this.notifier.success($localize`Account ${account.nameWithHost} muted.`) this.account.mutedByUser = true this.userChanged.emit() @@ -135,7 +130,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.unblockAccountByUser(account) .subscribe( () => { - this.notifier.success(this.i18n('Account {{nameWithHost}} unmuted.', { nameWithHost: account.nameWithHost })) + this.notifier.success($localize`Account ${account.nameWithHost} unmuted.`) this.account.mutedByUser = false this.userChanged.emit() @@ -149,7 +144,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.blockServerByUser(host) .subscribe( () => { - this.notifier.success(this.i18n('Instance {{host}} muted.', { host })) + this.notifier.success($localize`Instance ${host} muted.`) this.account.mutedServerByUser = true this.userChanged.emit() @@ -163,7 +158,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.unblockServerByUser(host) .subscribe( () => { - this.notifier.success(this.i18n('Instance {{host}} unmuted.', { host })) + this.notifier.success($localize`Instance ${host} unmuted.`) this.account.mutedServerByUser = false this.userChanged.emit() @@ -177,7 +172,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.blockAccountByInstance(account) .subscribe( () => { - this.notifier.success(this.i18n('Account {{nameWithHost}} muted by the instance.', { nameWithHost: account.nameWithHost })) + this.notifier.success($localize`Account ${account.nameWithHost} muted by the instance.`) this.account.mutedByInstance = true this.userChanged.emit() @@ -191,7 +186,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.unblockAccountByInstance(account) .subscribe( () => { - this.notifier.success(this.i18n('Account {{nameWithHost}} unmuted by the instance.', { nameWithHost: account.nameWithHost })) + this.notifier.success($localize`Account ${account.nameWithHost} unmuted by the instance.`) this.account.mutedByInstance = false this.userChanged.emit() @@ -205,7 +200,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.blockServerByInstance(host) .subscribe( () => { - this.notifier.success(this.i18n('Instance {{host}} muted by the instance.', { host })) + this.notifier.success($localize`Instance ${host} muted by the instance.`) this.account.mutedServerByInstance = true this.userChanged.emit() @@ -219,7 +214,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { this.blocklistService.unblockServerByInstance(host) .subscribe( () => { - this.notifier.success(this.i18n('Instance {{host}} unmuted by the instance.', { host })) + this.notifier.success($localize`Instance ${host} unmuted by the instance.`) this.account.mutedServerByInstance = false this.userChanged.emit() @@ -230,14 +225,14 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { } async bulkRemoveCommentsOf (body: BulkRemoveCommentsOfBody) { - const message = this.i18n('Are you sure you want to remove all the comments of this account?') - const res = await this.confirmService.confirm(message, this.i18n('Delete account comments')) + const message = $localize`Are you sure you want to remove all the comments of this account?` + const res = await this.confirmService.confirm(message, $localize`Delete account comments`) if (res === false) return this.bulkService.removeCommentsOf(body) .subscribe( () => { - this.notifier.success(this.i18n('Will remove comments of this account (may take several minutes).')) + this.notifier.success($localize`Will remove comments of this account (may take several minutes).`) }, err => this.notifier.error(err.message) @@ -265,29 +260,29 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { if (this.user && authUser.hasRight(UserRight.MANAGE_USERS) && authUser.canManage(this.user)) { this.userActions.push([ { - label: this.i18n('Edit user'), - description: this.i18n('Change quota, role, and more.'), + label: $localize`Edit user`, + description: $localize`Change quota, role, and more.`, linkBuilder: ({ user }) => this.getRouterUserEditLink(user) }, { - label: this.i18n('Delete user'), - description: this.i18n('Videos will be deleted, comments will be tombstoned.'), + label: $localize`Delete user`, + description: $localize`Videos will be deleted, comments will be tombstoned.`, handler: ({ user }) => this.removeUser(user) }, { - label: this.i18n('Ban'), - description: this.i18n('User won\'t be able to login anymore, but videos and comments will be kept as is.'), + label: $localize`Ban`, + description: $localize`User won't be able to login anymore, but videos and comments will be kept as is.`, handler: ({ user }) => this.openBanUserModal(user), isDisplayed: ({ user }) => !user.blocked }, { - label: this.i18n('Unban user'), - description: this.i18n('Allow the user to login and create videos/comments again'), + label: $localize`Unban user`, + description: $localize`Allow the user to login and create videos/comments again`, handler: ({ user }) => this.unbanUser(user), isDisplayed: ({ user }) => user.blocked }, { - label: this.i18n('Set Email as Verified'), + label: $localize`Set Email as Verified`, handler: ({ user }) => this.setEmailAsVerified(user), isDisplayed: ({ user }) => this.requiresEmailVerification && !user.blocked && user.emailVerified === false } @@ -299,32 +294,32 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { // User actions this.userActions.push([ { - label: this.i18n('Mute this account'), - description: this.i18n('Hide any content from that user for you.'), + label: $localize`Mute this account`, + description: $localize`Hide any content from that user for you.`, isDisplayed: ({ account }) => account.mutedByUser === false, handler: ({ account }) => this.blockAccountByUser(account) }, { - label: this.i18n('Unmute this account'), - description: this.i18n('Show back content from that user for you.'), + label: $localize`Unmute this account`, + description: $localize`Show back content from that user for you.`, isDisplayed: ({ account }) => account.mutedByUser === true, handler: ({ account }) => this.unblockAccountByUser(account) }, { - label: this.i18n('Mute the instance'), - description: this.i18n('Hide any content from that instance for you.'), + label: $localize`Mute the instance`, + description: $localize`Hide any content from that instance for you.`, isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === false, handler: ({ account }) => this.blockServerByUser(account.host) }, { - label: this.i18n('Unmute the instance'), - description: this.i18n('Show back content from that instance for you.'), + label: $localize`Unmute the instance`, + description: $localize`Show back content from that instance for you.`, isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === true, handler: ({ account }) => this.unblockServerByUser(account.host) }, { - label: this.i18n('Remove comments from your videos'), - description: this.i18n('Remove comments of this account from your videos.'), + label: $localize`Remove comments from your videos`, + description: $localize`Remove comments of this account from your videos.`, handler: ({ account }) => this.bulkRemoveCommentsOf({ accountName: account.nameWithHost, scope: 'my-videos' }) } ]) @@ -335,14 +330,14 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { if (authUser.hasRight(UserRight.MANAGE_ACCOUNTS_BLOCKLIST)) { instanceActions = instanceActions.concat([ { - label: this.i18n('Mute this account by your instance'), - description: this.i18n('Hide any content from that user for you, your instance and its users.'), + label: $localize`Mute this account by your instance`, + description: $localize`Hide any content from that user for you, your instance and its users.`, isDisplayed: ({ account }) => account.mutedByInstance === false, handler: ({ account }) => this.blockAccountByInstance(account) }, { - label: this.i18n('Unmute this account by your instance'), - description: this.i18n('Show back content from that user for you, your instance and its users.'), + label: $localize`Unmute this account by your instance`, + description: $localize`Show back content from that user for you, your instance and its users.`, isDisplayed: ({ account }) => account.mutedByInstance === true, handler: ({ account }) => this.unblockAccountByInstance(account) } @@ -353,14 +348,14 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { if (authUser.hasRight(UserRight.MANAGE_SERVERS_BLOCKLIST)) { instanceActions = instanceActions.concat([ { - label: this.i18n('Mute the instance by your instance'), - description: this.i18n('Hide any content from that instance for you, your instance and its users.'), + label: $localize`Mute the instance by your instance`, + description: $localize`Hide any content from that instance for you, your instance and its users.`, isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === false, handler: ({ account }) => this.blockServerByInstance(account.host) }, { - label: this.i18n('Unmute the instance by your instance'), - description: this.i18n('Show back content from that instance for you, your instance and its users.'), + label: $localize`Unmute the instance by your instance`, + description: $localize`Show back content from that instance for you, your instance and its users.`, isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === true, handler: ({ account }) => this.unblockServerByInstance(account.host) } @@ -370,8 +365,8 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { if (authUser.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT)) { instanceActions = instanceActions.concat([ { - label: this.i18n('Remove comments from your instance'), - description: this.i18n('Remove comments of this account from your instance.'), + label: $localize`Remove comments from your instance`, + description: $localize`Remove comments of this account from your instance.`, handler: ({ account }) => this.bulkRemoveCommentsOf({ accountName: account.nameWithHost, scope: 'instance' }) } ]) diff --git a/client/src/app/shared/shared-moderation/video-block.component.ts b/client/src/app/shared/shared-moderation/video-block.component.ts index 054651e71..2bef9efdd 100644 --- a/client/src/app/shared/shared-moderation/video-block.component.ts +++ b/client/src/app/shared/shared-moderation/video-block.component.ts @@ -4,7 +4,6 @@ import { FormReactive, FormValidatorService, VideoBlockValidatorsService } from import { Video } from '@app/shared/shared-main' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoBlockService } from './video-block.service' @Component({ @@ -28,8 +27,7 @@ export class VideoBlockComponent extends FormReactive implements OnInit { private modalService: NgbModal, private videoBlockValidatorsService: VideoBlockValidatorsService, private videoBlocklistService: VideoBlockService, - private notifier: Notifier, - private i18n: I18n + private notifier: Notifier ) { super() } @@ -59,7 +57,7 @@ export class VideoBlockComponent extends FormReactive implements OnInit { this.videoBlocklistService.blockVideo(this.video.id, reason, unfederate) .subscribe( () => { - this.notifier.success(this.i18n('Video blocked.')) + this.notifier.success($localize`Video blocked.`) this.hide() this.video.blacklisted = true diff --git a/client/src/app/shared/shared-thumbnail/video-thumbnail.component.ts b/client/src/app/shared/shared-thumbnail/video-thumbnail.component.ts index 812c7a508..b2a2cf240 100644 --- a/client/src/app/shared/shared-thumbnail/video-thumbnail.component.ts +++ b/client/src/app/shared/shared-thumbnail/video-thumbnail.component.ts @@ -1,6 +1,5 @@ import { Component, EventEmitter, Input, Output } from '@angular/core' import { ScreenService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { Video } from '../shared-main' @Component({ @@ -25,12 +24,9 @@ export class VideoThumbnailComponent { addToWatchLaterText: string addedToWatchLaterText: string - constructor ( - private screenService: ScreenService, - private i18n: I18n - ) { - this.addToWatchLaterText = this.i18n('Add to watch later') - this.addedToWatchLaterText = this.i18n('Remove from watch later') + constructor (private screenService: ScreenService) { + this.addToWatchLaterText = $localize`Add to watch later` + this.addedToWatchLaterText = $localize`Remove from watch later` } getImageUrl () { diff --git a/client/src/app/shared/shared-user-settings/user-interface-settings.component.ts b/client/src/app/shared/shared-user-settings/user-interface-settings.component.ts index 875ffa3f1..80b88c129 100644 --- a/client/src/app/shared/shared-user-settings/user-interface-settings.component.ts +++ b/client/src/app/shared/shared-user-settings/user-interface-settings.component.ts @@ -2,7 +2,6 @@ import { Subject, Subscription } from 'rxjs' import { Component, Input, OnDestroy, OnInit } from '@angular/core' import { AuthService, Notifier, ServerService, UserService } from '@app/core' import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig, User, UserUpdateMe } from '@shared/models' @Component({ @@ -25,8 +24,7 @@ export class UserInterfaceSettingsComponent extends FormReactive implements OnIn private authService: AuthService, private notifier: Notifier, private userService: UserService, - private serverService: ServerService, - private i18n: I18n + private serverService: ServerService ) { super() } @@ -73,14 +71,14 @@ export class UserInterfaceSettingsComponent extends FormReactive implements OnIn () => { this.authService.refreshUserInformation() - if (this.notifyOnUpdate) this.notifier.success(this.i18n('Interface settings updated.')) + if (this.notifyOnUpdate) this.notifier.success($localize`Interface settings updated.`) }, err => this.notifier.error(err.message) ) } else { this.userService.updateMyAnonymousProfile(details) - if (this.notifyOnUpdate) this.notifier.success(this.i18n('Interface settings updated.')) + if (this.notifyOnUpdate) this.notifier.success($localize`Interface settings updated.`) } } } diff --git a/client/src/app/shared/shared-user-settings/user-video-settings.component.ts b/client/src/app/shared/shared-user-settings/user-video-settings.component.ts index eb340e24d..ab77f6f9c 100644 --- a/client/src/app/shared/shared-user-settings/user-video-settings.component.ts +++ b/client/src/app/shared/shared-user-settings/user-video-settings.component.ts @@ -4,7 +4,6 @@ import { first } from 'rxjs/operators' import { Component, Input, OnDestroy, OnInit } from '@angular/core' import { AuthService, Notifier, ServerService, User, UserService } from '@app/core' import { FormReactive, FormValidatorService, ItemSelectCheckboxValue, SelectOptionsItem } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { UserUpdateMe } from '@shared/models' import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type' @@ -30,14 +29,13 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, private authService: AuthService, private notifier: Notifier, private userService: UserService, - private serverService: ServerService, - private i18n: I18n + private serverService: ServerService ) { super() } ngOnInit () { - this.allLanguagesGroup = this.i18n('All languages') + this.allLanguagesGroup = $localize`All languages` let oldForm: any @@ -56,7 +54,7 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, ]).subscribe(([ languages, config ]) => { const group = this.allLanguagesGroup - this.languageItems = [ { label: this.i18n('Unknown language'), id: '_unknown', group } ] + this.languageItems = [ { label: $localize`Unknown language`, id: '_unknown', group } ] this.languageItems = this.languageItems .concat(languages.map(l => ({ label: l.label, id: l.id, group }))) @@ -101,12 +99,12 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, if (Array.isArray(videoLanguages)) { if (videoLanguages.length > 20) { - this.notifier.error(this.i18n('Too many languages are enabled. Please enable them all or stay below 20 enabled languages.')) + this.notifier.error($localize`Too many languages are enabled. Please enable them all or stay below 20 enabled languages.`) return } if (videoLanguages.length === 0) { - this.notifier.error(this.i18n('You need to enable at least 1 video language.')) + this.notifier.error($localize`You need to enable at least 1 video language.`) return } @@ -133,22 +131,14 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, () => { this.authService.refreshUserInformation() - if (this.notifyOnUpdate) this.notifier.success(this.i18n('Video settings updated.')) + if (this.notifyOnUpdate) this.notifier.success($localize`Video settings updated.`) }, err => this.notifier.error(err.message) ) } else { this.userService.updateMyAnonymousProfile(details) - if (this.notifyOnUpdate) this.notifier.success(this.i18n('Display/Video settings updated.')) + if (this.notifyOnUpdate) this.notifier.success($localize`Display/Video settings updated.`) } } - - getDefaultVideoLanguageLabel () { - return this.i18n('No language') - } - - getSelectedVideoLanguageLabel () { - return this.i18n('{{\'{0} languages selected') - } } diff --git a/client/src/app/shared/shared-user-subscription/subscribe-button.component.ts b/client/src/app/shared/shared-user-subscription/subscribe-button.component.ts index 72fa3f4fd..b918fda06 100644 --- a/client/src/app/shared/shared-user-subscription/subscribe-button.component.ts +++ b/client/src/app/shared/shared-user-subscription/subscribe-button.component.ts @@ -3,7 +3,6 @@ import { Component, Input, OnChanges, OnInit } from '@angular/core' import { Router } from '@angular/router' import { AuthService, Notifier } from '@app/core' import { Account, VideoChannel, VideoService } from '@app/shared/shared-main' -import { I18n } from '@ngx-translate/i18n-polyfill' import { FeedFormat } from '@shared/models' import { UserSubscriptionService } from './user-subscription.service' @@ -31,7 +30,6 @@ export class SubscribeButtonComponent implements OnInit, OnChanges { private router: Router, private notifier: Notifier, private userSubscriptionService: UserSubscriptionService, - private i18n: I18n, private videoService: VideoService ) { } @@ -108,20 +106,14 @@ export class SubscribeButtonComponent implements OnInit, OnChanges { () => { this.notifier.success( this.account - ? this.i18n( - 'Subscribed to all current channels of {{nameWithHost}}. You will be notified of all their new videos.', - { nameWithHost: this.account.displayName } - ) - : this.i18n( - 'Subscribed to {{nameWithHost}}. You will be notified of all their new videos.', - { nameWithHost: this.videoChannels[0].displayName } - ) - , - this.i18n('Subscribed') + ? $localize`Subscribed to all current channels of ${this.account.displayName}. You will be notified of all their new videos.` + : $localize`Subscribed to ${this.videoChannels[0].displayName}. You will be notified of all their new videos.`, + + $localize`Subscribed` ) }, - err => this.notifier.error(err.message) + err => this.notifier.error(err.message) ) } @@ -144,10 +136,10 @@ export class SubscribeButtonComponent implements OnInit, OnChanges { complete: () => { this.notifier.success( this.account - ? this.i18n('Unsubscribed from all channels of {{nameWithHost}}', { nameWithHost: this.account.nameWithHost }) - : this.i18n('Unsubscribed from {{nameWithHost}}', { nameWithHost: this.videoChannels[ 0 ].nameWithHost }) - , - this.i18n('Unsubscribed') + ? $localize`Unsubscribed from all channels of ${this.account.nameWithHost}` + : $localize`Unsubscribed from ${this.videoChannels[ 0 ].nameWithHost}`, + + $localize`Unsubscribed` ) }, diff --git a/client/src/app/shared/shared-video-miniature/abstract-video-list.ts b/client/src/app/shared/shared-video-miniature/abstract-video-list.ts index e18002b74..1b5b8a64b 100644 --- a/client/src/app/shared/shared-video-miniature/abstract-video-list.ts +++ b/client/src/app/shared/shared-video-miniature/abstract-video-list.ts @@ -14,7 +14,6 @@ import { } from '@app/core' import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook' import { GlobalIconName } from '@app/shared/shared-icons' -import { I18n } from '@ngx-translate/i18n-polyfill' import { isLastMonth, isLastWeek, isToday, isYesterday } from '@shared/core-utils/miscs/date' import { ServerConfig, VideoSortField } from '@shared/models' import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type' @@ -89,7 +88,6 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor protected abstract screenService: ScreenService protected abstract storageService: LocalStorageService protected abstract router: Router - protected abstract i18n: I18n abstract titlePage: string private resizeSubscription: Subscription @@ -111,11 +109,11 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor this.groupedDateLabels = { [GroupDate.UNKNOWN]: null, - [GroupDate.TODAY]: this.i18n('Today'), - [GroupDate.YESTERDAY]: this.i18n('Yesterday'), - [GroupDate.LAST_WEEK]: this.i18n('Last week'), - [GroupDate.LAST_MONTH]: this.i18n('Last month'), - [GroupDate.OLDER]: this.i18n('Older') + [GroupDate.TODAY]: $localize`Today`, + [GroupDate.YESTERDAY]: $localize`Yesterday`, + [GroupDate.LAST_WEEK]: $localize`Last week`, + [GroupDate.LAST_MONTH]: $localize`Last month`, + [GroupDate.OLDER]: $localize`Older` } // Subscribe to route changes @@ -192,7 +190,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor }, error => { - const message = this.i18n('Cannot load more videos. Try again later.') + const message = $localize`Cannot load more videos. Try again later.` console.error(message, { error }) this.notifier.error(message) diff --git a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts index 3d1fc8690..39358e08b 100644 --- a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts +++ b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts @@ -1,10 +1,18 @@ import { Component, EventEmitter, Input, OnChanges, Output, ViewChild } from '@angular/core' import { AuthService, ConfirmService, Notifier, ScreenService } from '@app/core' -import { VideoBlockComponent, VideoBlockService, VideoReportComponent, BlocklistService } from '@app/shared/shared-moderation' +import { BlocklistService, VideoBlockComponent, VideoBlockService, VideoReportComponent } from '@app/shared/shared-moderation' import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoCaption } from '@shared/models' -import { DropdownAction, DropdownButtonSize, DropdownDirection, RedundancyService, Video, VideoDetails, VideoService, Actor } from '../shared-main' +import { + Actor, + DropdownAction, + DropdownButtonSize, + DropdownDirection, + RedundancyService, + Video, + VideoDetails, + VideoService +} from '../shared-main' import { VideoAddToPlaylistComponent } from '../shared-video-playlist' import { VideoDownloadComponent } from './video-download.component' @@ -71,8 +79,7 @@ export class VideoActionsDropdownComponent implements OnChanges { private videoBlocklistService: VideoBlockService, private screenService: ScreenService, private videoService: VideoService, - private redundancyService: RedundancyService, - private i18n: I18n + private redundancyService: RedundancyService ) { } get user () { @@ -153,17 +160,15 @@ export class VideoActionsDropdownComponent implements OnChanges { /* Action handlers */ async unblockVideo () { - const confirmMessage = this.i18n( - 'Do you really want to unblock this video? It will be available again in the videos list.' - ) + const confirmMessage = $localize`Do you really want to unblock this video? It will be available again in the videos list.` - const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblock')) + const res = await this.confirmService.confirm(confirmMessage, $localize`Unblock`) if (res === false) return this.videoBlocklistService.unblockVideo(this.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video {{name}} unblocked.', { name: this.video.name })) + this.notifier.success($localize`Video ${this.video.name} unblocked.`) this.video.blacklisted = false this.video.blockedReason = null @@ -178,14 +183,13 @@ export class VideoActionsDropdownComponent implements OnChanges { async removeVideo () { this.modalOpened.emit() - const res = await this.confirmService.confirm(this.i18n('Do you really want to delete this video?'), this.i18n('Delete')) + const res = await this.confirmService.confirm($localize`Do you really want to delete this video?`, $localize`Delete`) if (res === false) return this.videoService.removeVideo(this.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video {{videoName}} deleted.', { videoName: this.video.name })) - + this.notifier.success($localize`Video ${this.video.name} deleted.`) this.videoRemoved.emit() }, @@ -197,7 +201,7 @@ export class VideoActionsDropdownComponent implements OnChanges { this.redundancyService.addVideoRedundancy(this.video) .subscribe( () => { - const message = this.i18n('This video will be duplicated by your instance.') + const message = $localize`This video will be duplicated by your instance.` this.notifier.success(message) }, @@ -211,8 +215,7 @@ export class VideoActionsDropdownComponent implements OnChanges { this.blocklistService.blockAccountByUser(params) .subscribe( () => { - this.notifier.success(this.i18n('Account {{nameWithHost}} muted.', params)) - + this.notifier.success($localize`Account ${params.nameWithHost} muted.`) this.videoAccountMuted.emit() }, @@ -236,7 +239,7 @@ export class VideoActionsDropdownComponent implements OnChanges { this.videoActions = [ [ { - label: this.i18n('Save to playlist'), + label: $localize`Save to playlist`, handler: () => this.playlistDropdown.toggle(), isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.playlist, iconName: 'playlist-add' @@ -244,43 +247,43 @@ export class VideoActionsDropdownComponent implements OnChanges { ], [ // actions regarding the video { - label: this.i18n('Download'), + label: $localize`Download`, handler: () => this.showDownloadModal(), isDisplayed: () => this.displayOptions.download && this.isVideoDownloadable(), iconName: 'download' }, { - label: this.i18n('Update'), + label: $localize`Update`, linkBuilder: ({ video }) => [ '/videos/update', video.uuid ], iconName: 'edit', isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.update && this.isVideoUpdatable() }, { - label: this.i18n('Block'), + label: $localize`Block`, handler: () => this.showBlockModal(), iconName: 'no', isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoBlockable() }, { - label: this.i18n('Unblock'), + label: $localize`Unblock`, handler: () => this.unblockVideo(), iconName: 'undo', isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoUnblockable() }, { - label: this.i18n('Mirror'), + label: $localize`Mirror`, handler: () => this.duplicateVideo(), isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.duplicate && this.canVideoBeDuplicated(), iconName: 'cloud-download' }, { - label: this.i18n('Delete'), + label: $localize`Delete`, handler: () => this.removeVideo(), isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.delete && this.isVideoRemovable(), iconName: 'delete' }, { - label: this.i18n('Report'), + label: $localize`Report`, handler: () => this.showReportModal(), isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.report, iconName: 'flag' @@ -288,7 +291,7 @@ export class VideoActionsDropdownComponent implements OnChanges { ], [ // actions regarding the account/its server { - label: this.i18n('Mute account'), + label: $localize`Mute account`, handler: () => this.muteVideoAccount(), isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.mute && this.isVideoAccountMutable(), iconName: 'no' diff --git a/client/src/app/shared/shared-video-miniature/video-download.component.ts b/client/src/app/shared/shared-video-miniature/video-download.component.ts index e3d6a1969..99838f712 100644 --- a/client/src/app/shared/shared-video-miniature/video-download.component.ts +++ b/client/src/app/shared/shared-video-miniature/video-download.component.ts @@ -2,7 +2,6 @@ import { mapValues, pick } from 'lodash-es' import { Component, ElementRef, ViewChild } from '@angular/core' import { AuthService, Notifier } from '@app/core' import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { VideoCaption, VideoFile, VideoPrivacy } from '@shared/models' import { BytesPipe, NumberFormatterPipe, VideoDetails, VideoService } from '../shared-main' @@ -38,8 +37,7 @@ export class VideoDownloadComponent { private notifier: Notifier, private modalService: NgbModal, private videoService: VideoService, - private auth: AuthService, - private i18n: I18n + private auth: AuthService ) { this.bytesPipe = new BytesPipe() this.numbersPipe = new NumberFormatterPipe() @@ -47,8 +45,8 @@ export class VideoDownloadComponent { get typeText () { return this.type === 'video' - ? this.i18n('video') - : this.i18n('subtitles') + ? $localize`video` + : $localize`subtitles` } getVideoFiles () { @@ -135,7 +133,7 @@ export class VideoDownloadComponent { } activateCopiedMessage () { - this.notifier.success(this.i18n('Copied')) + this.notifier.success($localize`Copied`) } switchToType (type: DownloadType) { @@ -144,11 +142,11 @@ export class VideoDownloadComponent { getMetadataFormat (format: any) { const keyToTranslateFunction = { - 'encoder': (value: string) => ({ label: this.i18n('Encoder'), value }), - 'format_long_name': (value: string) => ({ label: this.i18n('Format name'), value }), - 'size': (value: number) => ({ label: this.i18n('Size'), value: this.bytesPipe.transform(value, 2) }), + 'encoder': (value: string) => ({ label: $localize`Encoder`, value }), + 'format_long_name': (value: string) => ({ label: $localize`Format name`, value }), + 'size': (value: number) => ({ label: $localize`Size`, value: this.bytesPipe.transform(value, 2) }), 'bit_rate': (value: number) => ({ - label: this.i18n('Bitrate'), + label: $localize`Bitrate`, value: `${this.numbersPipe.transform(value)}bps` }) } @@ -168,25 +166,25 @@ export class VideoDownloadComponent { if (!stream) return undefined let keyToTranslateFunction = { - 'codec_long_name': (value: string) => ({ label: this.i18n('Codec'), value }), - 'profile': (value: string) => ({ label: this.i18n('Profile'), value }), + 'codec_long_name': (value: string) => ({ label: $localize`Codec`, value }), + 'profile': (value: string) => ({ label: $localize`Profile`, value }), 'bit_rate': (value: number) => ({ - label: this.i18n('Bitrate'), + label: $localize`Bitrate`, value: `${this.numbersPipe.transform(value)}bps` }) } if (type === 'video') { keyToTranslateFunction = Object.assign(keyToTranslateFunction, { - 'width': (value: number) => ({ label: this.i18n('Resolution'), value: `${value}x${stream.height}` }), - 'display_aspect_ratio': (value: string) => ({ label: this.i18n('Aspect ratio'), value }), - 'avg_frame_rate': (value: string) => ({ label: this.i18n('Average frame rate'), value }), - 'pix_fmt': (value: string) => ({ label: this.i18n('Pixel format'), value }) + 'width': (value: number) => ({ label: $localize`Resolution`, value: `${value}x${stream.height}` }), + 'display_aspect_ratio': (value: string) => ({ label: $localize`Aspect ratio`, value }), + 'avg_frame_rate': (value: string) => ({ label: $localize`Average frame rate`, value }), + 'pix_fmt': (value: string) => ({ label: $localize`Pixel format`, value }) }) } else { keyToTranslateFunction = Object.assign(keyToTranslateFunction, { - 'sample_rate': (value: number) => ({ label: this.i18n('Sample rate'), value }), - 'channel_layout': (value: number) => ({ label: this.i18n('Channel Layout'), value }) + 'sample_rate': (value: number) => ({ label: $localize`Sample rate`, value }), + 'channel_layout': (value: number) => ({ label: $localize`Channel Layout`, value }) }) } diff --git a/client/src/app/shared/shared-video-miniature/video-miniature.component.ts b/client/src/app/shared/shared-video-miniature/video-miniature.component.ts index 3c7046de5..cc5665ab1 100644 --- a/client/src/app/shared/shared-video-miniature/video-miniature.component.ts +++ b/client/src/app/shared/shared-video-miniature/video-miniature.component.ts @@ -11,7 +11,6 @@ import { Output } from '@angular/core' import { AuthService, ScreenService, ServerService, User } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig, VideoPlaylistType, VideoPrivacy, VideoState } from '@shared/models' import { Video } from '../shared-main' import { VideoPlaylistService } from '../shared-video-playlist' @@ -95,7 +94,6 @@ export class VideoMiniatureComponent implements OnInit { constructor ( private screenService: ScreenService, private serverService: ServerService, - private i18n: I18n, private authService: AuthService, private videoPlaylistService: VideoPlaylistService, private cd: ChangeDetectorRef, @@ -116,10 +114,7 @@ export class VideoMiniatureComponent implements OnInit { this.setUpBy() - this.channelLinkTitle = this.i18n( - '{{name}} (channel page)', - { name: this.video.channel.name, handle: this.video.byVideoChannel } - ) + this.channelLinkTitle = $localize`${this.video.channel.name} (channel page)` // We rely on mouseenter to lazy load actions if (this.screenService.isInTouchScreen()) { @@ -164,24 +159,24 @@ export class VideoMiniatureComponent implements OnInit { if (!video.state) return '' if (video.privacy.id !== VideoPrivacy.PRIVATE && video.state.id === VideoState.PUBLISHED) { - return this.i18n('Published') + return $localize`Published` } if (video.scheduledUpdate) { const updateAt = new Date(video.scheduledUpdate.updateAt.toString()).toLocaleString(this.localeId) - return this.i18n('Publication scheduled on ') + updateAt + return $localize`Publication scheduled on ` + updateAt } if (video.state.id === VideoState.TO_TRANSCODE && video.waitTranscoding === true) { - return this.i18n('Waiting transcoding') + return $localize`Waiting transcoding` } if (video.state.id === VideoState.TO_TRANSCODE) { - return this.i18n('To transcode') + return $localize`To transcode` } if (video.state.id === VideoState.TO_IMPORT) { - return this.i18n('To import') + return $localize`To import` } return '' diff --git a/client/src/app/shared/shared-video-miniature/videos-selection.component.ts b/client/src/app/shared/shared-video-miniature/videos-selection.component.ts index 3e0e3b983..2b060b130 100644 --- a/client/src/app/shared/shared-video-miniature/videos-selection.component.ts +++ b/client/src/app/shared/shared-video-miniature/videos-selection.component.ts @@ -13,7 +13,6 @@ import { } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { AuthService, ComponentPagination, LocalStorageService, Notifier, ScreenService, ServerService, UserService } from '@app/core' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ResultList, VideoSortField } from '@shared/models' import { PeerTubeTemplateDirective, Video } from '../shared-main' import { AbstractVideoList } from './abstract-video-list' @@ -45,7 +44,6 @@ export class VideosSelectionComponent extends AbstractVideoList implements OnIni globalButtonsTemplate: TemplateRef constructor ( - protected i18n: I18n, protected router: Router, protected route: ActivatedRoute, protected notifier: Notifier, diff --git a/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts b/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts index f611fc46b..757ffa099 100644 --- a/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts +++ b/client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts @@ -4,7 +4,6 @@ import { debounceTime, filter } from 'rxjs/operators' import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core' import { AuthService, DisableForReuseHook, Notifier } from '@app/core' import { FormReactive, FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/shared-forms' -import { I18n } from '@ngx-translate/i18n-polyfill' import { Video, VideoExistInPlaylist, VideoPlaylistCreate, VideoPlaylistElementCreate, VideoPlaylistPrivacy } from '@shared/models' import { secondsToTime } from '../../../assets/player/utils' import { CachedPlaylist, VideoPlaylistService } from './video-playlist.service' @@ -53,7 +52,6 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, protected formValidatorService: FormValidatorService, private authService: AuthService, private notifier: Notifier, - private i18n: I18n, private videoPlaylistService: VideoPlaylistService, private videoPlaylistValidatorsService: VideoPlaylistValidatorsService, private cd: ChangeDetectorRef @@ -204,7 +202,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, playlist.playlistElementId, this.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Video removed from {{name}}', { name: playlist.displayName })) + this.notifier.success($localize`Video removed from ${playlist.displayName}`) }, err => { @@ -262,8 +260,8 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, .subscribe( () => { const message = body.startTimestamp || body.stopTimestamp - ? this.i18n('Video added in {{n}} at timestamps {{t}}', { n: playlist.displayName, t: this.formatTimestamp(playlist) }) - : this.i18n('Video added in {{n}}', { n: playlist.displayName }) + ? $localize`Video added in ${playlist.displayName} at timestamps ${this.formatTimestamp(playlist)}` + : $localize`Video added in ${playlist.displayName}` this.notifier.success(message) }, diff --git a/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts b/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts index 57a5fbe61..5879c4978 100644 --- a/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts +++ b/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts @@ -2,7 +2,6 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, In import { AuthService, Notifier, ServerService } from '@app/core' import { Video } from '@app/shared/shared-main' import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' -import { I18n } from '@ngx-translate/i18n-polyfill' import { ServerConfig, VideoPlaylistElementType, VideoPlaylistElementUpdate } from '@shared/models' import { secondsToTime } from '../../../assets/player/utils' import { VideoPlaylistElement } from './video-playlist-element.model' @@ -44,7 +43,6 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit { private authService: AuthService, private serverService: ServerService, private notifier: Notifier, - private i18n: I18n, private videoPlaylistService: VideoPlaylistService, private cdr: ChangeDetectorRef ) {} @@ -97,8 +95,7 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit { this.videoPlaylistService.removeVideoFromPlaylist(this.playlist.id, playlistElement.id, videoId) .subscribe( () => { - this.notifier.success(this.i18n('Video removed from {{name}}', { name: this.playlist.displayName })) - + this.notifier.success($localize`Video removed from ${this.playlist.displayName}`) this.elementRemoved.emit(playlistElement) }, @@ -117,7 +114,7 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit { this.videoPlaylistService.updateVideoOfPlaylist(this.playlist.id, playlistElement.id, body, this.playlistElement.video.id) .subscribe( () => { - this.notifier.success(this.i18n('Timestamps updated')) + this.notifier.success($localize`Timestamps updated`) playlistElement.startTimestamp = body.startTimestamp playlistElement.stopTimestamp = body.stopTimestamp @@ -140,10 +137,10 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit { if (start === null && stop === null) return '' - if (start !== null && stop === null) return this.i18n('Starts at ') + startFormatted - if (start === null && stop !== null) return this.i18n('Stops at ') + stopFormatted + if (start !== null && stop === null) return $localize`Starts at ` + startFormatted + if (start === null && stop !== null) return $localize`Stops at ` + stopFormatted - return this.i18n('Starts at ') + startFormatted + this.i18n(' and stops at ') + stopFormatted + return $localize`Starts at ` + startFormatted + $localize` and stops at ` + stopFormatted } onDropdownOpenChange () { -- cgit v1.2.3