From 5b6ef295f85c32b0a7b18b643c57eb2bf7075ea1 Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Mon, 15 Jun 2026 16:55:00 -0700 Subject: [PATCH] =?UTF-8?q?Video=20detail:=20trailer=20billboard=20reveals?= =?UTF-8?q?=20with=20a=20left=E2=86=92right=20wipe=20+=20fade?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the flat opacity crossfade with a soft, feathered left→right wipe of the trailer in (mask via @property, falls back to crossfade) — "a rollover and a fade". The wipe now fires ONLY when YouTube reports PLAYING (handshake + state events), not on a blind timer, with a 4.5s safety net. When the trailer ENDS the original backdrop fades back in and the iframe is torn down. --- webui/static/video/video-detail.js | 44 ++++++++++++++++++++++++++++-- webui/static/video/video-side.css | 29 ++++++++++++++++++-- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/webui/static/video/video-detail.js b/webui/static/video/video-detail.js index d429510e..c7503641 100644 --- a/webui/static/video/video-detail.js +++ b/webui/static/video/video-detail.js @@ -724,6 +724,7 @@ // ── billboard autoplay trailer (opt-in setting) ─────────────────────────── var prefs = null, bbTrailerTimer = null, bbMuted = true; + var bbMsgHandler = null, bbRevealTimer = null; function loadPrefs(cb) { if (prefs) { cb(prefs); return; } fetch('/api/video/prefs', { headers: { 'Accept': 'application/json' } }) @@ -745,6 +746,7 @@ function startBillboardTrailer(key) { var bb = q('.vd-billboard'); if (!bb || bb.querySelector('[data-vd-bb-trailer]')) return; bbMuted = true; + bb.classList.remove('vd-billboard--restoring'); var wrap = document.createElement('div'); wrap.className = 'vd-bb-trailer'; wrap.setAttribute('data-vd-bb-trailer', ''); wrap.innerHTML = '