Showing tag poster and photos on tag page. Improved campaign fallback logic, fixes wrong ratio selected.
This commit is contained in:
parent
bc26e07812
commit
84b9bbd1b6
|
|
@ -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>
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -89,18 +89,10 @@
|
||||||
>
|
>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
<Logo
|
||||||
v-if="tag.poster?.entity"
|
:photo="tag.poster"
|
||||||
:href="`/${tag.poster.entity.type}/${tag.poster.entity.slug}`"
|
:favicon="true"
|
||||||
class="favicon-link"
|
/>
|
||||||
>
|
|
||||||
<img
|
|
||||||
:src="!tag.poster.entity.parent || tag.poster.entity.isIndependent ? `/logos/${tag.poster.entity.slug}/favicon.png` : `/logos/${tag.poster.entity.parent.slug}/favicon.png`"
|
|
||||||
:alt="tag.poster.entity.name"
|
|
||||||
:title="tag.poster.entity.name"
|
|
||||||
class="favicon"
|
|
||||||
>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
|
|
@ -120,6 +112,8 @@ import { ref, onMounted, inject } from 'vue';
|
||||||
import navigate from '#/src/navigate.js';
|
import navigate from '#/src/navigate.js';
|
||||||
import events from '#/src/events.js';
|
import events from '#/src/events.js';
|
||||||
|
|
||||||
|
import Logo from '#/components/tags/logo.vue';
|
||||||
|
|
||||||
const pageContext = inject('pageContext');
|
const pageContext = inject('pageContext');
|
||||||
const showcase = pageContext.pageProps.tagShowcase;
|
const showcase = pageContext.pageProps.tagShowcase;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,17 @@
|
||||||
v-html="description"
|
v-html="description"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Photos
|
||||||
|
v-if="tag.poster || tag.photos.length > 0"
|
||||||
|
:tag="tag"
|
||||||
|
/>
|
||||||
|
|
||||||
<Domains
|
<Domains
|
||||||
:path="`/tag/${tag.slug}`"
|
:path="`/tag/${tag.slug}`"
|
||||||
:domains="['scenes', 'movies']"
|
:domains="['scenes', 'movies']"
|
||||||
:domain="domain"
|
:domain="domain"
|
||||||
class="domains-bar"
|
class="domains-bar"
|
||||||
|
:class="{ light: tag.poster || tag.photos.length }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Scenes v-if="domain === 'scenes'" />
|
<Scenes v-if="domain === 'scenes'" />
|
||||||
|
|
@ -33,6 +39,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { inject } from 'vue';
|
import { inject } from 'vue';
|
||||||
|
|
||||||
|
import Photos from '#/components/tags/photos.vue';
|
||||||
import Scenes from '#/components/scenes/scenes.vue';
|
import Scenes from '#/components/scenes/scenes.vue';
|
||||||
import Movies from '#/components/movies/movies.vue';
|
import Movies from '#/components/movies/movies.vue';
|
||||||
import Domains from '#/components/domains/domains.vue';
|
import Domains from '#/components/domains/domains.vue';
|
||||||
|
|
@ -69,6 +76,7 @@ const domain = pageContext.routeParams.domain;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: .25rem 1rem;
|
padding: .25rem 1rem;
|
||||||
|
margin-bottom: -1px; /* for some reason there's a gap between description */
|
||||||
color: var(--text-light);
|
color: var(--text-light);
|
||||||
background: var(--grey-dark-40);
|
background: var(--grey-dark-40);
|
||||||
}
|
}
|
||||||
|
|
@ -94,4 +102,9 @@ const domain = pageContext.routeParams.domain;
|
||||||
background: var(--grey-dark-40);
|
background: var(--grey-dark-40);
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.domains-bar.light {
|
||||||
|
background: var(--background-base-10);
|
||||||
|
border-bottom: solid 1px var(--shadow-weak-40);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@ export async function onBeforeRender(pageContext) {
|
||||||
fetchTagsById([tagSlug], {}, pageContext.user),
|
fetchTagsById([tagSlug], {}, pageContext.user),
|
||||||
fetchReleases(pageContext),
|
fetchReleases(pageContext),
|
||||||
getRandomCampaigns([
|
getRandomCampaigns([
|
||||||
|
{
|
||||||
|
tagSlugs: [tagSlug],
|
||||||
|
minRatio: 0.75,
|
||||||
|
maxRatio: 1.25,
|
||||||
|
},
|
||||||
{ tagSlugs: [tagSlug], minRatio: 3 },
|
{ tagSlugs: [tagSlug], minRatio: 3 },
|
||||||
{ tagSlugs: [tagSlug], minRatio: 3 },
|
{ tagSlugs: [tagSlug], minRatio: 3 },
|
||||||
pageContext.routeParams.domain === 'scenes'
|
pageContext.routeParams.domain === 'scenes'
|
||||||
|
|
@ -55,7 +60,7 @@ export async function onBeforeRender(pageContext) {
|
||||||
const description = tag.description && md.renderInline(tag.description);
|
const description = tag.description && md.renderInline(tag.description);
|
||||||
|
|
||||||
const campaignIndex = getCampaignIndex(releases.length);
|
const campaignIndex = getCampaignIndex(releases.length);
|
||||||
const [metaCampaign, paginationCampaign, sceneCampaign] = campaigns;
|
const [photosCampaign, metaCampaign, paginationCampaign, sceneCampaign] = campaigns;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pageContext: {
|
pageContext: {
|
||||||
|
|
@ -67,6 +72,7 @@ export async function onBeforeRender(pageContext) {
|
||||||
},
|
},
|
||||||
campaigns: {
|
campaigns: {
|
||||||
index: campaignIndex,
|
index: campaignIndex,
|
||||||
|
photos: photosCampaign,
|
||||||
meta: metaCampaign,
|
meta: metaCampaign,
|
||||||
scenes: releases.length > 5 && sceneCampaign,
|
scenes: releases.length > 5 && sceneCampaign,
|
||||||
pagination: paginationCampaign,
|
pagination: paginationCampaign,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ function curateCampaign(campaign) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectRandomCampaign(primaryCampaigns, entityCampaigns, preferredCampaigns, allCampaigns, options) {
|
function selectRandomCampaign(primaryCampaigns, entityCampaigns, preferredCampaigns) {
|
||||||
if (primaryCampaigns.length > 0) {
|
if (primaryCampaigns.length > 0) {
|
||||||
return primaryCampaigns[crypto.randomInt(primaryCampaigns.length)];
|
return primaryCampaigns[crypto.randomInt(primaryCampaigns.length)];
|
||||||
}
|
}
|
||||||
|
|
@ -46,14 +46,10 @@ function selectRandomCampaign(primaryCampaigns, entityCampaigns, preferredCampai
|
||||||
return preferredCampaigns[crypto.randomInt(preferredCampaigns.length)];
|
return preferredCampaigns[crypto.randomInt(preferredCampaigns.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allCampaigns.length > 0 && options.allowRandomFallback !== false) {
|
|
||||||
return allCampaigns[crypto.randomInt(allCampaigns.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getRandomCampaign(options = {}, context = {}) {
|
export async function getRandomCampaign(options = {}, context = {}, pass = 0) {
|
||||||
const campaigns = options.campaigns
|
const campaigns = options.campaigns
|
||||||
|| await redis.hGetAll('traxxx:campaigns').then((rawCampaigns) => Object.values(rawCampaigns).map((rawCampaign) => JSON.parse(rawCampaign)));
|
|| await redis.hGetAll('traxxx:campaigns').then((rawCampaigns) => Object.values(rawCampaigns).map((rawCampaign) => JSON.parse(rawCampaign)));
|
||||||
|
|
||||||
|
|
@ -103,6 +99,18 @@ export async function getRandomCampaign(options = {}, context = {}) {
|
||||||
|
|
||||||
const randomCampaign = selectRandomCampaign(primaryCampaigns, randomEntityCampaigns, validCampaigns, campaigns, options);
|
const randomCampaign = selectRandomCampaign(primaryCampaigns, randomEntityCampaigns, validCampaigns, campaigns, options);
|
||||||
|
|
||||||
|
// no campaign found, gradually widen scope
|
||||||
|
if (!randomCampaign && pass === 0 && options.allowRandomFallback !== false) {
|
||||||
|
return getRandomCampaign({
|
||||||
|
minRatio: options.minRatio,
|
||||||
|
maxRatio: options.maxRatio,
|
||||||
|
}, context, pass + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!randomCampaign && pass === 1 && options.allowRandomFallback !== false && options.allowRandomRatio) {
|
||||||
|
return getRandomCampaign({}, context, pass + 1);
|
||||||
|
}
|
||||||
|
|
||||||
return randomCampaign;
|
return randomCampaign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { curateEntity } from './entities.js';
|
||||||
|
|
||||||
export function curateMedia(media, context = {}) {
|
export function curateMedia(media, context = {}) {
|
||||||
if (!media) {
|
if (!media) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -21,6 +23,11 @@ export function curateMedia(media, context = {}) {
|
||||||
type: mime[0],
|
type: mime[0],
|
||||||
subtype: mime[1],
|
subtype: mime[1],
|
||||||
},
|
},
|
||||||
|
comment: media.comment,
|
||||||
|
entity: media.entity && curateEntity({
|
||||||
|
...media.entity,
|
||||||
|
parent: media.entity_parent,
|
||||||
|
}),
|
||||||
type: context.type || null,
|
type: context.type || null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
src/tags.js
28
src/tags.js
|
|
@ -2,7 +2,7 @@ import knex from './knex.js';
|
||||||
import redis from './redis.js';
|
import redis from './redis.js';
|
||||||
import initLogger from './logger.js';
|
import initLogger from './logger.js';
|
||||||
|
|
||||||
import { curateEntity } from './entities.js';
|
import { curateMedia } from './media.js';
|
||||||
|
|
||||||
const logger = initLogger();
|
const logger = initLogger();
|
||||||
|
|
||||||
|
|
@ -13,18 +13,8 @@ function curateTag(tag, context) {
|
||||||
slug: tag.slug,
|
slug: tag.slug,
|
||||||
description: tag.description,
|
description: tag.description,
|
||||||
priority: tag.priority,
|
priority: tag.priority,
|
||||||
poster: tag.poster && {
|
poster: tag.poster && curateMedia(tag.poster),
|
||||||
id: tag.poster.id,
|
photos: tag.photos?.map((photo) => curateMedia(photo)) || [],
|
||||||
path: tag.poster.path,
|
|
||||||
thumbnail: tag.poster.thumbnail,
|
|
||||||
lazy: tag.poster.lazy,
|
|
||||||
isS3: tag.poster.is_s3,
|
|
||||||
comment: tag.poster.comment,
|
|
||||||
entity: tag.poster.entity && curateEntity({
|
|
||||||
...tag.poster.entity,
|
|
||||||
parent: tag.poster.entity_parent,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
alerts: {
|
alerts: {
|
||||||
only: context?.alerts?.filter((alert) => alert.is_only).flatMap((alert) => alert.alert_ids) || [],
|
only: context?.alerts?.filter((alert) => alert.is_only).flatMap((alert) => alert.alert_ids) || [],
|
||||||
multi: context?.alerts?.filter((alert) => !alert.is_only).flatMap((alert) => alert.alert_ids) || [],
|
multi: context?.alerts?.filter((alert) => !alert.is_only).flatMap((alert) => alert.alert_ids) || [],
|
||||||
|
|
@ -80,7 +70,7 @@ export async function fetchTags(options = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchTagsById(tagIds, options = {}, reqUser) {
|
export async function fetchTagsById(tagIds, options = {}, reqUser) {
|
||||||
const [tags, posters, alerts] = await Promise.all([
|
const [tags, posters, photos, alerts] = await Promise.all([
|
||||||
knex('tags')
|
knex('tags')
|
||||||
.whereIn('tags.id', tagIds.filter((tagId) => typeof tagId === 'number'))
|
.whereIn('tags.id', tagIds.filter((tagId) => typeof tagId === 'number'))
|
||||||
.orWhereIn('tags.slug', tagIds.filter((tagId) => typeof tagId === 'string'))
|
.orWhereIn('tags.slug', tagIds.filter((tagId) => typeof tagId === 'string'))
|
||||||
|
|
@ -97,6 +87,14 @@ export async function fetchTagsById(tagIds, options = {}, reqUser) {
|
||||||
.leftJoin('entities as parents', 'parents.id', 'entities.parent_id')
|
.leftJoin('entities as parents', 'parents.id', 'entities.parent_id')
|
||||||
.whereIn('tags.id', tagIds.filter((tagId) => typeof tagId === 'number'))
|
.whereIn('tags.id', tagIds.filter((tagId) => typeof tagId === 'number'))
|
||||||
.orWhereIn('tags.slug', tagIds.filter((tagId) => typeof tagId === 'string')),
|
.orWhereIn('tags.slug', tagIds.filter((tagId) => typeof tagId === 'string')),
|
||||||
|
knex('tags_photos')
|
||||||
|
.select('tags_photos.tag_id', 'media.*', knex.raw('row_to_json(entities) as entity'), knex.raw('row_to_json(parents) as entity_parent'))
|
||||||
|
.leftJoin('tags', 'tags.id', 'tags_photos.tag_id')
|
||||||
|
.leftJoin('media', 'media.id', 'tags_photos.media_id')
|
||||||
|
.leftJoin('entities', 'entities.id', 'media.entity_id')
|
||||||
|
.leftJoin('entities as parents', 'parents.id', 'entities.parent_id')
|
||||||
|
.whereIn('tags.id', tagIds.filter((tagId) => typeof tagId === 'number'))
|
||||||
|
.orWhereIn('tags.slug', tagIds.filter((tagId) => typeof tagId === 'string')),
|
||||||
reqUser
|
reqUser
|
||||||
? knex('alerts_users_tags')
|
? knex('alerts_users_tags')
|
||||||
.select('alerts_users_tags.*')
|
.select('alerts_users_tags.*')
|
||||||
|
|
@ -116,6 +114,7 @@ export async function fetchTagsById(tagIds, options = {}, reqUser) {
|
||||||
return tags.map((tagEntry) => curateTag({
|
return tags.map((tagEntry) => curateTag({
|
||||||
...tagEntry,
|
...tagEntry,
|
||||||
poster: postersByTagId[tagEntry.id],
|
poster: postersByTagId[tagEntry.id],
|
||||||
|
photos: photos.filter((photo) => photo.tag_id === tagEntry.id),
|
||||||
}, {
|
}, {
|
||||||
alerts: alerts.filter((alert) => alert.tag_id === tagEntry.id),
|
alerts: alerts.filter((alert) => alert.tag_id === tagEntry.id),
|
||||||
append: options.append,
|
append: options.append,
|
||||||
|
|
@ -133,6 +132,7 @@ export async function fetchTagsById(tagIds, options = {}, reqUser) {
|
||||||
return curateTag({
|
return curateTag({
|
||||||
...tag,
|
...tag,
|
||||||
poster: postersByTagId[tag.id],
|
poster: postersByTagId[tag.id],
|
||||||
|
photos: photos.filter((photo) => photo.tag_id === tag.id),
|
||||||
}, {
|
}, {
|
||||||
alerts: alerts.filter((alert) => alert.tag_id === tag.id),
|
alerts: alerts.filter((alert) => alert.tag_id === tag.id),
|
||||||
append: options.append,
|
append: options.append,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue