]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/+admin/overview/comments/video-comment-list.component.ts
Support bulk registration request removal
[github/Chocobozzz/PeerTube.git] / client / src / app / +admin / overview / comments / video-comment-list.component.ts
1 import { SortMeta } from 'primeng/api'
2 import { Component, OnInit } from '@angular/core'
3 import { ActivatedRoute, Router } from '@angular/router'
4 import { AuthService, ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core'
5 import { AdvancedInputFilter } from '@app/shared/shared-forms'
6 import { DropdownAction } from '@app/shared/shared-main'
7 import { BulkService } from '@app/shared/shared-moderation'
8 import { VideoCommentAdmin, VideoCommentService } from '@app/shared/shared-video-comment'
9 import { FeedFormat, UserRight } from '@shared/models'
10 import { prepareIcu } from '@app/helpers'
11
12 @Component({
13 selector: 'my-video-comment-list',
14 templateUrl: './video-comment-list.component.html',
15 styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-comment-list.component.scss' ]
16 })
17 export class VideoCommentListComponent extends RestTable <VideoCommentAdmin> implements OnInit {
18 comments: VideoCommentAdmin[]
19 totalRecords = 0
20 sort: SortMeta = { field: 'createdAt', order: -1 }
21 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
22
23 videoCommentActions: DropdownAction<VideoCommentAdmin>[][] = []
24
25 syndicationItems = [
26 {
27 format: FeedFormat.RSS,
28 label: 'media rss 2.0',
29 url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.RSS.toLowerCase()
30 },
31 {
32 format: FeedFormat.ATOM,
33 label: 'atom 1.0',
34 url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.ATOM.toLowerCase()
35 },
36 {
37 format: FeedFormat.JSON,
38 label: 'json 1.0',
39 url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.JSON.toLowerCase()
40 }
41 ]
42
43 bulkActions: DropdownAction<VideoCommentAdmin[]>[] = []
44
45 inputFilters: AdvancedInputFilter[] = [
46 {
47 title: $localize`Advanced filters`,
48 children: [
49 {
50 value: 'local:true',
51 label: $localize`Local comments`
52 },
53 {
54 value: 'local:false',
55 label: $localize`Remote comments`
56 },
57 {
58 value: 'localVideo:true',
59 label: $localize`Comments on local videos`
60 }
61 ]
62 }
63 ]
64
65 get authUser () {
66 return this.auth.getUser()
67 }
68
69 constructor (
70 protected router: Router,
71 protected route: ActivatedRoute,
72 private auth: AuthService,
73 private notifier: Notifier,
74 private confirmService: ConfirmService,
75 private videoCommentService: VideoCommentService,
76 private markdownRenderer: MarkdownService,
77 private bulkService: BulkService
78 ) {
79 super()
80
81 this.videoCommentActions = [
82 [
83 {
84 label: $localize`Delete this comment`,
85 handler: comment => this.deleteComment(comment),
86 isDisplayed: () => this.authUser.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT)
87 },
88
89 {
90 label: $localize`Delete all comments of this account`,
91 description: $localize`Comments are deleted after a few minutes`,
92 handler: comment => this.deleteUserComments(comment),
93 isDisplayed: () => this.authUser.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT)
94 }
95 ]
96 ]
97 }
98
99 ngOnInit () {
100 this.initialize()
101
102 this.bulkActions = [
103 {
104 label: $localize`Delete`,
105 handler: comments => this.removeComments(comments),
106 isDisplayed: () => this.authUser.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT),
107 iconName: 'delete'
108 }
109 ]
110 }
111
112 getIdentifier () {
113 return 'VideoCommentListComponent'
114 }
115
116 toHtml (text: string) {
117 return this.markdownRenderer.textMarkdownToHTML({ markdown: text, withHtml: true, withEmoji: true })
118 }
119
120 reloadData () {
121 this.videoCommentService.getAdminVideoComments({
122 pagination: this.pagination,
123 sort: this.sort,
124 search: this.search
125 }).subscribe({
126 next: async resultList => {
127 this.totalRecords = resultList.total
128
129 this.comments = []
130
131 for (const c of resultList.data) {
132 this.comments.push(
133 new VideoCommentAdmin(c, await this.toHtml(c.text))
134 )
135 }
136 },
137
138 error: err => this.notifier.error(err.message)
139 })
140 }
141
142 private removeComments (comments: VideoCommentAdmin[]) {
143 const commentArgs = comments.map(c => ({ videoId: c.video.id, commentId: c.id }))
144
145 this.videoCommentService.deleteVideoComments(commentArgs)
146 .subscribe({
147 next: () => {
148 this.notifier.success(
149 prepareIcu($localize`{count, plural, =1 {1 comment deleted.} other {{count} comments deleted.}}`)(
150 { count: commentArgs.length },
151 $localize`${commentArgs.length} comment(s) deleted.`
152 )
153 )
154
155 this.reloadData()
156 },
157
158 error: err => this.notifier.error(err.message),
159
160 complete: () => this.selectedRows = []
161 })
162 }
163
164 private deleteComment (comment: VideoCommentAdmin) {
165 this.videoCommentService.deleteVideoComment(comment.video.id, comment.id)
166 .subscribe({
167 next: () => this.reloadData(),
168
169 error: err => this.notifier.error(err.message)
170 })
171 }
172
173 private async deleteUserComments (comment: VideoCommentAdmin) {
174 const message = $localize`Do you really want to delete all comments of ${comment.by}?`
175 const res = await this.confirmService.confirm(message, $localize`Delete`)
176 if (res === false) return
177
178 const options = {
179 accountName: comment.by,
180 scope: 'instance' as 'instance'
181 }
182
183 this.bulkService.removeCommentsOf(options)
184 .subscribe({
185 next: () => {
186 this.notifier.success($localize`Comments of ${options.accountName} will be deleted in a few minutes`)
187 },
188
189 error: err => this.notifier.error(err.message)
190 })
191 }
192 }