Support multiple avatars/banners

This commit is contained in:
Chocobozzz 2022-02-26 12:52:51 +01:00
parent 1e0538bab0
commit 4129b2f3dc
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
7 changed files with 104 additions and 31 deletions

@ -1 +1 @@
Subproject commit 3e8c3fcdb063e2d8f4b3ba04fdcdeda588538751
Subproject commit 28216aa41a392ae3b3f87871fefa22dadc471cf6

View File

@ -7,8 +7,8 @@
:title="linkTitle"
>
<img
v-if="actor.avatar && !avatarError"
:src="actor.avatar.url"
v-if="avatarUrl && !avatarError"
:src="avatarUrl"
alt=""
:class="{ account: isAccount }"
@error="setAvatarError()"
@ -39,6 +39,20 @@
},
computed: {
avatarUrl (): string {
const avatars = this.actor.avatars
if (avatars.length === 0) return ''
avatars.sort((a1, a2) => {
if (a1.width < a2.width) return -1
if (a1.width > a2.width) return 1
return 0
})
return avatars[0].url
},
linkTitle (): string {
if (this.type === 'channel') return this.$gettext('Go on this channel page')

View File

@ -5,7 +5,12 @@ import { DBChannel, EnhancedVideoChannel, IndexableChannel } from '../../types/c
import { ChannelsSearchQuery } from '../../types/search-query/channel-search.model'
import { buildSort, extractQueryResult } from './elastic-search-queries'
import { buildChannelOrAccountCommonMapping, buildMultiMatchBool } from './shared'
import { formatAvatarForAPI, formatAvatarForDB } from './shared/elastic-search-avatar'
import {
formatActorImageForAPI,
formatActorImageForDB,
formatActorImagesForAPI,
formatActorImagesForDB
} from './shared/elastic-search-avatar'
async function queryChannels (search: ChannelsSearchQuery) {
const bool: any = {}
@ -86,7 +91,12 @@ function formatChannelForAPI (c: DBChannel, fromHost?: string): EnhancedVideoCha
followersCount: c.followersCount,
createdAt: c.createdAt,
updatedAt: c.updatedAt,
avatar: formatAvatarForAPI(c),
avatar: formatActorImageForAPI(c.avatar),
avatars: formatActorImagesForAPI(c.avatars, c.avatar),
banner: formatActorImageForAPI(c.banner),
banners: formatActorImagesForAPI(c.banners, c.banner),
displayName: c.displayName,
description: c.description,
@ -106,7 +116,8 @@ function formatChannelForAPI (c: DBChannel, fromHost?: string): EnhancedVideoCha
createdAt: c.ownerAccount.createdAt,
updatedAt: c.ownerAccount.updatedAt,
avatar: formatAvatarForAPI(c.ownerAccount)
avatar: formatActorImageForAPI(c.ownerAccount.avatar),
avatars: formatActorImagesForAPI(c.ownerAccount.avatars, c.ownerAccount.avatar)
}
}
}
@ -119,7 +130,11 @@ function formatChannelForDB (c: IndexableChannel): DBChannel {
host: c.host,
url: c.url,
avatar: formatAvatarForDB(c),
avatar: formatActorImageForDB(c.avatar, c.host),
avatars: formatActorImagesForDB(c.avatars, c.host),
banner: formatActorImageForDB(c.banner, c.host),
banners: formatActorImagesForDB(c.banners, c.host),
displayName: c.displayName,
@ -151,7 +166,8 @@ function formatChannelForDB (c: IndexableChannel): DBChannel {
handle: `${c.ownerAccount.name}@${c.ownerAccount.host}`,
avatar: formatAvatarForDB(c.ownerAccount)
avatar: formatActorImageForDB(c.ownerAccount.avatar, c.ownerAccount.host),
avatars: formatActorImagesForDB(c.ownerAccount.avatars, c.ownerAccount.host)
}
}
}

View File

@ -1,6 +1,7 @@
import { AccountSummary, VideoChannelSummary } from '../../../../PeerTube/shared/models'
import { AdditionalActorAttributes } from '../../../types/actor.model'
import { buildAvatarMapping, formatAvatarForAPI, formatAvatarForDB } from './elastic-search-avatar'
import { formatActorImageForDB } from './'
import { buildActorImageMapping, formatActorImageForAPI, formatActorImagesForAPI, formatActorImagesForDB } from './elastic-search-avatar'
function buildChannelOrAccountSummaryMapping () {
return {
@ -30,7 +31,12 @@ function buildChannelOrAccountSummaryMapping () {
},
avatar: {
properties: buildAvatarMapping()
properties: buildActorImageMapping()
},
// Introduced in 4.2
avatars: {
properties: buildActorImageMapping()
}
}
}
@ -69,7 +75,8 @@ function formatActorSummaryForAPI (actor: (AccountSummary | VideoChannelSummary)
url: actor.url,
host: actor.host,
avatar: formatAvatarForAPI(actor)
avatar: formatActorImageForAPI(actor.avatar),
avatars: formatActorImagesForAPI(actor.avatars, actor.avatar)
}
}
@ -83,7 +90,8 @@ function formatActorForDB (actor: AccountSummary | VideoChannelSummary) {
handle: `${actor.name}@${actor.host}`,
avatar: formatAvatarForDB(actor)
avatar: formatActorImageForDB(actor.avatar, actor.host),
avatars: formatActorImagesForDB(actor.avatars, actor.host)
}
}

View File

@ -1,34 +1,59 @@
import { ActorImage } from '../../../../PeerTube/shared/models'
import { buildUrl } from '../../../helpers/utils'
function formatAvatarForAPI (obj: { avatar?: ActorImage & { url: string } }) {
if (!obj.avatar) return null
function formatActorImageForAPI (image?: ActorImage) {
if (!image) return null
return {
url: obj.avatar.url,
path: obj.avatar.path,
createdAt: obj.avatar.createdAt,
updatedAt: obj.avatar.updatedAt
url: image.url,
path: image.path,
width: image.width,
createdAt: image.createdAt,
updatedAt: image.updatedAt
}
}
function formatAvatarForDB (obj: { avatar?: ActorImage, host: string }) {
if (!obj.avatar) return null
function formatActorImagesForAPI (images?: ActorImage[], image?: ActorImage) {
// Does not exist in PeerTube < 4.2
if (!images) {
if (!image) return []
return [ image ]
}
return images.map(a => formatActorImageForAPI(a))
}
// ---------------------------------------------------------------------------
function formatActorImageForDB (image: ActorImage, host: string) {
if (!image) return null
return {
url: buildUrl(obj.host, obj.avatar.path),
path: obj.avatar.path,
createdAt: obj.avatar.createdAt,
updatedAt: obj.avatar.updatedAt
url: buildUrl(host, image.path),
path: image.path,
width: image.width,
createdAt: image.createdAt,
updatedAt: image.updatedAt
}
}
function buildAvatarMapping () {
function formatActorImagesForDB (images: ActorImage[], host: string) {
if (!images) return null
return images.map(image => formatActorImageForDB(image, host))
}
// ---------------------------------------------------------------------------
function buildActorImageMapping () {
return {
path: {
type: 'keyword'
},
width: {
type: 'long'
},
createdAt: {
type: 'date',
format: 'date_optional_time'
@ -41,7 +66,11 @@ function buildAvatarMapping () {
}
export {
formatAvatarForAPI,
formatAvatarForDB,
buildAvatarMapping
formatActorImageForAPI,
formatActorImagesForAPI,
formatActorImageForDB,
formatActorImagesForDB,
buildActorImageMapping
}

View File

@ -2,8 +2,10 @@ import { ActorImage } from '../../PeerTube/shared/models'
export type AdditionalActorAttributes = {
handle: string
avatar: ActorImageExtended
url: string
avatar: ActorImageExtended
avatars: ActorImageExtended[]
}
export type ActorImageExtended = ActorImage & { url: string }

View File

@ -13,7 +13,11 @@ export interface DBChannel extends Omit<VideoChannel, 'isLocal'> {
ownerAccount?: Account & AdditionalActorAttributes
avatar?: ActorImageExtended
avatar: ActorImageExtended
avatars: ActorImageExtended[]
banner: ActorImageExtended
banners: ActorImageExtended[]
score?: number
}