diff options
Diffstat (limited to 'client/src/app/+admin')
5 files changed, 92 insertions, 22 deletions
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts b/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts index 9b55cb43c..96f5b830e 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts +++ b/client/src/app/+admin/config/edit-custom-config/edit-configuration.service.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { Injectable } from '@angular/core' | 1 | import { Injectable } from '@angular/core' |
2 | import { FormGroup } from '@angular/forms' | 2 | import { FormGroup } from '@angular/forms' |
3 | import { prepareIcu } from '@app/helpers' | ||
3 | 4 | ||
4 | export type ResolutionOption = { | 5 | export type ResolutionOption = { |
5 | id: string | 6 | id: string |
@@ -86,9 +87,10 @@ export class EditConfigurationService { | |||
86 | return { | 87 | return { |
87 | value, | 88 | value, |
88 | atMost: noneOnAuto, // auto switches everything to a least estimation since ffmpeg will take as many threads as possible | 89 | atMost: noneOnAuto, // auto switches everything to a least estimation since ffmpeg will take as many threads as possible |
89 | unit: value > 1 | 90 | unit: prepareIcu($localize`{value, plural, =1 {thread} other {threads}}`)( |
90 | ? $localize`threads` | 91 | { value }, |
91 | : $localize`thread` | 92 | $localize`threads` |
93 | ) | ||
92 | } | 94 | } |
93 | } | 95 | } |
94 | } | 96 | } |
diff --git a/client/src/app/+admin/follows/following-list/follow-modal.component.ts b/client/src/app/+admin/follows/following-list/follow-modal.component.ts index c40b36e10..bac7b2b01 100644 --- a/client/src/app/+admin/follows/following-list/follow-modal.component.ts +++ b/client/src/app/+admin/follows/following-list/follow-modal.component.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' | 1 | import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' |
2 | import { Notifier } from '@app/core' | 2 | import { Notifier } from '@app/core' |
3 | import { prepareIcu } from '@app/helpers' | ||
3 | import { splitAndGetNotEmpty, UNIQUE_HOSTS_OR_HANDLE_VALIDATOR } from '@app/shared/form-validators/host-validators' | 4 | import { splitAndGetNotEmpty, UNIQUE_HOSTS_OR_HANDLE_VALIDATOR } from '@app/shared/form-validators/host-validators' |
4 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' | 5 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' |
5 | import { InstanceFollowService } from '@app/shared/shared-instance' | 6 | import { InstanceFollowService } from '@app/shared/shared-instance' |
@@ -60,7 +61,13 @@ export class FollowModalComponent extends FormReactive implements OnInit { | |||
60 | this.followService.follow(hostsOrHandles) | 61 | this.followService.follow(hostsOrHandles) |
61 | .subscribe({ | 62 | .subscribe({ |
62 | next: () => { | 63 | next: () => { |
63 | this.notifier.success($localize`Follow request(s) sent!`) | 64 | this.notifier.success( |
65 | prepareIcu($localize`{count, plural, =1 {Follow request} other {Follow requests}} sent!`)( | ||
66 | { count: hostsOrHandles.length }, | ||
67 | $localize`Follow request(s) sent!` | ||
68 | ) | ||
69 | ) | ||
70 | |||
64 | this.newFollow.emit() | 71 | this.newFollow.emit() |
65 | }, | 72 | }, |
66 | 73 | ||
diff --git a/client/src/app/+admin/overview/comments/video-comment-list.component.ts b/client/src/app/+admin/overview/comments/video-comment-list.component.ts index f3f43a900..f1b27d846 100644 --- a/client/src/app/+admin/overview/comments/video-comment-list.component.ts +++ b/client/src/app/+admin/overview/comments/video-comment-list.component.ts | |||
@@ -7,6 +7,7 @@ import { DropdownAction } from '@app/shared/shared-main' | |||
7 | import { BulkService } from '@app/shared/shared-moderation' | 7 | import { BulkService } from '@app/shared/shared-moderation' |
8 | import { VideoCommentAdmin, VideoCommentService } from '@app/shared/shared-video-comment' | 8 | import { VideoCommentAdmin, VideoCommentService } from '@app/shared/shared-video-comment' |
9 | import { FeedFormat, UserRight } from '@shared/models' | 9 | import { FeedFormat, UserRight } from '@shared/models' |
10 | import { prepareIcu } from '@app/helpers' | ||
10 | 11 | ||
11 | @Component({ | 12 | @Component({ |
12 | selector: 'my-video-comment-list', | 13 | selector: 'my-video-comment-list', |
@@ -145,7 +146,13 @@ export class VideoCommentListComponent extends RestTable implements OnInit { | |||
145 | this.videoCommentService.deleteVideoComments(commentArgs) | 146 | this.videoCommentService.deleteVideoComments(commentArgs) |
146 | .subscribe({ | 147 | .subscribe({ |
147 | next: () => { | 148 | next: () => { |
148 | this.notifier.success($localize`${commentArgs.length} comments deleted.`) | 149 | this.notifier.success( |
150 | prepareIcu($localize`{count, plural, =1 {1 comment} other {{count} comments}} deleted.`)( | ||
151 | { count: commentArgs.length }, | ||
152 | $localize`${commentArgs.length} comment(s) deleted.` | ||
153 | ) | ||
154 | ) | ||
155 | |||
149 | this.reloadData() | 156 | this.reloadData() |
150 | }, | 157 | }, |
151 | 158 | ||
diff --git a/client/src/app/+admin/overview/users/user-list/user-list.component.ts b/client/src/app/+admin/overview/users/user-list/user-list.component.ts index 9d11bd02e..f7dc22256 100644 --- a/client/src/app/+admin/overview/users/user-list/user-list.component.ts +++ b/client/src/app/+admin/overview/users/user-list/user-list.component.ts | |||
@@ -2,7 +2,7 @@ import { SortMeta } from 'primeng/api' | |||
2 | import { Component, OnInit, ViewChild } from '@angular/core' | 2 | import { Component, OnInit, ViewChild } from '@angular/core' |
3 | import { ActivatedRoute, Router } from '@angular/router' | 3 | import { ActivatedRoute, Router } from '@angular/router' |
4 | import { AuthService, ConfirmService, LocalStorageService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' | 4 | import { AuthService, ConfirmService, LocalStorageService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' |
5 | import { getAPIHost } from '@app/helpers' | 5 | import { prepareIcu, getAPIHost } from '@app/helpers' |
6 | import { AdvancedInputFilter } from '@app/shared/shared-forms' | 6 | import { AdvancedInputFilter } from '@app/shared/shared-forms' |
7 | import { Actor, DropdownAction } from '@app/shared/shared-main' | 7 | import { Actor, DropdownAction } from '@app/shared/shared-main' |
8 | import { AccountMutedStatus, BlocklistService, UserBanModalComponent, UserModerationDisplayType } from '@app/shared/shared-moderation' | 8 | import { AccountMutedStatus, BlocklistService, UserBanModalComponent, UserModerationDisplayType } from '@app/shared/shared-moderation' |
@@ -209,13 +209,25 @@ export class UserListComponent extends RestTable implements OnInit { | |||
209 | } | 209 | } |
210 | 210 | ||
211 | async unbanUsers (users: User[]) { | 211 | async unbanUsers (users: User[]) { |
212 | const res = await this.confirmService.confirm($localize`Do you really want to unban ${users.length} users?`, $localize`Unban`) | 212 | const res = await this.confirmService.confirm( |
213 | prepareIcu($localize`Do you really want to unban {count, plural, =1 {1 user} other {{count} users}}?`)( | ||
214 | { count: users.length }, | ||
215 | $localize`Do you really want to unban ${users.length} users?` | ||
216 | ), | ||
217 | $localize`Unban` | ||
218 | ) | ||
219 | |||
213 | if (res === false) return | 220 | if (res === false) return |
214 | 221 | ||
215 | this.userAdminService.unbanUsers(users) | 222 | this.userAdminService.unbanUsers(users) |
216 | .subscribe({ | 223 | .subscribe({ |
217 | next: () => { | 224 | next: () => { |
218 | this.notifier.success($localize`${users.length} users unbanned.`) | 225 | this.notifier.success( |
226 | prepareIcu($localize`{count, plural, =1 {1 user} other {{count} users}} unbanned.`)( | ||
227 | { count: users.length }, | ||
228 | $localize`${users.length} users unbanned.` | ||
229 | ) | ||
230 | ) | ||
219 | this.reloadData() | 231 | this.reloadData() |
220 | }, | 232 | }, |
221 | 233 | ||
@@ -224,21 +236,28 @@ export class UserListComponent extends RestTable implements OnInit { | |||
224 | } | 236 | } |
225 | 237 | ||
226 | async removeUsers (users: User[]) { | 238 | async removeUsers (users: User[]) { |
227 | for (const user of users) { | 239 | if (users.some(u => u.username === 'root')) { |
228 | if (user.username === 'root') { | 240 | this.notifier.error($localize`You cannot delete root.`) |
229 | this.notifier.error($localize`You cannot delete root.`) | 241 | return |
230 | return | ||
231 | } | ||
232 | } | 242 | } |
233 | 243 | ||
234 | const message = $localize`If you remove these users, you will not be able to create others with the same username!` | 244 | const message = $localize`<p>You can't create users or channels with a username that already used by a deleted user/channel.</p>` + |
245 | $localize`It means the following usernames will be permanently deleted and cannot be recovered:` + | ||
246 | '<ul>' + users.map(u => '<li>' + u.username + '</li>').join('') + '</ul>' | ||
247 | |||
235 | const res = await this.confirmService.confirm(message, $localize`Delete`) | 248 | const res = await this.confirmService.confirm(message, $localize`Delete`) |
236 | if (res === false) return | 249 | if (res === false) return |
237 | 250 | ||
238 | this.userAdminService.removeUser(users) | 251 | this.userAdminService.removeUser(users) |
239 | .subscribe({ | 252 | .subscribe({ |
240 | next: () => { | 253 | next: () => { |
241 | this.notifier.success($localize`${users.length} users deleted.`) | 254 | this.notifier.success( |
255 | prepareIcu($localize`{count, plural, =1 {1 user} other {{count} users}} deleted.`)( | ||
256 | { count: users.length }, | ||
257 | $localize`${users.length} users deleted.` | ||
258 | ) | ||
259 | ) | ||
260 | |||
242 | this.reloadData() | 261 | this.reloadData() |
243 | }, | 262 | }, |
244 | 263 | ||
@@ -250,7 +269,13 @@ export class UserListComponent extends RestTable implements OnInit { | |||
250 | this.userAdminService.updateUsers(users, { emailVerified: true }) | 269 | this.userAdminService.updateUsers(users, { emailVerified: true }) |
251 | .subscribe({ | 270 | .subscribe({ |
252 | next: () => { | 271 | next: () => { |
253 | this.notifier.success($localize`${users.length} users email set as verified.`) | 272 | this.notifier.success( |
273 | prepareIcu($localize`{count, plural, =1 {1 user} other {{count} users}} email set as verified.`)( | ||
274 | { count: users.length }, | ||
275 | $localize`${users.length} users email set as verified.` | ||
276 | ) | ||
277 | ) | ||
278 | |||
254 | this.reloadData() | 279 | this.reloadData() |
255 | }, | 280 | }, |
256 | 281 | ||
diff --git a/client/src/app/+admin/overview/videos/video-list.component.ts b/client/src/app/+admin/overview/videos/video-list.component.ts index 82ff372aa..67e52d100 100644 --- a/client/src/app/+admin/overview/videos/video-list.component.ts +++ b/client/src/app/+admin/overview/videos/video-list.component.ts | |||
@@ -3,6 +3,7 @@ import { finalize } from 'rxjs/operators' | |||
3 | import { Component, OnInit, ViewChild } from '@angular/core' | 3 | import { Component, OnInit, ViewChild } from '@angular/core' |
4 | import { ActivatedRoute, Router } from '@angular/router' | 4 | import { ActivatedRoute, Router } from '@angular/router' |
5 | import { AuthService, ConfirmService, Notifier, RestPagination, RestTable } from '@app/core' | 5 | import { AuthService, ConfirmService, Notifier, RestPagination, RestTable } from '@app/core' |
6 | import { prepareIcu } from '@app/helpers' | ||
6 | import { AdvancedInputFilter } from '@app/shared/shared-forms' | 7 | import { AdvancedInputFilter } from '@app/shared/shared-forms' |
7 | import { DropdownAction, Video, VideoService } from '@app/shared/shared-main' | 8 | import { DropdownAction, Video, VideoService } from '@app/shared/shared-main' |
8 | import { VideoBlockComponent, VideoBlockService } from '@app/shared/shared-moderation' | 9 | import { VideoBlockComponent, VideoBlockService } from '@app/shared/shared-moderation' |
@@ -196,14 +197,24 @@ export class VideoListComponent extends RestTable implements OnInit { | |||
196 | } | 197 | } |
197 | 198 | ||
198 | private async removeVideos (videos: Video[]) { | 199 | private async removeVideos (videos: Video[]) { |
199 | const message = $localize`Are you sure you want to delete these ${videos.length} videos?` | 200 | const message = prepareIcu($localize`Are you sure you want to delete {count, plural, =1 {this video} other {these {count} videos}}?`)( |
201 | { count: videos.length }, | ||
202 | $localize`Are you sure you want to delete these ${videos.length} videos?` | ||
203 | ) | ||
204 | |||
200 | const res = await this.confirmService.confirm(message, $localize`Delete`) | 205 | const res = await this.confirmService.confirm(message, $localize`Delete`) |
201 | if (res === false) return | 206 | if (res === false) return |
202 | 207 | ||
203 | this.videoService.removeVideo(videos.map(v => v.id)) | 208 | this.videoService.removeVideo(videos.map(v => v.id)) |
204 | .subscribe({ | 209 | .subscribe({ |
205 | next: () => { | 210 | next: () => { |
206 | this.notifier.success($localize`Deleted ${videos.length} videos.`) | 211 | this.notifier.success( |
212 | prepareIcu($localize`Deleted {count, plural, =1 {1 video} other {{count} videos}}.`)( | ||
213 | { count: videos.length }, | ||
214 | $localize`Deleted ${videos.length} videos.` | ||
215 | ) | ||
216 | ) | ||
217 | |||
207 | this.reloadData() | 218 | this.reloadData() |
208 | }, | 219 | }, |
209 | 220 | ||
@@ -215,7 +226,13 @@ export class VideoListComponent extends RestTable implements OnInit { | |||
215 | this.videoBlockService.unblockVideo(videos.map(v => v.id)) | 226 | this.videoBlockService.unblockVideo(videos.map(v => v.id)) |
216 | .subscribe({ | 227 | .subscribe({ |
217 | next: () => { | 228 | next: () => { |
218 | this.notifier.success($localize`Unblocked ${videos.length} videos.`) | 229 | this.notifier.success( |
230 | prepareIcu($localize`Unblocked {count, plural, =1 {1 video} other {{count} videos}}.`)( | ||
231 | { count: videos.length }, | ||
232 | $localize`Unblocked ${videos.length} videos.` | ||
233 | ) | ||
234 | ) | ||
235 | |||
219 | this.reloadData() | 236 | this.reloadData() |
220 | }, | 237 | }, |
221 | 238 | ||
@@ -224,9 +241,21 @@ export class VideoListComponent extends RestTable implements OnInit { | |||
224 | } | 241 | } |
225 | 242 | ||
226 | private async removeVideoFiles (videos: Video[], type: 'hls' | 'webtorrent') { | 243 | private async removeVideoFiles (videos: Video[], type: 'hls' | 'webtorrent') { |
227 | const message = type === 'hls' | 244 | let message: string |
228 | ? $localize`Are you sure you want to delete ${videos.length} HLS streaming playlists?` | 245 | |
229 | : $localize`Are you sure you want to delete WebTorrent files of ${videos.length} videos?` | 246 | if (type === 'hls') { |
247 | // eslint-disable-next-line max-len | ||
248 | message = prepareIcu($localize`Are you sure you want to delete {count, plural, =1 {1 HLS streaming playlist} other {{count} HLS streaming playlists}}?`)( | ||
249 | { count: videos.length }, | ||
250 | $localize`Are you sure you want to delete ${videos.length} HLS streaming playlists?` | ||
251 | ) | ||
252 | } else { | ||
253 | // eslint-disable-next-line max-len | ||
254 | message = prepareIcu($localize`Are you sure you want to delete WebTorrent files of {count, plural, =1 {1 video} other {{count} videos}}?`)( | ||
255 | { count: videos.length }, | ||
256 | $localize`Are you sure you want to delete WebTorrent files of ${videos.length} videos?` | ||
257 | ) | ||
258 | } | ||
230 | 259 | ||
231 | const res = await this.confirmService.confirm(message, $localize`Delete`) | 260 | const res = await this.confirmService.confirm(message, $localize`Delete`) |
232 | if (res === false) return | 261 | if (res === false) return |