]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/+videos/+video-watch/comment/video-comment.component.ts
Add ability to report comments in front end
[github/Chocobozzz/PeerTube.git] / client / src / app / +videos / +video-watch / comment / video-comment.component.ts
1
2 import { Component, EventEmitter, Input, OnChanges, OnInit, Output, ViewChild } from '@angular/core'
3 import { MarkdownService, Notifier, UserService } from '@app/core'
4 import { AuthService } from '@app/core/auth'
5 import { Account, Actor, DropdownAction, Video } from '@app/shared/shared-main'
6 import { CommentReportComponent } from '@app/shared/shared-moderation/comment-report.component'
7 import { I18n } from '@ngx-translate/i18n-polyfill'
8 import { User, UserRight } from '@shared/models'
9 import { VideoCommentThreadTree } from './video-comment-thread-tree.model'
10 import { VideoComment } from './video-comment.model'
11
12 @Component({
13 selector: 'my-video-comment',
14 templateUrl: './video-comment.component.html',
15 styleUrls: ['./video-comment.component.scss']
16 })
17 export class VideoCommentComponent implements OnInit, OnChanges {
18 @ViewChild('commentReportModal') commentReportModal: CommentReportComponent
19
20 @Input() video: Video
21 @Input() comment: VideoComment
22 @Input() parentComments: VideoComment[] = []
23 @Input() commentTree: VideoCommentThreadTree
24 @Input() inReplyToCommentId: number
25 @Input() highlightedComment = false
26 @Input() firstInThread = false
27
28 @Output() wantedToDelete = new EventEmitter<VideoComment>()
29 @Output() wantedToReply = new EventEmitter<VideoComment>()
30 @Output() threadCreated = new EventEmitter<VideoCommentThreadTree>()
31 @Output() resetReply = new EventEmitter()
32 @Output() timestampClicked = new EventEmitter<number>()
33
34 prependModerationActions: DropdownAction<any>[]
35
36 sanitizedCommentHTML = ''
37 newParentComments: VideoComment[] = []
38
39 commentAccount: Account
40 commentUser: User
41
42 constructor (
43 private i18n: I18n,
44 private markdownService: MarkdownService,
45 private authService: AuthService,
46 private userService: UserService,
47 private notifier: Notifier
48 ) {}
49
50 get user () {
51 return this.authService.getUser()
52 }
53
54 ngOnInit () {
55 this.init()
56 }
57
58 ngOnChanges () {
59 this.init()
60 }
61
62 onCommentReplyCreated (createdComment: VideoComment) {
63 if (!this.commentTree) {
64 this.commentTree = {
65 comment: this.comment,
66 children: []
67 }
68
69 this.threadCreated.emit(this.commentTree)
70 }
71
72 this.commentTree.children.unshift({
73 comment: createdComment,
74 children: []
75 })
76 this.resetReply.emit()
77 }
78
79 onWantToReply (comment?: VideoComment) {
80 this.wantedToReply.emit(comment || this.comment)
81 }
82
83 onWantToDelete (comment?: VideoComment) {
84 this.wantedToDelete.emit(comment || this.comment)
85 }
86
87 isUserLoggedIn () {
88 return this.authService.isLoggedIn()
89 }
90
91 onResetReply () {
92 this.resetReply.emit()
93 }
94
95 handleTimestampClicked (timestamp: number) {
96 this.timestampClicked.emit(timestamp)
97 }
98
99 isRemovableByUser () {
100 return this.comment.account && this.isUserLoggedIn() &&
101 (
102 this.user.account.id === this.comment.account.id ||
103 this.user.account.id === this.video.account.id ||
104 this.user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT)
105 )
106 }
107
108 switchToDefaultAvatar ($event: Event) {
109 ($event.target as HTMLImageElement).src = Actor.GET_DEFAULT_AVATAR_URL()
110 }
111
112 private getUserIfNeeded (account: Account) {
113 if (!account.userId) return
114 if (!this.authService.isLoggedIn()) return
115
116 const user = this.authService.getUser()
117 if (user.hasRight(UserRight.MANAGE_USERS)) {
118 this.userService.getUserWithCache(account.userId)
119 .subscribe(
120 user => this.commentUser = user,
121
122 err => this.notifier.error(err.message)
123 )
124 }
125 }
126
127 private async init () {
128 const html = await this.markdownService.textMarkdownToHTML(this.comment.text, true)
129 this.sanitizedCommentHTML = await this.markdownService.processVideoTimestamps(html)
130 this.newParentComments = this.parentComments.concat([ this.comment ])
131
132 if (this.comment.account) {
133 this.commentAccount = new Account(this.comment.account)
134 this.getUserIfNeeded(this.commentAccount)
135 } else {
136 this.comment.account = null
137 }
138
139 if (this.isUserLoggedIn()) {
140 this.prependModerationActions = [
141 {
142 label: this.i18n('Report comment'),
143 handler: () => this.showReportModal()
144 }
145 ]
146 } else {
147 this.prependModerationActions = undefined
148 }
149 }
150
151 private showReportModal () {
152 this.commentReportModal.show()
153 }
154 }