ef6a8f097b7c222fa37bf143fad14f29cb651802
[oweals/peertube.git] / server / lib / video-comment.ts
1 import * as Sequelize from 'sequelize'
2 import { ResultList } from '../../shared/models'
3 import { VideoCommentThreadTree } from '../../shared/models/videos/video-comment.model'
4 import { VideoModel } from '../models/video/video'
5 import { VideoCommentModel } from '../models/video/video-comment'
6 import { getVideoCommentActivityPubUrl, sendVideoRateChangeToFollowers } from './activitypub'
7 import { sendCreateVideoCommentToOrigin, sendCreateVideoCommentToVideoFollowers } from './activitypub/send'
8
9 async function createVideoComment (obj: {
10   text: string,
11   inReplyToComment: VideoCommentModel,
12   video: VideoModel
13   accountId: number
14 }, t: Sequelize.Transaction) {
15   let originCommentId: number = null
16
17   if (obj.inReplyToComment) {
18     originCommentId = obj.inReplyToComment.originCommentId || obj.inReplyToComment.id
19   }
20
21   const comment = await VideoCommentModel.create({
22     text: obj.text,
23     originCommentId,
24     inReplyToCommentId: obj.inReplyToComment.id,
25     videoId: obj.video.id,
26     accountId: obj.accountId,
27     url: 'fake url'
28   }, { transaction: t, validate: false })
29
30   comment.set('url', getVideoCommentActivityPubUrl(obj.video, comment))
31
32   const savedComment = await comment.save({ transaction: t })
33   savedComment.InReplyToVideoComment = obj.inReplyToComment
34   savedComment.Video = obj.video
35
36   if (savedComment.Video.isOwned()) {
37     await sendCreateVideoCommentToVideoFollowers(savedComment, t)
38   } else {
39     await sendCreateVideoCommentToOrigin(savedComment, t)
40   }
41
42   return savedComment
43 }
44
45 function buildFormattedCommentTree (resultList: ResultList<VideoCommentModel>): VideoCommentThreadTree {
46   // Comments are sorted by id ASC
47   const comments = resultList.data
48
49   const comment = comments.shift()
50   const thread: VideoCommentThreadTree = {
51     comment: comment.toFormattedJSON(),
52     children: []
53   }
54   const idx = {
55     [comment.id]: thread
56   }
57
58   while (comments.length !== 0) {
59     const childComment = comments.shift()
60
61     const childCommentThread: VideoCommentThreadTree = {
62       comment: childComment.toFormattedJSON(),
63       children: []
64     }
65
66     const parentCommentThread = idx[childComment.inReplyToCommentId]
67     if (!parentCommentThread) {
68       const msg = `Cannot format video thread tree, parent ${childComment.inReplyToCommentId} not found for child ${childComment.id}`
69       throw new Error(msg)
70     }
71
72     parentCommentThread.children.push(childCommentThread)
73     idx[childComment.id] = childCommentThread
74   }
75
76   return thread
77 }
78
79 // ---------------------------------------------------------------------------
80
81 export {
82   createVideoComment,
83   buildFormattedCommentTree
84 }