14 } from 'sequelize-typescript'
15 import { UserNotification, UserNotificationType } from '../../../shared'
16 import { getSort, throwIfNotValid } from '../utils'
17 import { isBooleanValid } from '../../helpers/custom-validators/misc'
18 import { isUserNotificationTypeValid } from '../../helpers/custom-validators/user-notifications'
19 import { UserModel } from './user'
20 import { VideoModel } from '../video/video'
21 import { VideoCommentModel } from '../video/video-comment'
22 import { Op } from 'sequelize'
23 import { VideoChannelModel } from '../video/video-channel'
24 import { AccountModel } from './account'
25 import { VideoAbuseModel } from '../video/video-abuse'
26 import { VideoBlacklistModel } from '../video/video-blacklist'
27 import { VideoImportModel } from '../video/video-import'
33 function buildVideoInclude (required: boolean) {
35 attributes: [ 'id', 'uuid', 'name' ],
36 model: () => VideoModel.unscoped(),
41 function buildChannelInclude () {
44 attributes: [ 'id', 'name' ],
45 model: () => VideoChannelModel.unscoped()
49 function buildAccountInclude () {
52 attributes: [ 'id', 'name' ],
53 model: () => AccountModel.unscoped()
58 [ScopeNames.WITH_ALL]: {
60 Object.assign(buildVideoInclude(false), {
61 include: [ buildChannelInclude() ]
64 attributes: [ 'id', 'originCommentId' ],
65 model: () => VideoCommentModel.unscoped(),
68 buildAccountInclude(),
69 buildVideoInclude(true)
74 model: () => VideoAbuseModel.unscoped(),
76 include: [ buildVideoInclude(true) ]
80 model: () => VideoBlacklistModel.unscoped(),
82 include: [ buildVideoInclude(true) ]
85 attributes: [ 'id', 'magnetUri', 'targetUrl', 'torrentName' ],
86 model: () => VideoImportModel.unscoped(),
88 include: [ buildVideoInclude(false) ]
94 tableName: 'userNotification',
100 fields: [ 'commentId' ]
104 export class UserNotificationModel extends Model<UserNotificationModel> {
108 @Is('UserNotificationType', value => throwIfNotValid(value, isUserNotificationTypeValid, 'type'))
110 type: UserNotificationType
114 @Is('UserNotificationRead', value => throwIfNotValid(value, isBooleanValid, 'read'))
124 @ForeignKey(() => UserModel)
128 @BelongsTo(() => UserModel, {
136 @ForeignKey(() => VideoModel)
140 @BelongsTo(() => VideoModel, {
148 @ForeignKey(() => VideoCommentModel)
152 @BelongsTo(() => VideoCommentModel, {
158 Comment: VideoCommentModel
160 @ForeignKey(() => VideoAbuseModel)
164 @BelongsTo(() => VideoAbuseModel, {
170 VideoAbuse: VideoAbuseModel
172 @ForeignKey(() => VideoBlacklistModel)
174 videoBlacklistId: number
176 @BelongsTo(() => VideoBlacklistModel, {
182 VideoBlacklist: VideoBlacklistModel
184 @ForeignKey(() => VideoImportModel)
186 videoImportId: number
188 @BelongsTo(() => VideoImportModel, {
194 VideoImport: VideoImportModel
196 static listForApi (userId: number, start: number, count: number, sort: string, unread?: boolean) {
197 const query: IFindOptions<UserNotificationModel> = {
200 order: getSort(sort),
206 if (unread !== undefined) query.where['read'] = !unread
208 return UserNotificationModel.scope(ScopeNames.WITH_ALL)
209 .findAndCountAll(query)
210 .then(({ rows, count }) => {
218 static markAsRead (userId: number, notificationIds: number[]) {
223 [Op.any]: notificationIds
228 return UserNotificationModel.update({ read: true }, query)
231 toFormattedJSON (): UserNotification {
232 const video = this.Video ? Object.assign(this.formatVideo(this.Video), {
234 id: this.Video.VideoChannel.id,
235 displayName: this.Video.VideoChannel.getDisplayName()
239 const videoImport = this.VideoImport ? {
240 id: this.VideoImport.id,
241 video: this.VideoImport.Video ? this.formatVideo(this.VideoImport.Video) : undefined,
242 torrentName: this.VideoImport.torrentName,
243 magnetUri: this.VideoImport.magnetUri,
244 targetUrl: this.VideoImport.targetUrl
247 const comment = this.Comment ? {
249 threadId: this.Comment.getThreadId(),
251 id: this.Comment.Account.id,
252 displayName: this.Comment.Account.getDisplayName()
254 video: this.formatVideo(this.Comment.Video)
257 const videoAbuse = this.VideoAbuse ? {
258 id: this.VideoAbuse.id,
259 video: this.formatVideo(this.VideoAbuse.Video)
262 const videoBlacklist = this.VideoBlacklist ? {
263 id: this.VideoBlacklist.id,
264 video: this.formatVideo(this.VideoBlacklist.Video)
276 createdAt: this.createdAt.toISOString(),
277 updatedAt: this.updatedAt.toISOString()
281 private formatVideo (video: VideoModel) {