mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-02-25 18:55:32 -06:00
Add mentions to comments
This commit is contained in:
@@ -114,5 +114,6 @@ async function videoChannelController (req: express.Request, res: express.Respon
|
||||
async function videoCommentController (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
const videoComment: VideoCommentModel = res.locals.videoComment
|
||||
|
||||
return res.json(videoComment.toActivityPubObject())
|
||||
const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, undefined)
|
||||
return res.json(videoComment.toActivityPubObject(threadParentComments))
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ACTIVITY_PUB } from '../../../initializers'
|
||||
import { ActorModel } from '../../../models/activitypub/actor'
|
||||
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
|
||||
import { VideoModel } from '../../../models/video/video'
|
||||
import { VideoCommentModel } from '../../../models/video/video-comment'
|
||||
import { VideoShareModel } from '../../../models/video/video-share'
|
||||
import { activitypubHttpJobScheduler, ActivityPubHttpPayload } from '../../jobs/activitypub-http-job-scheduler'
|
||||
|
||||
@@ -84,6 +85,34 @@ function getOriginVideoAudience (video: VideoModel, actorsInvolvedInVideo: Actor
|
||||
}
|
||||
}
|
||||
|
||||
function getOriginVideoCommentAudience (
|
||||
videoComment: VideoCommentModel,
|
||||
threadParentComments: VideoCommentModel[],
|
||||
actorsInvolvedInVideo: ActorModel[],
|
||||
isOrigin = false
|
||||
) {
|
||||
const to = [ ACTIVITY_PUB.PUBLIC ]
|
||||
const cc = [ ]
|
||||
|
||||
// Owner of the video we comment
|
||||
if (isOrigin === false) {
|
||||
cc.push(videoComment.Video.VideoChannel.Account.Actor.url)
|
||||
}
|
||||
|
||||
// Followers of the poster
|
||||
cc.push(videoComment.Account.Actor.followersUrl)
|
||||
|
||||
// Send to actors we reply to
|
||||
for (const parentComment of threadParentComments) {
|
||||
cc.push(parentComment.Account.Actor.url)
|
||||
}
|
||||
|
||||
return {
|
||||
to,
|
||||
cc: cc.concat(actorsInvolvedInVideo.map(a => a.followersUrl))
|
||||
}
|
||||
}
|
||||
|
||||
function getObjectFollowersAudience (actorsInvolvedInObject: ActorModel[]) {
|
||||
return {
|
||||
to: actorsInvolvedInObject.map(a => a.followersUrl),
|
||||
@@ -92,10 +121,10 @@ function getObjectFollowersAudience (actorsInvolvedInObject: ActorModel[]) {
|
||||
}
|
||||
|
||||
async function getActorsInvolvedInVideo (video: VideoModel, t: Transaction) {
|
||||
const actorsToForwardView = await VideoShareModel.loadActorsByShare(video.id, t)
|
||||
actorsToForwardView.push(video.VideoChannel.Account.Actor)
|
||||
const actors = await VideoShareModel.loadActorsByShare(video.id, t)
|
||||
actors.push(video.VideoChannel.Account.Actor)
|
||||
|
||||
return actorsToForwardView
|
||||
return actors
|
||||
}
|
||||
|
||||
async function getAudience (actorSender: ActorModel, t: Transaction, isPublic = true) {
|
||||
@@ -138,5 +167,6 @@ export {
|
||||
getActorsInvolvedInVideo,
|
||||
getObjectFollowersAudience,
|
||||
forwardActivity,
|
||||
audiencify
|
||||
audiencify,
|
||||
getOriginVideoCommentAudience
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ import { VideoAbuseModel } from '../../../models/video/video-abuse'
|
||||
import { VideoCommentModel } from '../../../models/video/video-comment'
|
||||
import { getVideoAbuseActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoViewActivityPubUrl } from '../url'
|
||||
import {
|
||||
audiencify, broadcastToFollowers, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience, getOriginVideoAudience,
|
||||
audiencify, broadcastToFollowers, getActorsInvolvedInVideo, getAudience, getObjectFollowersAudience,
|
||||
getOriginVideoAudience, getOriginVideoCommentAudience,
|
||||
unicastTo
|
||||
} from './misc'
|
||||
|
||||
@@ -35,11 +36,12 @@ async function sendVideoAbuse (byActor: ActorModel, videoAbuse: VideoAbuseModel,
|
||||
|
||||
async function sendCreateVideoCommentToOrigin (comment: VideoCommentModel, t: Transaction) {
|
||||
const byActor = comment.Account.Actor
|
||||
const threadParentComments = await VideoCommentModel.listThreadParentComments(comment, t)
|
||||
const commentObject = comment.toActivityPubObject(threadParentComments)
|
||||
|
||||
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(comment.Video, t)
|
||||
const audience = getOriginVideoAudience(comment.Video, actorsInvolvedInVideo)
|
||||
const audience = getOriginVideoCommentAudience(comment, threadParentComments, actorsInvolvedInVideo)
|
||||
|
||||
const commentObject = comment.toActivityPubObject()
|
||||
const data = await createActivityData(comment.url, byActor, commentObject, t, audience)
|
||||
|
||||
return unicastTo(data, byActor, comment.Video.VideoChannel.Account.Actor.sharedInboxUrl, t)
|
||||
@@ -47,15 +49,15 @@ async function sendCreateVideoCommentToOrigin (comment: VideoCommentModel, t: Tr
|
||||
|
||||
async function sendCreateVideoCommentToVideoFollowers (comment: VideoCommentModel, t: Transaction) {
|
||||
const byActor = comment.Account.Actor
|
||||
const threadParentComments = await VideoCommentModel.listThreadParentComments(comment, t)
|
||||
const commentObject = comment.toActivityPubObject(threadParentComments)
|
||||
|
||||
const actorsToForwardView = await getActorsInvolvedInVideo(comment.Video, t)
|
||||
const audience = getObjectFollowersAudience(actorsToForwardView)
|
||||
|
||||
const commentObject = comment.toActivityPubObject()
|
||||
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(comment.Video, t)
|
||||
const audience = getOriginVideoCommentAudience(comment, threadParentComments, actorsInvolvedInVideo)
|
||||
const data = await createActivityData(comment.url, byActor, commentObject, t, audience)
|
||||
|
||||
const followersException = [ byActor ]
|
||||
return broadcastToFollowers(data, byActor, actorsToForwardView, t, followersException)
|
||||
return broadcastToFollowers(data, byActor, actorsInvolvedInVideo, t, followersException)
|
||||
}
|
||||
|
||||
async function sendCreateViewToOrigin (byActor: ActorModel, video: VideoModel, t: Transaction) {
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
AfterDestroy, AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, IFindOptions, Is, Model, Scopes, Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript'
|
||||
import { ActivityTagObject } from '../../../shared/models/activitypub/objects/common-objects'
|
||||
import { VideoCommentObject } from '../../../shared/models/activitypub/objects/video-comment-object'
|
||||
import { VideoComment } from '../../../shared/models/videos/video-comment.model'
|
||||
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
|
||||
@@ -270,6 +271,30 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
|
||||
})
|
||||
}
|
||||
|
||||
static listThreadParentComments (comment: VideoCommentModel, t: Sequelize.Transaction) {
|
||||
const query = {
|
||||
order: [ [ 'createdAt', 'ASC' ] ],
|
||||
where: {
|
||||
[ Sequelize.Op.or ]: [
|
||||
{ id: comment.getThreadId() },
|
||||
{ originCommentId: comment.getThreadId() }
|
||||
],
|
||||
id: {
|
||||
[ Sequelize.Op.ne ]: comment.id
|
||||
}
|
||||
},
|
||||
transaction: t
|
||||
}
|
||||
|
||||
return VideoCommentModel
|
||||
.scope([ ScopeNames.WITH_ACCOUNT ])
|
||||
.findAll(query)
|
||||
}
|
||||
|
||||
getThreadId (): number {
|
||||
return this.originCommentId || this.id
|
||||
}
|
||||
|
||||
isOwned () {
|
||||
return this.Account.isOwned()
|
||||
}
|
||||
@@ -289,7 +314,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
|
||||
} as VideoComment
|
||||
}
|
||||
|
||||
toActivityPubObject (): VideoCommentObject {
|
||||
toActivityPubObject (threadParentComments: VideoCommentModel[]): VideoCommentObject {
|
||||
let inReplyTo: string
|
||||
// New thread, so in AS we reply to the video
|
||||
if (this.inReplyToCommentId === null) {
|
||||
@@ -298,6 +323,17 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
|
||||
inReplyTo = this.InReplyToVideoComment.url
|
||||
}
|
||||
|
||||
const tag: ActivityTagObject[] = []
|
||||
for (const parentComment of threadParentComments) {
|
||||
const actor = parentComment.Account.Actor
|
||||
|
||||
tag.push({
|
||||
type: 'Mention',
|
||||
href: actor.url,
|
||||
name: `@${actor.preferredUsername}@${actor.getHost()}`
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Note' as 'Note',
|
||||
id: this.url,
|
||||
@@ -306,7 +342,8 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
|
||||
updated: this.updatedAt.toISOString(),
|
||||
published: this.createdAt.toISOString(),
|
||||
url: this.url,
|
||||
attributedTo: this.Account.Actor.url
|
||||
attributedTo: this.Account.Actor.url,
|
||||
tag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user