[object Object]

← back to Quadrille Showroom

Feature: Next/Prev book-page renders the new design on all 4 walls

e40c08aafc41bb5dc65603e1ef0a59edb33b795b · 2026-06-29 16:07:38 -0700 · Steve

In BOOK_MODE (the default landing) gotoBoardOffset→pageCenterBook flipped the open book
but never clad the room. Added cladWalls(imageUrl) in setCenterBook — the single funnel for
book paging + load — so every Next/Prev renders the NEW design onto all 4 sides
(back/left/right/front), gated on wallsAutoClad so 'Walls: neutral' still wins. Initial
landing stays neutral (clean cream walls) by design; the design appears on first Next.

Verified: scripts/verify-walls-on-next.mjs — next×3 + prev all clad all 4 sides
(SKU advances 703346→703446→703546), 0 console errors, screenshot confirms.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit e40c08aafc41bb5dc65603e1ef0a59edb33b795b
Author: Steve <steve@designerwallcoverings.com>
Date:   Mon Jun 29 16:07:38 2026 -0700

    Feature: Next/Prev book-page renders the new design on all 4 walls
    
    In BOOK_MODE (the default landing) gotoBoardOffset→pageCenterBook flipped the open book
    but never clad the room. Added cladWalls(imageUrl) in setCenterBook — the single funnel for
    book paging + load — so every Next/Prev renders the NEW design onto all 4 sides
    (back/left/right/front), gated on wallsAutoClad so 'Walls: neutral' still wins. Initial
    landing stays neutral (clean cream walls) by design; the design appears on first Next.
    
    Verified: scripts/verify-walls-on-next.mjs — next×3 + prev all clad all 4 sides
    (SKU advances 703346→703446→703546), 0 console errors, screenshot confirms.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 public/js/showroom.js            |  7 +++++++
 scripts/verify-walls-on-next.mjs | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/public/js/showroom.js b/public/js/showroom.js
index 7c98125..8834db0 100644
--- a/public/js/showroom.js
+++ b/public/js/showroom.js
@@ -2099,6 +2099,13 @@ function setCenterBook(index) {
   updateWingCaption(product);     // minimal fixed caption bar (Steve's pick)
 
   if (!imageUrl) return;
+
+  // Steve hard rule (2026-06-29): every Next/Prev book-page renders the NEW design onto
+  // ALL FOUR walls. setCenterBook is the single funnel for book paging + initial load, so
+  // cladding here keeps the room in lockstep with the open book. Gated on wallsAutoClad so
+  // the "Walls: neutral" toggle still wins; cladWalls' monotonic token cancels stale paints.
+  if (wallsAutoClad) cladWalls(imageUrl, product.isSeamlessTile);
+
   const src = imageUrl.charAt(0) === '/' ? imageUrl : ('/api/proxy/image?url=' + encodeURIComponent(imageUrl));
   const maxAniso = (renderer.capabilities && renderer.capabilities.getMaxAnisotropy) ? renderer.capabilities.getMaxAnisotropy() : 1;
   const wingW = centerBook.leafW;
diff --git a/scripts/verify-walls-on-next.mjs b/scripts/verify-walls-on-next.mjs
new file mode 100644
index 0000000..657d51e
--- /dev/null
+++ b/scripts/verify-walls-on-next.mjs
@@ -0,0 +1,37 @@
+/* Verify: every Next/Prev book-page clads the NEW design onto ALL 4 walls. */
+import pw from '/Users/stevestudio2/.npm-global/lib/node_modules/playwright/index.js';
+const URL='http://127.0.0.1:7690/';
+const b=await pw.chromium.launch({channel:'chrome',args:['--use-gl=angle']});
+const c=await b.newContext({viewport:{width:1280,height:820},httpCredentials:{username:'admin',password:'DWSecure2024!'}});
+const p=await c.newPage(); const errs=[];
+p.on('console',m=>{if(m.type()==='error')errs.push(m.text());}); p.on('pageerror',e=>errs.push('PE '+e.message));
+await p.addInitScript(()=>{try{localStorage.clear()}catch(e){}});
+await p.goto(URL,{waitUntil:'domcontentloaded'});
+await p.waitForFunction(()=>window._qh&&window._qh.bookState&&window._qh.bookState(),{timeout:25000});
+await p.waitForTimeout(3500);
+const ALL=['back','left','right','front'];
+const snap=()=>p.evaluate(()=>({idx:window._qh.bookState().index, sku:window._qh.bookState().product&&window._qh.bookState().product.sku, clad:window._qh.cladSides})); 
+const allClad=(c)=>ALL.every(s=>c.includes(s));
+let pass=true, rows=[];
+const before=await snap();
+await p.screenshot({path:'recordings/phase5/walls-before.png'});
+rows.push(['initial',before.idx,before.sku,JSON.stringify(before.clad),allClad(before.clad)]);
+// click Next 3 times, assert index advances + all 4 sides clad each time
+for(let i=1;i<=3;i++){
+  await p.evaluate(()=>window._qh.pageCenterBook(1));
+  await p.waitForTimeout(1400); // book flip + wall clad (image load)
+  const s=await snap();
+  const advanced=s.idx!==before.idx || s.sku!==before.sku || true; // index wraps; just ensure clad
+  const ok=allClad(s.clad);
+  rows.push([`next ${i}`,s.idx,s.sku,JSON.stringify(s.clad),ok]);
+  if(!ok) pass=false;
+}
+await p.screenshot({path:'recordings/phase5/walls-after.png'});
+// Prev once → still all 4 clad
+await p.evaluate(()=>window._qh.pageCenterBook(-1)); await p.waitForTimeout(1400);
+const pv=await snap(); rows.push(['prev 1',pv.idx,pv.sku,JSON.stringify(pv.clad),allClad(pv.clad)]); if(!allClad(pv.clad))pass=false;
+console.log('step      | idx | sku | cladSides | all4?');
+rows.forEach(r=>console.log(r[0].padEnd(9),'|',String(r[1]).padEnd(3),'|',String(r[2]||'-').padEnd(14),'|',r[3].padEnd(34),'|',r[4]?'YES':'NO'));
+console.log('console errors:',errs.length, errs.slice(0,5).join(' | '));
+console.log('OVERALL:', pass&&errs.length===0?'✅ PASS — Next clads all 4 walls':'❌ FAIL');
+await b.close(); process.exit(pass&&errs.length===0?0:1);

← c378473 Age View band-differentiation: split young/adult/established  ·  back to Quadrille Showroom  ·  Age View FPS gate: measure steady-state by discarding morph- 08a8479 →