]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/models/video/video-comment.ts
8e84bfc06ab0603429b4811c8837a73c8f93136f
[github/Chocobozzz/PeerTube.git] / server / models / video / video-comment.ts
1 import * as Sequelize from 'sequelize'
2 import {
3 AfterDestroy, AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, IFindOptions, Is, Model, Scopes, Table,
4 UpdatedAt
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'
12
13 enum ScopeNames {
14 WITH_ACCOUNT = 'WITH_ACCOUNT'
15 }
16
17 @Scopes({
18 [ScopeNames.WITH_ACCOUNT]: {
19 include: [
20 () => AccountModel
21 ]
22 }
23 })
24 @Table({
25 tableName: 'videoComment',
26 indexes: [
27 {
28 fields: [ 'videoId' ]
29 },
30 {
31 fields: [ 'videoId', 'originCommentId' ]
32 }
33 ]
34 })
35 export class VideoCommentModel extends Model<VideoCommentModel> {
36 @CreatedAt
37 createdAt: Date
38
39 @UpdatedAt
40 updatedAt: Date
41
42 @AllowNull(false)
43 @Is('VideoCommentUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url'))
44 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.URL.max))
45 url: string
46
47 @AllowNull(false)
48 @Column(DataType.TEXT)
49 text: string
50
51 @ForeignKey(() => VideoCommentModel)
52 @Column
53 originCommentId: number
54
55 @BelongsTo(() => VideoCommentModel, {
56 foreignKey: {
57 allowNull: true
58 },
59 onDelete: 'CASCADE'
60 })
61 OriginVideoComment: VideoCommentModel
62
63 @ForeignKey(() => VideoCommentModel)
64 @Column
65 inReplyToCommentId: number
66
67 @BelongsTo(() => VideoCommentModel, {
68 foreignKey: {
69 allowNull: true
70 },
71 onDelete: 'CASCADE'
72 })
73 InReplyToVideoComment: VideoCommentModel
74
75 @ForeignKey(() => VideoModel)
76 @Column
77 videoId: number
78
79 @BelongsTo(() => VideoModel, {
80 foreignKey: {
81 allowNull: false
82 },
83 onDelete: 'CASCADE'
84 })
85 Video: VideoModel
86
87 @ForeignKey(() => AccountModel)
88 @Column
89 accountId: number
90
91 @BelongsTo(() => AccountModel, {
92 foreignKey: {
93 allowNull: false
94 },
95 onDelete: 'CASCADE'
96 })
97 Account: AccountModel
98
99 @AfterDestroy
100 static sendDeleteIfOwned (instance: VideoCommentModel) {
101 // TODO
102 return undefined
103 }
104
105 static loadById (id: number, t?: Sequelize.Transaction) {
106 const query: IFindOptions<VideoCommentModel> = {
107 where: {
108 id
109 }
110 }
111
112 if (t !== undefined) query.transaction = t
113
114 return VideoCommentModel.findOne(query)
115 }
116
117 static loadByUrl (url: string, t?: Sequelize.Transaction) {
118 const query: IFindOptions<VideoCommentModel> = {
119 where: {
120 url
121 }
122 }
123
124 if (t !== undefined) query.transaction = t
125
126 return VideoCommentModel.findOne(query)
127 }
128
129 static listThreadsForApi (videoId: number, start: number, count: number, sort: string) {
130 const query = {
131 offset: start,
132 limit: count,
133 order: [ getSort(sort) ],
134 where: {
135 videoId,
136 inReplyToCommentId: null
137 }
138 }
139
140 return VideoCommentModel
141 .scope([ ScopeNames.WITH_ACCOUNT ])
142 .findAndCountAll(query)
143 .then(({ rows, count }) => {
144 return { total: count, data: rows }
145 })
146 }
147
148 static listThreadCommentsForApi (videoId: number, threadId: number) {
149 const query = {
150 order: [ [ 'id', 'ASC' ] ],
151 where: {
152 videoId,
153 [ Sequelize.Op.or ]: [
154 { id: threadId },
155 { originCommentId: threadId }
156 ]
157 }
158 }
159
160 return VideoCommentModel
161 .scope([ ScopeNames.WITH_ACCOUNT ])
162 .findAndCountAll(query)
163 .then(({ rows, count }) => {
164 return { total: count, data: rows }
165 })
166 }
167
168 toFormattedJSON () {
169 return {
170 id: this.id,
171 url: this.url,
172 text: this.text,
173 threadId: this.originCommentId || this.id,
174 inReplyToCommentId: this.inReplyToCommentId,
175 videoId: this.videoId,
176 createdAt: this.createdAt,
177 updatedAt: this.updatedAt,
178 account: {
179 name: this.Account.name
180 }
181 } as VideoComment
182 }
183 }