Added trailers. Improved scene page scaling.

This commit is contained in:
2024-03-24 04:22:37 +01:00
parent 8a32febb8a
commit 08e4146d91
23 changed files with 3204 additions and 413 deletions

View File

@@ -6,16 +6,32 @@
:style="{ 'background-image': scene.poster.isS3 ? `url('https://cdndev.traxxx.me/${scene.poster.thumbnail}')` : `url('/media/${scene.poster.thumbnail}')` }"
>
<div class="banner">
<div class="poster-container">
<div
v-if="scene.trailer"
class="trailer"
>
<Player
:video="scene.trailer"
:poster="poster"
class="item"
:class="{ playing }"
@play="playing = true; paused = false;"
@pause="playing = false; paused = true;"
/>
</div>
<div
v-else-if="scene.poster"
class="poster-container"
>
<a
:href="scene.poster.isS3 ? `https://cdndev.traxxx.me/${scene.poster.path}` : `/media/${scene.poster.path}`"
:href="getPath(scene.poster)"
target="_blank"
class="poster-link"
>
<img
v-if="scene.poster"
:src="scene.poster.isS3 ? `https://cdndev.traxxx.me/${scene.poster.thumbnail}` : `/media/${scene.poster.thumbnail}`"
:style="{ 'background-image': scene.poster.isS3 ? `url(https://cdndev.traxxx.me/${scene.poster.lazy})` : `url(/media/${scene.poster.lazy})` }"
:src="getPath(scene.poster, 'thumbnail')"
:style="{ 'background-image': getPath(scene.poster, 'lazy') }"
:width="scene.poster.width"
:height="scene.poster.height"
class="poster"
@@ -34,13 +50,13 @@
class="photo-container"
>
<a
:href="photo.isS3 ? `https://cdndev.traxxx.me/${photo.path}` : `/media/${photo.path}`"
:href="getPath(photo)"
target="_blank"
class="photo-link"
>
<img
:src="photo.isS3 ? `https://cdndev.traxxx.me/${photo.thumbnail}` : `/media/${photo.thumbnail}`"
:style="{ 'background-image': photo.isS3 ? `url(https://cdndev.traxxx.me/${photo.lazy})` : `url(/media/${photo.lazy})` }"
:src="getPath(photo, 'thumbnail')"
:style="{ 'background-image': getPath(photo, 'lazy') }"
:width="photo.width"
:height="photo.height"
class="photo"
@@ -65,7 +81,10 @@
>
</Link>
<template v-if="!scene.channel.isIndependent && scene.network">
<span
v-if="!scene.channel.isIndependent && scene.network"
class="network-container"
>
by
<Link
:href="`/${scene.network.type}/${scene.network.slug}`"
@@ -77,21 +96,32 @@
class="network-logo entity-logo"
>
</Link>
</template>
</span>
</div>
<time
:datetime="scene.effectiveDate.toISOString()"
class="date"
class="date ellipsis"
>{{ formatDate(scene.effectiveDate, 'MMMM d, y') }}</time>
</div>
<div class="header">
<h2
v-if="scene.title"
:title="scene.title"
class="title"
>{{ scene.title }}</h2>
<h2
v-else-if="scene.actors.length > 0"
class="title notitle"
>Scene featuring {{ scene.actors.map((actor) => actor.name).join(', ') }}</h2>
<h2
v-else
class="title notitle"
>No title</h2>
<div class="actions">
<div
v-if="user"
@@ -178,6 +208,14 @@
<h3 class="heading">Director</h3>
{{ scene.directors.map((director) => director.name).join(', ') }}
</div>
<div
v-if="scene.shootId"
class="detail"
>
<h3 class="heading">Shoot</h3>
{{ scene.shootId }}
</div>
</div>
<div class="section details">
@@ -204,19 +242,40 @@
</template>
<script setup>
import { ref, inject } from 'vue';
import { ref, computed, inject } from 'vue';
import { post, del } from '#/src/api.js';
import { formatDate, formatDuration } from '#/utils/format.js';
import getPath from '#/src/get-path.js';
import Icon from '../../components/icon/icon.vue';
import ActorTile from '../../components/actors/tile.vue';
import Icon from '#/components/icon/icon.vue';
import ActorTile from '#/components/actors/tile.vue';
import Player from '#/components/video/player.vue';
const { pageProps, user } = inject('pageContext');
const { scene } = pageProps;
const favorited = ref(scene.stashes.some((sceneStash) => sceneStash.primary));
const playing = ref(false);
const paused = ref(false);
const poster = computed(() => {
if (scene.poster) {
return getPath(scene.poster, 'thumbnail');
}
if (scene.covers?.length > 0) {
return getPath(scene.covers[0], 'thumbnail');
}
if (scene.photos?.length > 0) {
return getPath(scene.photos[0], 'thumbnail');
}
return null;
});
async function stash() {
try {
favorited.value = true;
@@ -247,6 +306,7 @@ async function unstash() {
.content {
width: 100%;
max-width: 1200px;
margin: 0 .5rem;
display: flex;
flex-direction: column;
}
@@ -287,6 +347,28 @@ async function unstash() {
box-shadow: 0 0 3px var(--shadow-weak-10);
}
.trailer {
max-width: 100%;
width: calc(21/9 * 16rem);
margin-right: .5rem;
flex-shrink: 0;
aspect-ratio: 16/9;
}
:deep(.player) {
width: 100%;
height: 100%;
flex-shrink: 0;
&:not(.playing) {
&[poster],
.vjs-tech[poster],
.vjs-poster img {
object-fit: cover;
}
}
}
.album {
height: auto;
flex-grow: 1;
@@ -346,7 +428,14 @@ async function unstash() {
}
.entity-logo {
height: 1.5rem;
width: 10rem;
max-height: 100%;
object-fit: contain;
}
.network-container {
display: flex;
align-items: center;
}
.date {
@@ -356,23 +445,32 @@ async function unstash() {
.info,
.header {
border: solid 1px var(--shadow-weak-40);
border-top: none;
border-bottom: none;
}
.info {
padding: 0;
}
.header {
display: flex;
align-items: center;
align-items: flex-start;
justify-content: space-between;
padding: 1rem 1rem 0.5rem 1rem;
padding: 1rem .5rem .5rem .5rem;
}
.title {
margin: 0 .5rem 0 0;
white-space: nowrap;
line-height: 1.25;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.notitle {
color: var(--grey-dark-10);
}
.actions {
@@ -390,6 +488,9 @@ async function unstash() {
.button {
flex-shrink: 0;
padding: .75rem;
}
.button:not(:last-child) {
margin-right: .5rem;
}
}
@@ -418,10 +519,6 @@ async function unstash() {
color: var(--text-light);
}
.info {
padding: 0 1rem;
}
.actors,
.tags {
margin-bottom: 1rem;
@@ -475,19 +572,62 @@ async function unstash() {
margin-left: .25rem;
}
@media(--small-10) {
@media(--small) {
.content {
margin: 0;
}
.info {
margin: 0 .5rem;
}
.banner-container {
border-radius: 0;
margin-top: 0;
}
.network-container {
display: none;
}
.header {
flex-direction: column-reverse;
}
.actions {
width: 100%;
justify-content: space-between;
margin-bottom: 1.5rem;
}
.title {
width: 100%;
margin-left: .5rem;
white-space: wrap;
}
.meta {
border-radius: 0;
}
.entity-logo {
width: 7.5rem;
}
}
@media(--small-10) {
.banner {
justify-content: center;
border-radius: 0;
}
.poster-container {
padding: 0;
border-radius: 0;
margin: 0;
flex-shrink: 1;
}
.trailer {
margin: 0;
flex-shrink: 1;
}
@@ -506,27 +646,15 @@ async function unstash() {
.info {
padding: 0 .5rem;
}
.actors {
grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
}
}
@media (--small) {
.header {
flex-direction: column-reverse;
}
.actions {
width: 100%;
justify-content: space-between;
margin-bottom: 1.5rem;
}
.title {
width: 100%;
margin-left: 1rem;
white-space: wrap;
}
.meta {
border-radius: 0;
@media(--small-60) {
.actors {
grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
}
}
</style>