From eaa529528cafcfb291009f9f99d296c81e792899 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 24 May 2022 16:29:01 +0200 Subject: Support ICU in TS components --- .../select/select-checkbox-all.component.ts | 8 ++++- .../instance-features-table.component.ts | 18 ++++++++---- .../shared/shared-main/angular/from-now.pipe.ts | 34 +++++++++++++++------- .../app/shared/shared-main/video/video.model.ts | 11 +++---- .../shared-moderation/user-ban-modal.component.ts | 21 ++++++++++--- .../user-moderation-dropdown.component.ts | 3 +- .../shared-moderation/video-block.component.ts | 8 +++-- .../user-video-settings.component.html | 2 +- .../video-miniature.component.ts | 2 +- 9 files changed, 75 insertions(+), 32 deletions(-) (limited to 'client/src/app/shared') diff --git a/client/src/app/shared/shared-forms/select/select-checkbox-all.component.ts b/client/src/app/shared/shared-forms/select/select-checkbox-all.component.ts index ebf7b77a6..2c3226f68 100644 --- a/client/src/app/shared/shared-forms/select/select-checkbox-all.component.ts +++ b/client/src/app/shared/shared-forms/select/select-checkbox-all.component.ts @@ -1,6 +1,7 @@ import { Component, forwardRef, Input } from '@angular/core' import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' import { Notifier } from '@app/core' +import { prepareIcu } from '@app/helpers' import { SelectOptionsItem } from '../../../../types/select-options-item.model' import { ItemSelectCheckboxValue } from './select-checkbox.component' @@ -78,7 +79,12 @@ export class SelectCheckboxAllComponent implements ControlValueAccessor { if (!outputItems) return true if (outputItems.length >= this.maxItems) { - this.notifier.error($localize`You can't select more than ${this.maxItems} items`) + this.notifier.error( + prepareIcu($localize`You can't select more than {maxItems, plural, =1 {1 item} other {{maxItems} items}}`)( + { maxItems: this.maxItems }, + $localize`You can't select more than ${this.maxItems} items` + ) + ) return false } 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 6335de450..e405c5790 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,5 +1,6 @@ import { Component, OnInit } from '@angular/core' import { ServerService } from '@app/core' +import { prepareIcu } from '@app/helpers' import { ServerConfig } from '@shared/models' import { PeertubeModalService } from '../shared-main/peertube-modal/peertube-modal.service' @@ -65,15 +66,20 @@ export class InstanceFeaturesTableComponent implements OnInit { private getApproximateTime (seconds: number) { const hours = Math.floor(seconds / 3600) - let pluralSuffix = '' - if (hours > 1) pluralSuffix = 's' - if (hours > 0) return `~ ${hours} hour${pluralSuffix}` - const minutes = Math.floor(seconds % 3600 / 60) + if (hours !== 0) { + return prepareIcu($localize`~ {hours, plural, =1 {1 hour} other {{hours} hours}}`)( + { hours }, + $localize`~ ${hours} hours` + ) + } - if (minutes === 1) return $localize`~ 1 minute` + const minutes = Math.floor(seconds % 3600 / 60) - return $localize`~ ${minutes} minutes` + return prepareIcu($localize`~ {minutes, plural, =1 {1 minute} other {{minutes} minutes}}`)( + { minutes }, + $localize`~ ${minutes} minutes` + ) } private buildQuotaHelpIndication () { 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 d62c1f88e..dc6a25e83 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,37 +1,51 @@ import { Pipe, PipeTransform } from '@angular/core' +import { prepareIcu } from '@app/helpers' // 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 { + private yearICU = prepareIcu($localize`{interval, plural, =1 {1 year ago} other {{interval} years ago}}`) + private monthICU = prepareIcu($localize`{interval, plural, =1 {1 month ago} other {{interval} months ago}}`) + private weekICU = prepareIcu($localize`{interval, plural, =1 {1 week ago} other {{interval} weeks ago}}`) + private dayICU = prepareIcu($localize`{interval, plural, =1 {1 day ago} other {{interval} days ago}}`) + private hourICU = prepareIcu($localize`{interval, plural, =1 {1 hour ago} other {{interval} hours ago}}`) + 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 $localize`${interval} years ago` - if (interval === 1) return $localize`1 year ago` + if (interval >= 1) { + return this.yearICU({ interval }, $localize`${interval} year(s) ago`) + } interval = Math.floor(seconds / 2419200) // 12 months = 360 days, but a year ~ 365 days // Display "1 year ago" rather than "12 months ago" if (interval >= 12) return $localize`1 year ago` - if (interval > 1) return $localize`${interval} months ago` - if (interval === 1) return $localize`1 month ago` + + if (interval >= 1) { + return this.monthICU({ interval }, $localize`${interval} month(s) ago`) + } interval = Math.floor(seconds / 604800) // 4 weeks ~ 28 days, but our month is 30 days // Display "1 month ago" rather than "4 weeks ago" if (interval >= 4) return $localize`1 month ago` - if (interval > 1) return $localize`${interval} weeks ago` - if (interval === 1) return $localize`1 week ago` + + if (interval >= 1) { + return this.weekICU({ interval }, $localize`${interval} week(s) ago`) + } interval = Math.floor(seconds / 86400) - if (interval > 1) return $localize`${interval} days ago` - if (interval === 1) return $localize`1 day ago` + if (interval >= 1) { + return this.dayICU({ interval }, $localize`${interval} day(s) ago`) + } interval = Math.floor(seconds / 3600) - if (interval > 1) return $localize`${interval} hours ago` - if (interval === 1) return $localize`1 hour ago` + if (interval >= 1) { + return this.hourICU({ interval }, $localize`${interval} hour(s) ago`) + } interval = Math.floor(seconds / 60) if (interval >= 1) return $localize`${interval} min ago` diff --git a/client/src/app/shared/shared-main/video/video.model.ts b/client/src/app/shared/shared-main/video/video.model.ts index 022bb95ad..2e4ab87d7 100644 --- a/client/src/app/shared/shared-main/video/video.model.ts +++ b/client/src/app/shared/shared-main/video/video.model.ts @@ -1,6 +1,6 @@ import { AuthUser } from '@app/core' import { User } from '@app/core/users/user.model' -import { durationToString, getAbsoluteAPIUrl, getAbsoluteEmbedUrl } from '@app/helpers' +import { durationToString, prepareIcu, getAbsoluteAPIUrl, getAbsoluteEmbedUrl } from '@app/helpers' import { Actor } from '@app/shared/shared-main/account/actor.model' import { buildVideoWatchPath } from '@shared/core-utils' import { peertubeTranslate } from '@shared/core-utils/i18n' @@ -19,6 +19,9 @@ import { } from '@shared/models' export class Video implements VideoServerModel { + private static readonly viewsICU = prepareIcu($localize`{views, plural, =0 {No view} =1 {1 view} other {{views} views}}`) + private static readonly viewersICU = prepareIcu($localize`{viewers, plural, =0 {No viewers} =1 {1 viewer} other {{viewers} viewers}}`) + byVideoChannel: string byAccount: string @@ -269,12 +272,10 @@ export class Video implements VideoServerModel { } getExactNumberOfViews () { - if (this.views < 1000) return '' - if (this.isLive) { - return $localize`${this.views} viewers` + return Video.viewersICU({ viewers: this.viewers }, $localize`${this.viewers} viewer(s)`) } - return $localize`${this.views} views` + return Video.viewsICU({ views: this.views }, $localize`{${this.views} view(s)}`) } } 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 9edfac388..8b483499a 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 @@ -1,6 +1,7 @@ import { forkJoin } from 'rxjs' import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' import { Notifier } from '@app/core' +import { prepareIcu } from '@app/helpers' import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' @@ -63,9 +64,16 @@ export class UserBanModalComponent extends FormReactive implements OnInit { forkJoin(observables) .subscribe({ next: () => { - const message = Array.isArray(this.usersToBan) - ? $localize`${this.usersToBan.length} users banned.` - : $localize`User ${this.usersToBan.username} banned.` + let message: string + + if (Array.isArray(this.usersToBan)) { + message = prepareIcu($localize`{count, plural, =1 {1 user} other {{count} users}} banned.`)( + { count: this.usersToBan.length }, + $localize`${this.usersToBan.length} users banned.` + ) + } else { + message = $localize`User ${this.usersToBan.username} banned.` + } this.notifier.success(message) @@ -79,7 +87,12 @@ export class UserBanModalComponent extends FormReactive implements OnInit { } getModalTitle () { - if (Array.isArray(this.usersToBan)) return $localize`Ban ${this.usersToBan.length} users` + if (Array.isArray(this.usersToBan)) { + return prepareIcu($localize`Ban {count, plural, =1 {1 user} other {{count} users}}`)( + { count: this.usersToBan.length }, + $localize`Ban ${this.usersToBan.length} users` + ) + } return $localize`Ban "${this.usersToBan.username}"` } 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 787318c2c..c69a45c25 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 @@ -100,7 +100,8 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges { return } - const message = $localize`If you remove user ${user.username}, you won't be able to create another with the same username!` + // eslint-disable-next-line max-len + const message = $localize`If you remove this user, you won't be able to create another user or channel with ${user.username} username!` const res = await this.confirmService.confirm(message, $localize`Delete ${user.username}`) if (res === false) return 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 400913f02..e14473b89 100644 --- a/client/src/app/shared/shared-moderation/video-block.component.ts +++ b/client/src/app/shared/shared-moderation/video-block.component.ts @@ -1,5 +1,6 @@ import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' import { Notifier } from '@app/core' +import { prepareIcu } from '@app/helpers' import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' import { Video } from '@app/shared/shared-main' import { NgbModal } from '@ng-bootstrap/ng-bootstrap' @@ -80,9 +81,10 @@ export class VideoBlockComponent extends FormReactive implements OnInit { this.videoBlocklistService.blockVideo(options) .subscribe({ next: () => { - const message = this.isMultiple - ? $localize`Blocked ${this.videos.length} videos.` - : $localize`Blocked ${this.getSingleVideo().name}` + const message = prepareIcu($localize`{count, plural, =1 {Blocked {videoName}} other {Blocked {count} videos}}.`)( + { count: this.videos.length, videoName: this.getSingleVideo().name }, + $localize`Blocked ${this.videos.length} videos.` + ) this.notifier.success(message) this.hide() diff --git a/client/src/app/shared/shared-user-settings/user-video-settings.component.html b/client/src/app/shared/shared-user-settings/user-video-settings.component.html index 446ade445..836972a33 100644 --- a/client/src/app/shared/shared-user-settings/user-video-settings.component.html +++ b/client/src/app/shared/shared-user-settings/user-video-settings.component.html @@ -30,7 +30,7 @@
- +
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 42c472579..534a78b3f 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 @@ -175,7 +175,7 @@ export class VideoMiniatureComponent implements OnInit { if (video.scheduledUpdate) { const updateAt = new Date(video.scheduledUpdate.updateAt.toString()).toLocaleString(this.localeId) - return $localize`Publication scheduled on ` + updateAt + return $localize`Publication scheduled on ${updateAt}` } if (video.state.id === VideoState.TRANSCODING_FAILED) { -- cgit v1.2.3