aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/account
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/account')
-rw-r--r--server/models/account/account.ts4
-rw-r--r--server/models/account/user-notification.ts171
2 files changed, 137 insertions, 38 deletions
diff --git a/server/models/account/account.ts b/server/models/account/account.ts
index a99e9b1ad..84ef0b30d 100644
--- a/server/models/account/account.ts
+++ b/server/models/account/account.ts
@@ -288,6 +288,10 @@ export class AccountModel extends Model<AccountModel> {
288 return this.Actor.isOwned() 288 return this.Actor.isOwned()
289 } 289 }
290 290
291 isOutdated () {
292 return this.Actor.isOutdated()
293 }
294
291 getDisplayName () { 295 getDisplayName () {
292 return this.name 296 return this.name
293 } 297 }
diff --git a/server/models/account/user-notification.ts b/server/models/account/user-notification.ts
index 9e4f982a3..6cdbb827b 100644
--- a/server/models/account/user-notification.ts
+++ b/server/models/account/user-notification.ts
@@ -27,11 +27,33 @@ import { VideoBlacklistModel } from '../video/video-blacklist'
27import { VideoImportModel } from '../video/video-import' 27import { VideoImportModel } from '../video/video-import'
28import { ActorModel } from '../activitypub/actor' 28import { ActorModel } from '../activitypub/actor'
29import { ActorFollowModel } from '../activitypub/actor-follow' 29import { ActorFollowModel } from '../activitypub/actor-follow'
30import { AvatarModel } from '../avatar/avatar'
31import { ServerModel } from '../server/server'
30 32
31enum ScopeNames { 33enum ScopeNames {
32 WITH_ALL = 'WITH_ALL' 34 WITH_ALL = 'WITH_ALL'
33} 35}
34 36
37function buildActorWithAvatarInclude () {
38 return {
39 attributes: [ 'preferredUsername' ],
40 model: () => ActorModel.unscoped(),
41 required: true,
42 include: [
43 {
44 attributes: [ 'filename' ],
45 model: () => AvatarModel.unscoped(),
46 required: false
47 },
48 {
49 attributes: [ 'host' ],
50 model: () => ServerModel.unscoped(),
51 required: false
52 }
53 ]
54 }
55}
56
35function buildVideoInclude (required: boolean) { 57function buildVideoInclude (required: boolean) {
36 return { 58 return {
37 attributes: [ 'id', 'uuid', 'name' ], 59 attributes: [ 'id', 'uuid', 'name' ],
@@ -40,19 +62,21 @@ function buildVideoInclude (required: boolean) {
40 } 62 }
41} 63}
42 64
43function buildChannelInclude (required: boolean) { 65function buildChannelInclude (required: boolean, withActor = false) {
44 return { 66 return {
45 required, 67 required,
46 attributes: [ 'id', 'name' ], 68 attributes: [ 'id', 'name' ],
47 model: () => VideoChannelModel.unscoped() 69 model: () => VideoChannelModel.unscoped(),
70 include: withActor === true ? [ buildActorWithAvatarInclude() ] : []
48 } 71 }
49} 72}
50 73
51function buildAccountInclude (required: boolean) { 74function buildAccountInclude (required: boolean, withActor = false) {
52 return { 75 return {
53 required, 76 required,
54 attributes: [ 'id', 'name' ], 77 attributes: [ 'id', 'name' ],
55 model: () => AccountModel.unscoped() 78 model: () => AccountModel.unscoped(),
79 include: withActor === true ? [ buildActorWithAvatarInclude() ] : []
56 } 80 }
57} 81}
58 82
@@ -60,47 +84,40 @@ function buildAccountInclude (required: boolean) {
60 [ScopeNames.WITH_ALL]: { 84 [ScopeNames.WITH_ALL]: {
61 include: [ 85 include: [
62 Object.assign(buildVideoInclude(false), { 86 Object.assign(buildVideoInclude(false), {
63 include: [ buildChannelInclude(true) ] 87 include: [ buildChannelInclude(true, true) ]
64 }), 88 }),
89
65 { 90 {
66 attributes: [ 'id', 'originCommentId' ], 91 attributes: [ 'id', 'originCommentId' ],
67 model: () => VideoCommentModel.unscoped(), 92 model: () => VideoCommentModel.unscoped(),
68 required: false, 93 required: false,
69 include: [ 94 include: [
70 buildAccountInclude(true), 95 buildAccountInclude(true, true),
71 buildVideoInclude(true) 96 buildVideoInclude(true)
72 ] 97 ]
73 }, 98 },
99
74 { 100 {
75 attributes: [ 'id' ], 101 attributes: [ 'id' ],
76 model: () => VideoAbuseModel.unscoped(), 102 model: () => VideoAbuseModel.unscoped(),
77 required: false, 103 required: false,
78 include: [ buildVideoInclude(true) ] 104 include: [ buildVideoInclude(true) ]
79 }, 105 },
106
80 { 107 {
81 attributes: [ 'id' ], 108 attributes: [ 'id' ],
82 model: () => VideoBlacklistModel.unscoped(), 109 model: () => VideoBlacklistModel.unscoped(),
83 required: false, 110 required: false,
84 include: [ buildVideoInclude(true) ] 111 include: [ buildVideoInclude(true) ]
85 }, 112 },
113
86 { 114 {
87 attributes: [ 'id', 'magnetUri', 'targetUrl', 'torrentName' ], 115 attributes: [ 'id', 'magnetUri', 'targetUrl', 'torrentName' ],
88 model: () => VideoImportModel.unscoped(), 116 model: () => VideoImportModel.unscoped(),
89 required: false, 117 required: false,
90 include: [ buildVideoInclude(false) ] 118 include: [ buildVideoInclude(false) ]
91 }, 119 },
92 { 120
93 attributes: [ 'id', 'name' ],
94 model: () => AccountModel.unscoped(),
95 required: false,
96 include: [
97 {
98 attributes: [ 'id', 'preferredUsername' ],
99 model: () => ActorModel.unscoped(),
100 required: true
101 }
102 ]
103 },
104 { 121 {
105 attributes: [ 'id' ], 122 attributes: [ 'id' ],
106 model: () => ActorFollowModel.unscoped(), 123 model: () => ActorFollowModel.unscoped(),
@@ -111,7 +128,23 @@ function buildAccountInclude (required: boolean) {
111 model: () => ActorModel.unscoped(), 128 model: () => ActorModel.unscoped(),
112 required: true, 129 required: true,
113 as: 'ActorFollower', 130 as: 'ActorFollower',
114 include: [ buildAccountInclude(true) ] 131 include: [
132 {
133 attributes: [ 'id', 'name' ],
134 model: () => AccountModel.unscoped(),
135 required: true
136 },
137 {
138 attributes: [ 'filename' ],
139 model: () => AvatarModel.unscoped(),
140 required: false
141 },
142 {
143 attributes: [ 'host' ],
144 model: () => ServerModel.unscoped(),
145 required: false
146 }
147 ]
115 }, 148 },
116 { 149 {
117 attributes: [ 'preferredUsername' ], 150 attributes: [ 'preferredUsername' ],
@@ -124,7 +157,9 @@ function buildAccountInclude (required: boolean) {
124 ] 157 ]
125 } 158 }
126 ] 159 ]
127 } 160 },
161
162 buildAccountInclude(false, true)
128 ] 163 ]
129 } 164 }
130}) 165})
@@ -132,10 +167,63 @@ function buildAccountInclude (required: boolean) {
132 tableName: 'userNotification', 167 tableName: 'userNotification',
133 indexes: [ 168 indexes: [
134 { 169 {
135 fields: [ 'videoId' ] 170 fields: [ 'userId' ]
171 },
172 {
173 fields: [ 'videoId' ],
174 where: {
175 videoId: {
176 [Op.ne]: null
177 }
178 }
136 }, 179 },
137 { 180 {
138 fields: [ 'commentId' ] 181 fields: [ 'commentId' ],
182 where: {
183 commentId: {
184 [Op.ne]: null
185 }
186 }
187 },
188 {
189 fields: [ 'videoAbuseId' ],
190 where: {
191 videoAbuseId: {
192 [Op.ne]: null
193 }
194 }
195 },
196 {
197 fields: [ 'videoBlacklistId' ],
198 where: {
199 videoBlacklistId: {
200 [Op.ne]: null
201 }
202 }
203 },
204 {
205 fields: [ 'videoImportId' ],
206 where: {
207 videoImportId: {
208 [Op.ne]: null
209 }
210 }
211 },
212 {
213 fields: [ 'accountId' ],
214 where: {
215 accountId: {
216 [Op.ne]: null
217 }
218 }
219 },
220 {
221 fields: [ 'actorFollowId' ],
222 where: {
223 actorFollowId: {
224 [Op.ne]: null
225 }
226 }
139 } 227 }
140 ] 228 ]
141}) 229})
@@ -297,12 +385,9 @@ export class UserNotificationModel extends Model<UserNotificationModel> {
297 } 385 }
298 386
299 toFormattedJSON (): UserNotification { 387 toFormattedJSON (): UserNotification {
300 const video = this.Video ? Object.assign(this.formatVideo(this.Video), { 388 const video = this.Video
301 channel: { 389 ? Object.assign(this.formatVideo(this.Video),{ channel: this.formatActor(this.Video.VideoChannel) })
302 id: this.Video.VideoChannel.id, 390 : undefined
303 displayName: this.Video.VideoChannel.getDisplayName()
304 }
305 }) : undefined
306 391
307 const videoImport = this.VideoImport ? { 392 const videoImport = this.VideoImport ? {
308 id: this.VideoImport.id, 393 id: this.VideoImport.id,
@@ -315,10 +400,7 @@ export class UserNotificationModel extends Model<UserNotificationModel> {
315 const comment = this.Comment ? { 400 const comment = this.Comment ? {
316 id: this.Comment.id, 401 id: this.Comment.id,
317 threadId: this.Comment.getThreadId(), 402 threadId: this.Comment.getThreadId(),
318 account: { 403 account: this.formatActor(this.Comment.Account),
319 id: this.Comment.Account.id,
320 displayName: this.Comment.Account.getDisplayName()
321 },
322 video: this.formatVideo(this.Comment.Video) 404 video: this.formatVideo(this.Comment.Video)
323 } : undefined 405 } : undefined
324 406
@@ -332,17 +414,16 @@ export class UserNotificationModel extends Model<UserNotificationModel> {
332 video: this.formatVideo(this.VideoBlacklist.Video) 414 video: this.formatVideo(this.VideoBlacklist.Video)
333 } : undefined 415 } : undefined
334 416
335 const account = this.Account ? { 417 const account = this.Account ? this.formatActor(this.Account) : undefined
336 id: this.Account.id,
337 displayName: this.Account.getDisplayName(),
338 name: this.Account.Actor.preferredUsername
339 } : undefined
340 418
341 const actorFollow = this.ActorFollow ? { 419 const actorFollow = this.ActorFollow ? {
342 id: this.ActorFollow.id, 420 id: this.ActorFollow.id,
343 follower: { 421 follower: {
422 id: this.ActorFollow.ActorFollower.Account.id,
344 displayName: this.ActorFollow.ActorFollower.Account.getDisplayName(), 423 displayName: this.ActorFollow.ActorFollower.Account.getDisplayName(),
345 name: this.ActorFollow.ActorFollower.preferredUsername 424 name: this.ActorFollow.ActorFollower.preferredUsername,
425 avatar: this.ActorFollow.ActorFollower.Avatar ? { path: this.ActorFollow.ActorFollower.Avatar.getWebserverPath() } : undefined,
426 host: this.ActorFollow.ActorFollower.getHost()
346 }, 427 },
347 following: { 428 following: {
348 type: this.ActorFollow.ActorFollowing.VideoChannel ? 'channel' as 'channel' : 'account' as 'account', 429 type: this.ActorFollow.ActorFollowing.VideoChannel ? 'channel' as 'channel' : 'account' as 'account',
@@ -374,4 +455,18 @@ export class UserNotificationModel extends Model<UserNotificationModel> {
374 name: video.name 455 name: video.name
375 } 456 }
376 } 457 }
458
459 private formatActor (accountOrChannel: AccountModel | VideoChannelModel) {
460 const avatar = accountOrChannel.Actor.Avatar
461 ? { path: accountOrChannel.Actor.Avatar.getWebserverPath() }
462 : undefined
463
464 return {
465 id: accountOrChannel.id,
466 displayName: accountOrChannel.getDisplayName(),
467 name: accountOrChannel.Actor.preferredUsername,
468 host: accountOrChannel.Actor.getHost(),
469 avatar
470 }
471 }
377} 472}