diff options
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/activitypub/url.ts | 13 | ||||
-rw-r--r-- | server/lib/video-comment.ts | 74 |
2 files changed, 81 insertions, 6 deletions
diff --git a/server/lib/activitypub/url.ts b/server/lib/activitypub/url.ts index bb2d4d11e..729bb8dda 100644 --- a/server/lib/activitypub/url.ts +++ b/server/lib/activitypub/url.ts | |||
@@ -3,17 +3,18 @@ import { ActorModel } from '../../models/activitypub/actor' | |||
3 | import { ActorFollowModel } from '../../models/activitypub/actor-follow' | 3 | import { ActorFollowModel } from '../../models/activitypub/actor-follow' |
4 | import { VideoModel } from '../../models/video/video' | 4 | import { VideoModel } from '../../models/video/video' |
5 | import { VideoAbuseModel } from '../../models/video/video-abuse' | 5 | import { VideoAbuseModel } from '../../models/video/video-abuse' |
6 | import { VideoCommentModel } from '../../models/video/video-comment' | ||
6 | 7 | ||
7 | function getVideoActivityPubUrl (video: VideoModel) { | 8 | function getVideoActivityPubUrl (video: VideoModel) { |
8 | return CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid | 9 | return CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid |
9 | } | 10 | } |
10 | 11 | ||
11 | function getVideoChannelActivityPubUrl (videoChannelUUID: string) { | 12 | function getVideoCommentActivityPubUrl (video: VideoModel, videoComment: VideoCommentModel) { |
12 | return CONFIG.WEBSERVER.URL + '/video-channels/' + videoChannelUUID | 13 | return CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid + '#comment-' + videoComment.id |
13 | } | 14 | } |
14 | 15 | ||
15 | function getApplicationActivityPubUrl () { | 16 | function getVideoChannelActivityPubUrl (videoChannelUUID: string) { |
16 | return CONFIG.WEBSERVER.URL + '/application/peertube' | 17 | return CONFIG.WEBSERVER.URL + '/video-channels/' + videoChannelUUID |
17 | } | 18 | } |
18 | 19 | ||
19 | function getAccountActivityPubUrl (accountName: string) { | 20 | function getAccountActivityPubUrl (accountName: string) { |
@@ -63,7 +64,6 @@ function getUndoActivityPubUrl (originalUrl: string) { | |||
63 | } | 64 | } |
64 | 65 | ||
65 | export { | 66 | export { |
66 | getApplicationActivityPubUrl, | ||
67 | getVideoActivityPubUrl, | 67 | getVideoActivityPubUrl, |
68 | getVideoChannelActivityPubUrl, | 68 | getVideoChannelActivityPubUrl, |
69 | getAccountActivityPubUrl, | 69 | getAccountActivityPubUrl, |
@@ -75,5 +75,6 @@ export { | |||
75 | getUndoActivityPubUrl, | 75 | getUndoActivityPubUrl, |
76 | getVideoViewActivityPubUrl, | 76 | getVideoViewActivityPubUrl, |
77 | getVideoLikeActivityPubUrl, | 77 | getVideoLikeActivityPubUrl, |
78 | getVideoDislikeActivityPubUrl | 78 | getVideoDislikeActivityPubUrl, |
79 | getVideoCommentActivityPubUrl | ||
79 | } | 80 | } |
diff --git a/server/lib/video-comment.ts b/server/lib/video-comment.ts new file mode 100644 index 000000000..edb72d4e2 --- /dev/null +++ b/server/lib/video-comment.ts | |||
@@ -0,0 +1,74 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | import { ResultList } from '../../shared/models' | ||
3 | import { VideoCommentThread } 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 | inReplyToComment: number, | ||
11 | video: VideoModel | ||
12 | actorId: number | ||
13 | }, t: Sequelize.Transaction) { | ||
14 | let originCommentId: number = null | ||
15 | if (obj.inReplyToComment) { | ||
16 | const repliedComment = await VideoCommentModel.loadById(obj.inReplyToComment) | ||
17 | if (!repliedComment) throw new Error('Unknown replied comment.') | ||
18 | |||
19 | originCommentId = repliedComment.originCommentId || repliedComment.id | ||
20 | } | ||
21 | |||
22 | const comment = await VideoCommentModel.create({ | ||
23 | text: obj.text, | ||
24 | originCommentId, | ||
25 | inReplyToComment: obj.inReplyToComment, | ||
26 | videoId: obj.video.id, | ||
27 | actorId: obj.actorId | ||
28 | }, { transaction: t }) | ||
29 | |||
30 | comment.set('url', getVideoCommentActivityPubUrl(obj.video, comment)) | ||
31 | |||
32 | return comment.save({ transaction: t }) | ||
33 | } | ||
34 | |||
35 | function buildFormattedCommentTree (resultList: ResultList<VideoCommentModel>): VideoCommentThread { | ||
36 | // Comments are sorted by id ASC | ||
37 | const comments = resultList.data | ||
38 | |||
39 | const comment = comments.shift() | ||
40 | const thread: VideoCommentThread = { | ||
41 | comment: comment.toFormattedJSON(), | ||
42 | children: [] | ||
43 | } | ||
44 | const idx = { | ||
45 | [comment.id]: thread | ||
46 | } | ||
47 | |||
48 | while (comments.length !== 0) { | ||
49 | const childComment = comments.shift() | ||
50 | |||
51 | const childCommentThread: VideoCommentThread = { | ||
52 | comment: childComment.toFormattedJSON(), | ||
53 | children: [] | ||
54 | } | ||
55 | |||
56 | const parentCommentThread = idx[childComment.inReplyToCommentId] | ||
57 | if (!parentCommentThread) { | ||
58 | const msg = `Cannot format video thread tree, parent ${childComment.inReplyToCommentId} not found for child ${childComment.id}` | ||
59 | throw new Error(msg) | ||
60 | } | ||
61 | |||
62 | parentCommentThread.children.push(childCommentThread) | ||
63 | idx[childComment.id] = childCommentThread | ||
64 | } | ||
65 | |||
66 | return thread | ||
67 | } | ||
68 | |||
69 | // --------------------------------------------------------------------------- | ||
70 | |||
71 | export { | ||
72 | createVideoComment, | ||
73 | buildFormattedCommentTree | ||
74 | } | ||