diff options
author | Chocobozzz <me@florianbigard.com> | 2021-06-29 17:18:30 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-06-29 17:18:39 +0200 |
commit | 911186dae411d78788ccede093c251303187589a (patch) | |
tree | 967a07cd985ae4e2ea5249855726455fe929471d /client/src/app/+videos/+video-watch/shared/comment/video-comment.component.ts | |
parent | b0c43e36dbdc2c964f6828a78b146faebfb75b21 (diff) | |
download | PeerTube-911186dae411d78788ccede093c251303187589a.tar.gz PeerTube-911186dae411d78788ccede093c251303187589a.tar.zst PeerTube-911186dae411d78788ccede093c251303187589a.zip |
Reorganize watch components
Diffstat (limited to 'client/src/app/+videos/+video-watch/shared/comment/video-comment.component.ts')
-rw-r--r-- | client/src/app/+videos/+video-watch/shared/comment/video-comment.component.ts | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/client/src/app/+videos/+video-watch/shared/comment/video-comment.component.ts b/client/src/app/+videos/+video-watch/shared/comment/video-comment.component.ts new file mode 100644 index 000000000..04f8f0d58 --- /dev/null +++ b/client/src/app/+videos/+video-watch/shared/comment/video-comment.component.ts | |||
@@ -0,0 +1,208 @@ | |||
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, 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 { User, UserRight } from '@shared/models' | ||
9 | |||
10 | @Component({ | ||
11 | selector: 'my-video-comment', | ||
12 | templateUrl: './video-comment.component.html', | ||
13 | styleUrls: ['./video-comment.component.scss'] | ||
14 | }) | ||
15 | export class VideoCommentComponent implements OnInit, OnChanges { | ||
16 | @ViewChild('commentReportModal') commentReportModal: CommentReportComponent | ||
17 | |||
18 | @Input() video: Video | ||
19 | @Input() comment: VideoComment | ||
20 | @Input() parentComments: VideoComment[] = [] | ||
21 | @Input() commentTree: VideoCommentThreadTree | ||
22 | @Input() inReplyToCommentId: number | ||
23 | @Input() highlightedComment = false | ||
24 | @Input() firstInThread = false | ||
25 | @Input() redraftValue?: string | ||
26 | |||
27 | @Output() wantedToReply = new EventEmitter<VideoComment>() | ||
28 | @Output() wantedToDelete = new EventEmitter<VideoComment>() | ||
29 | @Output() wantedToRedraft = 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 markdownService: MarkdownService, | ||
44 | private authService: AuthService, | ||
45 | private userService: UserService, | ||
46 | private notifier: Notifier | ||
47 | ) {} | ||
48 | |||
49 | get user () { | ||
50 | return this.authService.getUser() | ||
51 | } | ||
52 | |||
53 | ngOnInit () { | ||
54 | this.init() | ||
55 | } | ||
56 | |||
57 | ngOnChanges () { | ||
58 | this.init() | ||
59 | } | ||
60 | |||
61 | onCommentReplyCreated (createdComment: VideoComment) { | ||
62 | if (!this.commentTree) { | ||
63 | this.commentTree = { | ||
64 | comment: this.comment, | ||
65 | hasDisplayedChildren: false, | ||
66 | children: [] | ||
67 | } | ||
68 | |||
69 | this.threadCreated.emit(this.commentTree) | ||
70 | } | ||
71 | |||
72 | this.commentTree.children.unshift({ | ||
73 | comment: createdComment, | ||
74 | hasDisplayedChildren: false, | ||
75 | children: [] | ||
76 | }) | ||
77 | |||
78 | this.resetReply.emit() | ||
79 | |||
80 | this.redraftValue = undefined | ||
81 | } | ||
82 | |||
83 | onWantToReply (comment?: VideoComment) { | ||
84 | this.wantedToReply.emit(comment || this.comment) | ||
85 | } | ||
86 | |||
87 | onWantToDelete (comment?: VideoComment) { | ||
88 | this.wantedToDelete.emit(comment || this.comment) | ||
89 | } | ||
90 | |||
91 | onWantToRedraft (comment?: VideoComment) { | ||
92 | this.wantedToRedraft.emit(comment || this.comment) | ||
93 | } | ||
94 | |||
95 | isUserLoggedIn () { | ||
96 | return this.authService.isLoggedIn() | ||
97 | } | ||
98 | |||
99 | onResetReply () { | ||
100 | this.resetReply.emit() | ||
101 | } | ||
102 | |||
103 | handleTimestampClicked (timestamp: number) { | ||
104 | this.timestampClicked.emit(timestamp) | ||
105 | } | ||
106 | |||
107 | isRemovableByUser () { | ||
108 | return this.comment.account && this.isUserLoggedIn() && | ||
109 | ( | ||
110 | this.user.account.id === this.comment.account.id || | ||
111 | this.user.account.id === this.video.account.id || | ||
112 | this.user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) | ||
113 | ) | ||
114 | } | ||
115 | |||
116 | isRedraftableByUser () { | ||
117 | return ( | ||
118 | this.comment.account && | ||
119 | this.isUserLoggedIn() && | ||
120 | this.user.account.id === this.comment.account.id && | ||
121 | this.comment.totalReplies === 0 | ||
122 | ) | ||
123 | } | ||
124 | |||
125 | isReportableByUser () { | ||
126 | return ( | ||
127 | this.comment.account && | ||
128 | this.isUserLoggedIn() && | ||
129 | this.comment.isDeleted === false && | ||
130 | this.user.account.id !== this.comment.account.id | ||
131 | ) | ||
132 | } | ||
133 | |||
134 | isCommentDisplayed () { | ||
135 | // Not deleted | ||
136 | return !this.comment.isDeleted || | ||
137 | this.comment.totalReplies !== 0 || // Or root comment thread has replies | ||
138 | (this.commentTree?.hasDisplayedChildren) // Or this is a reply that have other replies | ||
139 | } | ||
140 | |||
141 | isChild () { | ||
142 | return this.parentComments.length !== 0 | ||
143 | } | ||
144 | |||
145 | private getUserIfNeeded (account: Account) { | ||
146 | if (!account.userId) return | ||
147 | if (!this.authService.isLoggedIn()) return | ||
148 | |||
149 | const user = this.authService.getUser() | ||
150 | if (user.hasRight(UserRight.MANAGE_USERS)) { | ||
151 | this.userService.getUserWithCache(account.userId) | ||
152 | .subscribe( | ||
153 | user => this.commentUser = user, | ||
154 | |||
155 | err => this.notifier.error(err.message) | ||
156 | ) | ||
157 | } | ||
158 | } | ||
159 | |||
160 | private async init () { | ||
161 | // Before HTML rendering restore line feed for markdown list compatibility | ||
162 | const commentText = this.comment.text.replace(/<br.?\/?>/g, '\r\n') | ||
163 | const html = await this.markdownService.textMarkdownToHTML(commentText, true, true) | ||
164 | this.sanitizedCommentHTML = this.markdownService.processVideoTimestamps(html) | ||
165 | this.newParentComments = this.parentComments.concat([ this.comment ]) | ||
166 | |||
167 | if (this.comment.account) { | ||
168 | this.commentAccount = new Account(this.comment.account) | ||
169 | this.getUserIfNeeded(this.commentAccount) | ||
170 | } else { | ||
171 | this.comment.account = null | ||
172 | } | ||
173 | |||
174 | this.prependModerationActions = [] | ||
175 | |||
176 | if (this.isReportableByUser()) { | ||
177 | this.prependModerationActions.push({ | ||
178 | label: $localize`Report this comment`, | ||
179 | iconName: 'flag', | ||
180 | handler: () => this.showReportModal() | ||
181 | }) | ||
182 | } | ||
183 | |||
184 | if (this.isRemovableByUser()) { | ||
185 | this.prependModerationActions.push({ | ||
186 | label: $localize`Remove`, | ||
187 | iconName: 'delete', | ||
188 | handler: () => this.onWantToDelete() | ||
189 | }) | ||
190 | } | ||
191 | |||
192 | if (this.isRedraftableByUser()) { | ||
193 | this.prependModerationActions.push({ | ||
194 | label: $localize`Remove & re-draft`, | ||
195 | iconName: 'edit', | ||
196 | handler: () => this.onWantToRedraft() | ||
197 | }) | ||
198 | } | ||
199 | |||
200 | if (this.prependModerationActions.length === 0) { | ||
201 | this.prependModerationActions = undefined | ||
202 | } | ||
203 | } | ||
204 | |||
205 | private showReportModal () { | ||
206 | this.commentReportModal.show() | ||
207 | } | ||
208 | } | ||