From d0800f7661f13fabe7bb6f4aa0ea50764f106405 Mon Sep 17 00:00:00 2001 From: kontrollanten <6680299+kontrollanten@users.noreply.github.com> Date: Mon, 28 Feb 2022 08:34:43 +0100 Subject: 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 --- .../shared/shared-main/account/account.model.ts | 16 +++++---- .../app/shared/shared-main/account/actor.model.ts | 20 ++++++----- .../misc/channels-setup-message.component.ts | 2 +- .../shared-main/users/user-notification.model.ts | 8 ++--- .../video-channel/video-channel.model.ts | 42 ++++++++++++---------- .../video-channel/video-channel.service.ts | 2 +- .../app/shared/shared-main/video/video.model.ts | 12 +++++-- 7 files changed, 61 insertions(+), 41 deletions(-) (limited to 'client/src/app/shared/shared-main') 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 { userId?: number - static GET_ACTOR_AVATAR_URL (actor: { avatar?: { url?: string, path: string } }) { - return Actor.GET_ACTOR_AVATAR_URL(actor) + static GET_ACTOR_AVATAR_URL (actor: { avatars: { width: number, url?: string, path: string }[] }, size: number) { + return Actor.GET_ACTOR_AVATAR_URL(actor, size) } - static GET_DEFAULT_AVATAR_URL () { + static GET_DEFAULT_AVATAR_URL (size: number) { + if (size <= 48) { + return `${window.location.origin}/client/assets/images/default-avatar-account-48x48.png` + } + return `${window.location.origin}/client/assets/images/default-avatar-account.png` } @@ -42,12 +46,12 @@ export class Account extends Actor implements ServerAccount { this.mutedServerByInstance = false } - updateAvatar (newAvatar: ActorImage) { - this.avatar = newAvatar + updateAvatar (newAvatars: ActorImage[]) { + this.avatars = newAvatars } resetAvatar () { - this.avatar = null + this.avatars = [] } 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 { createdAt: Date | string - avatar: ActorImage + // TODO: remove, deprecated in 4.2 + avatar: never + + avatars: ActorImage[] isLocal: boolean - static GET_ACTOR_AVATAR_URL (actor: { avatar?: { url?: string, path: string } }) { - if (actor?.avatar?.url) return actor.avatar.url + static GET_ACTOR_AVATAR_URL (actor: { avatars: { width: number, url?: string, path: string }[] }, size: number) { + const avatar = actor.avatars.sort((a, b) => a.width - b.width).find(a => a.width >= size) - if (actor?.avatar) { - const absoluteAPIUrl = getAbsoluteAPIUrl() + if (!avatar) return '' + if (avatar.url) return avatar.url - return absoluteAPIUrl + actor.avatar.path - } + const absoluteAPIUrl = getAbsoluteAPIUrl() - return '' + return absoluteAPIUrl + avatar.path } static CREATE_BY_STRING (accountName: string, host: string, forceHostname = false) { @@ -55,7 +57,7 @@ export abstract class Actor implements ServerActor { if (hash.createdAt) this.createdAt = new Date(hash.createdAt.toString()) - this.avatar = hash.avatar + this.avatars = hash.avatars this.isLocal = Actor.IS_LOCAL(this.host) } } 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 { hasChannelNotConfigured () { if (!this.user.videoChannels) return false - return this.user.videoChannels.filter((channel: VideoChannel) => (!channel.avatar || !channel.description)).length > 0 + return this.user.videoChannels.filter((channel: VideoChannel) => (channel.avatars.length === 0 || !channel.description)).length > 0 } 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 { return [ this.buildVideoUrl(comment.video), { threadId: comment.threadId } ] } - private setAccountAvatarUrl (actor: { avatarUrl?: string, avatar?: { url?: string, path: string } }) { - actor.avatarUrl = Account.GET_ACTOR_AVATAR_URL(actor) || Account.GET_DEFAULT_AVATAR_URL() + private setAccountAvatarUrl (actor: { avatarUrl?: string, avatars: { width: number, url?: string, path: string }[] }) { + actor.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(actor, 48) || Account.GET_DEFAULT_AVATAR_URL(48) } - private setVideoChannelAvatarUrl (actor: { avatarUrl?: string, avatar?: { url?: string, path: string } }) { - actor.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(actor) || VideoChannel.GET_DEFAULT_AVATAR_URL() + private setVideoChannelAvatarUrl (actor: { avatarUrl?: string, avatars: { width: number, url?: string, path: string }[] }) { + actor.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(actor, 48) || VideoChannel.GET_DEFAULT_AVATAR_URL(48) } } 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 { nameWithHost: string nameWithHostForced: string - banner: ActorImage + // TODO: remove, deprecated in 4.2 + banner: never + + banners: ActorImage[] + bannerUrl: string updatedAt: Date | string @@ -24,23 +28,25 @@ export class VideoChannel extends Actor implements ServerVideoChannel { viewsPerDay?: ViewsPerDate[] - static GET_ACTOR_AVATAR_URL (actor: { avatar?: { url?: string, path: string } }) { - return Actor.GET_ACTOR_AVATAR_URL(actor) + static GET_ACTOR_AVATAR_URL (actor: { avatars: { width: number, url?: string, path: string }[] }, size: number) { + return Actor.GET_ACTOR_AVATAR_URL(actor, size) } static GET_ACTOR_BANNER_URL (channel: ServerVideoChannel) { - if (channel?.banner?.url) return channel.banner.url - - if (channel?.banner) { - const absoluteAPIUrl = getAbsoluteAPIUrl() + if (!channel) return '' - return absoluteAPIUrl + channel.banner.path - } + const banner = channel.banners[0] + if (!banner) return '' - return '' + if (banner.url) return banner.url + return getAbsoluteAPIUrl() + banner.path } - static GET_DEFAULT_AVATAR_URL () { + static GET_DEFAULT_AVATAR_URL (size: number) { + if (size <= 48) { + return `${window.location.origin}/client/assets/images/default-avatar-video-channel-48x48.png` + } + return `${window.location.origin}/client/assets/images/default-avatar-video-channel.png` } @@ -51,7 +57,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel { this.description = hash.description this.support = hash.support - this.banner = hash.banner + this.banners = hash.banners this.isLocal = hash.isLocal @@ -74,24 +80,24 @@ export class VideoChannel extends Actor implements ServerVideoChannel { this.updateComputedAttributes() } - updateAvatar (newAvatar: ActorImage) { - this.avatar = newAvatar + updateAvatar (newAvatars: ActorImage[]) { + this.avatars = newAvatars this.updateComputedAttributes() } resetAvatar () { - this.updateAvatar(null) + this.updateAvatar([]) } - updateBanner (newBanner: ActorImage) { - this.banner = newBanner + updateBanner (newBanners: ActorImage[]) { + this.banners = newBanners this.updateComputedAttributes() } resetBanner () { - this.updateBanner(null) + this.updateBanner([]) } 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 { changeVideoChannelImage (videoChannelName: string, avatarForm: FormData, type: 'avatar' | 'banner') { const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName + '/' + type + '/pick' - return this.authHttp.post<{ avatar?: ActorImage, banner?: ActorImage }>(url, avatarForm) + return this.authHttp.post<{ avatars?: ActorImage[], banners?: ActorImage[] }>(url, avatarForm) .pipe(catchError(err => this.restExtractor.handleError(err))) } 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 { displayName: string url: string host: string - avatar?: ActorImage + + // TODO: remove, deprecated in 4.2 + avatar: ActorImage + + avatars: ActorImage[] } channel: { @@ -93,7 +97,11 @@ export class Video implements VideoServerModel { displayName: string url: string host: string - avatar?: ActorImage + + // TODO: remove, deprecated in 4.2 + avatar: ActorImage + + avatars: ActorImage[] } userHistory?: { -- cgit v1.2.3