← back to Wallco Ai
homepage hero: prefer photoreal room-mockup over flat tile when available (heroImageUrl helper picks /designs/room/design_<id>_<room>.png if room_mockups[] non-empty); heroDesigns() biases toward rooms-first, falls back to high-sat flat tiles to fill 6 slides
46eb2943b761cbe36f151a02d1961e58051c8a7e · 2026-05-28 11:05:33 -0700 · Steve Abrams
Files touched
Diff
commit 46eb2943b761cbe36f151a02d1961e58051c8a7e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu May 28 11:05:33 2026 -0700
homepage hero: prefer photoreal room-mockup over flat tile when available (heroImageUrl helper picks /designs/room/design_<id>_<room>.png if room_mockups[] non-empty); heroDesigns() biases toward rooms-first, falls back to high-sat flat tiles to fill 6 slides
---
server.js | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/server.js b/server.js
index e270c44..e0315ce 100644
--- a/server.js
+++ b/server.js
@@ -4708,12 +4708,29 @@ const HAMBURGER_JS = `
</script>`;
// ── Hero rotation images (highest-saturation designs, sat > 0.4)
+// Map a design row to the URL we want in the hero slot. Prefer a photoreal
+// room-mockup over the flat tile when available — Steve directive 2026-05-28
+// "use room settings for hero images". Room files served by the static route
+// at /designs/room/ from data/rooms/design_<id>_<room>.png. Falls back to the
+// flat tile (d.image_url) for designs with no rooms yet.
+function heroImageUrl(d) {
+ if (Array.isArray(d.room_mockups) && d.room_mockups.length) {
+ return '/designs/room/design_' + d.id + '_' + d.room_mockups[0] + '.png';
+ }
+ return d.image_url;
+}
function heroDesigns() {
- const h = DESIGNS
- .filter(d => d.saturation > 0.3)
- .sort((a,b) => b.saturation - a.saturation);
- // fallback: if none qualify, use all sorted by saturation
- return h.length >= 2 ? h : [...DESIGNS].sort((a,b) => b.saturation - a.saturation);
+ // Prefer designs with a photoreal room AND solid saturation. Fall back to
+ // any rooms, then to high-sat flat tiles, so the page never blanks out.
+ const withRooms = DESIGNS.filter(d => Array.isArray(d.room_mockups) && d.room_mockups.length);
+ if (withRooms.length >= 6) {
+ return withRooms.sort((a,b) => (b.saturation || 0) - (a.saturation || 0));
+ }
+ // Mix mode: pad the rooms set with high-sat flat tiles so we still hit ≥6 slides
+ const flatHi = DESIGNS.filter(d => d.saturation > 0.3 && !(Array.isArray(d.room_mockups) && d.room_mockups.length))
+ .sort((a,b) => b.saturation - a.saturation);
+ const mixed = [...withRooms, ...flatHi];
+ return mixed.length >= 2 ? mixed : [...DESIGNS].sort((a,b) => b.saturation - a.saturation);
}
// ── HOME PAGE
@@ -4777,7 +4794,7 @@ app.get('/', (req, res) => {
});
const heroSlides = heroes.slice(0, 6).map((d, i) =>
- `<div class="hero-slide ${i===0?'active':''}" data-idx="${i}" style="background-image:url('${d.image_url}');--card-bg:url('${d.image_url}')" aria-label="${d.title}"></div>`
+ `<div class="hero-slide ${i===0?'active':''}" data-idx="${i}" style="background-image:url('${heroImageUrl(d)}');--card-bg:url('${heroImageUrl(d)}')" aria-label="${d.title}"></div>`
).join('\n');
// Top categories by count — used to render the home random-rail chip strip.
@@ -4833,7 +4850,7 @@ app.get('/', (req, res) => {
// fetching during <head> parse instead of after body scan discovers the
// background-image URLs. heroes[0] is the most likely LCP candidate.
preloadImages: [
- heroes[0]?.image_url,
+ heroes[0] && heroImageUrl(heroes[0]),
...featured.slice(0, 4).map(d => d.image_url)
].filter(Boolean)
})}
← f538318 /design/:id 'Sell on Etsy' button — go one-click force-add b
·
back to Wallco Ai
·
/designs grid bulk-action: scrub URL creds on fetch — same f 223088a →