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