aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared
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 /client/src/app/shared
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 'client/src/app/shared')
-rw-r--r--client/src/app/shared/shared-abuse-list/abuse-list-table.component.html2
-rw-r--r--client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.ts2
-rw-r--r--client/src/app/shared/shared-actor-image/actor-avatar.component.scss29
-rw-r--r--client/src/app/shared/shared-actor-image/actor-avatar.component.ts15
-rw-r--r--client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.html2
-rw-r--r--client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.scss2
-rw-r--r--client/src/app/shared/shared-forms/select/select-channel.component.ts2
-rw-r--r--client/src/app/shared/shared-main/account/account.model.ts16
-rw-r--r--client/src/app/shared/shared-main/account/actor.model.ts20
-rw-r--r--client/src/app/shared/shared-main/misc/channels-setup-message.component.ts2
-rw-r--r--client/src/app/shared/shared-main/users/user-notification.model.ts8
-rw-r--r--client/src/app/shared/shared-main/video-channel/video-channel.model.ts42
-rw-r--r--client/src/app/shared/shared-main/video-channel/video-channel.service.ts2
-rw-r--r--client/src/app/shared/shared-main/video/video.model.ts12
-rw-r--r--client/src/app/shared/shared-moderation/account-blocklist.component.html2
-rw-r--r--client/src/app/shared/shared-video-miniature/video-miniature.component.html2
16 files changed, 82 insertions, 78 deletions
diff --git a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html
index 07cc73461..f0a27c6e2 100644
--- a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html
+++ b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html
@@ -43,7 +43,7 @@
43 <td *ngIf="isAdminView()"> 43 <td *ngIf="isAdminView()">
44 <a *ngIf="abuse.reporterAccount" [href]="abuse.reporterAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> 44 <a *ngIf="abuse.reporterAccount" [href]="abuse.reporterAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
45 <div class="chip two-lines"> 45 <div class="chip two-lines">
46 <my-actor-avatar [account]="abuse.reporterAccount"></my-actor-avatar> 46 <my-actor-avatar [account]="abuse.reporterAccount" size="32"></my-actor-avatar>
47 <div> 47 <div>
48 {{ abuse.reporterAccount.displayName }} 48 {{ abuse.reporterAccount.displayName }}
49 <span>{{ abuse.reporterAccount.nameWithHost }}</span> 49 <span>{{ abuse.reporterAccount.nameWithHost }}</span>
diff --git a/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.ts b/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.ts
index 8b7d64ed3..01bb401fb 100644
--- a/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.ts
+++ b/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.ts
@@ -72,7 +72,7 @@ export class ActorAvatarEditComponent implements OnInit {
72 } 72 }
73 73
74 hasAvatar () { 74 hasAvatar () {
75 return !!this.preview || !!this.actor.avatar 75 return !!this.preview || this.actor.avatars.length !== 0
76 } 76 }
77 77
78 isChannel () { 78 isChannel () {
diff --git a/client/src/app/shared/shared-actor-image/actor-avatar.component.scss b/client/src/app/shared/shared-actor-image/actor-avatar.component.scss
index a2424b593..68bf74553 100644
--- a/client/src/app/shared/shared-actor-image/actor-avatar.component.scss
+++ b/client/src/app/shared/shared-actor-image/actor-avatar.component.scss
@@ -20,38 +20,23 @@
20 } 20 }
21} 21}
22 22
23.avatar-18 { 23$sizes: '18', '25', '28', '32', '34', '35', '36', '40', '48', '75', '80', '100', '120';
24 --avatarSize: 18px;
25 --initialFontSize: 13px;
26}
27 24
28.avatar-25 { 25@each $size in $sizes {
29 --avatarSize: 25px; 26 .avatar-#{$size} {
27 --avatarSize: #{$size}px;
28 }
30} 29}
31 30
32.avatar-32 { 31.avatar-18 {
33 --avatarSize: 32px; 32 --initialFontSize: 13px;
34}
35
36.avatar-34 {
37 --avatarSize: 34px;
38}
39
40.avatar-36 {
41 --avatarSize: 36px;
42}
43
44.avatar-40 {
45 --avatarSize: 40px;
46} 33}
47 34
48.avatar-100 { 35.avatar-100 {
49 --avatarSize: 100px;
50 --initialFontSize: 40px; 36 --initialFontSize: 40px;
51} 37}
52 38
53.avatar-120 { 39.avatar-120 {
54 --avatarSize: 120px;
55 --initialFontSize: 46px; 40 --initialFontSize: 46px;
56} 41}
57 42
diff --git a/client/src/app/shared/shared-actor-image/actor-avatar.component.ts b/client/src/app/shared/shared-actor-image/actor-avatar.component.ts
index c323dc724..bc7e8a096 100644
--- a/client/src/app/shared/shared-actor-image/actor-avatar.component.ts
+++ b/client/src/app/shared/shared-actor-image/actor-avatar.component.ts
@@ -4,11 +4,11 @@ import { Account } from '../shared-main/account/account.model'
4 4
5type ActorInput = { 5type ActorInput = {
6 name: string 6 name: string
7 avatar?: { url?: string, path: string } 7 avatars: { width: number, url?: string, path: string }[]
8 url: string 8 url: string
9} 9}
10 10
11export type ActorAvatarSize = '18' | '25' | '32' | '34' | '36' | '40' | '100' | '120' 11export type ActorAvatarSize = '18' | '25' | '28' | '32' | '34' | '35' | '36' | '40' | '48' | '75' | '80' | '100' | '120'
12 12
13@Component({ 13@Component({
14 selector: 'my-actor-avatar', 14 selector: 'my-actor-avatar',
@@ -23,7 +23,7 @@ export class ActorAvatarComponent {
23 23
24 @Input() previewImage: string 24 @Input() previewImage: string
25 25
26 @Input() size: ActorAvatarSize 26 @Input() size: ActorAvatarSize = '32'
27 27
28 // Use an external link 28 // Use an external link
29 @Input() href: string 29 @Input() href: string
@@ -50,14 +50,13 @@ export class ActorAvatarComponent {
50 } 50 }
51 51
52 get defaultAvatarUrl () { 52 get defaultAvatarUrl () {
53 if (this.channel) return VideoChannel.GET_DEFAULT_AVATAR_URL() 53 if (this.account) return Account.GET_DEFAULT_AVATAR_URL(+this.size)
54 54 if (this.channel) return VideoChannel.GET_DEFAULT_AVATAR_URL(+this.size)
55 return Account.GET_DEFAULT_AVATAR_URL()
56 } 55 }
57 56
58 get avatarUrl () { 57 get avatarUrl () {
59 if (this.account) return Account.GET_ACTOR_AVATAR_URL(this.account) 58 if (this.account) return Account.GET_ACTOR_AVATAR_URL(this.account, +this.size)
60 if (this.channel) return VideoChannel.GET_ACTOR_AVATAR_URL(this.channel) 59 if (this.channel) return VideoChannel.GET_ACTOR_AVATAR_URL(this.channel, +this.size)
61 60
62 return '' 61 return ''
63 } 62 }
diff --git a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.html b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.html
index de150aac9..52a402329 100644
--- a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.html
+++ b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.html
@@ -1,7 +1,7 @@
1<div *ngIf="channel" class="channel"> 1<div *ngIf="channel" class="channel">
2 2
3 <div class="channel-avatar-row"> 3 <div class="channel-avatar-row">
4 <my-actor-avatar [channel]="channel" [internalHref]="getVideoChannelLink()" i18n-title title="See this video channel"></my-actor-avatar> 4 <my-actor-avatar [channel]="channel" [internalHref]="getVideoChannelLink()" i18n-title title="See this video channel" size="75"></my-actor-avatar>
5 5
6 <h6> 6 <h6>
7 <a [routerLink]="getVideoChannelLink()" i18n-title title="See this video channel"> 7 <a [routerLink]="getVideoChannelLink()" i18n-title title="See this video channel">
diff --git a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.scss b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.scss
index 39e8d2091..e8ef478d9 100644
--- a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.scss
+++ b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/channel-miniature-markup.component.scss
@@ -26,8 +26,6 @@
26 } 26 }
27 27
28 my-actor-avatar { 28 my-actor-avatar {
29 @include actor-avatar-size(75px);
30
31 grid-column: 1; 29 grid-column: 1;
32 grid-row: 1 / 4; 30 grid-row: 1 / 4;
33 } 31 }
diff --git a/client/src/app/shared/shared-forms/select/select-channel.component.ts b/client/src/app/shared/shared-forms/select/select-channel.component.ts
index 40a7c53bb..5fcae0050 100644
--- a/client/src/app/shared/shared-forms/select/select-channel.component.ts
+++ b/client/src/app/shared/shared-forms/select/select-channel.component.ts
@@ -31,7 +31,7 @@ export class SelectChannelComponent implements ControlValueAccessor, OnChanges {
31 this.channels = this.items.map(c => { 31 this.channels = this.items.map(c => {
32 const avatarPath = c.avatarPath 32 const avatarPath = c.avatarPath
33 ? c.avatarPath 33 ? c.avatarPath
34 : VideoChannel.GET_DEFAULT_AVATAR_URL() 34 : VideoChannel.GET_DEFAULT_AVATAR_URL(20)
35 35
36 return Object.assign({}, c, { avatarPath }) 36 return Object.assign({}, c, { avatarPath })
37 }) 37 })
diff --git a/client/src/app/shared/shared-main/account/account.model.ts b/client/src/app/shared/shared-main/account/account.model.ts
index 8b78d01a6..a26a9c11c 100644
--- a/client/src/app/shared/shared-main/account/account.model.ts
+++ b/client/src/app/shared/shared-main/account/account.model.ts
@@ -17,11 +17,15 @@ export class Account extends Actor implements ServerAccount {
17 17
18 userId?: number 18 userId?: number
19 19
20 static GET_ACTOR_AVATAR_URL (actor: { avatar?: { url?: string, path: string } }) { 20 static GET_ACTOR_AVATAR_URL (actor: { avatars: { width: number, url?: string, path: string }[] }, size: number) {
21 return Actor.GET_ACTOR_AVATAR_URL(actor) 21 return Actor.GET_ACTOR_AVATAR_URL(actor, size)
22 } 22 }
23 23
24 static GET_DEFAULT_AVATAR_URL () { 24 static GET_DEFAULT_AVATAR_URL (size: number) {
25 if (size <= 48) {
26 return `${window.location.origin}/client/assets/images/default-avatar-account-48x48.png`
27 }
28
25 return `${window.location.origin}/client/assets/images/default-avatar-account.png` 29 return `${window.location.origin}/client/assets/images/default-avatar-account.png`
26 } 30 }
27 31
@@ -42,12 +46,12 @@ export class Account extends Actor implements ServerAccount {
42 this.mutedServerByInstance = false 46 this.mutedServerByInstance = false
43 } 47 }
44 48
45 updateAvatar (newAvatar: ActorImage) { 49 updateAvatar (newAvatars: ActorImage[]) {
46 this.avatar = newAvatar 50 this.avatars = newAvatars
47 } 51 }
48 52
49 resetAvatar () { 53 resetAvatar () {
50 this.avatar = null 54 this.avatars = []
51 } 55 }
52 56
53 updateBlockStatus (blockStatus: BlockStatus) { 57 updateBlockStatus (blockStatus: BlockStatus) {
diff --git a/client/src/app/shared/shared-main/account/actor.model.ts b/client/src/app/shared/shared-main/account/actor.model.ts
index 082f44fb9..a54f51aa4 100644
--- a/client/src/app/shared/shared-main/account/actor.model.ts
+++ b/client/src/app/shared/shared-main/account/actor.model.ts
@@ -13,20 +13,22 @@ export abstract class Actor implements ServerActor {
13 13
14 createdAt: Date | string 14 createdAt: Date | string
15 15
16 avatar: ActorImage 16 // TODO: remove, deprecated in 4.2
17 avatar: never
18
19 avatars: ActorImage[]
17 20
18 isLocal: boolean 21 isLocal: boolean
19 22
20 static GET_ACTOR_AVATAR_URL (actor: { avatar?: { url?: string, path: string } }) { 23 static GET_ACTOR_AVATAR_URL (actor: { avatars: { width: number, url?: string, path: string }[] }, size: number) {
21 if (actor?.avatar?.url) return actor.avatar.url 24 const avatar = actor.avatars.sort((a, b) => a.width - b.width).find(a => a.width >= size)
22 25
23 if (actor?.avatar) { 26 if (!avatar) return ''
24 const absoluteAPIUrl = getAbsoluteAPIUrl() 27 if (avatar.url) return avatar.url
25 28
26 return absoluteAPIUrl + actor.avatar.path 29 const absoluteAPIUrl = getAbsoluteAPIUrl()
27 }
28 30
29 return '' 31 return absoluteAPIUrl + avatar.path
30 } 32 }
31 33
32 static CREATE_BY_STRING (accountName: string, host: string, forceHostname = false) { 34 static CREATE_BY_STRING (accountName: string, host: string, forceHostname = false) {
@@ -55,7 +57,7 @@ export abstract class Actor implements ServerActor {
55 57
56 if (hash.createdAt) this.createdAt = new Date(hash.createdAt.toString()) 58 if (hash.createdAt) this.createdAt = new Date(hash.createdAt.toString())
57 59
58 this.avatar = hash.avatar 60 this.avatars = hash.avatars
59 this.isLocal = Actor.IS_LOCAL(this.host) 61 this.isLocal = Actor.IS_LOCAL(this.host)
60 } 62 }
61} 63}
diff --git a/client/src/app/shared/shared-main/misc/channels-setup-message.component.ts b/client/src/app/shared/shared-main/misc/channels-setup-message.component.ts
index 702475029..4f9cbc525 100644
--- a/client/src/app/shared/shared-main/misc/channels-setup-message.component.ts
+++ b/client/src/app/shared/shared-main/misc/channels-setup-message.component.ts
@@ -19,7 +19,7 @@ export class ChannelsSetupMessageComponent implements OnInit {
19 hasChannelNotConfigured () { 19 hasChannelNotConfigured () {
20 if (!this.user.videoChannels) return false 20 if (!this.user.videoChannels) return false
21 21
22 return this.user.videoChannels.filter((channel: VideoChannel) => (!channel.avatar || !channel.description)).length > 0 22 return this.user.videoChannels.filter((channel: VideoChannel) => (channel.avatars.length === 0 || !channel.description)).length > 0
23 } 23 }
24 24
25 ngOnInit () { 25 ngOnInit () {
diff --git a/client/src/app/shared/shared-main/users/user-notification.model.ts b/client/src/app/shared/shared-main/users/user-notification.model.ts
index 439547102..1eb69d5a2 100644
--- a/client/src/app/shared/shared-main/users/user-notification.model.ts
+++ b/client/src/app/shared/shared-main/users/user-notification.model.ts
@@ -254,11 +254,11 @@ export class UserNotification implements UserNotificationServer {
254 return [ this.buildVideoUrl(comment.video), { threadId: comment.threadId } ] 254 return [ this.buildVideoUrl(comment.video), { threadId: comment.threadId } ]
255 } 255 }
256 256
257 private setAccountAvatarUrl (actor: { avatarUrl?: string, avatar?: { url?: string, path: string } }) { 257 private setAccountAvatarUrl (actor: { avatarUrl?: string, avatars: { width: number, url?: string, path: string }[] }) {
258 actor.avatarUrl = Account.GET_ACTOR_AVATAR_URL(actor) || Account.GET_DEFAULT_AVATAR_URL() 258 actor.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(actor, 48) || Account.GET_DEFAULT_AVATAR_URL(48)
259 } 259 }
260 260
261 private setVideoChannelAvatarUrl (actor: { avatarUrl?: string, avatar?: { url?: string, path: string } }) { 261 private setVideoChannelAvatarUrl (actor: { avatarUrl?: string, avatars: { width: number, url?: string, path: string }[] }) {
262 actor.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(actor) || VideoChannel.GET_DEFAULT_AVATAR_URL() 262 actor.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(actor, 48) || VideoChannel.GET_DEFAULT_AVATAR_URL(48)
263 } 263 }
264} 264}
diff --git a/client/src/app/shared/shared-main/video-channel/video-channel.model.ts b/client/src/app/shared/shared-main/video-channel/video-channel.model.ts
index ac2679b42..e22b0cfd0 100644
--- a/client/src/app/shared/shared-main/video-channel/video-channel.model.ts
+++ b/client/src/app/shared/shared-main/video-channel/video-channel.model.ts
@@ -12,7 +12,11 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
12 nameWithHost: string 12 nameWithHost: string
13 nameWithHostForced: string 13 nameWithHostForced: string
14 14
15 banner: ActorImage 15 // TODO: remove, deprecated in 4.2
16 banner: never
17
18 banners: ActorImage[]
19
16 bannerUrl: string 20 bannerUrl: string
17 21
18 updatedAt: Date | string 22 updatedAt: Date | string
@@ -24,23 +28,25 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
24 28
25 viewsPerDay?: ViewsPerDate[] 29 viewsPerDay?: ViewsPerDate[]
26 30
27 static GET_ACTOR_AVATAR_URL (actor: { avatar?: { url?: string, path: string } }) { 31 static GET_ACTOR_AVATAR_URL (actor: { avatars: { width: number, url?: string, path: string }[] }, size: number) {
28 return Actor.GET_ACTOR_AVATAR_URL(actor) 32 return Actor.GET_ACTOR_AVATAR_URL(actor, size)
29 } 33 }
30 34
31 static GET_ACTOR_BANNER_URL (channel: ServerVideoChannel) { 35 static GET_ACTOR_BANNER_URL (channel: ServerVideoChannel) {
32 if (channel?.banner?.url) return channel.banner.url 36 if (!channel) return ''
33
34 if (channel?.banner) {
35 const absoluteAPIUrl = getAbsoluteAPIUrl()
36 37
37 return absoluteAPIUrl + channel.banner.path 38 const banner = channel.banners[0]
38 } 39 if (!banner) return ''
39 40
40 return '' 41 if (banner.url) return banner.url
42 return getAbsoluteAPIUrl() + banner.path
41 } 43 }
42 44
43 static GET_DEFAULT_AVATAR_URL () { 45 static GET_DEFAULT_AVATAR_URL (size: number) {
46 if (size <= 48) {
47 return `${window.location.origin}/client/assets/images/default-avatar-video-channel-48x48.png`
48 }
49
44 return `${window.location.origin}/client/assets/images/default-avatar-video-channel.png` 50 return `${window.location.origin}/client/assets/images/default-avatar-video-channel.png`
45 } 51 }
46 52
@@ -51,7 +57,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
51 this.description = hash.description 57 this.description = hash.description
52 this.support = hash.support 58 this.support = hash.support
53 59
54 this.banner = hash.banner 60 this.banners = hash.banners
55 61
56 this.isLocal = hash.isLocal 62 this.isLocal = hash.isLocal
57 63
@@ -74,24 +80,24 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
74 this.updateComputedAttributes() 80 this.updateComputedAttributes()
75 } 81 }
76 82
77 updateAvatar (newAvatar: ActorImage) { 83 updateAvatar (newAvatars: ActorImage[]) {
78 this.avatar = newAvatar 84 this.avatars = newAvatars
79 85
80 this.updateComputedAttributes() 86 this.updateComputedAttributes()
81 } 87 }
82 88
83 resetAvatar () { 89 resetAvatar () {
84 this.updateAvatar(null) 90 this.updateAvatar([])
85 } 91 }
86 92
87 updateBanner (newBanner: ActorImage) { 93 updateBanner (newBanners: ActorImage[]) {
88 this.banner = newBanner 94 this.banners = newBanners
89 95
90 this.updateComputedAttributes() 96 this.updateComputedAttributes()
91 } 97 }
92 98
93 resetBanner () { 99 resetBanner () {
94 this.updateBanner(null) 100 this.updateBanner([])
95 } 101 }
96 102
97 updateComputedAttributes () { 103 updateComputedAttributes () {
diff --git a/client/src/app/shared/shared-main/video-channel/video-channel.service.ts b/client/src/app/shared/shared-main/video-channel/video-channel.service.ts
index f37f13c51..480d250fb 100644
--- a/client/src/app/shared/shared-main/video-channel/video-channel.service.ts
+++ b/client/src/app/shared/shared-main/video-channel/video-channel.service.ts
@@ -80,7 +80,7 @@ export class VideoChannelService {
80 changeVideoChannelImage (videoChannelName: string, avatarForm: FormData, type: 'avatar' | 'banner') { 80 changeVideoChannelImage (videoChannelName: string, avatarForm: FormData, type: 'avatar' | 'banner') {
81 const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName + '/' + type + '/pick' 81 const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName + '/' + type + '/pick'
82 82
83 return this.authHttp.post<{ avatar?: ActorImage, banner?: ActorImage }>(url, avatarForm) 83 return this.authHttp.post<{ avatars?: ActorImage[], banners?: ActorImage[] }>(url, avatarForm)
84 .pipe(catchError(err => this.restExtractor.handleError(err))) 84 .pipe(catchError(err => this.restExtractor.handleError(err)))
85 } 85 }
86 86
diff --git a/client/src/app/shared/shared-main/video/video.model.ts b/client/src/app/shared/shared-main/video/video.model.ts
index fe5643688..8e275181c 100644
--- a/client/src/app/shared/shared-main/video/video.model.ts
+++ b/client/src/app/shared/shared-main/video/video.model.ts
@@ -84,7 +84,11 @@ export class Video implements VideoServerModel {
84 displayName: string 84 displayName: string
85 url: string 85 url: string
86 host: string 86 host: string
87 avatar?: ActorImage 87
88 // TODO: remove, deprecated in 4.2
89 avatar: ActorImage
90
91 avatars: ActorImage[]
88 } 92 }
89 93
90 channel: { 94 channel: {
@@ -93,7 +97,11 @@ export class Video implements VideoServerModel {
93 displayName: string 97 displayName: string
94 url: string 98 url: string
95 host: string 99 host: string
96 avatar?: ActorImage 100
101 // TODO: remove, deprecated in 4.2
102 avatar: ActorImage
103
104 avatars: ActorImage[]
97 } 105 }
98 106
99 userHistory?: { 107 userHistory?: {
diff --git a/client/src/app/shared/shared-moderation/account-blocklist.component.html b/client/src/app/shared/shared-moderation/account-blocklist.component.html
index 637abcb51..0143194e9 100644
--- a/client/src/app/shared/shared-moderation/account-blocklist.component.html
+++ b/client/src/app/shared/shared-moderation/account-blocklist.component.html
@@ -33,7 +33,7 @@
33 <td> 33 <td>
34 <a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> 34 <a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer">
35 <div class="chip two-lines"> 35 <div class="chip two-lines">
36 <my-actor-avatar [account]="accountBlock.blockedAccount"></my-actor-avatar> 36 <my-actor-avatar [account]="accountBlock.blockedAccount" size="32"></my-actor-avatar>
37 <div> 37 <div>
38 {{ accountBlock.blockedAccount.displayName }} 38 {{ accountBlock.blockedAccount.displayName }}
39 <span class="text-muted">{{ accountBlock.blockedAccount.nameWithHost }}</span> 39 <span class="text-muted">{{ accountBlock.blockedAccount.nameWithHost }}</span>
diff --git a/client/src/app/shared/shared-video-miniature/video-miniature.component.html b/client/src/app/shared/shared-video-miniature/video-miniature.component.html
index 30483831a..3cf128de0 100644
--- a/client/src/app/shared/shared-video-miniature/video-miniature.component.html
+++ b/client/src/app/shared/shared-video-miniature/video-miniature.component.html
@@ -13,11 +13,13 @@
13 <my-actor-avatar 13 <my-actor-avatar
14 *ngIf="displayOptions.avatar && displayOwnerVideoChannel() && !displayAsRow" [title]="channelLinkTitle" 14 *ngIf="displayOptions.avatar && displayOwnerVideoChannel() && !displayAsRow" [title]="channelLinkTitle"
15 [channel]="video.channel" [size]="actorImageSize" [internalHref]="[ '/c', video.byVideoChannel ]" 15 [channel]="video.channel" [size]="actorImageSize" [internalHref]="[ '/c', video.byVideoChannel ]"
16 size="32"
16 ></my-actor-avatar> 17 ></my-actor-avatar>
17 18
18 <my-actor-avatar 19 <my-actor-avatar
19 *ngIf="displayOptions.avatar && displayOwnerAccount() && !displayAsRow" [title]="channelLinkTitle" 20 *ngIf="displayOptions.avatar && displayOwnerAccount() && !displayAsRow" [title]="channelLinkTitle"
20 [account]="video.account" [size]="actorImageSize" [internalHref]="[ '/c', video.byVideoChannel ]" 21 [account]="video.account" [size]="actorImageSize" [internalHref]="[ '/c', video.byVideoChannel ]"
22 size="32"
21 ></my-actor-avatar> 23 ></my-actor-avatar>
22 24
23 <div class="w-100 d-flex flex-column"> 25 <div class="w-100 d-flex flex-column">