<template> <div class="tile" :class="{ unstashed: !favorited && pageStash && user && pageStash.user.id === user?.id }" > <div class="tile-full"> <div class="poster-container"> <Link :href="`/scene/${scene.id}/${scene.slug || ''}`" :title="scene.title" target="_blank" class="poster" > <img v-if="scene.poster" :src="getPath(scene.poster, 'thumbnail')" :style="{ 'background-image': `url(${getPath(scene.poster, 'lazy')})` }" loading="lazy" fetchpriority="low" class="thumbnail" > <Icon v-else icon="clapboard" /> </Link> <Heart domain="scenes" :item="scene" :show-secondary="false" class="light tiled" @stashed="(stash) => { favorited = stash.id === currentStash.id ? true : favorited; }" @unstashed="(stash) => { favorited = stash.id === currentStash.id ? false : favorited; }" /> </div> <Meta :scene="scene" class="meta-full" /> <div class="info"> <Link :href="`/scene/${scene.id}/${scene.slug || ''}`" :title="scene.title" target="_blank" class="row title nolink" :class="{ notitle: !scene.title }" > <template v-if="scene.title">{{ scene.title }}</template> <template v-else> <span v-if="priorityTags.length > 0" class="title-tags" >{{ priorityTags.join(' & ') }} scene</span> <template v-else>Scene</template> <template v-if="scene.actors.length > 0"> with {{ scene.actors.map((actor) => actor.name).join(', ') }}</template> </template> </Link> <ul class="row actors nolist" :title="scene.actors.map((actor) => actor.name).join(', ')" > <li v-for="actor in scene.actors" :key="`actor-${scene.id}-${actor.id}`" class="actor" > <Link :href="`/actor/${actor.id}/${actor.slug}`" class="nolink" >{{ actor.name }}</Link> </li> </ul> <ul class="row tags nolist" :title="scene.tags.map((tag) => tag.name).join(', ')" > <li v-if="scene.shootId" class="tag shoot" > <Link :href="scene.studio ? `/studio/${scene.studio.slug}` : null" class="nolink" >{{ scene.shootId }}</Link> </li> <li v-for="tag in scene.tags" :key="`tag-${scene.id}-${tag.id}`" class="tag" > <Link :href="`/tag/${tag.slug}`" class="nolink" >{{ tag.name }}</Link> </li> </ul> </div> </div> <Meta :scene="scene" class="meta-compact" /> </div> </template> <script setup> import { ref, inject } from 'vue'; import getPath from '#/src/get-path.js'; import Meta from '#/components/scenes/meta.vue'; import Heart from '#/components/stashes/heart.vue'; const props = defineProps({ scene: { type: Object, default: null, }, }); const pageContext = inject('pageContext'); const user = pageContext.user; const pageStash = pageContext.pageProps.stash; const currentStash = pageStash || pageContext.assets?.primaryStash; const priorityTags = props.scene.tags.map((tag) => tag.name).slice(0, 2); const favorited = ref(props.scene.stashes.some((sceneStash) => sceneStash.id === currentStash?.id)); </script> <style scoped> .tile { display: flex; flex-direction: column; width: 100%; overflow: hidden; background: var(--background-base); border-radius: .25rem; box-shadow: 0 0 3px var(--shadow-weak-30); &:hover { box-shadow: 0 0 3px var(--shadow-weak-20); :deep(.bookmarks) .icon:not(.favorited):not(:hover) { fill: var(--text-light); } } &.unstashed { opacity: .5; } } .tile-full { display: flex; flex-direction: column; } .meta-compact { display: none; } .info { display: flex; flex-direction: column; } .poster-container { position: relative; overflow: hidden; font-size: 0; } .poster { display: flex; justify-content: center; align-items: center; aspect-ratio: 16/9; border-radius: .25rem .25rem 0 0; overflow: hidden; background: var(--background-dark-20); .icon { width: 3rem; height: 3rem; fill: var(--glass-weak-40); } } .thumbnail { width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; background-size: cover; background-position: center; } .row { margin: 0 .5rem .25rem .5rem; font-size: .9rem; } .title { display: block; margin-top: .5rem; margin-bottom: .4rem; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-weight: bold; } .title-tags { display: inline-block; &:first-letter { text-transform: capitalize; } } .notitle { color: var(--shadow); } .actor:hover, .tag:hover { color: var(--primary); } .actors { height: 1rem; overflow: hidden; white-space: pre-wrap; } .actor { &:not(:last-child)::after { content: ',\0020'; } } .tags { height: 1.25rem; overflow: hidden; } .tag { margin: 0 .5rem .25rem 0; padding: .1rem 0; color: var(--glass-strong-10); font-size: .75rem; } .shoot { font-size: .75rem; font-weight: bold; } @media(--small-20) { .tile.list { .tile-full { flex-direction: row; } .poster-container { width: 10rem; flex-shrink: 0; } .poster { border-radius: .25rem 0 0 0; } .bookmarks.tiled { right: auto; left: 0; } .meta-full { display: none; } .meta-compact { display: flex; } .info { width: 0; flex-grow: 1; justify-content: center; } .row { margin: 0 .5rem .5rem .5rem; } .title { margin-top: .6rem; margin-bottom: .6rem; } } } </style>