Using actors avatars table for secondary profile photos.

This commit is contained in:
DebaucheryLibrarian 2024-10-26 01:03:30 +02:00
parent 6b5aa9505e
commit a6af10ee20
5 changed files with 40 additions and 19 deletions

View File

@ -333,12 +333,14 @@
v-if="description.entity.type === 'network' || !description.entity.parent || description.entity.isIndependent" v-if="description.entity.type === 'network' || !description.entity.parent || description.entity.isIndependent"
:src="`/logos/${description.entity.slug}/thumbs/network.png`" :src="`/logos/${description.entity.slug}/thumbs/network.png`"
class="description-logo" class="description-logo"
loading="lazy"
> >
<img <img
v-else v-else
:src="`/logos/${description.entity.parent.slug}/thumbs/${description.entity.slug}.png`" :src="`/logos/${description.entity.parent.slug}/thumbs/${description.entity.slug}.png`"
class="description-logo" class="description-logo"
loading="lazy"
> >
</a> </a>
</p> </p>

View File

@ -79,7 +79,8 @@ defineProps({
padding: .25rem; padding: .25rem;
.icon { .icon {
fill: var(--highlight); fill: var(--highlight-strong-20);
filter: drop-shadow(0 0 1px var(--shadow));
} }
} }

View File

@ -37,10 +37,10 @@
<div <div
class="photos nobar" class="photos nobar"
:class="{ 'has-avatar': actor.avatar, 'has-photos': actor.avatar ? photos.length > 1 : photos.length > 0 }" :class="{ 'has-avatar': actor.avatar, 'has-photos': actor.avatar ? actor.photos.length > 1 : actor.photos.length > 0 }"
> >
<div <div
v-for="photo in photos" v-for="photo in actor.photos"
:key="`photo-${photo.id}`" :key="`photo-${photo.id}`"
class="photo-container" class="photo-container"
:class="{ avatar: photo.isAvatar }" :class="{ avatar: photo.isAvatar }"
@ -92,13 +92,6 @@ const { pageProps, routeParams } = pageContext;
const { actor } = pageProps; const { actor } = pageProps;
const domain = routeParams.domain; const domain = routeParams.domain;
const photos = Object.values(Object.fromEntries(actor.profiles
.filter((profile) => !!profile.avatar)
.map((profile) => [profile.avatar.id, {
...profile.avatar,
isAvatar: profile.avatar.id === actor.avatar.id,
}])));
</script> </script>
<style scoped> <style scoped>

View File

@ -748,14 +748,12 @@ const bustSizes = {
bustSizes.uk = bustSizes.us; bustSizes.uk = bustSizes.us;
bustSizes.jp = bustSizes.eu; bustSizes.jp = bustSizes.eu;
const avatars = Object.values(Object.fromEntries(actor.value.profiles.filter((profile) => !!profile.avatar).map((profile) => [profile.avatar.id, profile.avatar])));
const fields = computed(() => [ const fields = computed(() => [
...(avatars.length > 0 ? [{ ...(actor.value.photos.length > 0 ? [{
key: 'avatar', key: 'avatar',
type: 'avatar', type: 'avatar',
value: actor.value.avatar?.id, value: actor.value.avatar?.id,
options: avatars, options: actor.value.photos,
}] : []), }] : []),
...(user.role === 'admin' ...(user.role === 'admin'
? [{ ? [{
@ -1010,6 +1008,7 @@ async function submit() {
align-items: center; align-items: center;
padding: .25rem 1rem; padding: .25rem 1rem;
margin-bottom: .25rem; margin-bottom: .25rem;
overflow: hidden;
&.inline { &.inline {
display: inline-flex; display: inline-flex;
@ -1049,6 +1048,7 @@ async function submit() {
display: flex; display: flex;
align-items: center; align-items: center;
flex-grow: 1; flex-grow: 1;
overflow: hidden;
.input { .input {
flex-grow: 1; flex-grow: 1;
@ -1140,6 +1140,7 @@ async function submit() {
} }
.avatars { .avatars {
width: 100%;
display: flex; display: flex;
gap: .25rem; gap: .25rem;
padding-bottom: .5rem; padding-bottom: .5rem;

View File

@ -110,8 +110,15 @@ export function curateActor(actor, context = {}) {
description: profile.description, description: profile.description,
descriptionHash: profile.description_hash, descriptionHash: profile.description_hash,
entity: curateEntity({ ...profile.entity, parent: profile.parent_entity }), entity: curateEntity({ ...profile.entity, parent: profile.parent_entity }),
avatar: curateMedia(profile.avatar), // avatars: profile.avatars.map((avatar) => curateMedia(avatar)),
})), })),
photos: context.photos
?.map((photo) => ({
...curateMedia(photo),
isAvatar: photo.id === actor.avatar?.id,
profileIds: photo.profile_ids,
}))
.toSorted((photoA, photoB) => photoB.isAvatar - photoA.isAvatar),
createdAt: actor.created_at, createdAt: actor.created_at,
updatedAt: actor.updated_at, updatedAt: actor.updated_at,
scenes: actor.scenes, scenes: actor.scenes,
@ -149,7 +156,7 @@ export function sortActorsByGender(actors, context = {}) {
} }
export async function fetchActorsById(actorIds, options = {}, reqUser) { export async function fetchActorsById(actorIds, options = {}, reqUser) {
const [actors, profiles, stashes] = await Promise.all([ const [actors, profiles, photos, stashes] = await Promise.all([
knex('actors') knex('actors')
.select( .select(
'actors.*', 'actors.*',
@ -171,13 +178,29 @@ export async function fetchActorsById(actorIds, options = {}, reqUser) {
} }
}), }),
knex('actors_profiles') knex('actors_profiles')
.select('actors_profiles.*', knex.raw('row_to_json(entities) as entity'), knex.raw('row_to_json(parents) as parent_entity'), knex.raw('row_to_json(media) as avatar')) .select(
'actors_profiles.*',
knex.raw('row_to_json(entities) as entity'),
knex.raw('row_to_json(parents) as parent_entity'),
// knex.raw('coalesce(json_agg(media) filter (where media.id is not null), \'[]\') as avatars'),
)
.leftJoin('actors', 'actors.id', 'actors_profiles.actor_id') .leftJoin('actors', 'actors.id', 'actors_profiles.actor_id')
.leftJoin('entities', 'entities.id', 'actors_profiles.entity_id') .leftJoin('entities', 'entities.id', 'actors_profiles.entity_id')
.leftJoin('entities as parents', 'parents.id', 'entities.parent_id') .leftJoin('entities as parents', 'parents.id', 'entities.parent_id')
.leftJoin('media', 'media.id', 'actors_profiles.avatar_media_id') .leftJoin('actors_avatars', 'actors_avatars.profile_id', 'actors_profiles.id')
// .leftJoin('media', 'media.id', 'actors_avatars.media_id')
.whereIn('actors_profiles.actor_id', actorIds)
.groupBy('actors_profiles.id', 'entities.id', 'parents.id'),
knex('actors_avatars')
.select(
'media.*',
'actors_avatars.actor_id',
knex.raw('json_agg(actors_avatars.profile_id) as profile_ids'),
)
.whereIn('actor_id', actorIds) .whereIn('actor_id', actorIds)
.groupBy('actors_profiles.id', 'entities.id', 'parents.id', 'media.id'), .leftJoin('media', 'media.id', 'actors_avatars.media_id')
.groupBy('media.id', 'actors_avatars.actor_id', 'actors_avatars.created_at')
.orderBy('actors_avatars.created_at', 'desc'),
reqUser reqUser
? knex('stashes_actors') ? knex('stashes_actors')
.leftJoin('stashes', 'stashes.id', 'stashes_actors.stash_id') .leftJoin('stashes', 'stashes.id', 'stashes_actors.stash_id')
@ -204,6 +227,7 @@ export async function fetchActorsById(actorIds, options = {}, reqUser) {
return curateActor(actor, { return curateActor(actor, {
stashes: stashes.filter((stash) => stash.actor_id === actor.id), stashes: stashes.filter((stash) => stash.actor_id === actor.id),
profiles: profiles.filter((profile) => profile.actor_id === actor.id), profiles: profiles.filter((profile) => profile.actor_id === actor.id),
photos: photos.filter((photo) => photo.actor_id === actor.id),
append: options.append, append: options.append,
}); });
}).filter(Boolean); }).filter(Boolean);