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/report-modals/comment-report.component'
7 import { VideoComment, VideoCommentThreadTree } from '@app/shared/shared-video-comment'
8 import { I18n } from '@ngx-translate/i18n-polyfill'
9 import { User, UserRight } from '@shared/models'
12 selector: 'my-video-comment',
13 templateUrl: './video-comment.component.html',
14 styleUrls: ['./video-comment.component.scss']
16 export class VideoCommentComponent implements OnInit, OnChanges {
17 @ViewChild('commentReportModal') commentReportModal: CommentReportComponent
20 @Input() comment: VideoComment
21 @Input() parentComments: VideoComment[] = []
22 @Input() commentTree: VideoCommentThreadTree
23 @Input() inReplyToCommentId: number
24 @Input() highlightedComment = false
25 @Input() firstInThread = false
27 @Output() wantedToDelete = new EventEmitter<VideoComment>()
28 @Output() wantedToReply = new EventEmitter<VideoComment>()
29 @Output() threadCreated = new EventEmitter<VideoCommentThreadTree>()
30 @Output() resetReply = new EventEmitter()
31 @Output() timestampClicked = new EventEmitter<number>()
33 prependModerationActions: DropdownAction<any>[]
35 sanitizedCommentHTML = ''
36 newParentComments: VideoComment[] = []
38 commentAccount: Account
43 private markdownService: MarkdownService,
44 private authService: AuthService,
45 private userService: UserService,
46 private notifier: Notifier
50 return this.authService.getUser()
61 onCommentReplyCreated (createdComment: VideoComment) {
62 if (!this.commentTree) {
64 comment: this.comment,
68 this.threadCreated.emit(this.commentTree)
71 this.commentTree.children.unshift({
72 comment: createdComment,
75 this.resetReply.emit()
78 onWantToReply (comment?: VideoComment) {
79 this.wantedToReply.emit(comment || this.comment)
82 onWantToDelete (comment?: VideoComment) {
83 this.wantedToDelete.emit(comment || this.comment)
87 return this.authService.isLoggedIn()
91 this.resetReply.emit()
94 handleTimestampClicked (timestamp: number) {
95 this.timestampClicked.emit(timestamp)
98 isRemovableByUser () {
99 return this.comment.account && this.isUserLoggedIn() &&
101 this.user.account.id === this.comment.account.id ||
102 this.user.account.id === this.video.account.id ||
103 this.user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT)
107 switchToDefaultAvatar ($event: Event) {
108 ($event.target as HTMLImageElement).src = Actor.GET_DEFAULT_AVATAR_URL()
111 private getUserIfNeeded (account: Account) {
112 if (!account.userId) return
113 if (!this.authService.isLoggedIn()) return
115 const user = this.authService.getUser()
116 if (user.hasRight(UserRight.MANAGE_USERS)) {
117 this.userService.getUserWithCache(account.userId)
119 user => this.commentUser = user,
121 err => this.notifier.error(err.message)
126 private async init () {
127 const html = await this.markdownService.textMarkdownToHTML(this.comment.text, true)
128 this.sanitizedCommentHTML = await this.markdownService.processVideoTimestamps(html)
129 this.newParentComments = this.parentComments.concat([ this.comment ])
131 if (this.comment.account) {
132 this.commentAccount = new Account(this.comment.account)
133 this.getUserIfNeeded(this.commentAccount)
135 this.comment.account = null
138 if (this.isUserLoggedIn() && this.authService.getUser().account.id !== this.comment.account.id) {
139 this.prependModerationActions = [
141 label: this.i18n('Report comment'),
142 handler: () => this.showReportModal()
146 this.prependModerationActions = undefined
150 private showReportModal () {
151 this.commentReportModal.show()