+ const isPublic = true // Comments are always public
+ const audience = getAudience(videoComment.Account.Actor, isPublic)
+
+ const videoCommentObject = audiencify(videoComment.toActivityPubObject(threadParentComments), audience)
+
+ if (req.path.endsWith('/activity')) {
+ const data = createActivityData(videoComment.url, videoComment.Account.Actor, videoCommentObject, audience)
+ return activityPubResponse(activityPubContextify(data), res)
+ }
+
+ return activityPubResponse(activityPubContextify(videoCommentObject), res)
+}
+
+// ---------------------------------------------------------------------------
+
+async function actorFollowing (req: express.Request, actor: ActorModel) {
+ const handler = (start: number, count: number) => {
+ return ActorFollowModel.listAcceptedFollowingUrlsForApi([ actor.id ], undefined, start, count)
+ }
+
+ return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, handler, req.query.page)
+}
+
+async function actorFollowers (req: express.Request, actor: ActorModel) {
+ const handler = (start: number, count: number) => {
+ return ActorFollowModel.listAcceptedFollowerUrlsForApi([ actor.id ], undefined, start, count)
+ }
+
+ return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, handler, req.query.page)
+}
+
+function videoRates (req: express.Request, rateType: VideoRateType, video: VideoModel, url: string) {
+ const handler = async (start: number, count: number) => {
+ const result = await AccountVideoRateModel.listAndCountAccountUrlsByVideoId(rateType, video.id, start, count)
+ return {
+ total: result.count,
+ data: result.rows.map(r => r.Account.Actor.url)
+ }
+ }
+ return activityPubCollectionPagination(url, handler, req.query.page)