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