Showing tag poster and photos on tag page. Improved campaign fallback logic, fixes wrong ratio selected.

This commit is contained in:
2025-12-13 04:00:14 +01:00
parent bc26e07812
commit 84b9bbd1b6
8 changed files with 274 additions and 33 deletions

64
components/tags/logo.vue Normal file
View File

@@ -0,0 +1,64 @@
<template>
<a
v-if="photo.entity"
v-tooltip="photo.entity.name"
:to="`/${photo.entity.type}/${photo.entity.slug}`"
>
<img
v-if="favicon && photo.entity.type !== 'network' && !photo.entity.independent && photo.entity.parent"
:src="`/logos/${photo.entity.parent.slug}/favicon.png`"
class="album-logo favicon"
>
<img
v-else-if="favicon"
:src="`/logos/${photo.entity.slug}/favicon.png`"
class="album-logo favicon"
>
<img
v-else-if="photo.entity.type !== 'network' && !photo.entity.independent && photo.entity.parent"
:src="`/logos/${photo.entity.parent.slug}/${photo.entity.slug}.png`"
class="album-logo"
>
<img
v-else
:src="`/logos/${photo.entity.slug}/network.png`"
class="album-logo"
>
</a>
</template>
<script setup>
defineProps({
photo: {
type: Object,
default: null,
},
favicon: {
type: Boolean,
default: false,
},
});
</script>
<style scoped>
.album-logo {
max-height: .75rem;
max-width: 5rem;
position: absolute;
right: 0;
bottom: 0;
padding: .5rem;
transition: transform .25s ease, opacity .25s ease;
filter: drop-shadow(0 0 2px var(--shadow-weak));
}
@media(--small) {
.album-logo:not(.favicon) {
max-height: .5rem;
max-width: 3.5rem;
}
}
</style>

149
components/tags/photos.vue Normal file
View File

@@ -0,0 +1,149 @@
<template>
<div class="photos nobar">
<Campaign
v-if="campaigns?.photos"
:campaign="campaigns.photos"
/>
<div
v-for="photo in photos"
:key="`photo-${photo.id}`"
:title="photo.comment"
:href="`/img/${photo.path}`"
target="_blank"
rel="noopener noreferrer"
class="photo-container"
>
<img
:src="`/${photo.thumbnail}`"
:style="{ 'background-image': `url(/${photo.lazy})` }"
:alt="photo.comment"
:width="photo.thumbnailWidth"
:height="photo.thumbnailHeight"
class="photo"
loading="lazy"
@load="emit('load', $event)"
>
<Logo :photo="photo" />
<a
v-if="photo.comment && photo.entity"
:href="`/${photo.entity.type}/${photo.entity.slug}`"
class="photo-comment"
>{{ photo.comment }} for {{ photo.entity.name }}</a>
<span
v-else-if="photo.comment"
class="photo-comment"
>{{ photo.comment }}</span>
</div>
</div>
</template>
<script setup>
import { computed, inject } from 'vue';
import Logo from '#/components/tags/logo.vue';
import Campaign from '#/components/campaigns/campaign.vue';
const props = defineProps({
tag: {
type: Object,
default: null,
},
});
const emit = defineEmits(['load', 'campaign']);
const { campaigns } = inject('pageContext');
const photos = computed(() => {
/* sfw not currently implemented
if (props.tag.poster && this.$store.state.ui.sfw) {
return [props.tag.poster].concat(props.tag.photos).map((photo) => photo.sfw);
}
if (this.$store.state.ui.sfw) {
return props.tag.photos.map((photo) => photo.sfw);
}
*/
if (props.tag.poster) {
return [props.tag.poster].concat(props.tag.photos);
}
return props.tag.photos;
});
</script>
<style scoped>
.photos {
display: flex;
flex-shrink: 0;
gap: 0.5rem;
padding: .5rem;
border-bottom: solid 1px var(--shadow-weak-40);
background: var(--background-base-10);
overflow-x: auto;
}
.photo-container {
position: relative;
flex-shrink: 0;
font-size: 0;
overflow: hidden;
&:hover {
.photo-comment {
transform: translateY(0);
}
::v-deep(.album-logo) {
opacity: 0;
}
}
}
.photo,
.campaign {
height: 14rem;
width: auto;
flex-shrink: 0;
}
.photo {
object-fit: cover;
object-position: 50% 0;
border-radius: .25rem;
background-size: cover;
background-position: center;
box-shadow: 0 0px 3px var(--shadow-weak-30);
}
.photo-comment {
width: 100%;
position: absolute;
bottom: -1px;
left: 0;
box-sizing: border-box;
padding: .5rem;
color: var(--text-light);
background: var(--shadow);
font-size: .9rem;
text-shadow: 0 0 3px var(--shadow);
text-decoration: none;
white-space: normal;
line-height: 1.25;
transform: translateY(100%);
transition: transform .25s ease;
border-radius: 0 0 .25rem .25rem;
}
@media(--small) {
.photo,
.campaign {
height: 11rem;
}
}
</style>