diff options
author | kontrollanten <6680299+kontrollanten@users.noreply.github.com> | 2022-02-28 08:34:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-28 08:34:43 +0100 |
commit | d0800f7661f13fabe7bb6f4aa0ea50764f106405 (patch) | |
tree | d43e6b0b6f4a5a32e03487e6464edbcaf288be2a /server/controllers | |
parent | 5cad2ca9db9b9d138f8a33058d10b94a9fd50c69 (diff) | |
download | PeerTube-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/controllers')
-rw-r--r-- | server/controllers/activitypub/client.ts | 15 | ||||
-rw-r--r-- | server/controllers/api/accounts.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/users/me.ts | 19 | ||||
-rw-r--r-- | server/controllers/api/users/my-notifications.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/video-channel.ts | 20 | ||||
-rw-r--r-- | server/controllers/client.ts | 4 | ||||
-rw-r--r-- | server/controllers/lazy-static.ts | 10 |
7 files changed, 50 insertions, 22 deletions
diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index 4e6bd5e25..c4d1be121 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts | |||
@@ -18,10 +18,10 @@ import { | |||
18 | } from '../../lib/activitypub/url' | 18 | } from '../../lib/activitypub/url' |
19 | import { | 19 | import { |
20 | asyncMiddleware, | 20 | asyncMiddleware, |
21 | ensureIsLocalChannel, | ||
21 | executeIfActivityPub, | 22 | executeIfActivityPub, |
22 | localAccountValidator, | 23 | localAccountValidator, |
23 | videoChannelsNameWithHostValidator, | 24 | videoChannelsNameWithHostValidator, |
24 | ensureIsLocalChannel, | ||
25 | videosCustomGetValidator, | 25 | videosCustomGetValidator, |
26 | videosShareValidator | 26 | videosShareValidator |
27 | } from '../../middlewares' | 27 | } from '../../middlewares' |
@@ -265,8 +265,8 @@ async function videoAnnouncesController (req: express.Request, res: express.Resp | |||
265 | const handler = async (start: number, count: number) => { | 265 | const handler = async (start: number, count: number) => { |
266 | const result = await VideoShareModel.listAndCountByVideoId(video.id, start, count) | 266 | const result = await VideoShareModel.listAndCountByVideoId(video.id, start, count) |
267 | return { | 267 | return { |
268 | total: result.count, | 268 | total: result.total, |
269 | data: result.rows.map(r => r.url) | 269 | data: result.data.map(r => r.url) |
270 | } | 270 | } |
271 | } | 271 | } |
272 | const json = await activityPubCollectionPagination(getLocalVideoSharesActivityPubUrl(video), handler, req.query.page) | 272 | const json = await activityPubCollectionPagination(getLocalVideoSharesActivityPubUrl(video), handler, req.query.page) |
@@ -301,9 +301,10 @@ async function videoCommentsController (req: express.Request, res: express.Respo | |||
301 | 301 | ||
302 | const handler = async (start: number, count: number) => { | 302 | const handler = async (start: number, count: number) => { |
303 | const result = await VideoCommentModel.listAndCountByVideoForAP(video, start, count) | 303 | const result = await VideoCommentModel.listAndCountByVideoForAP(video, start, count) |
304 | |||
304 | return { | 305 | return { |
305 | total: result.count, | 306 | total: result.total, |
306 | data: result.rows.map(r => r.url) | 307 | data: result.data.map(r => r.url) |
307 | } | 308 | } |
308 | } | 309 | } |
309 | const json = await activityPubCollectionPagination(getLocalVideoCommentsActivityPubUrl(video), handler, req.query.page) | 310 | const json = await activityPubCollectionPagination(getLocalVideoCommentsActivityPubUrl(video), handler, req.query.page) |
@@ -425,8 +426,8 @@ function videoRates (req: express.Request, rateType: VideoRateType, video: MVide | |||
425 | const handler = async (start: number, count: number) => { | 426 | const handler = async (start: number, count: number) => { |
426 | const result = await AccountVideoRateModel.listAndCountAccountUrlsByVideoId(rateType, video.id, start, count) | 427 | const result = await AccountVideoRateModel.listAndCountAccountUrlsByVideoId(rateType, video.id, start, count) |
427 | return { | 428 | return { |
428 | total: result.count, | 429 | total: result.total, |
429 | data: result.rows.map(r => r.url) | 430 | data: result.data.map(r => r.url) |
430 | } | 431 | } |
431 | } | 432 | } |
432 | return activityPubCollectionPagination(url, handler, req.query.page) | 433 | return activityPubCollectionPagination(url, handler, req.query.page) |
diff --git a/server/controllers/api/accounts.ts b/server/controllers/api/accounts.ts index 46d89bafa..8d9f92d93 100644 --- a/server/controllers/api/accounts.ts +++ b/server/controllers/api/accounts.ts | |||
@@ -213,7 +213,7 @@ async function listAccountRatings (req: express.Request, res: express.Response) | |||
213 | sort: req.query.sort, | 213 | sort: req.query.sort, |
214 | type: req.query.rating | 214 | type: req.query.rating |
215 | }) | 215 | }) |
216 | return res.json(getFormattedObjects(resultList.rows, resultList.count)) | 216 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
217 | } | 217 | } |
218 | 218 | ||
219 | async function listAccountFollowers (req: express.Request, res: express.Response) { | 219 | async function listAccountFollowers (req: express.Request, res: express.Response) { |
diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts index c2ad0b710..a1d621152 100644 --- a/server/controllers/api/users/me.ts +++ b/server/controllers/api/users/me.ts | |||
@@ -1,7 +1,9 @@ | |||
1 | import 'multer' | 1 | import 'multer' |
2 | import express from 'express' | 2 | import express from 'express' |
3 | import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '@server/helpers/audit-logger' | 3 | import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '@server/helpers/audit-logger' |
4 | import { getBiggestActorImage } from '@server/lib/actor-image' | ||
4 | import { Hooks } from '@server/lib/plugins/hooks' | 5 | import { Hooks } from '@server/lib/plugins/hooks' |
6 | import { pick } from '@shared/core-utils' | ||
5 | import { ActorImageType, HttpStatusCode, UserUpdateMe, UserVideoQuota, UserVideoRate as FormattedUserVideoRate } from '@shared/models' | 7 | import { ActorImageType, HttpStatusCode, UserUpdateMe, UserVideoQuota, UserVideoRate as FormattedUserVideoRate } from '@shared/models' |
6 | import { AttributesOnly } from '@shared/typescript-utils' | 8 | import { AttributesOnly } from '@shared/typescript-utils' |
7 | import { createReqFiles } from '../../../helpers/express-utils' | 9 | import { createReqFiles } from '../../../helpers/express-utils' |
@@ -10,7 +12,7 @@ import { CONFIG } from '../../../initializers/config' | |||
10 | import { MIMETYPES } from '../../../initializers/constants' | 12 | import { MIMETYPES } from '../../../initializers/constants' |
11 | import { sequelizeTypescript } from '../../../initializers/database' | 13 | import { sequelizeTypescript } from '../../../initializers/database' |
12 | import { sendUpdateActor } from '../../../lib/activitypub/send' | 14 | import { sendUpdateActor } from '../../../lib/activitypub/send' |
13 | import { deleteLocalActorImageFile, updateLocalActorImageFile } from '../../../lib/local-actor' | 15 | import { deleteLocalActorImageFile, updateLocalActorImageFiles } from '../../../lib/local-actor' |
14 | import { getOriginalVideoFileTotalDailyFromUser, getOriginalVideoFileTotalFromUser, sendVerifyUserEmail } from '../../../lib/user' | 16 | import { getOriginalVideoFileTotalDailyFromUser, getOriginalVideoFileTotalFromUser, sendVerifyUserEmail } from '../../../lib/user' |
15 | import { | 17 | import { |
16 | asyncMiddleware, | 18 | asyncMiddleware, |
@@ -30,7 +32,6 @@ import { AccountVideoRateModel } from '../../../models/account/account-video-rat | |||
30 | import { UserModel } from '../../../models/user/user' | 32 | import { UserModel } from '../../../models/user/user' |
31 | import { VideoModel } from '../../../models/video/video' | 33 | import { VideoModel } from '../../../models/video/video' |
32 | import { VideoImportModel } from '../../../models/video/video-import' | 34 | import { VideoImportModel } from '../../../models/video/video-import' |
33 | import { pick } from '@shared/core-utils' | ||
34 | 35 | ||
35 | const auditLogger = auditLoggerFactory('users') | 36 | const auditLogger = auditLoggerFactory('users') |
36 | 37 | ||
@@ -253,9 +254,17 @@ async function updateMyAvatar (req: express.Request, res: express.Response) { | |||
253 | 254 | ||
254 | const userAccount = await AccountModel.load(user.Account.id) | 255 | const userAccount = await AccountModel.load(user.Account.id) |
255 | 256 | ||
256 | const avatar = await updateLocalActorImageFile(userAccount, avatarPhysicalFile, ActorImageType.AVATAR) | 257 | const avatars = await updateLocalActorImageFiles( |
258 | userAccount, | ||
259 | avatarPhysicalFile, | ||
260 | ActorImageType.AVATAR | ||
261 | ) | ||
257 | 262 | ||
258 | return res.json({ avatar: avatar.toFormattedJSON() }) | 263 | return res.json({ |
264 | // TODO: remove, deprecated in 4.2 | ||
265 | avatar: getBiggestActorImage(avatars).toFormattedJSON(), | ||
266 | avatars: avatars.map(avatar => avatar.toFormattedJSON()) | ||
267 | }) | ||
259 | } | 268 | } |
260 | 269 | ||
261 | async function deleteMyAvatar (req: express.Request, res: express.Response) { | 270 | async function deleteMyAvatar (req: express.Request, res: express.Response) { |
@@ -264,5 +273,5 @@ async function deleteMyAvatar (req: express.Request, res: express.Response) { | |||
264 | const userAccount = await AccountModel.load(user.Account.id) | 273 | const userAccount = await AccountModel.load(user.Account.id) |
265 | await deleteLocalActorImageFile(userAccount, ActorImageType.AVATAR) | 274 | await deleteLocalActorImageFile(userAccount, ActorImageType.AVATAR) |
266 | 275 | ||
267 | return res.status(HttpStatusCode.NO_CONTENT_204).end() | 276 | return res.json({ avatars: [] }) |
268 | } | 277 | } |
diff --git a/server/controllers/api/users/my-notifications.ts b/server/controllers/api/users/my-notifications.ts index d107a306e..58732158f 100644 --- a/server/controllers/api/users/my-notifications.ts +++ b/server/controllers/api/users/my-notifications.ts | |||
@@ -3,7 +3,6 @@ import express from 'express' | |||
3 | import { UserNotificationModel } from '@server/models/user/user-notification' | 3 | import { UserNotificationModel } from '@server/models/user/user-notification' |
4 | import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes' | 4 | import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes' |
5 | import { UserNotificationSetting } from '../../../../shared/models/users' | 5 | import { UserNotificationSetting } from '../../../../shared/models/users' |
6 | import { getFormattedObjects } from '../../../helpers/utils' | ||
7 | import { | 6 | import { |
8 | asyncMiddleware, | 7 | asyncMiddleware, |
9 | asyncRetryTransactionMiddleware, | 8 | asyncRetryTransactionMiddleware, |
@@ -20,6 +19,7 @@ import { | |||
20 | } from '../../../middlewares/validators/user-notifications' | 19 | } from '../../../middlewares/validators/user-notifications' |
21 | import { UserNotificationSettingModel } from '../../../models/user/user-notification-setting' | 20 | import { UserNotificationSettingModel } from '../../../models/user/user-notification-setting' |
22 | import { meRouter } from './me' | 21 | import { meRouter } from './me' |
22 | import { getFormattedObjects } from '@server/helpers/utils' | ||
23 | 23 | ||
24 | const myNotificationsRouter = express.Router() | 24 | const myNotificationsRouter = express.Router() |
25 | 25 | ||
diff --git a/server/controllers/api/video-channel.ts b/server/controllers/api/video-channel.ts index e65550a22..2f869d9b3 100644 --- a/server/controllers/api/video-channel.ts +++ b/server/controllers/api/video-channel.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import express from 'express' | 1 | import express from 'express' |
2 | import { pickCommonVideoQuery } from '@server/helpers/query' | 2 | import { pickCommonVideoQuery } from '@server/helpers/query' |
3 | import { getBiggestActorImage } from '@server/lib/actor-image' | ||
3 | import { Hooks } from '@server/lib/plugins/hooks' | 4 | import { Hooks } from '@server/lib/plugins/hooks' |
4 | import { ActorFollowModel } from '@server/models/actor/actor-follow' | 5 | import { ActorFollowModel } from '@server/models/actor/actor-follow' |
5 | import { getServerActor } from '@server/models/application/application' | 6 | import { getServerActor } from '@server/models/application/application' |
@@ -16,7 +17,7 @@ import { MIMETYPES } from '../../initializers/constants' | |||
16 | import { sequelizeTypescript } from '../../initializers/database' | 17 | import { sequelizeTypescript } from '../../initializers/database' |
17 | import { sendUpdateActor } from '../../lib/activitypub/send' | 18 | import { sendUpdateActor } from '../../lib/activitypub/send' |
18 | import { JobQueue } from '../../lib/job-queue' | 19 | import { JobQueue } from '../../lib/job-queue' |
19 | import { deleteLocalActorImageFile, updateLocalActorImageFile } from '../../lib/local-actor' | 20 | import { deleteLocalActorImageFile, updateLocalActorImageFiles } from '../../lib/local-actor' |
20 | import { createLocalVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel' | 21 | import { createLocalVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel' |
21 | import { | 22 | import { |
22 | asyncMiddleware, | 23 | asyncMiddleware, |
@@ -186,11 +187,15 @@ async function updateVideoChannelBanner (req: express.Request, res: express.Resp | |||
186 | const videoChannel = res.locals.videoChannel | 187 | const videoChannel = res.locals.videoChannel |
187 | const oldVideoChannelAuditKeys = new VideoChannelAuditView(videoChannel.toFormattedJSON()) | 188 | const oldVideoChannelAuditKeys = new VideoChannelAuditView(videoChannel.toFormattedJSON()) |
188 | 189 | ||
189 | const banner = await updateLocalActorImageFile(videoChannel, bannerPhysicalFile, ActorImageType.BANNER) | 190 | const banners = await updateLocalActorImageFiles(videoChannel, bannerPhysicalFile, ActorImageType.BANNER) |
190 | 191 | ||
191 | auditLogger.update(getAuditIdFromRes(res), new VideoChannelAuditView(videoChannel.toFormattedJSON()), oldVideoChannelAuditKeys) | 192 | auditLogger.update(getAuditIdFromRes(res), new VideoChannelAuditView(videoChannel.toFormattedJSON()), oldVideoChannelAuditKeys) |
192 | 193 | ||
193 | return res.json({ banner: banner.toFormattedJSON() }) | 194 | return res.json({ |
195 | // TODO: remove, deprecated in 4.2 | ||
196 | banner: getBiggestActorImage(banners).toFormattedJSON(), | ||
197 | banners: banners.map(b => b.toFormattedJSON()) | ||
198 | }) | ||
194 | } | 199 | } |
195 | 200 | ||
196 | async function updateVideoChannelAvatar (req: express.Request, res: express.Response) { | 201 | async function updateVideoChannelAvatar (req: express.Request, res: express.Response) { |
@@ -198,11 +203,14 @@ async function updateVideoChannelAvatar (req: express.Request, res: express.Resp | |||
198 | const videoChannel = res.locals.videoChannel | 203 | const videoChannel = res.locals.videoChannel |
199 | const oldVideoChannelAuditKeys = new VideoChannelAuditView(videoChannel.toFormattedJSON()) | 204 | const oldVideoChannelAuditKeys = new VideoChannelAuditView(videoChannel.toFormattedJSON()) |
200 | 205 | ||
201 | const avatar = await updateLocalActorImageFile(videoChannel, avatarPhysicalFile, ActorImageType.AVATAR) | 206 | const avatars = await updateLocalActorImageFiles(videoChannel, avatarPhysicalFile, ActorImageType.AVATAR) |
202 | |||
203 | auditLogger.update(getAuditIdFromRes(res), new VideoChannelAuditView(videoChannel.toFormattedJSON()), oldVideoChannelAuditKeys) | 207 | auditLogger.update(getAuditIdFromRes(res), new VideoChannelAuditView(videoChannel.toFormattedJSON()), oldVideoChannelAuditKeys) |
204 | 208 | ||
205 | return res.json({ avatar: avatar.toFormattedJSON() }) | 209 | return res.json({ |
210 | // TODO: remove, deprecated in 4.2 | ||
211 | avatar: getBiggestActorImage(avatars).toFormattedJSON(), | ||
212 | avatars: avatars.map(a => a.toFormattedJSON()) | ||
213 | }) | ||
206 | } | 214 | } |
207 | 215 | ||
208 | async function deleteVideoChannelAvatar (req: express.Request, res: express.Response) { | 216 | async function deleteVideoChannelAvatar (req: express.Request, res: express.Response) { |
diff --git a/server/controllers/client.ts b/server/controllers/client.ts index 8a56f2f75..f9514d988 100644 --- a/server/controllers/client.ts +++ b/server/controllers/client.ts | |||
@@ -68,7 +68,9 @@ const staticClientOverrides = [ | |||
68 | 'assets/images/icons/icon-512x512.png', | 68 | 'assets/images/icons/icon-512x512.png', |
69 | 'assets/images/default-playlist.jpg', | 69 | 'assets/images/default-playlist.jpg', |
70 | 'assets/images/default-avatar-account.png', | 70 | 'assets/images/default-avatar-account.png', |
71 | 'assets/images/default-avatar-video-channel.png' | 71 | 'assets/images/default-avatar-account-48x48.png', |
72 | 'assets/images/default-avatar-video-channel.png', | ||
73 | 'assets/images/default-avatar-video-channel-48x48.png' | ||
72 | ] | 74 | ] |
73 | 75 | ||
74 | for (const staticClientOverride of staticClientOverrides) { | 76 | for (const staticClientOverride of staticClientOverrides) { |
diff --git a/server/controllers/lazy-static.ts b/server/controllers/lazy-static.ts index a4076ee56..55bf02660 100644 --- a/server/controllers/lazy-static.ts +++ b/server/controllers/lazy-static.ts | |||
@@ -64,7 +64,15 @@ async function getActorImage (req: express.Request, res: express.Response, next: | |||
64 | logger.info('Lazy serve remote actor image %s.', image.fileUrl) | 64 | logger.info('Lazy serve remote actor image %s.', image.fileUrl) |
65 | 65 | ||
66 | try { | 66 | try { |
67 | await pushActorImageProcessInQueue({ filename: image.filename, fileUrl: image.fileUrl, type: image.type }) | 67 | await pushActorImageProcessInQueue({ |
68 | filename: image.filename, | ||
69 | fileUrl: image.fileUrl, | ||
70 | size: { | ||
71 | height: image.height, | ||
72 | width: image.width | ||
73 | }, | ||
74 | type: image.type | ||
75 | }) | ||
68 | } catch (err) { | 76 | } catch (err) { |
69 | logger.warn('Cannot process remote actor image %s.', image.fileUrl, { err }) | 77 | logger.warn('Cannot process remote actor image %s.', image.fileUrl, { err }) |
70 | return res.status(HttpStatusCode.NOT_FOUND_404).end() | 78 | return res.status(HttpStatusCode.NOT_FOUND_404).end() |