e3fe26e355d2d8851b0bdf3a5697ed0ab5a0263c
[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 } from './activitypub'
7
8 async function createVideoComment (obj: {
9   text: string,
10   inReplyToCommentId: number,
11   video: VideoModel
12   accountId: number
13 }, t: Sequelize.Transaction) {
14   let originCommentId: number = null
15
16   if (obj.inReplyToCommentId) {
17     const repliedComment = await VideoCommentModel.loadById(obj.inReplyToCommentId)
18     if (!repliedComment) throw new Error('Unknown replied comment.')
19
20     originCommentId = repliedComment.originCommentId || repliedComment.id
21   }
22
23   const comment = await VideoCommentModel.create({
24     text: obj.text,
25     originCommentId,
26     inReplyToCommentId: obj.inReplyToCommentId,
27     videoId: obj.video.id,
28     accountId: obj.accountId,
29     url: 'fake url'
30   }, { transaction: t, validate: false })
31
32   comment.set('url', getVideoCommentActivityPubUrl(obj.video, comment))
33
34   return comment.save({ transaction: t })
35 }
36
37 function buildFormattedCommentTree (resultList: ResultList<VideoCommentModel>): VideoCommentThreadTree {
38   // Comments are sorted by id ASC
39   const comments = resultList.data
40
41   const comment = comments.shift()
42   const thread: VideoCommentThreadTree = {
43     comment: comment.toFormattedJSON(),
44     children: []
45   }
46   const idx = {
47     [comment.id]: thread
48   }
49
50   while (comments.length !== 0) {
51     const childComment = comments.shift()
52
53     const childCommentThread: VideoCommentThreadTree = {
54       comment: childComment.toFormattedJSON(),
55       children: []
56     }
57
58     const parentCommentThread = idx[childComment.inReplyToCommentId]
59     if (!parentCommentThread) {
60       const msg = `Cannot format video thread tree, parent ${childComment.inReplyToCommentId} not found for child ${childComment.id}`
61       throw new Error(msg)
62     }
63
64     parentCommentThread.children.push(childCommentThread)
65     idx[childComment.id] = childCommentThread
66   }
67
68   return thread
69 }
70
71 // ---------------------------------------------------------------------------
72
73 export {
74   createVideoComment,
75   buildFormattedCommentTree
76 }