aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/shared')
-rw-r--r--client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts141
-rw-r--r--client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts24
-rw-r--r--client/src/app/shared/shared-abuse-list/moderation-comment-modal.component.ts8
-rw-r--r--client/src/app/shared/shared-custom-markup/custom-markup.service.ts4
-rw-r--r--client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.ts8
-rw-r--r--client/src/app/shared/shared-custom-markup/peertube-custom-tags/playlist-miniature-markup.component.ts8
-rw-r--r--client/src/app/shared/shared-custom-markup/peertube-custom-tags/video-miniature-markup.component.ts8
-rw-r--r--client/src/app/shared/shared-custom-markup/peertube-custom-tags/videos-list-markup.component.ts8
-rw-r--r--client/src/app/shared/shared-instance/instance-about-accordion.component.ts8
-rw-r--r--client/src/app/shared/shared-main/auth/auth-interceptor.service.ts2
-rw-r--r--client/src/app/shared/shared-main/users/user-notifications.component.ts24
-rw-r--r--client/src/app/shared/shared-moderation/account-blocklist.component.ts8
-rw-r--r--client/src/app/shared/shared-moderation/report-modals/account-report.component.ts8
-rw-r--r--client/src/app/shared/shared-moderation/report-modals/comment-report.component.ts8
-rw-r--r--client/src/app/shared/shared-moderation/report-modals/video-report.component.ts8
-rw-r--r--client/src/app/shared/shared-moderation/server-blocklist.component.ts8
-rw-r--r--client/src/app/shared/shared-moderation/user-ban-modal.component.ts8
-rw-r--r--client/src/app/shared/shared-moderation/user-moderation-dropdown.component.ts112
-rw-r--r--client/src/app/shared/shared-moderation/video-block.component.ts8
-rw-r--r--client/src/app/shared/shared-search/find-in-bulk.service.ts2
-rw-r--r--client/src/app/shared/shared-user-settings/user-interface-settings.component.ts27
-rw-r--r--client/src/app/shared/shared-user-settings/user-video-settings.component.ts15
-rw-r--r--client/src/app/shared/shared-user-subscription/subscribe-button.component.ts16
-rw-r--r--client/src/app/shared/shared-video-miniature/abstract-video-list.ts33
-rw-r--r--client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts32
-rw-r--r--client/src/app/shared/shared-video-miniature/video-download.component.ts3
-rw-r--r--client/src/app/shared/shared-video-miniature/video-miniature.component.ts11
-rw-r--r--client/src/app/shared/shared-video-playlist/video-add-to-playlist.component.ts51
-rw-r--r--client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts16
29 files changed, 311 insertions, 306 deletions
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 a7932ebab..e3bf9e1fb 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
@@ -145,23 +145,24 @@ export class AbuseListTableComponent extends RestTable implements OnInit {
145 const res = await this.confirmService.confirm($localize`Do you really want to delete this abuse report?`, $localize`Delete`) 145 const res = await this.confirmService.confirm($localize`Do you really want to delete this abuse report?`, $localize`Delete`)
146 if (res === false) return 146 if (res === false) return
147 147
148 this.abuseService.removeAbuse(abuse).subscribe( 148 this.abuseService.removeAbuse(abuse)
149 () => { 149 .subscribe({
150 this.notifier.success($localize`Abuse deleted.`) 150 next: () => {
151 this.reloadData() 151 this.notifier.success($localize`Abuse deleted.`)
152 }, 152 this.reloadData()
153 },
153 154
154 err => this.notifier.error(err.message) 155 error: err => this.notifier.error(err.message)
155 ) 156 })
156 } 157 }
157 158
158 updateAbuseState (abuse: AdminAbuse, state: AbuseState) { 159 updateAbuseState (abuse: AdminAbuse, state: AbuseState) {
159 this.abuseService.updateAbuse(abuse, { state }) 160 this.abuseService.updateAbuse(abuse, { state })
160 .subscribe( 161 .subscribe({
161 () => this.reloadData(), 162 next: () => this.reloadData(),
162 163
163 err => this.notifier.error(err.message) 164 error: err => this.notifier.error(err.message)
164 ) 165 })
165 } 166 }
166 167
167 onCountMessagesUpdated (event: { abuseId: number, countMessages: number }) { 168 onCountMessagesUpdated (event: { abuseId: number, countMessages: number }) {
@@ -198,55 +199,55 @@ export class AbuseListTableComponent extends RestTable implements OnInit {
198 ? this.abuseService.getAdminAbuses(options) 199 ? this.abuseService.getAdminAbuses(options)
199 : this.abuseService.getUserAbuses(options) 200 : this.abuseService.getUserAbuses(options)
200 201
201 return observable.subscribe( 202 return observable.subscribe({
202 async resultList => { 203 next: async resultList => {
203 this.totalRecords = resultList.total 204 this.totalRecords = resultList.total
204 205
205 this.abuses = [] 206 this.abuses = []
206 207
207 for (const a of resultList.data) { 208 for (const a of resultList.data) {
208 const abuse = a as ProcessedAbuse 209 const abuse = a as ProcessedAbuse
209 210
210 abuse.reasonHtml = await this.toHtml(abuse.reason) 211 abuse.reasonHtml = await this.toHtml(abuse.reason)
211 212
212 if (abuse.moderationComment) { 213 if (abuse.moderationComment) {
213 abuse.moderationCommentHtml = await this.toHtml(abuse.moderationComment) 214 abuse.moderationCommentHtml = await this.toHtml(abuse.moderationComment)
214 } 215 }
215 216
216 if (abuse.video) { 217 if (abuse.video) {
217 abuse.embedHtml = this.sanitizer.bypassSecurityTrustHtml(this.getVideoEmbed(abuse)) 218 abuse.embedHtml = this.sanitizer.bypassSecurityTrustHtml(this.getVideoEmbed(abuse))
218 219
219 if (abuse.video.channel?.ownerAccount) { 220 if (abuse.video.channel?.ownerAccount) {
220 abuse.video.channel.ownerAccount = new Account(abuse.video.channel.ownerAccount) 221 abuse.video.channel.ownerAccount = new Account(abuse.video.channel.ownerAccount)
221 }
222 } 222 }
223 }
223 224
224 if (abuse.comment) { 225 if (abuse.comment) {
225 if (abuse.comment.deleted) { 226 if (abuse.comment.deleted) {
226 abuse.truncatedCommentHtml = abuse.commentHtml = $localize`Deleted comment` 227 abuse.truncatedCommentHtml = abuse.commentHtml = $localize`Deleted comment`
227 } else { 228 } else {
228 const truncated = truncate(abuse.comment.text, { length: 100 }) 229 const truncated = truncate(abuse.comment.text, { length: 100 })
229 abuse.truncatedCommentHtml = await this.markdownRenderer.textMarkdownToHTML(truncated, true) 230 abuse.truncatedCommentHtml = await this.markdownRenderer.textMarkdownToHTML(truncated, true)
230 abuse.commentHtml = await this.markdownRenderer.textMarkdownToHTML(abuse.comment.text, true) 231 abuse.commentHtml = await this.markdownRenderer.textMarkdownToHTML(abuse.comment.text, true)
231 }
232 } 232 }
233 }
233 234
234 if (abuse.reporterAccount) { 235 if (abuse.reporterAccount) {
235 abuse.reporterAccount = new Account(abuse.reporterAccount) 236 abuse.reporterAccount = new Account(abuse.reporterAccount)
236 } 237 }
237 238
238 if (abuse.flaggedAccount) { 239 if (abuse.flaggedAccount) {
239 abuse.flaggedAccount = new Account(abuse.flaggedAccount) 240 abuse.flaggedAccount = new Account(abuse.flaggedAccount)
240 } 241 }
241 242
242 if (abuse.updatedAt === abuse.createdAt) delete abuse.updatedAt 243 if (abuse.updatedAt === abuse.createdAt) delete abuse.updatedAt
243 244
244 this.abuses.push(abuse) 245 this.abuses.push(abuse)
245 } 246 }
246 }, 247 },
247 248
248 err => this.notifier.error(err.message) 249 error: err => this.notifier.error(err.message)
249 ) 250 })
250 } 251 }
251 252
252 private buildInternalActions (): DropdownAction<ProcessedAbuse>[] { 253 private buildInternalActions (): DropdownAction<ProcessedAbuse>[] {
@@ -351,15 +352,15 @@ export class AbuseListTableComponent extends RestTable implements OnInit {
351 isDisplayed: abuse => abuse.video && !abuse.video.deleted && !abuse.video.blacklisted, 352 isDisplayed: abuse => abuse.video && !abuse.video.deleted && !abuse.video.blacklisted,
352 handler: abuse => { 353 handler: abuse => {
353 this.videoBlocklistService.blockVideo(abuse.video.id, undefined, abuse.video.channel.isLocal) 354 this.videoBlocklistService.blockVideo(abuse.video.id, undefined, abuse.video.channel.isLocal)
354 .subscribe( 355 .subscribe({
355 () => { 356 next: () => {
356 this.notifier.success($localize`Video blocked.`) 357 this.notifier.success($localize`Video blocked.`)
357 358
358 this.updateAbuseState(abuse, AbuseState.ACCEPTED) 359 this.updateAbuseState(abuse, AbuseState.ACCEPTED)
359 }, 360 },
360 361
361 err => this.notifier.error(err.message) 362 error: err => this.notifier.error(err.message)
362 ) 363 })
363 } 364 }
364 }, 365 },
365 { 366 {
@@ -367,15 +368,15 @@ export class AbuseListTableComponent extends RestTable implements OnInit {
367 isDisplayed: abuse => abuse.video && !abuse.video.deleted && abuse.video.blacklisted, 368 isDisplayed: abuse => abuse.video && !abuse.video.deleted && abuse.video.blacklisted,
368 handler: abuse => { 369 handler: abuse => {
369 this.videoBlocklistService.unblockVideo(abuse.video.id) 370 this.videoBlocklistService.unblockVideo(abuse.video.id)
370 .subscribe( 371 .subscribe({
371 () => { 372 next: () => {
372 this.notifier.success($localize`Video unblocked.`) 373 this.notifier.success($localize`Video unblocked.`)
373 374
374 this.updateAbuseState(abuse, AbuseState.ACCEPTED) 375 this.updateAbuseState(abuse, AbuseState.ACCEPTED)
375 }, 376 },
376 377
377 err => this.notifier.error(err.message) 378 error: err => this.notifier.error(err.message)
378 ) 379 })
379 } 380 }
380 }, 381 },
381 { 382 {
@@ -389,15 +390,15 @@ export class AbuseListTableComponent extends RestTable implements OnInit {
389 if (res === false) return 390 if (res === false) return
390 391
391 this.videoService.removeVideo(abuse.video.id) 392 this.videoService.removeVideo(abuse.video.id)
392 .subscribe( 393 .subscribe({
393 () => { 394 next: () => {
394 this.notifier.success($localize`Video deleted.`) 395 this.notifier.success($localize`Video deleted.`)
395 396
396 this.updateAbuseState(abuse, AbuseState.ACCEPTED) 397 this.updateAbuseState(abuse, AbuseState.ACCEPTED)
397 }, 398 },
398 399
399 err => this.notifier.error(err.message) 400 error: err => this.notifier.error(err.message)
400 ) 401 })
401 } 402 }
402 } 403 }
403 ] 404 ]
@@ -424,15 +425,15 @@ export class AbuseListTableComponent extends RestTable implements OnInit {
424 if (res === false) return 425 if (res === false) return
425 426
426 this.commentService.deleteVideoComment(abuse.comment.video.id, abuse.comment.id) 427 this.commentService.deleteVideoComment(abuse.comment.video.id, abuse.comment.id)
427 .subscribe( 428 .subscribe({
428 () => { 429 next: () => {
429 this.notifier.success($localize`Comment deleted.`) 430 this.notifier.success($localize`Comment deleted.`)
430 431
431 this.updateAbuseState(abuse, AbuseState.ACCEPTED) 432 this.updateAbuseState(abuse, AbuseState.ACCEPTED)
432 }, 433 },
433 434
434 err => this.notifier.error(err.message) 435 error: err => this.notifier.error(err.message)
435 ) 436 })
436 } 437 }
437 } 438 }
438 ] 439 ]
@@ -440,25 +441,25 @@ export class AbuseListTableComponent extends RestTable implements OnInit {
440 441
441 private muteAccountHelper (account: Account) { 442 private muteAccountHelper (account: Account) {
442 this.blocklistService.blockAccountByInstance(account) 443 this.blocklistService.blockAccountByInstance(account)
443 .subscribe( 444 .subscribe({
444 () => { 445 next: () => {
445 this.notifier.success($localize`Account ${account.nameWithHost} muted by the instance.`) 446 this.notifier.success($localize`Account ${account.nameWithHost} muted by the instance.`)
446 account.mutedByInstance = true 447 account.mutedByInstance = true
447 }, 448 },
448 449
449 err => this.notifier.error(err.message) 450 error: err => this.notifier.error(err.message)
450 ) 451 })
451 } 452 }
452 453
453 private muteServerHelper (host: string) { 454 private muteServerHelper (host: string) {
454 this.blocklistService.blockServerByInstance(host) 455 this.blocklistService.blockServerByInstance(host)
455 .subscribe( 456 .subscribe({
456 () => { 457 next: () => {
457 this.notifier.success($localize`Server ${host} muted by the instance.`) 458 this.notifier.success($localize`Server ${host} muted by the instance.`)
458 }, 459 },
459 460
460 err => this.notifier.error(err.message) 461 error: err => this.notifier.error(err.message)
461 ) 462 })
462 } 463 }
463 464
464 private toHtml (text: string) { 465 private toHtml (text: string) {
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 9abb4c094..6c8dc6d35 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
@@ -61,8 +61,8 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit {
61 this.sendingMessage = true 61 this.sendingMessage = true
62 62
63 this.abuseService.addAbuseMessage(this.abuse, this.form.value['message']) 63 this.abuseService.addAbuseMessage(this.abuse, this.form.value['message'])
64 .subscribe( 64 .subscribe({
65 () => { 65 next: () => {
66 this.form.reset() 66 this.form.reset()
67 this.sendingMessage = false 67 this.sendingMessage = false
68 this.countMessagesUpdated.emit({ abuseId: this.abuse.id, countMessages: this.abuseMessages.length + 1 }) 68 this.countMessagesUpdated.emit({ abuseId: this.abuse.id, countMessages: this.abuseMessages.length + 1 })
@@ -70,25 +70,25 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit {
70 this.loadMessages() 70 this.loadMessages()
71 }, 71 },
72 72
73 err => { 73 error: err => {
74 this.sendingMessage = false 74 this.sendingMessage = false
75 console.error(err) 75 console.error(err)
76 this.notifier.error('Sorry but you cannot send this message. Please retry later') 76 this.notifier.error('Sorry but you cannot send this message. Please retry later')
77 } 77 }
78 ) 78 })
79 } 79 }
80 80
81 deleteMessage (abuseMessage: AbuseMessage) { 81 deleteMessage (abuseMessage: AbuseMessage) {
82 this.abuseService.deleteAbuseMessage(this.abuse, abuseMessage) 82 this.abuseService.deleteAbuseMessage(this.abuse, abuseMessage)
83 .subscribe( 83 .subscribe({
84 () => { 84 next: () => {
85 this.countMessagesUpdated.emit({ abuseId: this.abuse.id, countMessages: this.abuseMessages.length - 1 }) 85 this.countMessagesUpdated.emit({ abuseId: this.abuse.id, countMessages: this.abuseMessages.length - 1 })
86 86
87 this.abuseMessages = this.abuseMessages.filter(m => m.id !== abuseMessage.id) 87 this.abuseMessages = this.abuseMessages.filter(m => m.id !== abuseMessage.id)
88 }, 88 },
89 89
90 err => this.notifier.error(err.message) 90 error: err => this.notifier.error(err.message)
91 ) 91 })
92 } 92 }
93 93
94 isMessageByMe (abuseMessage: AbuseMessage) { 94 isMessageByMe (abuseMessage: AbuseMessage) {
@@ -105,8 +105,8 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit {
105 105
106 private loadMessages () { 106 private loadMessages () {
107 this.abuseService.listAbuseMessages(this.abuse) 107 this.abuseService.listAbuseMessages(this.abuse)
108 .subscribe( 108 .subscribe({
109 async res => { 109 next: async res => {
110 this.abuseMessages = [] 110 this.abuseMessages = []
111 111
112 for (const m of res.data) { 112 for (const m of res.data) {
@@ -124,8 +124,8 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit {
124 }) 124 })
125 }, 125 },
126 126
127 err => this.notifier.error(err.message) 127 error: err => this.notifier.error(err.message)
128 ) 128 })
129 } 129 }
130 130
131} 131}
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 876aeea8a..06f1555ea 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
@@ -53,16 +53,16 @@ export class ModerationCommentModalComponent extends FormReactive implements OnI
53 const moderationComment: string = this.form.value[ 'moderationComment' ] 53 const moderationComment: string = this.form.value[ 'moderationComment' ]
54 54
55 this.abuseService.updateAbuse(this.abuseToComment, { moderationComment }) 55 this.abuseService.updateAbuse(this.abuseToComment, { moderationComment })
56 .subscribe( 56 .subscribe({
57 () => { 57 next: () => {
58 this.notifier.success($localize`Comment updated.`) 58 this.notifier.success($localize`Comment updated.`)
59 59
60 this.commentUpdated.emit(moderationComment) 60 this.commentUpdated.emit(moderationComment)
61 this.hide() 61 this.hide()
62 }, 62 },
63 63
64 err => this.notifier.error(err.message) 64 error: err => this.notifier.error(err.message)
65 ) 65 })
66 } 66 }
67 67
68} 68}
diff --git a/client/src/app/shared/shared-custom-markup/custom-markup.service.ts b/client/src/app/shared/shared-custom-markup/custom-markup.service.ts
index c9d33980e..63f2f76f5 100644
--- a/client/src/app/shared/shared-custom-markup/custom-markup.service.ts
+++ b/client/src/app/shared/shared-custom-markup/custom-markup.service.ts
@@ -1,4 +1,4 @@
1import { first } from 'rxjs/operators' 1import { firstValueFrom } from 'rxjs'
2import { ComponentRef, Injectable } from '@angular/core' 2import { ComponentRef, Injectable } from '@angular/core'
3import { MarkdownService } from '@app/core' 3import { MarkdownService } from '@app/core'
4import { 4import {
@@ -85,7 +85,7 @@ export class CustomMarkupService {
85 const component = this.execAngularBuilder(selector, e) 85 const component = this.execAngularBuilder(selector, e)
86 86
87 if (component.instance.loaded) { 87 if (component.instance.loaded) {
88 const p = component.instance.loaded.pipe(first()).toPromise() 88 const p = firstValueFrom(component.instance.loaded)
89 loadedPromises.push(p) 89 loadedPromises.push(p)
90 } 90 }
91 91
diff --git a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.ts b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.ts
index 5bb045a82..8c1357d7a 100644
--- a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.ts
+++ b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.ts
@@ -44,14 +44,14 @@ export class ChannelMiniatureMarkupComponent implements CustomMarkupComponent, O
44 tap(html => this.descriptionHTML = html), 44 tap(html => this.descriptionHTML = html),
45 switchMap(() => this.loadVideosObservable()), 45 switchMap(() => this.loadVideosObservable()),
46 finalize(() => this.loaded.emit(true)) 46 finalize(() => this.loaded.emit(true))
47 ).subscribe( 47 ).subscribe({
48 ({ total, data }) => { 48 next: ({ total, data }) => {
49 this.totalVideos = total 49 this.totalVideos = total
50 this.video = data[0] 50 this.video = data[0]
51 }, 51 },
52 52
53 err => this.notifier.error($localize`Error in channel miniature component: ${err.message}`) 53 error: err => this.notifier.error($localize`Error in channel miniature component: ${err.message}`)
54 ) 54 })
55 } 55 }
56 56
57 getVideoChannelLink () { 57 getVideoChannelLink () {
diff --git a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/playlist-miniature-markup.component.ts b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/playlist-miniature-markup.component.ts
index 5a5c34867..07fa6fd2d 100644
--- a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/playlist-miniature-markup.component.ts
+++ b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/playlist-miniature-markup.component.ts
@@ -41,10 +41,10 @@ export class PlaylistMiniatureMarkupComponent implements CustomMarkupComponent,
41 ngOnInit () { 41 ngOnInit () {
42 this.findInBulkService.getPlaylist(this.uuid) 42 this.findInBulkService.getPlaylist(this.uuid)
43 .pipe(finalize(() => this.loaded.emit(true))) 43 .pipe(finalize(() => this.loaded.emit(true)))
44 .subscribe( 44 .subscribe({
45 playlist => this.playlist = playlist, 45 next: playlist => this.playlist = playlist,
46 46
47 err => this.notifier.error($localize`Error in playlist miniature component: ${err.message}`) 47 error: err => this.notifier.error($localize`Error in playlist miniature component: ${err.message}`)
48 ) 48 })
49 } 49 }
50} 50}
diff --git a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/video-miniature-markup.component.ts b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/video-miniature-markup.component.ts
index 84c936ee7..56b43d85e 100644
--- a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/video-miniature-markup.component.ts
+++ b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/video-miniature-markup.component.ts
@@ -53,10 +53,10 @@ export class VideoMiniatureMarkupComponent implements CustomMarkupComponent, OnI
53 53
54 this.findInBulk.getVideo(this.uuid) 54 this.findInBulk.getVideo(this.uuid)
55 .pipe(finalize(() => this.loaded.emit(true))) 55 .pipe(finalize(() => this.loaded.emit(true)))
56 .subscribe( 56 .subscribe({
57 video => this.video = video, 57 next: video => this.video = video,
58 58
59 err => this.notifier.error($localize`Error in video miniature component: ${err.message}`) 59 error: err => this.notifier.error($localize`Error in video miniature component: ${err.message}`)
60 ) 60 })
61 } 61 }
62} 62}
diff --git a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/videos-list-markup.component.ts b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/videos-list-markup.component.ts
index 6473e9ba0..856e43681 100644
--- a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/videos-list-markup.component.ts
+++ b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/videos-list-markup.component.ts
@@ -71,11 +71,11 @@ export class VideosListMarkupComponent implements CustomMarkupComponent, OnInit
71 71
72 return this.getVideosObservable() 72 return this.getVideosObservable()
73 .pipe(finalize(() => this.loaded.emit(true))) 73 .pipe(finalize(() => this.loaded.emit(true)))
74 .subscribe( 74 .subscribe({
75 ({ data }) => this.videos = data, 75 next: ({ data }) => this.videos = data,
76 76
77 err => this.notifier.error($localize`Error in videos list component: ${err.message}`) 77 error: err => this.notifier.error($localize`Error in videos list component: ${err.message}`)
78 ) 78 })
79 } 79 }
80 80
81 getVideosObservable () { 81 getVideosObservable () {
diff --git a/client/src/app/shared/shared-instance/instance-about-accordion.component.ts b/client/src/app/shared/shared-instance/instance-about-accordion.component.ts
index 8e7bf2021..855c06aa1 100644
--- a/client/src/app/shared/shared-instance/instance-about-accordion.component.ts
+++ b/client/src/app/shared/shared-instance/instance-about-accordion.component.ts
@@ -36,8 +36,8 @@ export class InstanceAboutAccordionComponent implements OnInit {
36 36
37 ngOnInit (): void { 37 ngOnInit (): void {
38 this.instanceService.getAbout() 38 this.instanceService.getAbout()
39 .subscribe( 39 .subscribe({
40 async about => { 40 next: async about => {
41 this.about = about 41 this.about = about
42 42
43 this.aboutHtml = await this.instanceService.buildHtml(about) 43 this.aboutHtml = await this.instanceService.buildHtml(about)
@@ -45,8 +45,8 @@ export class InstanceAboutAccordionComponent implements OnInit {
45 this.init.emit(this) 45 this.init.emit(this)
46 }, 46 },
47 47
48 err => this.notifier.error(err.message) 48 error: err => this.notifier.error(err.message)
49 ) 49 })
50 } 50 }
51 51
52 getAdministratorsPanel () { 52 getAdministratorsPanel () {
diff --git a/client/src/app/shared/shared-main/auth/auth-interceptor.service.ts b/client/src/app/shared/shared-main/auth/auth-interceptor.service.ts
index a75c8a25c..51248c7b2 100644
--- a/client/src/app/shared/shared-main/auth/auth-interceptor.service.ts
+++ b/client/src/app/shared/shared-main/auth/auth-interceptor.service.ts
@@ -36,7 +36,7 @@ export class AuthInterceptor implements HttpInterceptor {
36 return this.handleNotAuthenticated(err) 36 return this.handleNotAuthenticated(err)
37 } 37 }
38 38
39 return observableThrowError(err) 39 return observableThrowError(() => err)
40 }) 40 })
41 ) 41 )
42 } 42 }
diff --git a/client/src/app/shared/shared-main/users/user-notifications.component.ts b/client/src/app/shared/shared-main/users/user-notifications.component.ts
index 96b141543..50005b855 100644
--- a/client/src/app/shared/shared-main/users/user-notifications.component.ts
+++ b/client/src/app/shared/shared-main/users/user-notifications.component.ts
@@ -56,8 +56,8 @@ export class UserNotificationsComponent implements OnInit {
56 } 56 }
57 57
58 this.userNotificationService.listMyNotifications(options) 58 this.userNotificationService.listMyNotifications(options)
59 .subscribe( 59 .subscribe({
60 result => { 60 next: result => {
61 this.notifications = reset ? result.data : this.notifications.concat(result.data) 61 this.notifications = reset ? result.data : this.notifications.concat(result.data)
62 this.componentPagination.totalItems = result.total 62 this.componentPagination.totalItems = result.total
63 63
@@ -66,8 +66,8 @@ export class UserNotificationsComponent implements OnInit {
66 this.onDataSubject.next(result.data) 66 this.onDataSubject.next(result.data)
67 }, 67 },
68 68
69 err => this.notifier.error(err.message) 69 error: err => this.notifier.error(err.message)
70 ) 70 })
71 } 71 }
72 72
73 onNearOfBottom () { 73 onNearOfBottom () {
@@ -84,26 +84,26 @@ export class UserNotificationsComponent implements OnInit {
84 if (notification.read) return 84 if (notification.read) return
85 85
86 this.userNotificationService.markAsRead(notification) 86 this.userNotificationService.markAsRead(notification)
87 .subscribe( 87 .subscribe({
88 () => { 88 next: () => {
89 notification.read = true 89 notification.read = true
90 }, 90 },
91 91
92 err => this.notifier.error(err.message) 92 error: err => this.notifier.error(err.message)
93 ) 93 })
94 } 94 }
95 95
96 markAllAsRead () { 96 markAllAsRead () {
97 this.userNotificationService.markAllAsRead() 97 this.userNotificationService.markAllAsRead()
98 .subscribe( 98 .subscribe({
99 () => { 99 next: () => {
100 for (const notification of this.notifications) { 100 for (const notification of this.notifications) {
101 notification.read = true 101 notification.read = true
102 } 102 }
103 }, 103 },
104 104
105 err => this.notifier.error(err.message) 105 error: err => this.notifier.error(err.message)
106 ) 106 })
107 } 107 }
108 108
109 changeSortColumn (column: string) { 109 changeSortColumn (column: string) {
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 1146aeec0..36f2a591b 100644
--- a/client/src/app/shared/shared-moderation/account-blocklist.component.ts
+++ b/client/src/app/shared/shared-moderation/account-blocklist.component.ts
@@ -62,13 +62,13 @@ export class GenericAccountBlocklistComponent extends RestTable implements OnIni
62 search: this.search 62 search: this.search
63 }) 63 })
64 64
65 return operation.subscribe( 65 return operation.subscribe({
66 resultList => { 66 next: resultList => {
67 this.blockedAccounts = resultList.data 67 this.blockedAccounts = resultList.data
68 this.totalRecords = resultList.total 68 this.totalRecords = resultList.total
69 }, 69 },
70 70
71 err => this.notifier.error(err.message) 71 error: err => this.notifier.error(err.message)
72 ) 72 })
73 } 73 }
74} 74}
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 cc8875f77..4ec02f11a 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
@@ -77,14 +77,14 @@ export class AccountReportComponent extends FormReactive implements OnInit {
77 account: { 77 account: {
78 id: this.account.id 78 id: this.account.id
79 } 79 }
80 }).subscribe( 80 }).subscribe({
81 () => { 81 next: () => {
82 this.notifier.success($localize`Account reported.`) 82 this.notifier.success($localize`Account reported.`)
83 this.hide() 83 this.hide()
84 }, 84 },
85 85
86 err => this.notifier.error(err.message) 86 error: err => this.notifier.error(err.message)
87 ) 87 })
88 } 88 }
89 89
90 isRemote () { 90 isRemote () {
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 c7395c7b7..7c0907ce4 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
@@ -77,14 +77,14 @@ export class CommentReportComponent extends FormReactive implements OnInit {
77 comment: { 77 comment: {
78 id: this.comment.id 78 id: this.comment.id
79 } 79 }
80 }).subscribe( 80 }).subscribe({
81 () => { 81 next: () => {
82 this.notifier.success($localize`Comment reported.`) 82 this.notifier.success($localize`Comment reported.`)
83 this.hide() 83 this.hide()
84 }, 84 },
85 85
86 err => this.notifier.error(err.message) 86 error: err => this.notifier.error(err.message)
87 ) 87 })
88 } 88 }
89 89
90 isRemote () { 90 isRemote () {
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 e509ac88f..278d60ac6 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
@@ -108,14 +108,14 @@ export class VideoReportComponent extends FormReactive implements OnInit {
108 startAt: hasStart && startAt ? startAt : undefined, 108 startAt: hasStart && startAt ? startAt : undefined,
109 endAt: hasEnd && endAt ? endAt : undefined 109 endAt: hasEnd && endAt ? endAt : undefined
110 } 110 }
111 }).subscribe( 111 }).subscribe({
112 () => { 112 next: () => {
113 this.notifier.success($localize`Video reported.`) 113 this.notifier.success($localize`Video reported.`)
114 this.hide() 114 this.hide()
115 }, 115 },
116 116
117 err => this.notifier.error(err.message) 117 error: err => this.notifier.error(err.message)
118 ) 118 })
119 } 119 }
120 120
121 isRemote () { 121 isRemote () {
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 274d8f6e9..da09b1d0e 100644
--- a/client/src/app/shared/shared-moderation/server-blocklist.component.ts
+++ b/client/src/app/shared/shared-moderation/server-blocklist.component.ts
@@ -88,13 +88,13 @@ export class GenericServerBlocklistComponent extends RestTable implements OnInit
88 search: this.search 88 search: this.search
89 }) 89 })
90 90
91 return operation.subscribe( 91 return operation.subscribe({
92 resultList => { 92 next: resultList => {
93 this.blockedServers = resultList.data 93 this.blockedServers = resultList.data
94 this.totalRecords = resultList.total 94 this.totalRecords = resultList.total
95 }, 95 },
96 96
97 err => this.notifier.error(err.message) 97 error: err => this.notifier.error(err.message)
98 ) 98 })
99 } 99 }
100} 100}
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 afc69a1b8..0a2d5e93a 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
@@ -47,8 +47,8 @@ export class UserBanModalComponent extends FormReactive implements OnInit {
47 const reason = this.form.value['reason'] || undefined 47 const reason = this.form.value['reason'] || undefined
48 48
49 this.userService.banUsers(this.usersToBan, reason) 49 this.userService.banUsers(this.usersToBan, reason)
50 .subscribe( 50 .subscribe({
51 () => { 51 next: () => {
52 const message = Array.isArray(this.usersToBan) 52 const message = Array.isArray(this.usersToBan)
53 ? $localize`${this.usersToBan.length} users banned.` 53 ? $localize`${this.usersToBan.length} users banned.`
54 : $localize`User ${this.usersToBan.username} banned.` 54 : $localize`User ${this.usersToBan.username} banned.`
@@ -59,8 +59,8 @@ export class UserBanModalComponent extends FormReactive implements OnInit {
59 this.hide() 59 this.hide()
60 }, 60 },
61 61
62 err => this.notifier.error(err.message) 62 error: err => this.notifier.error(err.message)
63 ) 63 })
64 } 64 }
65 65
66} 66}
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 8c5a48d42..9f1e1bf9b 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
@@ -67,14 +67,14 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges {
67 if (res === false) return 67 if (res === false) return
68 68
69 this.userService.unbanUsers(user) 69 this.userService.unbanUsers(user)
70 .subscribe( 70 .subscribe({
71 () => { 71 next: () => {
72 this.notifier.success($localize`User ${user.username} unbanned.`) 72 this.notifier.success($localize`User ${user.username} unbanned.`)
73 this.userChanged.emit() 73 this.userChanged.emit()
74 }, 74 },
75 75
76 err => this.notifier.error(err.message) 76 error: err => this.notifier.error(err.message)
77 ) 77 })
78 } 78 }
79 79
80 async removeUser (user: User) { 80 async removeUser (user: User) {
@@ -87,137 +87,139 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges {
87 const res = await this.confirmService.confirm(message, $localize`Delete`) 87 const res = await this.confirmService.confirm(message, $localize`Delete`)
88 if (res === false) return 88 if (res === false) return
89 89
90 this.userService.removeUser(user).subscribe( 90 this.userService.removeUser(user)
91 () => { 91 .subscribe({
92 this.notifier.success($localize`User ${user.username} deleted.`) 92 next: () => {
93 this.userDeleted.emit() 93 this.notifier.success($localize`User ${user.username} deleted.`)
94 }, 94 this.userDeleted.emit()
95 },
95 96
96 err => this.notifier.error(err.message) 97 error: err => this.notifier.error(err.message)
97 ) 98 })
98 } 99 }
99 100
100 setEmailAsVerified (user: User) { 101 setEmailAsVerified (user: User) {
101 this.userService.updateUser(user.id, { emailVerified: true }).subscribe( 102 this.userService.updateUser(user.id, { emailVerified: true })
102 () => { 103 .subscribe({
103 this.notifier.success($localize`User ${user.username} email set as verified`) 104 next: () => {
104 this.userChanged.emit() 105 this.notifier.success($localize`User ${user.username} email set as verified`)
105 }, 106 this.userChanged.emit()
106 107 },
107 err => this.notifier.error(err.message) 108
108 ) 109 error: err => this.notifier.error(err.message)
110 })
109 } 111 }
110 112
111 blockAccountByUser (account: Account) { 113 blockAccountByUser (account: Account) {
112 this.blocklistService.blockAccountByUser(account) 114 this.blocklistService.blockAccountByUser(account)
113 .subscribe( 115 .subscribe({
114 () => { 116 next: () => {
115 this.notifier.success($localize`Account ${account.nameWithHost} muted.`) 117 this.notifier.success($localize`Account ${account.nameWithHost} muted.`)
116 118
117 this.account.mutedByUser = true 119 this.account.mutedByUser = true
118 this.userChanged.emit() 120 this.userChanged.emit()
119 }, 121 },
120 122
121 err => this.notifier.error(err.message) 123 error: err => this.notifier.error(err.message)
122 ) 124 })
123 } 125 }
124 126
125 unblockAccountByUser (account: Account) { 127 unblockAccountByUser (account: Account) {
126 this.blocklistService.unblockAccountByUser(account) 128 this.blocklistService.unblockAccountByUser(account)
127 .subscribe( 129 .subscribe({
128 () => { 130 next: () => {
129 this.notifier.success($localize`Account ${account.nameWithHost} unmuted.`) 131 this.notifier.success($localize`Account ${account.nameWithHost} unmuted.`)
130 132
131 this.account.mutedByUser = false 133 this.account.mutedByUser = false
132 this.userChanged.emit() 134 this.userChanged.emit()
133 }, 135 },
134 136
135 err => this.notifier.error(err.message) 137 error: err => this.notifier.error(err.message)
136 ) 138 })
137 } 139 }
138 140
139 blockServerByUser (host: string) { 141 blockServerByUser (host: string) {
140 this.blocklistService.blockServerByUser(host) 142 this.blocklistService.blockServerByUser(host)
141 .subscribe( 143 .subscribe({
142 () => { 144 next: () => {
143 this.notifier.success($localize`Instance ${host} muted.`) 145 this.notifier.success($localize`Instance ${host} muted.`)
144 146
145 this.account.mutedServerByUser = true 147 this.account.mutedServerByUser = true
146 this.userChanged.emit() 148 this.userChanged.emit()
147 }, 149 },
148 150
149 err => this.notifier.error(err.message) 151 error: err => this.notifier.error(err.message)
150 ) 152 })
151 } 153 }
152 154
153 unblockServerByUser (host: string) { 155 unblockServerByUser (host: string) {
154 this.blocklistService.unblockServerByUser(host) 156 this.blocklistService.unblockServerByUser(host)
155 .subscribe( 157 .subscribe({
156 () => { 158 next: () => {
157 this.notifier.success($localize`Instance ${host} unmuted.`) 159 this.notifier.success($localize`Instance ${host} unmuted.`)
158 160
159 this.account.mutedServerByUser = false 161 this.account.mutedServerByUser = false
160 this.userChanged.emit() 162 this.userChanged.emit()
161 }, 163 },
162 164
163 err => this.notifier.error(err.message) 165 error: err => this.notifier.error(err.message)
164 ) 166 })
165 } 167 }
166 168
167 blockAccountByInstance (account: Account) { 169 blockAccountByInstance (account: Account) {
168 this.blocklistService.blockAccountByInstance(account) 170 this.blocklistService.blockAccountByInstance(account)
169 .subscribe( 171 .subscribe({
170 () => { 172 next: () => {
171 this.notifier.success($localize`Account ${account.nameWithHost} muted by the instance.`) 173 this.notifier.success($localize`Account ${account.nameWithHost} muted by the instance.`)
172 174
173 this.account.mutedByInstance = true 175 this.account.mutedByInstance = true
174 this.userChanged.emit() 176 this.userChanged.emit()
175 }, 177 },
176 178
177 err => this.notifier.error(err.message) 179 error: err => this.notifier.error(err.message)
178 ) 180 })
179 } 181 }
180 182
181 unblockAccountByInstance (account: Account) { 183 unblockAccountByInstance (account: Account) {
182 this.blocklistService.unblockAccountByInstance(account) 184 this.blocklistService.unblockAccountByInstance(account)
183 .subscribe( 185 .subscribe({
184 () => { 186 next: () => {
185 this.notifier.success($localize`Account ${account.nameWithHost} unmuted by the instance.`) 187 this.notifier.success($localize`Account ${account.nameWithHost} unmuted by the instance.`)
186 188
187 this.account.mutedByInstance = false 189 this.account.mutedByInstance = false
188 this.userChanged.emit() 190 this.userChanged.emit()
189 }, 191 },
190 192
191 err => this.notifier.error(err.message) 193 error: err => this.notifier.error(err.message)
192 ) 194 })
193 } 195 }
194 196
195 blockServerByInstance (host: string) { 197 blockServerByInstance (host: string) {
196 this.blocklistService.blockServerByInstance(host) 198 this.blocklistService.blockServerByInstance(host)
197 .subscribe( 199 .subscribe({
198 () => { 200 next: () => {
199 this.notifier.success($localize`Instance ${host} muted by the instance.`) 201 this.notifier.success($localize`Instance ${host} muted by the instance.`)
200 202
201 this.account.mutedServerByInstance = true 203 this.account.mutedServerByInstance = true
202 this.userChanged.emit() 204 this.userChanged.emit()
203 }, 205 },
204 206
205 err => this.notifier.error(err.message) 207 error: err => this.notifier.error(err.message)
206 ) 208 })
207 } 209 }
208 210
209 unblockServerByInstance (host: string) { 211 unblockServerByInstance (host: string) {
210 this.blocklistService.unblockServerByInstance(host) 212 this.blocklistService.unblockServerByInstance(host)
211 .subscribe( 213 .subscribe({
212 () => { 214 next: () => {
213 this.notifier.success($localize`Instance ${host} unmuted by the instance.`) 215 this.notifier.success($localize`Instance ${host} unmuted by the instance.`)
214 216
215 this.account.mutedServerByInstance = false 217 this.account.mutedServerByInstance = false
216 this.userChanged.emit() 218 this.userChanged.emit()
217 }, 219 },
218 220
219 err => this.notifier.error(err.message) 221 error: err => this.notifier.error(err.message)
220 ) 222 })
221 } 223 }
222 224
223 async bulkRemoveCommentsOf (body: BulkRemoveCommentsOfBody) { 225 async bulkRemoveCommentsOf (body: BulkRemoveCommentsOfBody) {
@@ -226,13 +228,13 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges {
226 if (res === false) return 228 if (res === false) return
227 229
228 this.bulkService.removeCommentsOf(body) 230 this.bulkService.removeCommentsOf(body)
229 .subscribe( 231 .subscribe({
230 () => { 232 next: () => {
231 this.notifier.success($localize`Will remove comments of this account (may take several minutes).`) 233 this.notifier.success($localize`Will remove comments of this account (may take several minutes).`)
232 }, 234 },
233 235
234 err => this.notifier.error(err.message) 236 error: err => this.notifier.error(err.message)
235 ) 237 })
236 } 238 }
237 239
238 getRouterUserEditLink (user: User) { 240 getRouterUserEditLink (user: User) {
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 fb47989dc..bc6952620 100644
--- a/client/src/app/shared/shared-moderation/video-block.component.ts
+++ b/client/src/app/shared/shared-moderation/video-block.component.ts
@@ -55,8 +55,8 @@ export class VideoBlockComponent extends FormReactive implements OnInit {
55 const unfederate = this.video.isLocal ? this.form.value[ 'unfederate' ] : undefined 55 const unfederate = this.video.isLocal ? this.form.value[ 'unfederate' ] : undefined
56 56
57 this.videoBlocklistService.blockVideo(this.video.id, reason, unfederate) 57 this.videoBlocklistService.blockVideo(this.video.id, reason, unfederate)
58 .subscribe( 58 .subscribe({
59 () => { 59 next: () => {
60 this.notifier.success($localize`Video blocked.`) 60 this.notifier.success($localize`Video blocked.`)
61 this.hide() 61 this.hide()
62 62
@@ -66,7 +66,7 @@ export class VideoBlockComponent extends FormReactive implements OnInit {
66 this.videoBlocked.emit() 66 this.videoBlocked.emit()
67 }, 67 },
68 68
69 err => this.notifier.error(err.message) 69 error: err => this.notifier.error(err.message)
70 ) 70 })
71 } 71 }
72} 72}
diff --git a/client/src/app/shared/shared-search/find-in-bulk.service.ts b/client/src/app/shared/shared-search/find-in-bulk.service.ts
index 61dd2cbc5..962e374a5 100644
--- a/client/src/app/shared/shared-search/find-in-bulk.service.ts
+++ b/client/src/app/shared/shared-search/find-in-bulk.service.ts
@@ -1,5 +1,5 @@
1import * as debug from 'debug' 1import * as debug from 'debug'
2import { Observable, Subject, throwError } from 'rxjs' 2import { Observable, Subject } from 'rxjs'
3import { first, map } from 'rxjs/operators' 3import { first, map } from 'rxjs/operators'
4import { Injectable, NgZone } from '@angular/core' 4import { Injectable, NgZone } from '@angular/core'
5import { buildBulkObservable } from '@app/helpers' 5import { buildBulkObservable } from '@app/helpers'
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 b721604e5..bd1cb0353 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
@@ -65,18 +65,21 @@ export class UserInterfaceSettingsComponent extends FormReactive implements OnIn
65 } 65 }
66 66
67 if (this.authService.isLoggedIn()) { 67 if (this.authService.isLoggedIn()) {
68 this.userService.updateMyProfile(details).subscribe( 68 this.userService.updateMyProfile(details)
69 () => { 69 .subscribe({
70 this.authService.refreshUserInformation() 70 next: () => {
71 71 this.authService.refreshUserInformation()
72 if (this.notifyOnUpdate) this.notifier.success($localize`Interface settings updated.`) 72
73 }, 73 if (this.notifyOnUpdate) this.notifier.success($localize`Interface settings updated.`)
74 74 },
75 err => this.notifier.error(err.message) 75
76 ) 76 error: err => this.notifier.error(err.message)
77 } else { 77 })
78 this.userService.updateMyAnonymousProfile(details) 78
79 if (this.notifyOnUpdate) this.notifier.success($localize`Interface settings updated.`) 79 return
80 } 80 }
81
82 this.userService.updateMyAnonymousProfile(details)
83 if (this.notifyOnUpdate) this.notifier.success($localize`Interface settings updated.`)
81 } 84 }
82} 85}
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 8b0eaea4f..4aac60c2b 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
@@ -162,15 +162,16 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit,
162 } 162 }
163 163
164 private updateLoggedProfile (details: UserUpdateMe) { 164 private updateLoggedProfile (details: UserUpdateMe) {
165 this.userService.updateMyProfile(details).subscribe( 165 this.userService.updateMyProfile(details)
166 () => { 166 .subscribe({
167 this.authService.refreshUserInformation() 167 next: () => {
168 this.authService.refreshUserInformation()
168 169
169 if (this.notifyOnUpdate) this.notifier.success($localize`Video settings updated.`) 170 if (this.notifyOnUpdate) this.notifier.success($localize`Video settings updated.`)
170 }, 171 },
171 172
172 err => this.notifier.error(err.message) 173 error: err => this.notifier.error(err.message)
173 ) 174 })
174 } 175 }
175 176
176 private updateAnonymousProfile (details: UserUpdateMe) { 177 private updateAnonymousProfile (details: UserUpdateMe) {
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 2261e07dd..796493bd9 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
@@ -102,8 +102,8 @@ export class SubscribeButtonComponent implements OnInit, OnChanges {
102 .map(handle => this.userSubscriptionService.addSubscription(handle)) 102 .map(handle => this.userSubscriptionService.addSubscription(handle))
103 103
104 forkJoin(observableBatch) 104 forkJoin(observableBatch)
105 .subscribe( 105 .subscribe({
106 () => { 106 next: () => {
107 this.notifier.success( 107 this.notifier.success(
108 this.account 108 this.account
109 ? $localize`Subscribed to all current channels of ${this.account.displayName}. You will be notified of all their new videos.` 109 ? $localize`Subscribed to all current channels of ${this.account.displayName}. You will be notified of all their new videos.`
@@ -113,8 +113,8 @@ export class SubscribeButtonComponent implements OnInit, OnChanges {
113 ) 113 )
114 }, 114 },
115 115
116 err => this.notifier.error(err.message) 116 error: err => this.notifier.error(err.message)
117 ) 117 })
118 } 118 }
119 119
120 unsubscribe () { 120 unsubscribe () {
@@ -182,11 +182,11 @@ export class SubscribeButtonComponent implements OnInit, OnChanges {
182 merge( 182 merge(
183 this.userSubscriptionService.listenToSubscriptionCacheChange(handle), 183 this.userSubscriptionService.listenToSubscriptionCacheChange(handle),
184 this.userSubscriptionService.doesSubscriptionExist(handle) 184 this.userSubscriptionService.doesSubscriptionExist(handle)
185 ).subscribe( 185 ).subscribe({
186 res => this.subscribed.set(handle, res), 186 next: res => this.subscribed.set(handle, res),
187 187
188 err => this.notifier.error(err.message) 188 error: err => this.notifier.error(err.message)
189 ) 189 })
190 } 190 }
191 } 191 }
192} 192}
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 33061a837..d8b2ee17d 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
@@ -204,28 +204,29 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, AfterConte
204 } 204 }
205 205
206 loadMoreVideos (reset = false) { 206 loadMoreVideos (reset = false) {
207 this.getVideosObservable(this.pagination.currentPage).subscribe( 207 this.getVideosObservable(this.pagination.currentPage)
208 ({ data }) => { 208 .subscribe({
209 this.hasDoneFirstQuery = true 209 next: ({ data }) => {
210 this.lastQueryLength = data.length 210 this.hasDoneFirstQuery = true
211 this.lastQueryLength = data.length
211 212
212 if (reset) this.videos = [] 213 if (reset) this.videos = []
213 this.videos = this.videos.concat(data) 214 this.videos = this.videos.concat(data)
214 215
215 if (this.groupByDate) this.buildGroupedDateLabels() 216 if (this.groupByDate) this.buildGroupedDateLabels()
216 217
217 this.onMoreVideos() 218 this.onMoreVideos()
218 219
219 this.onDataSubject.next(data) 220 this.onDataSubject.next(data)
220 }, 221 },
221 222
222 error => { 223 error: err => {
223 const message = $localize`Cannot load more videos. Try again later.` 224 const message = $localize`Cannot load more videos. Try again later.`
224 225
225 console.error(message, { error }) 226 console.error(message, { err })
226 this.notifier.error(message) 227 this.notifier.error(message)
227 } 228 }
228 ) 229 })
229 } 230 }
230 231
231 reloadVideos () { 232 reloadVideos () {
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 3c2b46d16..2ba091438 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
@@ -183,8 +183,8 @@ export class VideoActionsDropdownComponent implements OnChanges {
183 if (res === false) return 183 if (res === false) return
184 184
185 this.videoBlocklistService.unblockVideo(this.video.id) 185 this.videoBlocklistService.unblockVideo(this.video.id)
186 .subscribe( 186 .subscribe({
187 () => { 187 next: () => {
188 this.notifier.success($localize`Video ${this.video.name} unblocked.`) 188 this.notifier.success($localize`Video ${this.video.name} unblocked.`)
189 189
190 this.video.blacklisted = false 190 this.video.blacklisted = false
@@ -193,8 +193,8 @@ export class VideoActionsDropdownComponent implements OnChanges {
193 this.videoUnblocked.emit() 193 this.videoUnblocked.emit()
194 }, 194 },
195 195
196 err => this.notifier.error(err.message) 196 error: err => this.notifier.error(err.message)
197 ) 197 })
198 } 198 }
199 199
200 async removeVideo () { 200 async removeVideo () {
@@ -209,40 +209,40 @@ export class VideoActionsDropdownComponent implements OnChanges {
209 if (res === false) return 209 if (res === false) return
210 210
211 this.videoService.removeVideo(this.video.id) 211 this.videoService.removeVideo(this.video.id)
212 .subscribe( 212 .subscribe({
213 () => { 213 next: () => {
214 this.notifier.success($localize`Video ${this.video.name} deleted.`) 214 this.notifier.success($localize`Video ${this.video.name} deleted.`)
215 this.videoRemoved.emit() 215 this.videoRemoved.emit()
216 }, 216 },
217 217
218 error => this.notifier.error(error.message) 218 error: err => this.notifier.error(err.message)
219 ) 219 })
220 } 220 }
221 221
222 duplicateVideo () { 222 duplicateVideo () {
223 this.redundancyService.addVideoRedundancy(this.video) 223 this.redundancyService.addVideoRedundancy(this.video)
224 .subscribe( 224 .subscribe({
225 () => { 225 next: () => {
226 const message = $localize`This video will be duplicated by your instance.` 226 const message = $localize`This video will be duplicated by your instance.`
227 this.notifier.success(message) 227 this.notifier.success(message)
228 }, 228 },
229 229
230 err => this.notifier.error(err.message) 230 error: err => this.notifier.error(err.message)
231 ) 231 })
232 } 232 }
233 233
234 muteVideoAccount () { 234 muteVideoAccount () {
235 const params = { nameWithHost: Actor.CREATE_BY_STRING(this.video.account.name, this.video.account.host) } 235 const params = { nameWithHost: Actor.CREATE_BY_STRING(this.video.account.name, this.video.account.host) }
236 236
237 this.blocklistService.blockAccountByUser(params) 237 this.blocklistService.blockAccountByUser(params)
238 .subscribe( 238 .subscribe({
239 () => { 239 next: () => {
240 this.notifier.success($localize`Account ${params.nameWithHost} muted.`) 240 this.notifier.success($localize`Account ${params.nameWithHost} muted.`)
241 this.videoAccountMuted.emit() 241 this.videoAccountMuted.emit()
242 }, 242 },
243 243
244 err => this.notifier.error(err.message) 244 error: err => this.notifier.error(err.message)
245 ) 245 })
246 } 246 }
247 247
248 onVideoBlocked () { 248 onVideoBlocked () {
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 355ce8be3..28fefb9dd 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
@@ -1,4 +1,5 @@
1import { mapValues, pick } from 'lodash-es' 1import { mapValues, pick } from 'lodash-es'
2import { firstValueFrom } from 'rxjs'
2import { tap } from 'rxjs/operators' 3import { tap } from 'rxjs/operators'
3import { Component, ElementRef, Inject, LOCALE_ID, ViewChild } from '@angular/core' 4import { Component, ElementRef, Inject, LOCALE_ID, ViewChild } from '@angular/core'
4import { AuthService, HooksService, Notifier } from '@app/core' 5import { AuthService, HooksService, Notifier } from '@app/core'
@@ -265,6 +266,6 @@ export class VideoDownloadComponent {
265 const observable = this.videoService.getVideoFileMetadata(file.metadataUrl) 266 const observable = this.videoService.getVideoFileMetadata(file.metadataUrl)
266 .pipe(tap(res => file.metadata = res)) 267 .pipe(tap(res => file.metadata = res))
267 268
268 return observable.toPromise() 269 return firstValueFrom(observable)
269 } 270 }
270} 271}
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 67e0de6a2..cb81ba3bd 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
@@ -214,11 +214,12 @@ export class VideoMiniatureComponent implements OnInit {
214 addToWatchLater () { 214 addToWatchLater () {
215 const body = { videoId: this.video.id } 215 const body = { videoId: this.video.id }
216 216
217 this.videoPlaylistService.addVideoInPlaylist(this.watchLaterPlaylist.id, body).subscribe( 217 this.videoPlaylistService.addVideoInPlaylist(this.watchLaterPlaylist.id, body)
218 res => { 218 .subscribe(
219 this.watchLaterPlaylist.playlistElementId = res.videoPlaylistElement.id 219 res => {
220 } 220 this.watchLaterPlaylist.playlistElementId = res.videoPlaylistElement.id
221 ) 221 }
222 )
222 } 223 }
223 224
224 removeFromWatchLater () { 225 removeFromWatchLater () {
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 7069fa8fd..df3aeddb7 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
@@ -198,15 +198,16 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
198 privacy: VideoPlaylistPrivacy.PRIVATE 198 privacy: VideoPlaylistPrivacy.PRIVATE
199 } 199 }
200 200
201 this.videoPlaylistService.createVideoPlaylist(videoPlaylistCreate).subscribe( 201 this.videoPlaylistService.createVideoPlaylist(videoPlaylistCreate)
202 () => { 202 .subscribe({
203 this.isNewPlaylistBlockOpened = false 203 next: () => {
204 this.isNewPlaylistBlockOpened = false
204 205
205 this.cd.markForCheck() 206 this.cd.markForCheck()
206 }, 207 },
207 208
208 err => this.notifier.error(err.message) 209 error: err => this.notifier.error(err.message)
209 ) 210 })
210 } 211 }
211 212
212 onVideoPlaylistSearchChanged () { 213 onVideoPlaylistSearchChanged () {
@@ -268,17 +269,15 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
268 } 269 }
269 270
270 this.videoPlaylistService.updateVideoOfPlaylist(playlist.id, element.playlistElementId, body, this.video.id) 271 this.videoPlaylistService.updateVideoOfPlaylist(playlist.id, element.playlistElementId, body, this.video.id)
271 .subscribe( 272 .subscribe({
272 () => { 273 next: () => {
273 this.notifier.success($localize`Timestamps updated`) 274 this.notifier.success($localize`Timestamps updated`)
274 }, 275 },
275 276
276 err => { 277 error: err => this.notifier.error(err.message),
277 this.notifier.error(err.message)
278 },
279 278
280 () => this.cd.markForCheck() 279 complete: () => this.cd.markForCheck()
281 ) 280 })
282 } 281 }
283 282
284 private isOptionalRowDisplayed (playlist: PlaylistSummary) { 283 private isOptionalRowDisplayed (playlist: PlaylistSummary) {
@@ -302,17 +301,15 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
302 301
303 private removeVideoFromPlaylist (playlist: PlaylistSummary, elementId: number) { 302 private removeVideoFromPlaylist (playlist: PlaylistSummary, elementId: number) {
304 this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, elementId, this.video.id) 303 this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, elementId, this.video.id)
305 .subscribe( 304 .subscribe({
306 () => { 305 next: () => {
307 this.notifier.success($localize`Video removed from ${playlist.displayName}`) 306 this.notifier.success($localize`Video removed from ${playlist.displayName}`)
308 }, 307 },
309 308
310 err => { 309 error: err => this.notifier.error(err.message),
311 this.notifier.error(err.message)
312 },
313 310
314 () => this.cd.markForCheck() 311 complete: () => this.cd.markForCheck()
315 ) 312 })
316 } 313 }
317 314
318 private listenToVideoPlaylistChange () { 315 private listenToVideoPlaylistChange () {
@@ -371,8 +368,8 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
371 if (element.stopTimestamp && element.stopTimestamp !== this.video.duration) body.stopTimestamp = element.stopTimestamp 368 if (element.stopTimestamp && element.stopTimestamp !== this.video.duration) body.stopTimestamp = element.stopTimestamp
372 369
373 this.videoPlaylistService.addVideoInPlaylist(playlist.id, body) 370 this.videoPlaylistService.addVideoInPlaylist(playlist.id, body)
374 .subscribe( 371 .subscribe({
375 res => { 372 next: res => {
376 const message = body.startTimestamp || body.stopTimestamp 373 const message = body.startTimestamp || body.stopTimestamp
377 ? $localize`Video added in ${playlist.displayName} at timestamps ${this.formatTimestamp(element)}` 374 ? $localize`Video added in ${playlist.displayName} at timestamps ${this.formatTimestamp(element)}`
378 : $localize`Video added in ${playlist.displayName}` 375 : $localize`Video added in ${playlist.displayName}`
@@ -382,12 +379,10 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
382 if (element) element.playlistElementId = res.videoPlaylistElement.id 379 if (element) element.playlistElementId = res.videoPlaylistElement.id
383 }, 380 },
384 381
385 err => { 382 error: err => this.notifier.error(err.message),
386 this.notifier.error(err.message)
387 },
388 383
389 () => this.cd.markForCheck() 384 complete: () => this.cd.markForCheck()
390 ) 385 })
391 } 386 }
392 387
393 private formatTimestamp (element: PlaylistElement) { 388 private formatTimestamp (element: PlaylistElement) {
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 2e495ec26..8d1e14f94 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
@@ -88,14 +88,14 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit {
88 const videoId = this.playlistElement.video ? this.playlistElement.video.id : undefined 88 const videoId = this.playlistElement.video ? this.playlistElement.video.id : undefined
89 89
90 this.videoPlaylistService.removeVideoFromPlaylist(this.playlist.id, playlistElement.id, videoId) 90 this.videoPlaylistService.removeVideoFromPlaylist(this.playlist.id, playlistElement.id, videoId)
91 .subscribe( 91 .subscribe({
92 () => { 92 next: () => {
93 this.notifier.success($localize`Video removed from ${this.playlist.displayName}`) 93 this.notifier.success($localize`Video removed from ${this.playlist.displayName}`)
94 this.elementRemoved.emit(playlistElement) 94 this.elementRemoved.emit(playlistElement)
95 }, 95 },
96 96
97 err => this.notifier.error(err.message) 97 error: err => this.notifier.error(err.message)
98 ) 98 })
99 99
100 this.moreDropdown.close() 100 this.moreDropdown.close()
101 } 101 }
@@ -107,8 +107,8 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit {
107 body.stopTimestamp = this.timestampOptions.stopTimestampEnabled ? this.timestampOptions.stopTimestamp : null 107 body.stopTimestamp = this.timestampOptions.stopTimestampEnabled ? this.timestampOptions.stopTimestamp : null
108 108
109 this.videoPlaylistService.updateVideoOfPlaylist(this.playlist.id, playlistElement.id, body, this.playlistElement.video.id) 109 this.videoPlaylistService.updateVideoOfPlaylist(this.playlist.id, playlistElement.id, body, this.playlistElement.video.id)
110 .subscribe( 110 .subscribe({
111 () => { 111 next: () => {
112 this.notifier.success($localize`Timestamps updated`) 112 this.notifier.success($localize`Timestamps updated`)
113 113
114 playlistElement.startTimestamp = body.startTimestamp 114 playlistElement.startTimestamp = body.startTimestamp
@@ -117,8 +117,8 @@ export class VideoPlaylistElementMiniatureComponent implements OnInit {
117 this.cdr.detectChanges() 117 this.cdr.detectChanges()
118 }, 118 },
119 119
120 err => this.notifier.error(err.message) 120 error: err => this.notifier.error(err.message)
121 ) 121 })
122 122
123 this.moreDropdown.close() 123 this.moreDropdown.close()
124 } 124 }