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/lib/activitypub/actors/image.ts | |
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/lib/activitypub/actors/image.ts')
-rw-r--r-- | server/lib/activitypub/actors/image.ts | 89 |
1 files changed, 48 insertions, 41 deletions
diff --git a/server/lib/activitypub/actors/image.ts b/server/lib/activitypub/actors/image.ts index 443ad0a63..d17c2ef1a 100644 --- a/server/lib/activitypub/actors/image.ts +++ b/server/lib/activitypub/actors/image.ts | |||
@@ -12,53 +12,52 @@ type ImageInfo = { | |||
12 | onDisk?: boolean | 12 | onDisk?: boolean |
13 | } | 13 | } |
14 | 14 | ||
15 | async function updateActorImageInstance (actor: MActorImages, type: ActorImageType, imageInfo: ImageInfo | null, t: Transaction) { | 15 | async function updateActorImages (actor: MActorImages, type: ActorImageType, imagesInfo: ImageInfo[], t: Transaction) { |
16 | const oldImageModel = type === ActorImageType.AVATAR | 16 | const avatarsOrBanners = type === ActorImageType.AVATAR |
17 | ? actor.Avatar | 17 | ? actor.Avatars |
18 | : actor.Banner | 18 | : actor.Banners |
19 | 19 | ||
20 | if (oldImageModel) { | 20 | if (imagesInfo.length === 0) { |
21 | // Don't update the avatar if the file URL did not change | 21 | await deleteActorImages(actor, type, t) |
22 | if (imageInfo?.fileUrl && oldImageModel.fileUrl === imageInfo.fileUrl) return actor | 22 | } |
23 | |||
24 | for (const imageInfo of imagesInfo) { | ||
25 | const oldImageModel = (avatarsOrBanners || []).find(i => i.width === imageInfo.width) | ||
23 | 26 | ||
24 | try { | 27 | if (oldImageModel) { |
25 | await oldImageModel.destroy({ transaction: t }) | 28 | // Don't update the avatar if the file URL did not change |
29 | if (imageInfo?.fileUrl && oldImageModel.fileUrl === imageInfo.fileUrl) { | ||
30 | continue | ||
31 | } | ||
26 | 32 | ||
27 | setActorImage(actor, type, null) | 33 | await safeDeleteActorImage(actor, oldImageModel, type, t) |
28 | } catch (err) { | ||
29 | logger.error('Cannot remove old actor image of actor %s.', actor.url, { err }) | ||
30 | } | 34 | } |
31 | } | ||
32 | 35 | ||
33 | if (imageInfo) { | ||
34 | const imageModel = await ActorImageModel.create({ | 36 | const imageModel = await ActorImageModel.create({ |
35 | filename: imageInfo.name, | 37 | filename: imageInfo.name, |
36 | onDisk: imageInfo.onDisk ?? false, | 38 | onDisk: imageInfo.onDisk ?? false, |
37 | fileUrl: imageInfo.fileUrl, | 39 | fileUrl: imageInfo.fileUrl, |
38 | height: imageInfo.height, | 40 | height: imageInfo.height, |
39 | width: imageInfo.width, | 41 | width: imageInfo.width, |
40 | type | 42 | type, |
43 | actorId: actor.id | ||
41 | }, { transaction: t }) | 44 | }, { transaction: t }) |
42 | 45 | ||
43 | setActorImage(actor, type, imageModel) | 46 | addActorImage(actor, type, imageModel) |
44 | } | 47 | } |
45 | 48 | ||
46 | return actor | 49 | return actor |
47 | } | 50 | } |
48 | 51 | ||
49 | async function deleteActorImageInstance (actor: MActorImages, type: ActorImageType, t: Transaction) { | 52 | async function deleteActorImages (actor: MActorImages, type: ActorImageType, t: Transaction) { |
50 | try { | 53 | try { |
51 | if (type === ActorImageType.AVATAR) { | 54 | const association = buildAssociationName(type) |
52 | await actor.Avatar.destroy({ transaction: t }) | ||
53 | |||
54 | actor.avatarId = null | ||
55 | actor.Avatar = null | ||
56 | } else { | ||
57 | await actor.Banner.destroy({ transaction: t }) | ||
58 | 55 | ||
59 | actor.bannerId = null | 56 | for (const image of actor[association]) { |
60 | actor.Banner = null | 57 | await image.destroy({ transaction: t }) |
61 | } | 58 | } |
59 | |||
60 | actor[association] = [] | ||
62 | } catch (err) { | 61 | } catch (err) { |
63 | logger.error('Cannot remove old image of actor %s.', actor.url, { err }) | 62 | logger.error('Cannot remove old image of actor %s.', actor.url, { err }) |
64 | } | 63 | } |
@@ -66,29 +65,37 @@ async function deleteActorImageInstance (actor: MActorImages, type: ActorImageTy | |||
66 | return actor | 65 | return actor |
67 | } | 66 | } |
68 | 67 | ||
68 | async function safeDeleteActorImage (actor: MActorImages, toDelete: MActorImage, type: ActorImageType, t: Transaction) { | ||
69 | try { | ||
70 | await toDelete.destroy({ transaction: t }) | ||
71 | |||
72 | const association = buildAssociationName(type) | ||
73 | actor[association] = actor[association].filter(image => image.id !== toDelete.id) | ||
74 | } catch (err) { | ||
75 | logger.error('Cannot remove old actor image of actor %s.', actor.url, { err }) | ||
76 | } | ||
77 | } | ||
78 | |||
69 | // --------------------------------------------------------------------------- | 79 | // --------------------------------------------------------------------------- |
70 | 80 | ||
71 | export { | 81 | export { |
72 | ImageInfo, | 82 | ImageInfo, |
73 | 83 | ||
74 | updateActorImageInstance, | 84 | updateActorImages, |
75 | deleteActorImageInstance | 85 | deleteActorImages |
76 | } | 86 | } |
77 | 87 | ||
78 | // --------------------------------------------------------------------------- | 88 | // --------------------------------------------------------------------------- |
79 | 89 | ||
80 | function setActorImage (actorModel: MActorImages, type: ActorImageType, imageModel: MActorImage) { | 90 | function addActorImage (actor: MActorImages, type: ActorImageType, imageModel: MActorImage) { |
81 | const id = imageModel | 91 | const association = buildAssociationName(type) |
82 | ? imageModel.id | 92 | if (!actor[association]) actor[association] = [] |
83 | : null | 93 | |
84 | 94 | actor[association].push(imageModel) | |
85 | if (type === ActorImageType.AVATAR) { | 95 | } |
86 | actorModel.avatarId = id | ||
87 | actorModel.Avatar = imageModel | ||
88 | } else { | ||
89 | actorModel.bannerId = id | ||
90 | actorModel.Banner = imageModel | ||
91 | } | ||
92 | 96 | ||
93 | return actorModel | 97 | function buildAssociationName (type: ActorImageType) { |
98 | return type === ActorImageType.AVATAR | ||
99 | ? 'Avatars' | ||
100 | : 'Banners' | ||
94 | } | 101 | } |