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