mirror of https://github.com/Chocobozzz/PeerTube
				
				
				
			Simplify ICU in components
							parent
							
								
									40346ead2b
								
							
						
					
					
						commit
						866c5f667d
					
				| 
						 | 
				
			
			@ -199,7 +199,11 @@
 | 
			
		|||
              "is-plain-object",
 | 
			
		||||
              "parse-srcset",
 | 
			
		||||
              "deepmerge",
 | 
			
		||||
              "core-js/features/reflect"
 | 
			
		||||
              "core-js/features/reflect",
 | 
			
		||||
              "@formatjs/intl-locale/polyfill",
 | 
			
		||||
              "@formatjs/intl-locale/should-polyfill",
 | 
			
		||||
              "@formatjs/intl-pluralrules/polyfill-force",
 | 
			
		||||
              "@formatjs/intl-pluralrules/should-polyfill"
 | 
			
		||||
            ],
 | 
			
		||||
            "scripts": [],
 | 
			
		||||
            "vendorChunk": true,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,6 +47,8 @@
 | 
			
		|||
    "@angular/service-worker": "^16.0.2",
 | 
			
		||||
    "@babel/core": "^7.18.5",
 | 
			
		||||
    "@babel/preset-env": "^7.18.2",
 | 
			
		||||
    "@formatjs/intl-locale": "^3.3.1",
 | 
			
		||||
    "@formatjs/intl-pluralrules": "^5.2.2",
 | 
			
		||||
    "@ng-bootstrap/ng-bootstrap": "^14.0.1",
 | 
			
		||||
    "@ng-select/ng-select": "^10.0.3",
 | 
			
		||||
    "@ngx-loading-bar/core": "^6.0.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import { Injectable } from '@angular/core'
 | 
			
		||||
import { FormGroup } from '@angular/forms'
 | 
			
		||||
import { prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU } from '@app/helpers'
 | 
			
		||||
 | 
			
		||||
export type ResolutionOption = {
 | 
			
		||||
  id: string
 | 
			
		||||
| 
						 | 
				
			
			@ -99,10 +99,7 @@ export class EditConfigurationService {
 | 
			
		|||
    return {
 | 
			
		||||
      value,
 | 
			
		||||
      atMost: noneOnAuto, // auto switches everything to a least estimation since ffmpeg will take as many threads as possible
 | 
			
		||||
      unit: prepareIcu($localize`{value, plural, =1 {thread} other {threads}}`)(
 | 
			
		||||
        { value },
 | 
			
		||||
        $localize`threads`
 | 
			
		||||
      )
 | 
			
		||||
      unit: formatICU($localize`{value, plural, =1 {thread} other {threads}}`, { value })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import { SortMeta } from 'primeng/api'
 | 
			
		||||
import { Component, OnInit } from '@angular/core'
 | 
			
		||||
import { ConfirmService, Notifier, RestPagination, RestTable } from '@app/core'
 | 
			
		||||
import { prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU } from '@app/helpers'
 | 
			
		||||
import { AdvancedInputFilter } from '@app/shared/shared-forms'
 | 
			
		||||
import { InstanceFollowService } from '@app/shared/shared-instance'
 | 
			
		||||
import { DropdownAction } from '@app/shared/shared-main'
 | 
			
		||||
| 
						 | 
				
			
			@ -63,9 +63,9 @@ export class FollowersListComponent extends RestTable <ActorFollow> implements O
 | 
			
		|||
      .subscribe({
 | 
			
		||||
        next: () => {
 | 
			
		||||
          // eslint-disable-next-line max-len
 | 
			
		||||
          const message = prepareIcu($localize`Accepted {count, plural, =1 {{followerName} follow request} other {{count} follow requests}}`)(
 | 
			
		||||
            { count: follows.length, followerName: this.buildFollowerName(follows[0]) },
 | 
			
		||||
            $localize`Follow requests accepted`
 | 
			
		||||
          const message = formatICU(
 | 
			
		||||
            $localize`Accepted {count, plural, =1 {{followerName} follow request} other {{count} follow requests}}`,
 | 
			
		||||
            { count: follows.length, followerName: this.buildFollowerName(follows[0]) }
 | 
			
		||||
          )
 | 
			
		||||
          this.notifier.success(message)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -78,9 +78,9 @@ export class FollowersListComponent extends RestTable <ActorFollow> implements O
 | 
			
		|||
 | 
			
		||||
  async rejectFollower (follows: ActorFollow[]) {
 | 
			
		||||
    // eslint-disable-next-line max-len
 | 
			
		||||
    const message = prepareIcu($localize`Do you really want to reject {count, plural, =1 {{followerName} follow request?} other {{count} follow requests?}}`)(
 | 
			
		||||
      { count: follows.length, followerName: this.buildFollowerName(follows[0]) },
 | 
			
		||||
      $localize`Do you really want to reject these follow requests?`
 | 
			
		||||
    const message = formatICU(
 | 
			
		||||
      $localize`Do you really want to reject {count, plural, =1 {{followerName} follow request?} other {{count} follow requests?}}`,
 | 
			
		||||
      { count: follows.length, followerName: this.buildFollowerName(follows[0]) }
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    const res = await this.confirmService.confirm(message, $localize`Reject`)
 | 
			
		||||
| 
						 | 
				
			
			@ -90,9 +90,9 @@ export class FollowersListComponent extends RestTable <ActorFollow> implements O
 | 
			
		|||
        .subscribe({
 | 
			
		||||
          next: () => {
 | 
			
		||||
            // eslint-disable-next-line max-len
 | 
			
		||||
            const message = prepareIcu($localize`Rejected {count, plural, =1 {{followerName} follow request} other {{count} follow requests}}`)(
 | 
			
		||||
              { count: follows.length, followerName: this.buildFollowerName(follows[0]) },
 | 
			
		||||
              $localize`Follow requests rejected`
 | 
			
		||||
            const message = formatICU(
 | 
			
		||||
              $localize`Rejected {count, plural, =1 {{followerName} follow request} other {{count} follow requests}}`,
 | 
			
		||||
              { count: follows.length, followerName: this.buildFollowerName(follows[0]) }
 | 
			
		||||
            )
 | 
			
		||||
            this.notifier.success(message)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -110,9 +110,9 @@ export class FollowersListComponent extends RestTable <ActorFollow> implements O
 | 
			
		|||
    message += '<br /><br />'
 | 
			
		||||
 | 
			
		||||
    // eslint-disable-next-line max-len
 | 
			
		||||
    message += prepareIcu($localize`Do you really want to delete {count, plural, =1 {{followerName} follow request?} other {{count} follow requests?}}`)(
 | 
			
		||||
      icuParams,
 | 
			
		||||
      $localize`Do you really want to delete these follow requests?`
 | 
			
		||||
    message += formatICU(
 | 
			
		||||
      $localize`Do you really want to delete {count, plural, =1 {{followerName} follow request?} other {{count} follow requests?}}`,
 | 
			
		||||
      icuParams
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    const res = await this.confirmService.confirm(message, $localize`Delete`)
 | 
			
		||||
| 
						 | 
				
			
			@ -122,9 +122,9 @@ export class FollowersListComponent extends RestTable <ActorFollow> implements O
 | 
			
		|||
        .subscribe({
 | 
			
		||||
          next: () => {
 | 
			
		||||
            // eslint-disable-next-line max-len
 | 
			
		||||
            const message = prepareIcu($localize`Removed {count, plural, =1 {{followerName} follow request} other {{count} follow requests}}`)(
 | 
			
		||||
              icuParams,
 | 
			
		||||
              $localize`Follow requests removed`
 | 
			
		||||
            const message = formatICU(
 | 
			
		||||
              $localize`Removed {count, plural, =1 {{followerName} follow request} other {{count} follow requests}}`,
 | 
			
		||||
              icuParams
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            this.notifier.success(message)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
 | 
			
		||||
import { Notifier } from '@app/core'
 | 
			
		||||
import { prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU } from '@app/helpers'
 | 
			
		||||
import { splitAndGetNotEmpty, UNIQUE_HOSTS_OR_HANDLE_VALIDATOR } from '@app/shared/form-validators/host-validators'
 | 
			
		||||
import { FormReactive, FormReactiveService } from '@app/shared/shared-forms'
 | 
			
		||||
import { InstanceFollowService } from '@app/shared/shared-instance'
 | 
			
		||||
| 
						 | 
				
			
			@ -62,9 +62,9 @@ export class FollowModalComponent extends FormReactive implements OnInit {
 | 
			
		|||
      .subscribe({
 | 
			
		||||
        next: () => {
 | 
			
		||||
          this.notifier.success(
 | 
			
		||||
            prepareIcu($localize`{count, plural, =1 {Follow request sent!} other {Follow requests sent!}}`)(
 | 
			
		||||
              { count: hostsOrHandles.length },
 | 
			
		||||
              $localize`Follow request(s) sent!`
 | 
			
		||||
            formatICU(
 | 
			
		||||
              $localize`{count, plural, =1 {Follow request sent!} other {Follow requests sent!}}`,
 | 
			
		||||
              { count: hostsOrHandles.length }
 | 
			
		||||
            )
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ import { InstanceFollowService } from '@app/shared/shared-instance'
 | 
			
		|||
import { ActorFollow } from '@shared/models'
 | 
			
		||||
import { FollowModalComponent } from './follow-modal.component'
 | 
			
		||||
import { DropdownAction } from '@app/shared/shared-main'
 | 
			
		||||
import { prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU } from '@app/helpers'
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  templateUrl: './following-list.component.html',
 | 
			
		||||
| 
						 | 
				
			
			@ -64,9 +64,9 @@ export class FollowingListComponent extends RestTable <ActorFollow> implements O
 | 
			
		|||
  async removeFollowing (follows: ActorFollow[]) {
 | 
			
		||||
    const icuParams = { count: follows.length, entryName: this.buildFollowingName(follows[0]) }
 | 
			
		||||
 | 
			
		||||
    const message = prepareIcu($localize`Do you really want to unfollow {count, plural, =1 {{entryName}?} other {{count} entries?}}`)(
 | 
			
		||||
      icuParams,
 | 
			
		||||
      $localize`Do you really want to unfollow these entries?`
 | 
			
		||||
    const message = formatICU(
 | 
			
		||||
      $localize`Do you really want to unfollow {count, plural, =1 {{entryName}?} other {{count} entries?}}`,
 | 
			
		||||
      icuParams
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    const res = await this.confirmService.confirm(message, $localize`Unfollow`)
 | 
			
		||||
| 
						 | 
				
			
			@ -76,9 +76,9 @@ export class FollowingListComponent extends RestTable <ActorFollow> implements O
 | 
			
		|||
      .subscribe({
 | 
			
		||||
        next: () => {
 | 
			
		||||
          // eslint-disable-next-line max-len
 | 
			
		||||
          const message = prepareIcu($localize`You are not following {count, plural, =1 {{entryName} anymore.} other {these {count} entries anymore.}}`)(
 | 
			
		||||
            icuParams,
 | 
			
		||||
            $localize`You are not following them anymore.`
 | 
			
		||||
          const message = formatICU(
 | 
			
		||||
            $localize`You are not following {count, plural, =1 {{entryName} anymore.} other {these {count} entries anymore.}}`,
 | 
			
		||||
            icuParams
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
          this.notifier.success(message)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@ import { SortMeta } from 'primeng/api'
 | 
			
		|||
import { Component, OnInit, ViewChild } from '@angular/core'
 | 
			
		||||
import { ActivatedRoute, Router } from '@angular/router'
 | 
			
		||||
import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable, ServerService } from '@app/core'
 | 
			
		||||
import { prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU } from '@app/helpers'
 | 
			
		||||
import { AdvancedInputFilter } from '@app/shared/shared-forms'
 | 
			
		||||
import { DropdownAction } from '@app/shared/shared-main'
 | 
			
		||||
import { UserRegistration, UserRegistrationState } from '@shared/models'
 | 
			
		||||
| 
						 | 
				
			
			@ -121,9 +121,9 @@ export class RegistrationListComponent extends RestTable <UserRegistration> impl
 | 
			
		|||
    const icuParams = { count: registrations.length, username: registrations[0].username }
 | 
			
		||||
 | 
			
		||||
    // eslint-disable-next-line max-len
 | 
			
		||||
    const message = prepareIcu($localize`Do you really want to delete {count, plural, =1 {{username} registration request?} other {{count} registration requests?}}`)(
 | 
			
		||||
      icuParams,
 | 
			
		||||
      $localize`Do you really want to delete these registration requests?`
 | 
			
		||||
    const message = formatICU(
 | 
			
		||||
      $localize`Do you really want to delete {count, plural, =1 {{username} registration request?} other {{count} registration requests?}}`,
 | 
			
		||||
      icuParams
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    const res = await this.confirmService.confirm(message, $localize`Delete`)
 | 
			
		||||
| 
						 | 
				
			
			@ -133,9 +133,9 @@ export class RegistrationListComponent extends RestTable <UserRegistration> impl
 | 
			
		|||
      .subscribe({
 | 
			
		||||
        next: () => {
 | 
			
		||||
          // eslint-disable-next-line max-len
 | 
			
		||||
          const message = prepareIcu($localize`Removed {count, plural, =1 {{username} registration request} other {{count} registration requests}}`)(
 | 
			
		||||
            icuParams,
 | 
			
		||||
            $localize`Registration requests removed`
 | 
			
		||||
          const message = formatICU(
 | 
			
		||||
            $localize`Removed {count, plural, =1 {{username} registration request} other {{count} registration requests}}`,
 | 
			
		||||
            icuParams
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
          this.notifier.success(message)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ import { DropdownAction } from '@app/shared/shared-main'
 | 
			
		|||
import { BulkService } from '@app/shared/shared-moderation'
 | 
			
		||||
import { VideoCommentAdmin, VideoCommentService } from '@app/shared/shared-video-comment'
 | 
			
		||||
import { FeedFormat, UserRight } from '@shared/models'
 | 
			
		||||
import { prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU } from '@app/helpers'
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'my-video-comment-list',
 | 
			
		||||
| 
						 | 
				
			
			@ -146,9 +146,9 @@ export class VideoCommentListComponent extends RestTable <VideoCommentAdmin> imp
 | 
			
		|||
      .subscribe({
 | 
			
		||||
        next: () => {
 | 
			
		||||
          this.notifier.success(
 | 
			
		||||
            prepareIcu($localize`{count, plural, =1 {1 comment deleted.} other {{count} comments deleted.}}`)(
 | 
			
		||||
              { count: commentArgs.length },
 | 
			
		||||
              $localize`${commentArgs.length} comment(s) deleted.`
 | 
			
		||||
            formatICU(
 | 
			
		||||
              $localize`{count, plural, =1 {1 comment deleted.} other {{count} comments deleted.}}`,
 | 
			
		||||
              { count: commentArgs.length }
 | 
			
		||||
            )
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@ import { SortMeta } from 'primeng/api'
 | 
			
		|||
import { Component, OnInit, ViewChild } from '@angular/core'
 | 
			
		||||
import { ActivatedRoute, Router } from '@angular/router'
 | 
			
		||||
import { AuthService, ConfirmService, LocalStorageService, Notifier, RestPagination, RestTable, ServerService } from '@app/core'
 | 
			
		||||
import { getAPIHost, prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU, getAPIHost } from '@app/helpers'
 | 
			
		||||
import { AdvancedInputFilter } from '@app/shared/shared-forms'
 | 
			
		||||
import { Actor, DropdownAction } from '@app/shared/shared-main'
 | 
			
		||||
import { AccountMutedStatus, BlocklistService, UserBanModalComponent, UserModerationDisplayType } from '@app/shared/shared-moderation'
 | 
			
		||||
| 
						 | 
				
			
			@ -210,9 +210,9 @@ export class UserListComponent extends RestTable <User> implements OnInit {
 | 
			
		|||
 | 
			
		||||
  async unbanUsers (users: User[]) {
 | 
			
		||||
    const res = await this.confirmService.confirm(
 | 
			
		||||
      prepareIcu($localize`Do you really want to unban {count, plural, =1 {1 user} other {{count} users}}?`)(
 | 
			
		||||
        { count: users.length },
 | 
			
		||||
        $localize`Do you really want to unban ${users.length} users?`
 | 
			
		||||
      formatICU(
 | 
			
		||||
        $localize`Do you really want to unban {count, plural, =1 {1 user} other {{count} users}}?`,
 | 
			
		||||
        { count: users.length }
 | 
			
		||||
      ),
 | 
			
		||||
      $localize`Unban`
 | 
			
		||||
    )
 | 
			
		||||
| 
						 | 
				
			
			@ -223,9 +223,9 @@ export class UserListComponent extends RestTable <User> implements OnInit {
 | 
			
		|||
        .subscribe({
 | 
			
		||||
          next: () => {
 | 
			
		||||
            this.notifier.success(
 | 
			
		||||
              prepareIcu($localize`{count, plural, =1 {1 user unbanned.} other {{count} users unbanned.}}`)(
 | 
			
		||||
                { count: users.length },
 | 
			
		||||
                $localize`${users.length} users unbanned.`
 | 
			
		||||
              formatICU(
 | 
			
		||||
                $localize`{count, plural, =1 {1 user unbanned.} other {{count} users unbanned.}}`,
 | 
			
		||||
                { count: users.length }
 | 
			
		||||
              )
 | 
			
		||||
            )
 | 
			
		||||
            this.reloadData()
 | 
			
		||||
| 
						 | 
				
			
			@ -252,9 +252,9 @@ export class UserListComponent extends RestTable <User> implements OnInit {
 | 
			
		|||
      .subscribe({
 | 
			
		||||
        next: () => {
 | 
			
		||||
          this.notifier.success(
 | 
			
		||||
            prepareIcu($localize`{count, plural, =1 {1 user deleted.} other {{count} users deleted.}}`)(
 | 
			
		||||
              { count: users.length },
 | 
			
		||||
              $localize`${users.length} users deleted.`
 | 
			
		||||
            formatICU(
 | 
			
		||||
              $localize`{count, plural, =1 {1 user deleted.} other {{count} users deleted.}}`,
 | 
			
		||||
              { count: users.length }
 | 
			
		||||
            )
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -270,9 +270,9 @@ export class UserListComponent extends RestTable <User> implements OnInit {
 | 
			
		|||
      .subscribe({
 | 
			
		||||
        next: () => {
 | 
			
		||||
          this.notifier.success(
 | 
			
		||||
            prepareIcu($localize`{count, plural, =1 {1 user email set as verified.} other {{count} user emails set as verified.}}`)(
 | 
			
		||||
              { count: users.length },
 | 
			
		||||
              $localize`${users.length} users email set as verified.`
 | 
			
		||||
            formatICU(
 | 
			
		||||
              $localize`{count, plural, =1 {1 user email set as verified.} other {{count} user emails set as verified.}}`,
 | 
			
		||||
              { count: users.length }
 | 
			
		||||
            )
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@ import { finalize } from 'rxjs/operators'
 | 
			
		|||
import { Component, OnInit, ViewChild } from '@angular/core'
 | 
			
		||||
import { ActivatedRoute, Router } from '@angular/router'
 | 
			
		||||
import { AuthService, ConfirmService, Notifier, RestPagination, RestTable } from '@app/core'
 | 
			
		||||
import { prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU } from '@app/helpers'
 | 
			
		||||
import { AdvancedInputFilter } from '@app/shared/shared-forms'
 | 
			
		||||
import { DropdownAction, Video, VideoService } from '@app/shared/shared-main'
 | 
			
		||||
import { VideoBlockComponent, VideoBlockService } from '@app/shared/shared-moderation'
 | 
			
		||||
| 
						 | 
				
			
			@ -219,9 +219,9 @@ export class VideoListComponent extends RestTable <Video> implements OnInit {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  private async removeVideos (videos: Video[]) {
 | 
			
		||||
    const message = prepareIcu($localize`Are you sure you want to delete {count, plural, =1 {this video} other {these {count} videos}}?`)(
 | 
			
		||||
      { count: videos.length },
 | 
			
		||||
      $localize`Are you sure you want to delete these ${videos.length} videos?`
 | 
			
		||||
    const message = formatICU(
 | 
			
		||||
      $localize`Are you sure you want to delete {count, plural, =1 {this video} other {these {count} videos}}?`,
 | 
			
		||||
      { count: videos.length }
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    const res = await this.confirmService.confirm(message, $localize`Delete`)
 | 
			
		||||
| 
						 | 
				
			
			@ -231,9 +231,9 @@ export class VideoListComponent extends RestTable <Video> implements OnInit {
 | 
			
		|||
      .subscribe({
 | 
			
		||||
        next: () => {
 | 
			
		||||
          this.notifier.success(
 | 
			
		||||
            prepareIcu($localize`Deleted {count, plural, =1 {1 video} other {{count} videos}}.`)(
 | 
			
		||||
              { count: videos.length },
 | 
			
		||||
              $localize`Deleted ${videos.length} videos.`
 | 
			
		||||
            formatICU(
 | 
			
		||||
              $localize`Deleted {count, plural, =1 {1 video} other {{count} videos}}.`,
 | 
			
		||||
              { count: videos.length }
 | 
			
		||||
            )
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -249,9 +249,9 @@ export class VideoListComponent extends RestTable <Video> implements OnInit {
 | 
			
		|||
      .subscribe({
 | 
			
		||||
        next: () => {
 | 
			
		||||
          this.notifier.success(
 | 
			
		||||
            prepareIcu($localize`Unblocked {count, plural, =1 {1 video} other {{count} videos}}.`)(
 | 
			
		||||
              { count: videos.length },
 | 
			
		||||
              $localize`Unblocked ${videos.length} videos.`
 | 
			
		||||
            formatICU(
 | 
			
		||||
              $localize`Unblocked {count, plural, =1 {1 video} other {{count} videos}}.`,
 | 
			
		||||
              { count: videos.length }
 | 
			
		||||
            )
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -267,15 +267,15 @@ export class VideoListComponent extends RestTable <Video> implements OnInit {
 | 
			
		|||
 | 
			
		||||
    if (type === 'hls') {
 | 
			
		||||
      // eslint-disable-next-line max-len
 | 
			
		||||
      message = prepareIcu($localize`Are you sure you want to delete {count, plural, =1 {1 HLS streaming playlist} other {{count} HLS streaming playlists}}?`)(
 | 
			
		||||
        { count: videos.length },
 | 
			
		||||
        $localize`Are you sure you want to delete ${videos.length} HLS streaming playlists?`
 | 
			
		||||
      message = formatICU(
 | 
			
		||||
        $localize`Are you sure you want to delete {count, plural, =1 {1 HLS streaming playlist} other {{count} HLS streaming playlists}}?`,
 | 
			
		||||
        { count: videos.length }
 | 
			
		||||
      )
 | 
			
		||||
    } else {
 | 
			
		||||
      // eslint-disable-next-line max-len
 | 
			
		||||
      message = prepareIcu($localize`Are you sure you want to delete WebTorrent files of {count, plural, =1 {1 video} other {{count} videos}}?`)(
 | 
			
		||||
        { count: videos.length },
 | 
			
		||||
        $localize`Are you sure you want to delete WebTorrent files of ${videos.length} videos?`
 | 
			
		||||
      message = formatICU(
 | 
			
		||||
        $localize`Are you sure you want to delete WebTorrent files of {count, plural, =1 {1 video} other {{count} videos}}?`,
 | 
			
		||||
        { count: videos.length }
 | 
			
		||||
      )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import { SortMeta } from 'primeng/api'
 | 
			
		||||
import { Component, OnInit } from '@angular/core'
 | 
			
		||||
import { ConfirmService, Notifier, RestPagination, RestTable } from '@app/core'
 | 
			
		||||
import { prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU } from '@app/helpers'
 | 
			
		||||
import { DropdownAction } from '@app/shared/shared-main'
 | 
			
		||||
import { RunnerJob, RunnerJobState } from '@shared/models'
 | 
			
		||||
import { RunnerJobFormatted, RunnerService } from '../runner.service'
 | 
			
		||||
| 
						 | 
				
			
			@ -57,9 +57,10 @@ export class RunnerJobListComponent extends RestTable <RunnerJob> implements OnI
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  async cancelJobs (jobs: RunnerJob[]) {
 | 
			
		||||
    const message = prepareIcu(
 | 
			
		||||
      $localize`Do you really want to cancel {count, plural, =1 {this job} other {{count} jobs}}? Children jobs will also be cancelled.`
 | 
			
		||||
    )({ count: jobs.length }, $localize`Do you really want to cancel these jobs? Children jobs will also be cancelled.`)
 | 
			
		||||
    const message = formatICU(
 | 
			
		||||
      $localize`Do you really want to cancel {count, plural, =1 {this job} other {{count} jobs}}? Children jobs will also be cancelled.`,
 | 
			
		||||
      { count: jobs.length }
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    const res = await this.confirmService.confirm(message, $localize`Cancel`)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@ import { Component, OnInit, ViewChild } from '@angular/core'
 | 
			
		|||
import { ActivatedRoute, Router } from '@angular/router'
 | 
			
		||||
import { AuthService, ComponentPagination, ConfirmService, Notifier, ScreenService, ServerService, User } from '@app/core'
 | 
			
		||||
import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook'
 | 
			
		||||
import { immutableAssign, prepareIcu } from '@app/helpers'
 | 
			
		||||
import { immutableAssign, formatICU } from '@app/helpers'
 | 
			
		||||
import { AdvancedInputFilter } from '@app/shared/shared-forms'
 | 
			
		||||
import { DropdownAction, Video, VideoService } from '@app/shared/shared-main'
 | 
			
		||||
import { LiveStreamInformationComponent } from '@app/shared/shared-video-live'
 | 
			
		||||
| 
						 | 
				
			
			@ -184,9 +184,9 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook {
 | 
			
		|||
                                    .map(([ k, _v ]) => parseInt(k, 10))
 | 
			
		||||
 | 
			
		||||
    const res = await this.confirmService.confirm(
 | 
			
		||||
      prepareIcu($localize`Do you really want to delete {length, plural, =1 {this video} other {{length} videos}}?`)(
 | 
			
		||||
        { length: toDeleteVideosIds.length },
 | 
			
		||||
        $localize`Do you really want to delete ${toDeleteVideosIds.length} videos?`
 | 
			
		||||
      formatICU(
 | 
			
		||||
        $localize`Do you really want to delete {length, plural, =1 {this video} other {{length} videos}}?`,
 | 
			
		||||
        { length: toDeleteVideosIds.length }
 | 
			
		||||
      ),
 | 
			
		||||
      $localize`Delete`
 | 
			
		||||
    )
 | 
			
		||||
| 
						 | 
				
			
			@ -205,9 +205,9 @@ export class MyVideosComponent implements OnInit, DisableForReuseHook {
 | 
			
		|||
      .subscribe({
 | 
			
		||||
        next: () => {
 | 
			
		||||
          this.notifier.success(
 | 
			
		||||
            prepareIcu($localize`{length, plural, =1 {Video has been deleted} other {{length} videos have been deleted}}`)(
 | 
			
		||||
              { length: toDeleteVideosIds.length },
 | 
			
		||||
              $localize`${toDeleteVideosIds.length} have been deleted.`
 | 
			
		||||
            formatICU(
 | 
			
		||||
              $localize`{length, plural, =1 {Video has been deleted} other {{length} videos have been deleted}}`,
 | 
			
		||||
              { length: toDeleteVideosIds.length }
 | 
			
		||||
            )
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,13 +12,14 @@ import { CoreModule, PluginService, RedirectService, ServerService } from './cor
 | 
			
		|||
import { EmptyComponent } from './empty.component'
 | 
			
		||||
import { HeaderComponent, SearchTypeaheadComponent, SuggestionComponent } from './header'
 | 
			
		||||
import { HighlightPipe } from './header/highlight.pipe'
 | 
			
		||||
import { polyfillICU } from './helpers'
 | 
			
		||||
import { LanguageChooserComponent, MenuComponent, NotificationComponent } from './menu'
 | 
			
		||||
import { AccountSetupWarningModalComponent } from './modal/account-setup-warning-modal.component'
 | 
			
		||||
import { AdminWelcomeModalComponent } from './modal/admin-welcome-modal.component'
 | 
			
		||||
import { ConfirmComponent } from './modal/confirm.component'
 | 
			
		||||
import { CustomModalComponent } from './modal/custom-modal.component'
 | 
			
		||||
import { InstanceConfigWarningModalComponent } from './modal/instance-config-warning-modal.component'
 | 
			
		||||
import { QuickSettingsModalComponent } from './modal/quick-settings-modal.component'
 | 
			
		||||
import { AdminWelcomeModalComponent } from './modal/admin-welcome-modal.component'
 | 
			
		||||
import { AccountSetupWarningModalComponent } from './modal/account-setup-warning-modal.component'
 | 
			
		||||
import { SharedActorImageModule } from './shared/shared-actor-image/shared-actor-image.module'
 | 
			
		||||
import { SharedFormModule } from './shared/shared-forms'
 | 
			
		||||
import { SharedGlobalIconModule } from './shared/shared-icons'
 | 
			
		||||
| 
						 | 
				
			
			@ -90,6 +91,11 @@ export function loadConfigFactory (server: ServerService, pluginService: PluginS
 | 
			
		|||
      useFactory: loadConfigFactory,
 | 
			
		||||
      deps: [ ServerService, PluginService, RedirectService ],
 | 
			
		||||
      multi: true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      provide: APP_INITIALIZER,
 | 
			
		||||
      useFactory: () => polyfillICU,
 | 
			
		||||
      multi: true
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
import IntlMessageFormat from 'intl-messageformat'
 | 
			
		||||
import { shouldPolyfill as shouldPolyfillLocale } from '@formatjs/intl-locale/should-polyfill'
 | 
			
		||||
import { shouldPolyfill as shouldPolyfillPlural } from '@formatjs/intl-pluralrules/should-polyfill'
 | 
			
		||||
import { logger } from '@root-helpers/logger'
 | 
			
		||||
import { environment } from '../../environments/environment'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -10,31 +12,68 @@ function getDevLocale () {
 | 
			
		|||
  return 'fr-FR'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function prepareIcu (icu: string) {
 | 
			
		||||
  let alreadyWarned = false
 | 
			
		||||
async function polyfillICU () {
 | 
			
		||||
  // Important to be in this order, Plural needs Locale (https://formatjs.io/docs/polyfills/intl-pluralrules)
 | 
			
		||||
  await polyfillICULocale()
 | 
			
		||||
  await polyfillICUPlural()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function polyfillICULocale () {
 | 
			
		||||
  // This locale is supported
 | 
			
		||||
  if (shouldPolyfillLocale()) {
 | 
			
		||||
    // TODO: remove, it's only needed to support Plural polyfill and so iOS 12
 | 
			
		||||
    console.log('Loading Intl Locale polyfill for ' + $localize.locale)
 | 
			
		||||
 | 
			
		||||
    await import('@formatjs/intl-locale/polyfill')
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function polyfillICUPlural () {
 | 
			
		||||
  const unsupportedLocale = shouldPolyfillPlural($localize.locale)
 | 
			
		||||
 | 
			
		||||
  // This locale is supported
 | 
			
		||||
  if (!unsupportedLocale) {
 | 
			
		||||
    return
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // TODO: remove, it's only needed to support iOS 12
 | 
			
		||||
  console.log('Loading Intl Plural rules polyfill for ' + $localize.locale)
 | 
			
		||||
 | 
			
		||||
  // Load the polyfill 1st BEFORE loading data
 | 
			
		||||
  await import('@formatjs/intl-pluralrules/polyfill-force')
 | 
			
		||||
  // Degraded mode, so only load the en local data
 | 
			
		||||
  await import(`@formatjs/intl-pluralrules/locale-data/en.js`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const icuCache = new Map<string, IntlMessageFormat>()
 | 
			
		||||
const icuWarnings = new Set<string>()
 | 
			
		||||
const fallback = 'String translation error'
 | 
			
		||||
 | 
			
		||||
function formatICU (icu: string, context: { [id: string]: number | string }) {
 | 
			
		||||
  try {
 | 
			
		||||
    const msg = new IntlMessageFormat(icu, $localize.locale)
 | 
			
		||||
    let msg = icuCache.get(icu)
 | 
			
		||||
 | 
			
		||||
    return (context: { [id: string]: number | string }, fallback: string) => {
 | 
			
		||||
      try {
 | 
			
		||||
        return msg.format(context) as string
 | 
			
		||||
      } catch (err) {
 | 
			
		||||
        if (!alreadyWarned) logger.warn(`Cannot format ICU ${icu}.`, err)
 | 
			
		||||
 | 
			
		||||
        alreadyWarned = true
 | 
			
		||||
        return fallback
 | 
			
		||||
      }
 | 
			
		||||
    if (!msg) {
 | 
			
		||||
      msg = new IntlMessageFormat(icu, $localize.locale)
 | 
			
		||||
      icuCache.set(icu, msg)
 | 
			
		||||
    }
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    logger.warn(`Cannot build intl message ${icu}.`, err)
 | 
			
		||||
 | 
			
		||||
    return (_context: unknown, fallback: string) => fallback
 | 
			
		||||
    return msg.format(context) as string
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    if (!icuWarnings.has(icu)) {
 | 
			
		||||
      logger.warn(`Cannot format ICU ${icu}.`, err)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    icuWarnings.add(icu)
 | 
			
		||||
    return fallback
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
  getDevLocale,
 | 
			
		||||
  prepareIcu,
 | 
			
		||||
  polyfillICU,
 | 
			
		||||
  formatICU,
 | 
			
		||||
  isOnDevLocale
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +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 { formatICU } from '@app/helpers'
 | 
			
		||||
import { SelectOptionsItem } from '../../../../types/select-options-item.model'
 | 
			
		||||
import { ItemSelectCheckboxValue } from './select-checkbox.component'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -80,9 +80,9 @@ export class SelectCheckboxAllComponent implements ControlValueAccessor {
 | 
			
		|||
 | 
			
		||||
    if (outputItems.length >= this.maxItems) {
 | 
			
		||||
      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`
 | 
			
		||||
        formatICU(
 | 
			
		||||
          $localize`You can't select more than {maxItems, plural, =1 {1 item} other {{maxItems} items}}`,
 | 
			
		||||
          { maxItems: this.maxItems }
 | 
			
		||||
        )
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import { Component, OnInit } from '@angular/core'
 | 
			
		||||
import { ServerService } from '@app/core'
 | 
			
		||||
import { prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU } from '@app/helpers'
 | 
			
		||||
import { ServerConfig } from '@shared/models'
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
| 
						 | 
				
			
			@ -71,17 +71,17 @@ export class InstanceFeaturesTableComponent implements OnInit {
 | 
			
		|||
    const hours = Math.floor(seconds / 3600)
 | 
			
		||||
 | 
			
		||||
    if (hours !== 0) {
 | 
			
		||||
      return prepareIcu($localize`~ {hours, plural, =1 {1 hour} other {{hours} hours}}`)(
 | 
			
		||||
        { hours },
 | 
			
		||||
        $localize`~ ${hours} hours`
 | 
			
		||||
      return formatICU(
 | 
			
		||||
        $localize`~ {hours, plural, =1 {1 hour} other {{hours} hours}}`,
 | 
			
		||||
        { hours }
 | 
			
		||||
      )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const minutes = Math.floor(seconds % 3600 / 60)
 | 
			
		||||
 | 
			
		||||
    return prepareIcu($localize`~ {minutes, plural, =1 {1 minute} other {{minutes} minutes}}`)(
 | 
			
		||||
      { minutes },
 | 
			
		||||
      $localize`~ ${minutes} minutes`
 | 
			
		||||
    return formatICU(
 | 
			
		||||
      $localize`~ {minutes, plural, =1 {1 minute} other {{minutes} minutes}}`,
 | 
			
		||||
      { minutes }
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,9 @@
 | 
			
		|||
import { Pipe, PipeTransform } from '@angular/core'
 | 
			
		||||
import { prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU } 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)
 | 
			
		||||
| 
						 | 
				
			
			@ -16,7 +11,7 @@ export class FromNowPipe implements PipeTransform {
 | 
			
		|||
 | 
			
		||||
    let interval = Math.floor(seconds / 31536000)
 | 
			
		||||
    if (interval >= 1) {
 | 
			
		||||
      return this.yearICU({ interval }, $localize`${interval} year(s) ago`)
 | 
			
		||||
      return formatICU($localize`{interval, plural, =1 {1 year ago} other {{interval} years ago}}`, { interval })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    interval = Math.floor(seconds / 2419200)
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +20,7 @@ export class FromNowPipe implements PipeTransform {
 | 
			
		|||
    if (interval >= 12) return $localize`1 year ago`
 | 
			
		||||
 | 
			
		||||
    if (interval >= 1) {
 | 
			
		||||
      return this.monthICU({ interval }, $localize`${interval} month(s) ago`)
 | 
			
		||||
      return formatICU($localize`{interval, plural, =1 {1 month ago} other {{interval} months ago}}`, { interval })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    interval = Math.floor(seconds / 604800)
 | 
			
		||||
| 
						 | 
				
			
			@ -34,17 +29,17 @@ export class FromNowPipe implements PipeTransform {
 | 
			
		|||
    if (interval >= 4) return $localize`1 month ago`
 | 
			
		||||
 | 
			
		||||
    if (interval >= 1) {
 | 
			
		||||
      return this.weekICU({ interval }, $localize`${interval} week(s) ago`)
 | 
			
		||||
      return formatICU($localize`{interval, plural, =1 {1 week ago} other {{interval} weeks ago}}`, { interval })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    interval = Math.floor(seconds / 86400)
 | 
			
		||||
    if (interval >= 1) {
 | 
			
		||||
      return this.dayICU({ interval }, $localize`${interval} day(s) ago`)
 | 
			
		||||
      return formatICU($localize`{interval, plural, =1 {1 day ago} other {{interval} days ago}}`, { interval })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    interval = Math.floor(seconds / 3600)
 | 
			
		||||
    if (interval >= 1) {
 | 
			
		||||
      return this.hourICU({ interval }, $localize`${interval} hour(s) ago`)
 | 
			
		||||
      return formatICU($localize`{interval, plural, =1 {1 hour ago} other {{interval} hours ago}}`, { interval })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    interval = Math.floor(seconds / 60)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import { AuthUser } from '@app/core'
 | 
			
		||||
import { User } from '@app/core/users/user.model'
 | 
			
		||||
import { durationToString, getAbsoluteAPIUrl, getAbsoluteEmbedUrl, prepareIcu } from '@app/helpers'
 | 
			
		||||
import { durationToString, formatICU, getAbsoluteAPIUrl, getAbsoluteEmbedUrl } from '@app/helpers'
 | 
			
		||||
import { Actor } from '@app/shared/shared-main/account/actor.model'
 | 
			
		||||
import { buildVideoWatchPath, getAllFiles } from '@shared/core-utils'
 | 
			
		||||
import { peertubeTranslate } from '@shared/core-utils/i18n'
 | 
			
		||||
| 
						 | 
				
			
			@ -19,9 +19,6 @@ 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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -290,9 +287,9 @@ export class Video implements VideoServerModel {
 | 
			
		|||
 | 
			
		||||
  getExactNumberOfViews () {
 | 
			
		||||
    if (this.isLive) {
 | 
			
		||||
      return Video.viewersICU({ viewers: this.viewers }, $localize`${this.viewers} viewer(s)`)
 | 
			
		||||
      return formatICU($localize`{viewers, plural, =0 {No viewers} =1 {1 viewer} other {{viewers} viewers}}`, { viewers: this.viewers })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return Video.viewsICU({ views: this.views }, $localize`{${this.views} view(s)}`)
 | 
			
		||||
    return formatICU($localize`{views, plural, =0 {No view} =1 {1 view} other {{views} views}}`, { views: this.views })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +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 { formatICU } from '@app/helpers'
 | 
			
		||||
import { FormReactive, FormReactiveService } from '@app/shared/shared-forms'
 | 
			
		||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
 | 
			
		||||
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
 | 
			
		||||
| 
						 | 
				
			
			@ -67,9 +67,9 @@ export class UserBanModalComponent extends FormReactive implements OnInit {
 | 
			
		|||
          let message: string
 | 
			
		||||
 | 
			
		||||
          if (Array.isArray(this.usersToBan)) {
 | 
			
		||||
            message = prepareIcu($localize`{count, plural, =1 {1 user banned.} other {{count} users banned.}}`)(
 | 
			
		||||
              { count: this.usersToBan.length },
 | 
			
		||||
              $localize`${this.usersToBan.length} users banned.`
 | 
			
		||||
            message = formatICU(
 | 
			
		||||
              $localize`{count, plural, =1 {1 user banned.} other {{count} users banned.}}`,
 | 
			
		||||
              { count: this.usersToBan.length }
 | 
			
		||||
            )
 | 
			
		||||
          } else {
 | 
			
		||||
            message = $localize`User ${this.usersToBan.username} banned.`
 | 
			
		||||
| 
						 | 
				
			
			@ -88,9 +88,9 @@ export class UserBanModalComponent extends FormReactive implements OnInit {
 | 
			
		|||
 | 
			
		||||
  getModalTitle () {
 | 
			
		||||
    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 formatICU(
 | 
			
		||||
        $localize`Ban {count, plural, =1 {1 user} other {{count} users}}`,
 | 
			
		||||
        { count: this.usersToBan.length }
 | 
			
		||||
      )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
 | 
			
		||||
import { Notifier } from '@app/core'
 | 
			
		||||
import { prepareIcu } from '@app/helpers'
 | 
			
		||||
import { formatICU } from '@app/helpers'
 | 
			
		||||
import { FormReactive, FormReactiveService } from '@app/shared/shared-forms'
 | 
			
		||||
import { Video } from '@app/shared/shared-main'
 | 
			
		||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
 | 
			
		||||
| 
						 | 
				
			
			@ -81,9 +81,9 @@ export class VideoBlockComponent extends FormReactive implements OnInit {
 | 
			
		|||
    this.videoBlocklistService.blockVideo(options)
 | 
			
		||||
        .subscribe({
 | 
			
		||||
          next: () => {
 | 
			
		||||
            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.`
 | 
			
		||||
            const message = formatICU(
 | 
			
		||||
              $localize`{count, plural, =1 {Blocked {videoName}.} other {Blocked {count} videos.}}`,
 | 
			
		||||
              { count: this.videos.length, videoName: this.getSingleVideo().name }
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            this.notifier.success(message)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,8 +89,7 @@
 | 
			
		|||
  ],
 | 
			
		||||
  "exclude": [
 | 
			
		||||
    "../node_modules",
 | 
			
		||||
    "../server",
 | 
			
		||||
    "node_modules"
 | 
			
		||||
    "../server"
 | 
			
		||||
  ],
 | 
			
		||||
  "angularCompilerOptions": {
 | 
			
		||||
    "strictInjectionParameters": true,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1647,6 +1647,14 @@
 | 
			
		|||
    "@formatjs/intl-localematcher" "0.2.32"
 | 
			
		||||
    tslib "^2.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/ecma402-abstract@1.16.0":
 | 
			
		||||
  version "1.16.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.16.0.tgz#15a0baa8401880d4010eb93440d996e896ca251c"
 | 
			
		||||
  integrity sha512-qIH2cmG/oHGrVdApbqDf6/YR+B2A4NdkBjKLeq369OMVkqMFsC5oPSP1xpiyL1cAn+PbNEZHxwOVMYD/C76c6g==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/intl-localematcher" "0.3.0"
 | 
			
		||||
    tslib "^2.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/fast-memoize@2.0.1":
 | 
			
		||||
  version "2.0.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.0.1.tgz#f15aaa73caad5562899c69bdcad8db82adcd3b0b"
 | 
			
		||||
| 
						 | 
				
			
			@ -1671,6 +1679,30 @@
 | 
			
		|||
    "@formatjs/ecma402-abstract" "1.15.0"
 | 
			
		||||
    tslib "^2.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-enumerator@1.3.1":
 | 
			
		||||
  version "1.3.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/intl-enumerator/-/intl-enumerator-1.3.1.tgz#32f0a3b5aece244977aad16fe1cd5c205defc7f8"
 | 
			
		||||
  integrity sha512-UMuD1tNRb8JC+mZo0KeuSntJNie0+TLxXl/1QxRIRMR7z2UuJgphrK/UTUibAx9hjywL1qGdNNhD6QX//pvNyA==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    tslib "^2.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-getcanonicallocales@2.2.1":
 | 
			
		||||
  version "2.2.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/intl-getcanonicallocales/-/intl-getcanonicallocales-2.2.1.tgz#0d70251b16bec06c1c4a40b37892ea5b51e3a2bb"
 | 
			
		||||
  integrity sha512-KooqmyY+Mhq3ioASPzoU6p6Cy9Mx+cWSVQSP6lF+vEW2tiaN90ti08cp82p1dzFschenduOYgPKrNcBpsDi6+g==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    tslib "^2.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-locale@^3.3.1":
 | 
			
		||||
  version "3.3.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/intl-locale/-/intl-locale-3.3.1.tgz#2b86e85319913e0bedfcd64884be33bc4bcef73e"
 | 
			
		||||
  integrity sha512-Rg3BLIjMzVxBcZCsPhvwIrcfc+UVEzPZPKnvoOLh6KNNWrzWnRo0ORQEE/KRDyvYZxAmALV/GHCcRl+qlchKuw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract" "1.16.0"
 | 
			
		||||
    "@formatjs/intl-enumerator" "1.3.1"
 | 
			
		||||
    "@formatjs/intl-getcanonicallocales" "2.2.1"
 | 
			
		||||
    tslib "^2.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-localematcher@0.2.32":
 | 
			
		||||
  version "0.2.32"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.2.32.tgz#00d4d307cd7d514b298e15a11a369b86c8933ec1"
 | 
			
		||||
| 
						 | 
				
			
			@ -1678,6 +1710,22 @@
 | 
			
		|||
  dependencies:
 | 
			
		||||
    tslib "^2.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-localematcher@0.3.0":
 | 
			
		||||
  version "0.3.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.3.0.tgz#9ad570d90d302b60bcbe78efd5fcd7593c440579"
 | 
			
		||||
  integrity sha512-NFoxXX3dtZ6B53NlCErq181NxN/noMZOWKHfcEPQRNfV0a19THxyjxu2RTSNS3532wGm6fOdid5qsBQWg0Rhtw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    tslib "^2.4.0"
 | 
			
		||||
 | 
			
		||||
"@formatjs/intl-pluralrules@^5.2.2":
 | 
			
		||||
  version "5.2.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@formatjs/intl-pluralrules/-/intl-pluralrules-5.2.2.tgz#6322d20a6d0172459e4faf4b0f06603c931673aa"
 | 
			
		||||
  integrity sha512-mEbnbRzsSCIYqaBmrmUlOsPu5MG6KfMcnzekPzUrUucX2dNiI1KWBGHK6IoXl5c8zx60L1NXJ6cSQ7akoc15SQ==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@formatjs/ecma402-abstract" "1.15.0"
 | 
			
		||||
    "@formatjs/intl-localematcher" "0.2.32"
 | 
			
		||||
    tslib "^2.4.0"
 | 
			
		||||
 | 
			
		||||
"@gar/promisify@^1.1.3":
 | 
			
		||||
  version "1.1.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue