]>
Commit | Line | Data |
---|---|---|
1 | import { cloneDeep } from 'lodash' | |
2 | import * as Sequelize from 'sequelize' | |
3 | import { logger } from '@server/helpers/logger' | |
4 | import { sequelizeTypescript } from '@server/initializers/database' | |
5 | import { ResultList } from '../../shared/models' | |
6 | import { VideoCommentThreadTree } from '../../shared/models/videos/video-comment.model' | |
7 | import { VideoCommentModel } from '../models/video/video-comment' | |
8 | import { MAccountDefault, MComment, MCommentOwnerVideoReply, MVideoFullLight, MCommentOwnerVideo } from '../typings/models' | |
9 | import { sendCreateVideoComment, sendDeleteVideoComment } from './activitypub/send' | |
10 | import { getVideoCommentActivityPubUrl } from './activitypub/url' | |
11 | import { Hooks } from './plugins/hooks' | |
12 | ||
13 | async function removeComment (videoCommentInstance: MCommentOwnerVideo) { | |
14 | const videoCommentInstanceBefore = cloneDeep(videoCommentInstance) | |
15 | ||
16 | await sequelizeTypescript.transaction(async t => { | |
17 | if (videoCommentInstance.isOwned() || videoCommentInstance.Video.isOwned()) { | |
18 | await sendDeleteVideoComment(videoCommentInstance, t) | |
19 | } | |
20 | ||
21 | markCommentAsDeleted(videoCommentInstance) | |
22 | ||
23 | await videoCommentInstance.save() | |
24 | }) | |
25 | ||
26 | logger.info('Video comment %d deleted.', videoCommentInstance.id) | |
27 | ||
28 | Hooks.runAction('action:api.video-comment.deleted', { comment: videoCommentInstanceBefore }) | |
29 | } | |
30 | ||
31 | async function createVideoComment (obj: { | |
32 | text: string | |
33 | inReplyToComment: MComment | null | |
34 | video: MVideoFullLight | |
35 | account: MAccountDefault | |
36 | }, t: Sequelize.Transaction) { | |
37 | let originCommentId: number | null = null | |
38 | let inReplyToCommentId: number | null = null | |
39 | ||
40 | if (obj.inReplyToComment && obj.inReplyToComment !== null) { | |
41 | originCommentId = obj.inReplyToComment.originCommentId || obj.inReplyToComment.id | |
42 | inReplyToCommentId = obj.inReplyToComment.id | |
43 | } | |
44 | ||
45 | const comment = await VideoCommentModel.create({ | |
46 | text: obj.text, | |
47 | originCommentId, | |
48 | inReplyToCommentId, | |
49 | videoId: obj.video.id, | |
50 | accountId: obj.account.id, | |
51 | url: new Date().toISOString() | |
52 | }, { transaction: t, validate: false }) | |
53 | ||
54 | comment.url = getVideoCommentActivityPubUrl(obj.video, comment) | |
55 | ||
56 | const savedComment: MCommentOwnerVideoReply = await comment.save({ transaction: t }) | |
57 | savedComment.InReplyToVideoComment = obj.inReplyToComment | |
58 | savedComment.Video = obj.video | |
59 | savedComment.Account = obj.account | |
60 | ||
61 | await sendCreateVideoComment(savedComment, t) | |
62 | ||
63 | return savedComment | |
64 | } | |
65 | ||
66 | function buildFormattedCommentTree (resultList: ResultList<VideoCommentModel>): VideoCommentThreadTree { | |
67 | // Comments are sorted by id ASC | |
68 | const comments = resultList.data | |
69 | ||
70 | const comment = comments.shift() | |
71 | const thread: VideoCommentThreadTree = { | |
72 | comment: comment.toFormattedJSON(), | |
73 | children: [] | |
74 | } | |
75 | const idx = { | |
76 | [comment.id]: thread | |
77 | } | |
78 | ||
79 | while (comments.length !== 0) { | |
80 | const childComment = comments.shift() | |
81 | ||
82 | const childCommentThread: VideoCommentThreadTree = { | |
83 | comment: childComment.toFormattedJSON(), | |
84 | children: [] | |
85 | } | |
86 | ||
87 | const parentCommentThread = idx[childComment.inReplyToCommentId] | |
88 | // Maybe the parent comment was blocked by the admin/user | |
89 | if (!parentCommentThread) continue | |
90 | ||
91 | parentCommentThread.children.push(childCommentThread) | |
92 | idx[childComment.id] = childCommentThread | |
93 | } | |
94 | ||
95 | return thread | |
96 | } | |
97 | ||
98 | function markCommentAsDeleted (comment: MComment): void { | |
99 | comment.text = '' | |
100 | comment.deletedAt = new Date() | |
101 | comment.accountId = null | |
102 | } | |
103 | ||
104 | // --------------------------------------------------------------------------- | |
105 | ||
106 | export { | |
107 | removeComment, | |
108 | createVideoComment, | |
109 | buildFormattedCommentTree, | |
110 | markCommentAsDeleted | |
111 | } |