1 import * as Sequelize from 'sequelize'
3 AfterDestroy, AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, IFindOptions, Is, Model, Scopes, Table,
5 } from 'sequelize-typescript'
6 import { VideoComment } from '../../../shared/models/videos/video-comment.model'
7 import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub'
8 import { CONSTRAINTS_FIELDS } from '../../initializers'
9 import { AccountModel } from '../account/account'
10 import { getSort, throwIfNotValid } from '../utils'
11 import { VideoModel } from './video'
14 WITH_ACCOUNT = 'WITH_ACCOUNT'
18 [ScopeNames.WITH_ACCOUNT]: {
25 tableName: 'videoComment',
31 fields: [ 'videoId', 'originCommentId' ]
35 export class VideoCommentModel extends Model<VideoCommentModel> {
43 @Is('VideoCommentUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url'))
44 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.URL.max))
48 @Column(DataType.TEXT)
51 @ForeignKey(() => VideoCommentModel)
53 originCommentId: number
55 @BelongsTo(() => VideoCommentModel, {
61 OriginVideoComment: VideoCommentModel
63 @ForeignKey(() => VideoCommentModel)
65 inReplyToCommentId: number
67 @BelongsTo(() => VideoCommentModel, {
73 InReplyToVideoComment: VideoCommentModel
75 @ForeignKey(() => VideoModel)
79 @BelongsTo(() => VideoModel, {
87 @ForeignKey(() => AccountModel)
91 @BelongsTo(() => AccountModel, {
100 static sendDeleteIfOwned (instance: VideoCommentModel) {
105 static loadById (id: number, t?: Sequelize.Transaction) {
106 const query: IFindOptions<VideoCommentModel> = {
112 if (t !== undefined) query.transaction = t
114 return VideoCommentModel.findOne(query)
117 static loadByUrl (url: string, t?: Sequelize.Transaction) {
118 const query: IFindOptions<VideoCommentModel> = {
124 if (t !== undefined) query.transaction = t
126 return VideoCommentModel.findOne(query)
129 static listThreadsForApi (videoId: number, start: number, count: number, sort: string) {
133 order: [ getSort(sort) ],
136 inReplyToCommentId: null
140 return VideoCommentModel
141 .scope([ ScopeNames.WITH_ACCOUNT ])
142 .findAndCountAll(query)
143 .then(({ rows, count }) => {
144 return { total: count, data: rows }
148 static listThreadCommentsForApi (videoId: number, threadId: number) {
150 order: [ [ 'id', 'ASC' ] ],
153 [ Sequelize.Op.or ]: [
155 { originCommentId: threadId }
160 return VideoCommentModel
161 .scope([ ScopeNames.WITH_ACCOUNT ])
162 .findAndCountAll(query)
163 .then(({ rows, count }) => {
164 return { total: count, data: rows }
173 threadId: this.originCommentId || this.id,
174 inReplyToCommentId: this.inReplyToCommentId,
175 videoId: this.videoId,
176 createdAt: this.createdAt,
177 updatedAt: this.updatedAt,
179 name: this.Account.name