]>
Commit | Line | Data |
---|---|---|
444c0a0e | 1 | import { cloneDeep } from 'lodash' |
bf1f6508 | 2 | import * as Sequelize from 'sequelize' |
444c0a0e C |
3 | import { logger } from '@server/helpers/logger' |
4 | import { sequelizeTypescript } from '@server/initializers/database' | |
bf1f6508 | 5 | import { ResultList } from '../../shared/models' |
d3ea8975 | 6 | import { VideoCommentThreadTree } from '../../shared/models/videos/video-comment.model' |
bf1f6508 | 7 | import { VideoCommentModel } from '../models/video/video-comment' |
de94ac86 | 8 | import { MAccountDefault, MComment, MCommentOwnerVideo, MCommentOwnerVideoReply, MVideoFullLight } from '../types/models' |
444c0a0e | 9 | import { sendCreateVideoComment, sendDeleteVideoComment } from './activitypub/send' |
de94ac86 | 10 | import { getLocalVideoCommentActivityPubUrl } from './activitypub/url' |
444c0a0e C |
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 | } | |
bf1f6508 C |
30 | |
31 | async function createVideoComment (obj: { | |
a1587156 C |
32 | text: string |
33 | inReplyToComment: MComment | null | |
34 | video: MVideoFullLight | |
453e83ea | 35 | account: MAccountDefault |
bf1f6508 | 36 | }, t: Sequelize.Transaction) { |
c1e791ba RK |
37 | let originCommentId: number | null = null |
38 | let inReplyToCommentId: number | null = null | |
d3ea8975 | 39 | |
c1e791ba | 40 | if (obj.inReplyToComment && obj.inReplyToComment !== null) { |
ea44f375 | 41 | originCommentId = obj.inReplyToComment.originCommentId || obj.inReplyToComment.id |
4635f59d | 42 | inReplyToCommentId = obj.inReplyToComment.id |
bf1f6508 C |
43 | } |
44 | ||
45 | const comment = await VideoCommentModel.create({ | |
46 | text: obj.text, | |
47 | originCommentId, | |
4635f59d | 48 | inReplyToCommentId, |
bf1f6508 | 49 | videoId: obj.video.id, |
4635f59d | 50 | accountId: obj.account.id, |
970ceac0 C |
51 | url: new Date().toISOString() |
52 | }, { transaction: t, validate: false }) | |
bf1f6508 | 53 | |
de94ac86 | 54 | comment.url = getLocalVideoCommentActivityPubUrl(obj.video, comment) |
bf1f6508 | 55 | |
453e83ea | 56 | const savedComment: MCommentOwnerVideoReply = await comment.save({ transaction: t }) |
ea44f375 C |
57 | savedComment.InReplyToVideoComment = obj.inReplyToComment |
58 | savedComment.Video = obj.video | |
4635f59d | 59 | savedComment.Account = obj.account |
ea44f375 | 60 | |
07197db4 | 61 | await sendCreateVideoComment(savedComment, t) |
ea44f375 C |
62 | |
63 | return savedComment | |
bf1f6508 C |
64 | } |
65 | ||
d3ea8975 | 66 | function buildFormattedCommentTree (resultList: ResultList<VideoCommentModel>): VideoCommentThreadTree { |
bf1f6508 C |
67 | // Comments are sorted by id ASC |
68 | const comments = resultList.data | |
69 | ||
70 | const comment = comments.shift() | |
d3ea8975 | 71 | const thread: VideoCommentThreadTree = { |
bf1f6508 C |
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 | ||
d3ea8975 | 82 | const childCommentThread: VideoCommentThreadTree = { |
bf1f6508 C |
83 | comment: childComment.toFormattedJSON(), |
84 | children: [] | |
85 | } | |
86 | ||
87 | const parentCommentThread = idx[childComment.inReplyToCommentId] | |
7ad9b984 C |
88 | // Maybe the parent comment was blocked by the admin/user |
89 | if (!parentCommentThread) continue | |
bf1f6508 C |
90 | |
91 | parentCommentThread.children.push(childCommentThread) | |
92 | idx[childComment.id] = childCommentThread | |
93 | } | |
94 | ||
95 | return thread | |
96 | } | |
97 | ||
444c0a0e | 98 | function markCommentAsDeleted (comment: MComment): void { |
69222afa JM |
99 | comment.text = '' |
100 | comment.deletedAt = new Date() | |
101 | comment.accountId = null | |
102 | } | |
103 | ||
bf1f6508 C |
104 | // --------------------------------------------------------------------------- |
105 | ||
106 | export { | |
444c0a0e | 107 | removeComment, |
bf1f6508 | 108 | createVideoComment, |
69222afa JM |
109 | buildFormattedCommentTree, |
110 | markCommentAsDeleted | |
bf1f6508 | 111 | } |