X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Fvideo%2Fvideo-comment.ts;h=868d04ff9e0a7b381e78a63d8e05553d309d8001;hb=d6bd50ba1d095d35ec3837afedd8319a05cded90;hp=66fca2484484084b4ad3107dbdf9f7a4e84fb83b;hpb=4cb6d4578893db310297d7e118ce2fb7ecb952a3;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts index 66fca2484..868d04ff9 100644 --- a/server/models/video/video-comment.ts +++ b/server/models/video/video-comment.ts @@ -1,8 +1,9 @@ import * as Sequelize from 'sequelize' import { - AfterDestroy, AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, IFindOptions, Is, Model, Scopes, Table, + AllowNull, BeforeDestroy, 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' @@ -103,6 +104,10 @@ enum ScopeNames { }, { fields: [ 'videoId', 'originCommentId' ] + }, + { + fields: [ 'url' ], + unique: true } ] }) @@ -174,10 +179,17 @@ export class VideoCommentModel extends Model { }) Account: AccountModel - @AfterDestroy - static async sendDeleteIfOwned (instance: VideoCommentModel) { + @BeforeDestroy + static async sendDeleteIfOwned (instance: VideoCommentModel, options) { + if (!instance.Account || !instance.Account.Actor) { + instance.Account = await instance.$get('Account', { + include: [ ActorModel ], + transaction: options.transaction + }) as AccountModel + } + if (instance.isOwned()) { - await sendDeleteVideoComment(instance, undefined) + await sendDeleteVideoComment(instance, options.transaction) } } @@ -207,7 +219,7 @@ export class VideoCommentModel extends Model { .findOne(query) } - static loadByUrl (url: string, t?: Sequelize.Transaction) { + static loadByUrlAndPopulateAccount (url: string, t?: Sequelize.Transaction) { const query: IFindOptions = { where: { url @@ -216,10 +228,10 @@ export class VideoCommentModel extends Model { if (t !== undefined) query.transaction = t - return VideoCommentModel.findOne(query) + return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT ]).findOne(query) } - static loadByUrlAndPopulateAccount (url: string, t?: Sequelize.Transaction) { + static loadByUrlAndPopulateReplyAndVideo (url: string, t?: Sequelize.Transaction) { const query: IFindOptions = { where: { url @@ -228,7 +240,7 @@ export class VideoCommentModel extends Model { if (t !== undefined) query.transaction = t - return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT ]).findOne(query) + return VideoCommentModel.scope([ ScopeNames.WITH_IN_REPLY_TO, ScopeNames.WITH_VIDEO ]).findOne(query) } static listThreadsForApi (videoId: number, start: number, count: number, sort: string) { @@ -252,7 +264,7 @@ export class VideoCommentModel extends Model { static listThreadCommentsForApi (videoId: number, threadId: number) { const query = { - order: [ [ 'createdAt', 'ASC' ] ], + order: [ [ 'createdAt', 'ASC' ], [ 'updatedAt', 'ASC' ] ], where: { videoId, [ Sequelize.Op.or ]: [ @@ -270,6 +282,33 @@ export class VideoCommentModel extends Model { }) } + static listThreadParentComments (comment: VideoCommentModel, t: Sequelize.Transaction, order: 'ASC' | 'DESC' = 'ASC') { + const query = { + order: [ [ 'createdAt', order ] ], + where: { + [ Sequelize.Op.or ]: [ + { id: comment.getThreadId() }, + { originCommentId: comment.getThreadId() } + ], + id: { + [ Sequelize.Op.ne ]: comment.id + }, + createdAt: { + [ Sequelize.Op.lt ]: comment.createdAt + } + }, + transaction: t + } + + return VideoCommentModel + .scope([ ScopeNames.WITH_ACCOUNT ]) + .findAll(query) + } + + getThreadId (): number { + return this.originCommentId || this.id + } + isOwned () { return this.Account.isOwned() } @@ -289,7 +328,7 @@ export class VideoCommentModel extends Model { } 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 +337,17 @@ export class VideoCommentModel extends Model { 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 +356,8 @@ export class VideoCommentModel extends Model { updated: this.updatedAt.toISOString(), published: this.createdAt.toISOString(), url: this.url, - attributedTo: this.Account.Actor.url + attributedTo: this.Account.Actor.url, + tag } } }