Removed info channels from overview. Fixed poster gap.
This commit is contained in:
parent
bfe6dc866d
commit
41d6324c28
|
@ -1,17 +1,33 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="campaign">
|
<iframe
|
||||||
<a
|
v-if="campaign?.banner?.type === 'html'"
|
||||||
:href="campaign.url"
|
ref="iframe"
|
||||||
target="_blank"
|
:width="campaign.banner.width"
|
||||||
class="campaign-link"
|
:height="campaign.banner.height"
|
||||||
|
:src="bannerSrc"
|
||||||
|
scrolling="no"
|
||||||
|
marginwidth="0"
|
||||||
|
marginheight="0"
|
||||||
|
class="campaign frame"
|
||||||
|
data-umami-event="campaign-click"
|
||||||
|
:data-umami-event-campaign-id="`${campaign.entity.slug}-${campaign.id}`"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<a
|
||||||
|
v-else-if="campaign.banner"
|
||||||
|
:href="campaign.url || campaign.affiliate?.url"
|
||||||
|
target="_blank"
|
||||||
|
class="campaign"
|
||||||
|
data-umami-event="campaign-click"
|
||||||
|
:data-umami-event-campaign-id="`${campaign.entity.slug}-${campaign.id}`"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
:src="bannerSrc"
|
||||||
|
:width="campaign.banner.width"
|
||||||
|
:height="campaign.banner.height"
|
||||||
|
class="campaign-banner"
|
||||||
>
|
>
|
||||||
<img
|
</a>
|
||||||
v-if="campaign.banner"
|
|
||||||
:src="getBanner(campaign)"
|
|
||||||
class="campaign-banner"
|
|
||||||
>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
@ -24,17 +40,19 @@ const props = defineProps({
|
||||||
|
|
||||||
// console.log(props.campaign?.banner);
|
// console.log(props.campaign?.banner);
|
||||||
|
|
||||||
function getBanner(campaign) {
|
const bannerSrc = (() => {
|
||||||
if (campaign.banner.entity.type === 'network' || !campaign.banner.entity.parent) {
|
if (props.campaign.banner) {
|
||||||
return `/banners/${campaign.banner.entity.slug}/${campaign.banner.id}.${campaign.banner.type || 'jpg'}`;
|
if (props.campaign.banner.entity.type === 'network' || !props.campaign.banner.entity.parent) {
|
||||||
}
|
return `/banners/${props.campaign.banner.entity.slug}/${props.campaign.banner.id}.${props.campaign.banner.type || 'jpg'}`;
|
||||||
|
}
|
||||||
|
|
||||||
if (campaign.banner.entity.type === 'channel' && campaign.banner.entity.parent?.type === 'network') {
|
if (props.campaign.banner.entity.type === 'channel' && props.campaign.banner.entity.parent?.type === 'network') {
|
||||||
return `/banners/${campaign.banner.entity.parent.slug}/${campaign.banner.entity.slug}/${campaign.banner.id}.${campaign.banner.type || 'jpg'}`;
|
return `/banners/${props.campaign.banner.entity.parent.slug}/${props.campaign.banner.entity.slug}/${props.campaign.banner.id}.${props.campaign.banner.type || 'jpg'}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@ -44,7 +62,14 @@ function getBanner(campaign) {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.frame {
|
||||||
|
border: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.campaign-banner {
|
.campaign-banner {
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="pagination-container">
|
<div class="pagination-container">
|
||||||
|
<Campaign
|
||||||
|
v-if="campaigns?.pagination"
|
||||||
|
:campaign="campaigns.pagination"
|
||||||
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="currentPage === pageTotal && total > env.maxMatches"
|
v-if="currentPage === pageTotal && total > env.maxMatches"
|
||||||
class="more"
|
class="more"
|
||||||
|
@ -89,6 +94,8 @@
|
||||||
import { computed, inject } from 'vue';
|
import { computed, inject } from 'vue';
|
||||||
import { parse } from 'path-to-regexp';
|
import { parse } from 'path-to-regexp';
|
||||||
|
|
||||||
|
import Campaign from '#/components/campaigns/campaign.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
page: {
|
page: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
@ -117,7 +124,6 @@ const props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['navigation']);
|
const emit = defineEmits(['navigation']);
|
||||||
|
|
||||||
const pageContext = inject('pageContext');
|
const pageContext = inject('pageContext');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -125,6 +131,7 @@ const {
|
||||||
urlParsed,
|
urlParsed,
|
||||||
pageProps,
|
pageProps,
|
||||||
env,
|
env,
|
||||||
|
campaigns,
|
||||||
} = pageContext;
|
} = pageContext;
|
||||||
|
|
||||||
const currentPage = computed(() => props.page || Number(routeParams?.page));
|
const currentPage = computed(() => props.page || Number(routeParams?.page));
|
||||||
|
@ -203,6 +210,7 @@ function getPath(page) {
|
||||||
.pagination-container {
|
.pagination-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,6 +294,12 @@ function getPath(page) {
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.campaign {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 6rem;
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
@media (--small-30) {
|
@media (--small-30) {
|
||||||
.pagination {
|
.pagination {
|
||||||
height: 4.5rem;
|
height: 4.5rem;
|
||||||
|
|
|
@ -54,6 +54,11 @@
|
||||||
>
|
>
|
||||||
<div class="meta">{{ total }} results</div>
|
<div class="meta">{{ total }} results</div>
|
||||||
|
|
||||||
|
<Campaign
|
||||||
|
v-if="campaigns?.meta"
|
||||||
|
:campaign="campaigns.meta"
|
||||||
|
/>
|
||||||
|
|
||||||
<select
|
<select
|
||||||
v-model="scope"
|
v-model="scope"
|
||||||
class="input"
|
class="input"
|
||||||
|
@ -83,23 +88,30 @@
|
||||||
v-if="showScopeTabs"
|
v-if="showScopeTabs"
|
||||||
class="scopes"
|
class="scopes"
|
||||||
>
|
>
|
||||||
<Link
|
<div class="scopes-pills">
|
||||||
:href="getPath('latest')"
|
<Link
|
||||||
class="scope nolink"
|
:href="getPath('latest')"
|
||||||
:active="scope === 'latest'"
|
class="scope nolink"
|
||||||
>Latest</Link>
|
:active="scope === 'latest'"
|
||||||
|
>Latest</Link>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
:href="getPath('upcoming')"
|
:href="getPath('upcoming')"
|
||||||
class="scope nolink"
|
class="scope nolink"
|
||||||
:active="scope === 'upcoming'"
|
:active="scope === 'upcoming'"
|
||||||
>Upcoming</Link>
|
>Upcoming</Link>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
:href="getPath('new')"
|
:href="getPath('new')"
|
||||||
class="scope nolink"
|
class="scope nolink"
|
||||||
:active="scope === 'new'"
|
:active="scope === 'new'"
|
||||||
>New</Link>
|
>New</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Campaign
|
||||||
|
v-if="campaigns?.scope"
|
||||||
|
:campaign="campaigns.scope"
|
||||||
|
/>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
|
@ -107,10 +119,10 @@
|
||||||
>
|
>
|
||||||
<template v-for="item in campaignScenes">
|
<template v-for="item in campaignScenes">
|
||||||
<li
|
<li
|
||||||
v-if="item === 'campaign' && campaign"
|
v-if="item === 'campaign' && sceneCampaign"
|
||||||
:key="`campaign-${item.id}`"
|
:key="`campaign-${item.id}`"
|
||||||
>
|
>
|
||||||
<Campaign :campaign="campaign" />
|
<Campaign :campaign="sceneCampaign" />
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
|
@ -172,7 +184,12 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { pageProps, routeParams, urlParsed } = inject('pageContext');
|
const {
|
||||||
|
pageProps,
|
||||||
|
routeParams,
|
||||||
|
urlParsed,
|
||||||
|
campaigns,
|
||||||
|
} = inject('pageContext');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
actor: pageActor,
|
actor: pageActor,
|
||||||
|
@ -206,10 +223,10 @@ const filters = ref({
|
||||||
actors: queryActors,
|
actors: queryActors,
|
||||||
});
|
});
|
||||||
|
|
||||||
const campaign = pageProps.campaigns?.scenes;
|
const sceneCampaign = campaigns?.scenes;
|
||||||
const campaignIndex = pageProps.campaigns?.index;
|
const campaignIndex = campaigns?.index;
|
||||||
|
|
||||||
const campaignScenes = computed(() => scenes.value.flatMap((scene, index) => (index === campaignIndex ? ['campaign', scene] : scene)));
|
const campaignScenes = computed(() => scenes.value.flatMap((scene, index) => (sceneCampaign && index === campaignIndex ? ['campaign', scene] : scene)));
|
||||||
|
|
||||||
function getPath(targetScope, preserveQuery) {
|
function getPath(targetScope, preserveQuery) {
|
||||||
const path = parse(routeParams.path).map((segment) => {
|
const path = parse(routeParams.path).map((segment) => {
|
||||||
|
@ -302,8 +319,15 @@ function updateFilter(prop, value, reload = true) {
|
||||||
|
|
||||||
.scenes-header {
|
.scenes-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: flex-end;
|
||||||
|
justify-content: space-between;
|
||||||
padding: .5rem 1rem .25rem 3rem;
|
padding: .5rem 1rem .25rem 3rem;
|
||||||
|
|
||||||
|
.campaign {
|
||||||
|
max-height: 6rem;
|
||||||
|
justify-content: center;
|
||||||
|
margin: .5rem 1rem 0 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.scenes-container {
|
.scenes-container {
|
||||||
|
@ -314,9 +338,9 @@ function updateFilter(prop, value, reload = true) {
|
||||||
|
|
||||||
.meta {
|
.meta {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-grow: 1;
|
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
margin-bottom: .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scenes {
|
.scenes {
|
||||||
|
@ -328,8 +352,21 @@ function updateFilter(prop, value, reload = true) {
|
||||||
|
|
||||||
.scopes {
|
.scopes {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: .75rem 1rem .25rem 1rem;
|
||||||
|
|
||||||
|
.campaign {
|
||||||
|
max-height: 6rem;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scopes-pills {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
gap: .5rem;
|
gap: .5rem;
|
||||||
padding: .75rem 0 .25rem 1rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.scope {
|
.scope {
|
||||||
|
@ -370,6 +407,19 @@ function updateFilter(prop, value, reload = true) {
|
||||||
|
|
||||||
.scopes {
|
.scopes {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
|
||||||
|
.campaign {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scopes-pills {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,6 @@ const scrollable = computed(() => children.value?.scrollWidth > children.value?.
|
||||||
|
|
||||||
@media(--small-20) {
|
@media(--small-20) {
|
||||||
.logo {
|
.logo {
|
||||||
height: 1rem;
|
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { render } from 'vike/abort'; /* eslint-disable-line import/extensions */
|
||||||
import { fetchEntitiesById } from '#/src/entities.js';
|
import { fetchEntitiesById } from '#/src/entities.js';
|
||||||
import { fetchScenes } from '#/src/scenes.js';
|
import { fetchScenes } from '#/src/scenes.js';
|
||||||
import { curateScenesQuery } from '#/src/web/scenes.js';
|
import { curateScenesQuery } from '#/src/web/scenes.js';
|
||||||
|
import { getRandomCampaigns } from '#/src/campaigns.js';
|
||||||
import redis from '#/src//redis.js';
|
import redis from '#/src//redis.js';
|
||||||
|
|
||||||
export async function onBeforeRender(pageContext) {
|
export async function onBeforeRender(pageContext) {
|
||||||
|
@ -12,7 +13,10 @@ export async function onBeforeRender(pageContext) {
|
||||||
throw render(404, `Cannot find ${pageContext.routeParams.entityType} '${pageContext.routeParams.entitySlug}'.`);
|
throw render(404, `Cannot find ${pageContext.routeParams.entityType} '${pageContext.routeParams.entitySlug}'.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [[entity], entityScenes] = await Promise.all([
|
const [
|
||||||
|
[entity],
|
||||||
|
entityScenes,
|
||||||
|
] = await Promise.all([
|
||||||
fetchEntitiesById([Number(entityId)], { includeChildren: true }),
|
fetchEntitiesById([Number(entityId)], { includeChildren: true }),
|
||||||
fetchScenes(await curateScenesQuery({
|
fetchScenes(await curateScenesQuery({
|
||||||
...pageContext.urlQuery,
|
...pageContext.urlQuery,
|
||||||
|
@ -26,6 +30,23 @@ export async function onBeforeRender(pageContext) {
|
||||||
}, pageContext.user),
|
}, pageContext.user),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const campaigns = await getRandomCampaigns([
|
||||||
|
{
|
||||||
|
entityIds: [entity.id, entity.parent?.id].filter(Boolean),
|
||||||
|
minRatio: 1.5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
entityIds: [entity.id, entity.parent?.id].filter(Boolean),
|
||||||
|
minRatio: 0.75,
|
||||||
|
maxRatio: 1.25,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
entityIds: [entity.id, entity.parent?.id].filter(Boolean),
|
||||||
|
parentEntityId: entity.parent?.id,
|
||||||
|
minRatio: 1.5,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
scenes,
|
scenes,
|
||||||
aggActors,
|
aggActors,
|
||||||
|
@ -35,6 +56,9 @@ export async function onBeforeRender(pageContext) {
|
||||||
limit,
|
limit,
|
||||||
} = entityScenes;
|
} = entityScenes;
|
||||||
|
|
||||||
|
const campaignIndex = Math.floor((Math.random() * (0.5 - 0.2) + 0.2) * scenes.length);
|
||||||
|
const [metaCampaign, sceneCampaign, paginationCampaign] = campaigns;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pageContext: {
|
pageContext: {
|
||||||
title: entity.name,
|
title: entity.name,
|
||||||
|
@ -47,6 +71,12 @@ export async function onBeforeRender(pageContext) {
|
||||||
total,
|
total,
|
||||||
limit,
|
limit,
|
||||||
},
|
},
|
||||||
|
campaigns: {
|
||||||
|
index: campaignIndex,
|
||||||
|
meta: metaCampaign,
|
||||||
|
scenes: scenes.length > 5 && sceneCampaign,
|
||||||
|
pagination: paginationCampaign,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="scene.photos.length > 0"
|
v-if="scene.photos.length > 0 || scene.caps.length > 0"
|
||||||
class="album"
|
class="album"
|
||||||
:class="{ single: scene.photos.length === 1 }"
|
:class="{ single: (scene.photos.length + scene.caps.length) === 1 }"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="photo in scene.photos"
|
v-for="photo in [...scene.photos, ...scene.caps]"
|
||||||
:key="`photo-${photo.id}`"
|
:key="`photo-${photo.id}`"
|
||||||
class="photo-container"
|
class="photo-container"
|
||||||
>
|
>
|
||||||
|
@ -444,6 +444,11 @@ function copySummary() {
|
||||||
margin-right: .5rem;
|
margin-right: .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.poster-link {
|
||||||
|
height: 100%;
|
||||||
|
width: calc(21/9 * 16rem);
|
||||||
|
}
|
||||||
|
|
||||||
.poster {
|
.poster {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -638,7 +643,7 @@ function copySummary() {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|
||||||
.actor {
|
.actor {
|
||||||
width: 8rem;
|
width: 10rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -786,6 +791,10 @@ function copySummary() {
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.poster-link {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.trailer {
|
.trailer {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
|
@ -812,7 +821,9 @@ function copySummary() {
|
||||||
}
|
}
|
||||||
|
|
||||||
.actors {
|
.actors {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
|
.actor {
|
||||||
|
width: 9rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.series {
|
.series {
|
||||||
|
@ -833,10 +844,4 @@ function copySummary() {
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(--small-60) {
|
|
||||||
.actors {
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -15,6 +15,8 @@ function getTitle(scene) {
|
||||||
export async function onBeforeRender(pageContext) {
|
export async function onBeforeRender(pageContext) {
|
||||||
const [scene] = await fetchScenesById([Number(pageContext.routeParams.sceneId)], {
|
const [scene] = await fetchScenesById([Number(pageContext.routeParams.sceneId)], {
|
||||||
reqUser: pageContext.user,
|
reqUser: pageContext.user,
|
||||||
|
includeAssets: true,
|
||||||
|
includePartOf: true,
|
||||||
actorStashes: true,
|
actorStashes: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="updates">
|
||||||
<Scenes
|
<Scenes
|
||||||
:show-filters="!!query"
|
:show-filters="!!query"
|
||||||
:show-meta="!!query"
|
:show-meta="!!query"
|
||||||
|
@ -16,3 +16,10 @@ import Scenes from '#/components/scenes/scenes.vue';
|
||||||
const pageContext = inject('pageContext');
|
const pageContext = inject('pageContext');
|
||||||
const query = Object.hasOwn(pageContext.urlParsed.search, 'q');
|
const query = Object.hasOwn(pageContext.urlParsed.search, 'q');
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.updates {
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,10 +1,31 @@
|
||||||
import { fetchScenes } from '#/src/scenes.js';
|
import { fetchScenes } from '#/src/scenes.js';
|
||||||
import { curateScenesQuery } from '#/src/web/scenes.js';
|
import { curateScenesQuery } from '#/src/web/scenes.js';
|
||||||
import { getRandomCampaign } from '#/src/campaigns.js';
|
import { getRandomCampaigns } from '#/src/campaigns.js';
|
||||||
|
|
||||||
export async function onBeforeRender(pageContext) {
|
export async function onBeforeRender(pageContext) {
|
||||||
const withQuery = Object.hasOwn(pageContext.urlParsed.search, 'q');
|
const withQuery = Object.hasOwn(pageContext.urlParsed.search, 'q');
|
||||||
|
|
||||||
|
const [
|
||||||
|
sceneResults,
|
||||||
|
campaigns,
|
||||||
|
] = await Promise.all([
|
||||||
|
fetchScenes(await curateScenesQuery({
|
||||||
|
...pageContext.urlQuery,
|
||||||
|
scope: pageContext.routeParams.scope || 'latest',
|
||||||
|
isShowcased: withQuery ? null : true,
|
||||||
|
tagFilter: pageContext.tagFilter,
|
||||||
|
}), {
|
||||||
|
page: Number(pageContext.routeParams.page) || 1,
|
||||||
|
limit: Number(pageContext.urlParsed.search.limit) || 29,
|
||||||
|
aggregate: withQuery,
|
||||||
|
}, pageContext.user),
|
||||||
|
getRandomCampaigns([
|
||||||
|
{ minRatio: 1.5 },
|
||||||
|
{ minRatio: 0.75, maxRatio: 1.25 },
|
||||||
|
{ minRatio: 1.5 },
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
scenes,
|
scenes,
|
||||||
aggTags,
|
aggTags,
|
||||||
|
@ -12,20 +33,10 @@ export async function onBeforeRender(pageContext) {
|
||||||
aggActors,
|
aggActors,
|
||||||
limit,
|
limit,
|
||||||
total,
|
total,
|
||||||
} = await fetchScenes(await curateScenesQuery({
|
} = sceneResults;
|
||||||
...pageContext.urlQuery,
|
|
||||||
scope: pageContext.routeParams.scope || 'latest',
|
|
||||||
isShowcased: withQuery ? null : true,
|
|
||||||
tagFilter: pageContext.tagFilter,
|
|
||||||
}), {
|
|
||||||
page: Number(pageContext.routeParams.page) || 1,
|
|
||||||
limit: Number(pageContext.urlParsed.search.limit) || 29,
|
|
||||||
aggregate: withQuery,
|
|
||||||
}, pageContext.user);
|
|
||||||
|
|
||||||
// const campaignIndex = Math.floor(Math.random() * (scenes.length - 5)) + 5;
|
|
||||||
const campaignIndex = Math.floor((Math.random() * (0.5 - 0.2) + 0.2) * scenes.length);
|
const campaignIndex = Math.floor((Math.random() * (0.5 - 0.2) + 0.2) * scenes.length);
|
||||||
const sceneCampaign = await getRandomCampaign({ minRatio: 0.75, maxRatio: 1.25 });
|
const [scopeCampaign, sceneCampaign, paginationCampaign] = campaigns;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pageContext: {
|
pageContext: {
|
||||||
|
@ -37,10 +48,12 @@ export async function onBeforeRender(pageContext) {
|
||||||
aggActors,
|
aggActors,
|
||||||
limit,
|
limit,
|
||||||
total,
|
total,
|
||||||
campaigns: {
|
},
|
||||||
index: campaignIndex,
|
campaigns: {
|
||||||
scenes: sceneCampaign,
|
index: campaignIndex,
|
||||||
},
|
scope: scopeCampaign,
|
||||||
|
scenes: scenes.length > 5 && sceneCampaign,
|
||||||
|
pagination: paginationCampaign,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,7 @@ export default {
|
||||||
'urlParsed',
|
'urlParsed',
|
||||||
'env',
|
'env',
|
||||||
'user',
|
'user',
|
||||||
|
'campaigns',
|
||||||
'meta',
|
'meta',
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,6 +15,7 @@ function curateCampaign(campaign) {
|
||||||
return {
|
return {
|
||||||
id: campaign.id,
|
id: campaign.id,
|
||||||
url: campaign.url,
|
url: campaign.url,
|
||||||
|
entity: campaign.entity && curateEntity({ ...campaign.entity, parent: campaign.parent_entity }),
|
||||||
banner: campaign.banner && {
|
banner: campaign.banner && {
|
||||||
id: campaign.banner.id,
|
id: campaign.banner.id,
|
||||||
type: campaign.banner.type,
|
type: campaign.banner.type,
|
||||||
|
@ -37,8 +38,8 @@ function curateCampaign(campaign) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getRandomCampaign(options = {}) {
|
export async function getRandomCampaign(options = {}) {
|
||||||
const rawCampaigns = await redis.hGetAll('traxxx:campaigns');
|
const campaigns = options.campaigns
|
||||||
const campaigns = Object.values(rawCampaigns).map((rawCampaign) => JSON.parse(rawCampaign));
|
|| await redis.hGetAll('traxxx:campaigns').then((rawCampaigns) => Object.values(rawCampaigns).map((rawCampaign) => JSON.parse(rawCampaign)));
|
||||||
|
|
||||||
const validCampaigns = campaigns.filter((campaign) => {
|
const validCampaigns = campaigns.filter((campaign) => {
|
||||||
if (options.minRatio && (!campaign.banner || campaign.banner.ratio < options.minRatio)) {
|
if (options.minRatio && (!campaign.banner || campaign.banner.ratio < options.minRatio)) {
|
||||||
|
@ -49,12 +50,34 @@ export async function getRandomCampaign(options = {}) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.entityIds && !options.entityIds.some((entityId) => campaign.entity.id === entityId || campaign.entity.parent?.id === entityId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const randomCampaign = validCampaigns[crypto.randomInt(validCampaigns.length)];
|
const primaryCampaigns = validCampaigns.filter((campaign) => campaign.entity.id === options.entityIds?.[0]);
|
||||||
|
|
||||||
return randomCampaign;
|
if (validCampaigns.length > 0) {
|
||||||
|
const randomCampaign = primaryCampaigns.length > 0
|
||||||
|
? primaryCampaigns[crypto.randomInt(primaryCampaigns.length)]
|
||||||
|
: validCampaigns[crypto.randomInt(validCampaigns.length)];
|
||||||
|
|
||||||
|
return randomCampaign;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getRandomCampaigns(allOptions = []) {
|
||||||
|
const rawCampaigns = await redis.hGetAll('traxxx:campaigns');
|
||||||
|
const campaigns = Object.values(rawCampaigns).map((rawCampaign) => JSON.parse(rawCampaign));
|
||||||
|
|
||||||
|
return Promise.all(allOptions.map(async (options) => getRandomCampaign({
|
||||||
|
...options,
|
||||||
|
campaigns,
|
||||||
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cacheCampaigns() {
|
export async function cacheCampaigns() {
|
||||||
|
@ -64,17 +87,29 @@ export async function cacheCampaigns() {
|
||||||
'campaigns.*',
|
'campaigns.*',
|
||||||
knex.raw('row_to_json(affiliates) as affiliate'),
|
knex.raw('row_to_json(affiliates) as affiliate'),
|
||||||
knex.raw('row_to_json(banners) as banner'),
|
knex.raw('row_to_json(banners) as banner'),
|
||||||
knex.raw('row_to_json(entities) as banner_entity'),
|
knex.raw('row_to_json(entities) as entity'),
|
||||||
knex.raw('row_to_json(parents) as banner_parent_entity'),
|
knex.raw('row_to_json(parents) as parent_entity'),
|
||||||
|
knex.raw('row_to_json(banner_entities) as banner_entity'),
|
||||||
|
knex.raw('row_to_json(banner_parents) as banner_parent_entity'),
|
||||||
knex.raw('json_agg(tags.slug) filter (where tags.id is not null) as banner_tags'),
|
knex.raw('json_agg(tags.slug) filter (where tags.id is not null) as banner_tags'),
|
||||||
)
|
)
|
||||||
.leftJoin('affiliates', 'affiliates.id', 'campaigns.affiliate_id')
|
.leftJoin('affiliates', 'affiliates.id', 'campaigns.affiliate_id')
|
||||||
.leftJoin('banners', 'banners.id', 'campaigns.banner_id')
|
.leftJoin('banners', 'banners.id', 'campaigns.banner_id')
|
||||||
.leftJoin('banners_tags', 'banners_tags.banner_id', 'banners.id')
|
.leftJoin('banners_tags', 'banners_tags.banner_id', 'banners.id')
|
||||||
.leftJoin('tags', 'tags.id', 'banners_tags.tag_id')
|
.leftJoin('tags', 'tags.id', 'banners_tags.tag_id')
|
||||||
.leftJoin('entities', 'entities.id', 'banners.entity_id')
|
.leftJoin('entities', 'entities.id', 'campaigns.entity_id')
|
||||||
.leftJoin('entities as parents', 'parents.id', 'entities.parent_id')
|
.leftJoin('entities as parents', 'parents.id', 'entities.parent_id')
|
||||||
.groupBy('campaigns.id', 'affiliates.id', 'banners.id', 'entities.id', 'parents.id');
|
.leftJoin('entities as banner_entities', 'banner_entities.id', 'banners.entity_id')
|
||||||
|
.leftJoin('entities as banner_parents', 'banner_parents.id', 'banner_entities.parent_id')
|
||||||
|
.groupBy(
|
||||||
|
'campaigns.id',
|
||||||
|
'affiliates.id',
|
||||||
|
'entities.id',
|
||||||
|
'parents.id',
|
||||||
|
'banners.id',
|
||||||
|
'banner_entities.id',
|
||||||
|
'banner_parents.id',
|
||||||
|
);
|
||||||
|
|
||||||
await redis.del('traxxx:campaigns');
|
await redis.del('traxxx:campaigns');
|
||||||
|
|
||||||
|
|
|
@ -30,16 +30,24 @@ export async function fetchEntities(options) {
|
||||||
if (options.query) {
|
if (options.query) {
|
||||||
builder.where((whereBuilder) => {
|
builder.where((whereBuilder) => {
|
||||||
whereBuilder
|
whereBuilder
|
||||||
.whereILike('entities.name', `%${options.query}%`)
|
.where((subBuilder) => {
|
||||||
.orWhereILike('entities.slug', `%${options.query}%`);
|
subBuilder
|
||||||
|
.whereILike('entities.name', `%${options.query}%`)
|
||||||
|
.orWhereILike('entities.slug', `%${options.query}%`);
|
||||||
|
})
|
||||||
|
.whereNot('entities.type', 'info');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.type === 'primary') {
|
if (options.type === 'primary') {
|
||||||
builder
|
builder
|
||||||
.where('entities.type', 'network')
|
.where((subBuilder) => {
|
||||||
.orWhere('entities.independent', true)
|
subBuilder
|
||||||
.orWhereNull('entities.parent_id');
|
.where('entities.type', 'network')
|
||||||
|
.orWhere('entities.independent', true)
|
||||||
|
.orWhereNull('entities.parent_id');
|
||||||
|
})
|
||||||
|
.whereNot('entities.type', 'info');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,8 @@ function curateScene(rawScene, assets) {
|
||||||
poster: curateMedia(assets.poster),
|
poster: curateMedia(assets.poster),
|
||||||
trailer: curateMedia(assets.trailer),
|
trailer: curateMedia(assets.trailer),
|
||||||
teaser: curateMedia(assets.teaser),
|
teaser: curateMedia(assets.teaser),
|
||||||
photos: assets.photos.map((photo) => curateMedia(photo)),
|
photos: assets.photos?.map((photo) => curateMedia(photo)) || [],
|
||||||
|
caps: assets.caps?.map((cap) => curateMedia(cap)) || [],
|
||||||
stashes: assets.stashes?.map((stash) => curateStash(stash)) || [],
|
stashes: assets.stashes?.map((stash) => curateStash(stash)) || [],
|
||||||
createdBatchId: rawScene.created_batch_id,
|
createdBatchId: rawScene.created_batch_id,
|
||||||
updatedBatchId: rawScene.updated_batch_id,
|
updatedBatchId: rawScene.updated_batch_id,
|
||||||
|
@ -92,6 +93,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
||||||
series,
|
series,
|
||||||
posters,
|
posters,
|
||||||
photos,
|
photos,
|
||||||
|
caps,
|
||||||
trailers,
|
trailers,
|
||||||
teasers,
|
teasers,
|
||||||
stashes,
|
stashes,
|
||||||
|
@ -125,24 +127,24 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
||||||
.whereNotNull('tags.id')
|
.whereNotNull('tags.id')
|
||||||
.whereIn('release_id', sceneIds)
|
.whereIn('release_id', sceneIds)
|
||||||
.orderBy('priority', 'desc'),
|
.orderBy('priority', 'desc'),
|
||||||
movies: knex('movies_scenes')
|
movies: context.includePartOf ? knex('movies_scenes')
|
||||||
.select('movies_scenes.scene_id', 'movies.*', knex.raw('json_agg(media) as movie_covers'))
|
.select('movies_scenes.scene_id', 'movies.*', knex.raw('json_agg(media) as movie_covers'))
|
||||||
.leftJoin('movies', 'movies.id', 'movies_scenes.movie_id')
|
.leftJoin('movies', 'movies.id', 'movies_scenes.movie_id')
|
||||||
.leftJoin('movies_covers', 'movies_covers.movie_id', 'movies.id')
|
.leftJoin('movies_covers', 'movies_covers.movie_id', 'movies.id')
|
||||||
.leftJoin('media', 'media.id', 'movies_covers.media_id')
|
.leftJoin('media', 'media.id', 'movies_covers.media_id')
|
||||||
.whereIn('scene_id', sceneIds)
|
.whereIn('scene_id', sceneIds)
|
||||||
.groupBy('movies.id', 'movies_scenes.scene_id'),
|
.groupBy('movies.id', 'movies_scenes.scene_id') : [],
|
||||||
series: knex('series_scenes')
|
series: context.includePartOf ? knex('series_scenes')
|
||||||
.select('series_scenes.scene_id', 'series.*', knex.raw('row_to_json(media) as serie_poster'))
|
.select('series_scenes.scene_id', 'series.*', knex.raw('row_to_json(media) as serie_poster'))
|
||||||
.leftJoin('series', 'series.id', 'series_scenes.serie_id')
|
.leftJoin('series', 'series.id', 'series_scenes.serie_id')
|
||||||
.leftJoin('series_posters', 'series_posters.serie_id', 'series.id')
|
.leftJoin('series_posters', 'series_posters.serie_id', 'series.id')
|
||||||
.leftJoin('media', 'media.id', 'series_posters.media_id')
|
.leftJoin('media', 'media.id', 'series_posters.media_id')
|
||||||
.whereIn('scene_id', sceneIds)
|
.whereIn('scene_id', sceneIds)
|
||||||
.groupBy('series.id', 'series_scenes.scene_id', 'media.*'),
|
.groupBy('series.id', 'series_scenes.scene_id', 'media.*') : [],
|
||||||
posters: knex('releases_posters')
|
posters: knex('releases_posters')
|
||||||
.whereIn('release_id', sceneIds)
|
.whereIn('release_id', sceneIds)
|
||||||
.leftJoin('media', 'media.id', 'releases_posters.media_id'),
|
.leftJoin('media', 'media.id', 'releases_posters.media_id'),
|
||||||
photos: knex.transaction(async (trx) => {
|
photos: context.includeAssets ? knex.transaction(async (trx) => {
|
||||||
if (reqUser) {
|
if (reqUser) {
|
||||||
await trx.select(knex.raw('set_config(\'user.id\', :userId, true)', { userId: reqUser.id }));
|
await trx.select(knex.raw('set_config(\'user.id\', :userId, true)', { userId: reqUser.id }));
|
||||||
}
|
}
|
||||||
|
@ -151,8 +153,18 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
||||||
.leftJoin('media', 'media.id', 'releases_photos.media_id')
|
.leftJoin('media', 'media.id', 'releases_photos.media_id')
|
||||||
.whereIn('release_id', sceneIds)
|
.whereIn('release_id', sceneIds)
|
||||||
.orderBy('index');
|
.orderBy('index');
|
||||||
}),
|
}) : [],
|
||||||
trailers: knex.transaction(async (trx) => {
|
caps: context.includeAssets ? knex.transaction(async (trx) => {
|
||||||
|
if (reqUser) {
|
||||||
|
await trx.select(knex.raw('set_config(\'user.id\', :userId, true)', { userId: reqUser.id }));
|
||||||
|
}
|
||||||
|
|
||||||
|
return trx('releases_caps')
|
||||||
|
.leftJoin('media', 'media.id', 'releases_caps.media_id')
|
||||||
|
.whereIn('release_id', sceneIds)
|
||||||
|
.orderBy('index');
|
||||||
|
}) : [],
|
||||||
|
trailers: context.includeAssets ? knex.transaction(async (trx) => {
|
||||||
if (reqUser) {
|
if (reqUser) {
|
||||||
await trx.select(knex.raw('set_config(\'user.id\', :userId, true)', { userId: reqUser.id }));
|
await trx.select(knex.raw('set_config(\'user.id\', :userId, true)', { userId: reqUser.id }));
|
||||||
}
|
}
|
||||||
|
@ -160,8 +172,8 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
||||||
return trx('releases_trailers')
|
return trx('releases_trailers')
|
||||||
.whereIn('release_id', sceneIds)
|
.whereIn('release_id', sceneIds)
|
||||||
.leftJoin('media', 'media.id', 'releases_trailers.media_id');
|
.leftJoin('media', 'media.id', 'releases_trailers.media_id');
|
||||||
}),
|
}) : [],
|
||||||
teasers: knex.transaction(async (trx) => {
|
teasers: context.includeAssets ? knex.transaction(async (trx) => {
|
||||||
if (reqUser) {
|
if (reqUser) {
|
||||||
await trx.select(knex.raw('set_config(\'user.id\', :userId, true)', { userId: reqUser.id }));
|
await trx.select(knex.raw('set_config(\'user.id\', :userId, true)', { userId: reqUser.id }));
|
||||||
}
|
}
|
||||||
|
@ -169,7 +181,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
||||||
return trx('releases_teasers')
|
return trx('releases_teasers')
|
||||||
.whereIn('release_id', sceneIds)
|
.whereIn('release_id', sceneIds)
|
||||||
.leftJoin('media', 'media.id', 'releases_teasers.media_id');
|
.leftJoin('media', 'media.id', 'releases_teasers.media_id');
|
||||||
}),
|
}) : [],
|
||||||
lastBatch: knex('batches')
|
lastBatch: knex('batches')
|
||||||
.select('id')
|
.select('id')
|
||||||
.where('showcased', true)
|
.where('showcased', true)
|
||||||
|
@ -205,6 +217,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
||||||
const sceneSeries = series.filter((serie) => serie.scene_id === sceneId);
|
const sceneSeries = series.filter((serie) => serie.scene_id === sceneId);
|
||||||
const scenePoster = posters.find((poster) => poster.release_id === sceneId);
|
const scenePoster = posters.find((poster) => poster.release_id === sceneId);
|
||||||
const scenePhotos = photos.filter((photo) => photo.release_id === sceneId);
|
const scenePhotos = photos.filter((photo) => photo.release_id === sceneId);
|
||||||
|
const sceneCaps = caps.filter((cap) => cap.release_id === sceneId);
|
||||||
const sceneTrailers = trailers.find((trailer) => trailer.release_id === sceneId);
|
const sceneTrailers = trailers.find((trailer) => trailer.release_id === sceneId);
|
||||||
const sceneTeasers = teasers.find((teaser) => teaser.release_id === sceneId);
|
const sceneTeasers = teasers.find((teaser) => teaser.release_id === sceneId);
|
||||||
const sceneStashes = stashes.filter((stash) => stash.scene_id === sceneId);
|
const sceneStashes = stashes.filter((stash) => stash.scene_id === sceneId);
|
||||||
|
@ -219,6 +232,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
||||||
series: sceneSeries,
|
series: sceneSeries,
|
||||||
poster: scenePoster,
|
poster: scenePoster,
|
||||||
photos: scenePhotos,
|
photos: scenePhotos,
|
||||||
|
caps: sceneCaps,
|
||||||
trailer: sceneTrailers,
|
trailer: sceneTrailers,
|
||||||
teaser: sceneTeasers,
|
teaser: sceneTeasers,
|
||||||
stashes: sceneStashes,
|
stashes: sceneStashes,
|
||||||
|
|
Loading…
Reference in New Issue