diff --git a/components/actors/tile.vue b/components/actors/tile.vue
index ad7ad2a..940a48a 100644
--- a/components/actors/tile.vue
+++ b/components/actors/tile.vue
@@ -104,6 +104,7 @@ const favorited = ref(props.actor.stashes.some((actorStash) => actorStash.id ===
border-radius: .25rem;
box-shadow: 0 0 3px var(--shadow-weak-30);
overflow: hidden;
+ background: var(--background);
&:hover {
box-shadow: 0 0 3px var(--shadow-weak-20);
diff --git a/components/campaigns/campaign.vue b/components/campaigns/campaign.vue
new file mode 100644
index 0000000..1463a4c
--- /dev/null
+++ b/components/campaigns/campaign.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
diff --git a/components/entities/tile.vue b/components/entities/tile.vue
index 0cc583c..ec289ec 100644
--- a/components/entities/tile.vue
+++ b/components/entities/tile.vue
@@ -5,7 +5,7 @@
>
@@ -33,7 +33,7 @@ defineProps({
box-sizing: border-box;
padding: 1rem;
border-radius: .5rem;
- background: var(--shadow-strong-40);
+ background: var(--shadow-strong-30);
color: var(--text-light);
font-size: 1.25rem;
font-weight: bold;
diff --git a/components/header/header.vue b/components/header/header.vue
index 38828f7..d125b63 100644
--- a/components/header/header.vue
+++ b/components/header/header.vue
@@ -438,7 +438,7 @@ function blurSearch(event) {
width: 1.25rem;
padding-left: 1rem;
height: 100%;
- fill: var(--glass-strong-20);
+ fill: var(--glass);
}
.notifs-trigger {
diff --git a/components/scenes/scenes.vue b/components/scenes/scenes.vue
index 09ffda0..a801cd4 100644
--- a/components/scenes/scenes.vue
+++ b/components/scenes/scenes.vue
@@ -105,12 +105,21 @@
(index === campaignIndex ? ['campaign', scene] : scene));
+
function getPath(targetScope, preserveQuery) {
const path = parse(routeParams.path).map((segment) => {
if (segment.name === 'scope') {
diff --git a/pages/auth/login/+Page.vue b/pages/auth/login/+Page.vue
index ea5154e..614fbef 100644
--- a/pages/auth/login/+Page.vue
+++ b/pages/auth/login/+Page.vue
@@ -115,7 +115,7 @@ async function login() {
}
onMounted(() => {
- userInput.value.focus();
+ userInput.value?.focus();
});
diff --git a/pages/entities/+Page.vue b/pages/entities/+Page.vue
index 26ab213..6b02907 100644
--- a/pages/entities/+Page.vue
+++ b/pages/entities/+Page.vue
@@ -87,6 +87,7 @@ const popularNetworks = [
'hussiepass',
'julesjordan',
'kink',
+ 'mikeadriano',
'mofos',
'naughtyamerica',
'newsensations',
diff --git a/pages/scene/+Page.vue b/pages/scene/+Page.vue
index 943a171..4a12209 100644
--- a/pages/scene/+Page.vue
+++ b/pages/scene/+Page.vue
@@ -709,6 +709,7 @@ function copySummary() {
.detail {
display: flex;
align-items: stretch;
+ flex-direction: row;
}
.input {
diff --git a/pages/updates/+onBeforeRender.js b/pages/updates/+onBeforeRender.js
index d437bb2..056ca50 100644
--- a/pages/updates/+onBeforeRender.js
+++ b/pages/updates/+onBeforeRender.js
@@ -1,5 +1,6 @@
import { fetchScenes } from '#/src/scenes.js';
import { curateScenesQuery } from '#/src/web/scenes.js';
+import { getRandomCampaign } from '#/src/campaigns.js';
export async function onBeforeRender(pageContext) {
const withQuery = Object.hasOwn(pageContext.urlParsed.search, 'q');
@@ -18,10 +19,14 @@ export async function onBeforeRender(pageContext) {
tagFilter: pageContext.tagFilter,
}), {
page: Number(pageContext.routeParams.page) || 1,
- limit: Number(pageContext.urlParsed.search.limit) || 30,
+ 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 sceneCampaign = await getRandomCampaign({ minRatio: 0.75, maxRatio: 1.25 });
+
return {
pageContext: {
title: pageContext.routeParams.scope,
@@ -32,6 +37,10 @@ export async function onBeforeRender(pageContext) {
aggActors,
limit,
total,
+ campaigns: {
+ index: campaignIndex,
+ scenes: sceneCampaign,
+ },
},
},
};
diff --git a/src/campaigns.js b/src/campaigns.js
new file mode 100644
index 0000000..5577332
--- /dev/null
+++ b/src/campaigns.js
@@ -0,0 +1,47 @@
+import { knexOwner as knex } from './knex.js';
+import { curateEntity } from './entities.js';
+
+function curateCampaign(campaign) {
+ if (!campaign) {
+ return null;
+ }
+
+ return {
+ id: campaign.id,
+ url: campaign.url,
+ banner: campaign.banner && {
+ id: campaign.banner.id,
+ type: campaign.banner.type,
+ entity: campaign.banner_entity && curateEntity({ ...campaign.banner_entity, parent: campaign.banner_parent_entity }),
+ tags: campaign.banner_tags?.map((tag) => ({
+ id: tag.id,
+ slug: tag.slug,
+ name: tag.name,
+ })) || [],
+ },
+ affiliateId: campaign.affiliate_id,
+ };
+}
+
+export async function getRandomCampaign(options = {}) {
+ const campaign = await knex.raw(`
+ SELECT
+ campaigns.*, row_to_json(banners) as banner, row_to_json(entities) as banner_entity, row_to_json(parents) as banner_parent_entity, json_agg(tags) filter (where tags.id is not null) as banner_tags
+ FROM campaigns
+ LEFT JOIN banners ON banners.id = campaigns.banner_id
+ LEFT JOIN banners_tags ON banners_tags.banner_id = banners.id
+ LEFT JOIN tags ON tags.id = banners_tags.tag_id
+ LEFT JOIN entities ON entities.id = banners.entity_id
+ LEFT JOIN entities as parents ON parents.id = entities.parent_id
+ WHERE campaigns.banner_id IS NOT NULL
+ AND ratio >= :minRatio
+ AND ratio <= :maxRatio
+ GROUP BY campaigns.id, banners.id, entities.id, parents.id
+ ORDER BY RANDOM()
+ `, {
+ minRatio: options.minRatio || 0,
+ maxRatio: options.maxRatio || 1000,
+ });
+
+ return curateCampaign(campaign.rows[0]);
+}
diff --git a/static b/static
index 31759c4..24d1136 160000
--- a/static
+++ b/static
@@ -1 +1 @@
-Subproject commit 31759c4a58d789bf6cfa7c96cdae32af42bdf86c
+Subproject commit 24d11363ef7632591ec6f49240079259f777ab9e