aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/account
diff options
context:
space:
mode:
authorkontrollanten <6680299+kontrollanten@users.noreply.github.com>2022-02-28 08:34:43 +0100
committerGitHub <noreply@github.com>2022-02-28 08:34:43 +0100
commitd0800f7661f13fabe7bb6f4aa0ea50764f106405 (patch)
treed43e6b0b6f4a5a32e03487e6464edbcaf288be2a /server/models/account
parent5cad2ca9db9b9d138f8a33058d10b94a9fd50c69 (diff)
downloadPeerTube-d0800f7661f13fabe7bb6f4aa0ea50764f106405.tar.gz
PeerTube-d0800f7661f13fabe7bb6f4aa0ea50764f106405.tar.zst
PeerTube-d0800f7661f13fabe7bb6f4aa0ea50764f106405.zip
Implement avatar miniatures (#4639)
* client: remove unused file * refactor(client/my-actor-avatar): size from input Read size from component input instead of scss, to make it possible to use smaller avatar images when implemented. * implement avatar miniatures close #4560 * fix(test): max file size * fix(search-index): normalize res acc to avatarMini * refactor avatars to an array * client/search: resize channel avatar to 120 * refactor(client/videos): remove unused function * client(actor-avatar): set default size * fix tests and avatars full result When findOne is used only an array containting one avatar is returned. * update migration version and version notations * server/search: harmonize normalizing * Cleanup avatar miniature PR Co-authored-by: Chocobozzz <me@florianbigard.com>
Diffstat (limited to 'server/models/account')
-rw-r--r--server/models/account/account-blocklist.ts83
-rw-r--r--server/models/account/account-video-rate.ts56
-rw-r--r--server/models/account/account.ts59
3 files changed, 103 insertions, 95 deletions
diff --git a/server/models/account/account-blocklist.ts b/server/models/account/account-blocklist.ts
index 1162962bf..a7b8db076 100644
--- a/server/models/account/account-blocklist.ts
+++ b/server/models/account/account-blocklist.ts
@@ -1,7 +1,7 @@
1import { Op, QueryTypes } from 'sequelize' 1import { FindOptions, Op, QueryTypes } from 'sequelize'
2import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' 2import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
3import { handlesToNameAndHost } from '@server/helpers/actors' 3import { handlesToNameAndHost } from '@server/helpers/actors'
4import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/types/models' 4import { MAccountBlocklist, MAccountBlocklistFormattable } from '@server/types/models'
5import { AttributesOnly } from '@shared/typescript-utils' 5import { AttributesOnly } from '@shared/typescript-utils'
6import { AccountBlock } from '../../../shared/models' 6import { AccountBlock } from '../../../shared/models'
7import { ActorModel } from '../actor/actor' 7import { ActorModel } from '../actor/actor'
@@ -9,27 +9,6 @@ import { ServerModel } from '../server/server'
9import { createSafeIn, getSort, searchAttribute } from '../utils' 9import { createSafeIn, getSort, searchAttribute } from '../utils'
10import { AccountModel } from './account' 10import { AccountModel } from './account'
11 11
12enum ScopeNames {
13 WITH_ACCOUNTS = 'WITH_ACCOUNTS'
14}
15
16@Scopes(() => ({
17 [ScopeNames.WITH_ACCOUNTS]: {
18 include: [
19 {
20 model: AccountModel,
21 required: true,
22 as: 'ByAccount'
23 },
24 {
25 model: AccountModel,
26 required: true,
27 as: 'BlockedAccount'
28 }
29 ]
30 }
31}))
32
33@Table({ 12@Table({
34 tableName: 'accountBlocklist', 13 tableName: 'accountBlocklist',
35 indexes: [ 14 indexes: [
@@ -123,33 +102,45 @@ export class AccountBlocklistModel extends Model<Partial<AttributesOnly<AccountB
123 }) { 102 }) {
124 const { start, count, sort, search, accountId } = parameters 103 const { start, count, sort, search, accountId } = parameters
125 104
126 const query = { 105 const getQuery = (forCount: boolean) => {
127 offset: start, 106 const query: FindOptions = {
128 limit: count, 107 offset: start,
129 order: getSort(sort) 108 limit: count,
130 } 109 order: getSort(sort),
110 where: { accountId }
111 }
131 112
132 const where = { 113 if (search) {
133 accountId 114 Object.assign(query.where, {
134 } 115 [Op.or]: [
116 searchAttribute(search, '$BlockedAccount.name$'),
117 searchAttribute(search, '$BlockedAccount.Actor.url$')
118 ]
119 })
120 }
135 121
136 if (search) { 122 if (forCount !== true) {
137 Object.assign(where, { 123 query.include = [
138 [Op.or]: [ 124 {
139 searchAttribute(search, '$BlockedAccount.name$'), 125 model: AccountModel,
140 searchAttribute(search, '$BlockedAccount.Actor.url$') 126 required: true,
127 as: 'ByAccount'
128 },
129 {
130 model: AccountModel,
131 required: true,
132 as: 'BlockedAccount'
133 }
141 ] 134 ]
142 }) 135 }
143 }
144 136
145 Object.assign(query, { where }) 137 return query
138 }
146 139
147 return AccountBlocklistModel 140 return Promise.all([
148 .scope([ ScopeNames.WITH_ACCOUNTS ]) 141 AccountBlocklistModel.count(getQuery(true)),
149 .findAndCountAll<MAccountBlocklistAccounts>(query) 142 AccountBlocklistModel.findAll(getQuery(false))
150 .then(({ rows, count }) => { 143 ]).then(([ total, data ]) => ({ total, data }))
151 return { total: count, data: rows }
152 })
153 } 144 }
154 145
155 static listHandlesBlockedBy (accountIds: number[]): Promise<string[]> { 146 static listHandlesBlockedBy (accountIds: number[]): Promise<string[]> {
diff --git a/server/models/account/account-video-rate.ts b/server/models/account/account-video-rate.ts
index e89d31adf..7303651eb 100644
--- a/server/models/account/account-video-rate.ts
+++ b/server/models/account/account-video-rate.ts
@@ -121,29 +121,40 @@ export class AccountVideoRateModel extends Model<Partial<AttributesOnly<AccountV
121 type?: string 121 type?: string
122 accountId: number 122 accountId: number
123 }) { 123 }) {
124 const query: FindOptions = { 124 const getQuery = (forCount: boolean) => {
125 offset: options.start, 125 const query: FindOptions = {
126 limit: options.count, 126 offset: options.start,
127 order: getSort(options.sort), 127 limit: options.count,
128 where: { 128 order: getSort(options.sort),
129 accountId: options.accountId 129 where: {
130 }, 130 accountId: options.accountId
131 include: [
132 {
133 model: VideoModel,
134 required: true,
135 include: [
136 {
137 model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, { withAccount: true } as SummaryOptions ] }),
138 required: true
139 }
140 ]
141 } 131 }
142 ] 132 }
133
134 if (options.type) query.where['type'] = options.type
135
136 if (forCount !== true) {
137 query.include = [
138 {
139 model: VideoModel,
140 required: true,
141 include: [
142 {
143 model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, { withAccount: true } as SummaryOptions ] }),
144 required: true
145 }
146 ]
147 }
148 ]
149 }
150
151 return query
143 } 152 }
144 if (options.type) query.where['type'] = options.type
145 153
146 return AccountVideoRateModel.findAndCountAll(query) 154 return Promise.all([
155 AccountVideoRateModel.count(getQuery(true)),
156 AccountVideoRateModel.findAll(getQuery(false))
157 ]).then(([ total, data ]) => ({ total, data }))
147 } 158 }
148 159
149 static listRemoteRateUrlsOfLocalVideos () { 160 static listRemoteRateUrlsOfLocalVideos () {
@@ -232,7 +243,10 @@ export class AccountVideoRateModel extends Model<Partial<AttributesOnly<AccountV
232 ] 243 ]
233 } 244 }
234 245
235 return AccountVideoRateModel.findAndCountAll<MAccountVideoRateAccountUrl>(query) 246 return Promise.all([
247 AccountVideoRateModel.count(query),
248 AccountVideoRateModel.findAll<MAccountVideoRateAccountUrl>(query)
249 ]).then(([ total, data ]) => ({ total, data }))
236 } 250 }
237 251
238 static cleanOldRatesOf (videoId: number, type: VideoRateType, beforeUpdatedAt: Date) { 252 static cleanOldRatesOf (videoId: number, type: VideoRateType, beforeUpdatedAt: Date) {
diff --git a/server/models/account/account.ts b/server/models/account/account.ts
index 619a598dd..8a7dfba94 100644
--- a/server/models/account/account.ts
+++ b/server/models/account/account.ts
@@ -54,6 +54,7 @@ export type SummaryOptions = {
54 whereActor?: WhereOptions 54 whereActor?: WhereOptions
55 whereServer?: WhereOptions 55 whereServer?: WhereOptions
56 withAccountBlockerIds?: number[] 56 withAccountBlockerIds?: number[]
57 forCount?: boolean
57} 58}
58 59
59@DefaultScope(() => ({ 60@DefaultScope(() => ({
@@ -73,22 +74,24 @@ export type SummaryOptions = {
73 where: options.whereServer 74 where: options.whereServer
74 } 75 }
75 76
76 const queryInclude: Includeable[] = [ 77 const actorInclude: Includeable = {
77 { 78 attributes: [ 'id', 'preferredUsername', 'url', 'serverId' ],
78 attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ], 79 model: ActorModel.unscoped(),
79 model: ActorModel.unscoped(), 80 required: options.actorRequired ?? true,
80 required: options.actorRequired ?? true, 81 where: options.whereActor,
81 where: options.whereActor, 82 include: [ serverInclude ]
82 include: [ 83 }
83 serverInclude,
84 84
85 { 85 if (options.forCount !== true) {
86 model: ActorImageModel.unscoped(), 86 actorInclude.include.push({
87 as: 'Avatar', 87 model: ActorImageModel,
88 required: false 88 as: 'Avatars',
89 } 89 required: false
90 ] 90 })
91 } 91 }
92
93 const queryInclude: Includeable[] = [
94 actorInclude
92 ] 95 ]
93 96
94 const query: FindOptions = { 97 const query: FindOptions = {
@@ -349,13 +352,10 @@ export class AccountModel extends Model<Partial<AttributesOnly<AccountModel>>> {
349 order: getSort(sort) 352 order: getSort(sort)
350 } 353 }
351 354
352 return AccountModel.findAndCountAll(query) 355 return Promise.all([
353 .then(({ rows, count }) => { 356 AccountModel.count(),
354 return { 357 AccountModel.findAll(query)
355 data: rows, 358 ]).then(([ total, data ]) => ({ total, data }))
356 total: count
357 }
358 })
359 } 359 }
360 360
361 static loadAccountIdFromVideo (videoId: number): Promise<MAccount> { 361 static loadAccountIdFromVideo (videoId: number): Promise<MAccount> {
@@ -407,16 +407,15 @@ export class AccountModel extends Model<Partial<AttributesOnly<AccountModel>>> {
407 } 407 }
408 408
409 toFormattedJSON (this: MAccountFormattable): Account { 409 toFormattedJSON (this: MAccountFormattable): Account {
410 const actor = this.Actor.toFormattedJSON() 410 return {
411 const account = { 411 ...this.Actor.toFormattedJSON(),
412
412 id: this.id, 413 id: this.id,
413 displayName: this.getDisplayName(), 414 displayName: this.getDisplayName(),
414 description: this.description, 415 description: this.description,
415 updatedAt: this.updatedAt, 416 updatedAt: this.updatedAt,
416 userId: this.userId ? this.userId : undefined 417 userId: this.userId ?? undefined
417 } 418 }
418
419 return Object.assign(actor, account)
420 } 419 }
421 420
422 toFormattedSummaryJSON (this: MAccountSummaryFormattable): AccountSummary { 421 toFormattedSummaryJSON (this: MAccountSummaryFormattable): AccountSummary {
@@ -424,10 +423,14 @@ export class AccountModel extends Model<Partial<AttributesOnly<AccountModel>>> {
424 423
425 return { 424 return {
426 id: this.id, 425 id: this.id,
427 name: actor.name,
428 displayName: this.getDisplayName(), 426 displayName: this.getDisplayName(),
427
428 name: actor.name,
429 url: actor.url, 429 url: actor.url,
430 host: actor.host, 430 host: actor.host,
431 avatars: actor.avatars,
432
433 // TODO: remove, deprecated in 4.2
431 avatar: actor.avatar 434 avatar: actor.avatar
432 } 435 }
433 } 436 }