From a8ce359cb764a991337fa445902f670d5008690c Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Mon, 22 Jun 2026 23:30:05 -0700 Subject: [PATCH] video discover phase 1e: 'what am I missing' gap rails on the discover page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit loadGaps() fetches /discover/gaps and prepends the gap rails ('Complete the ', 'More from ') above the rail stack, mirroring loadMoreLike. Cards are the standard un-owned TMDB cards — already actionable (VideoGet add-to-watchlist/get), so a missing franchise entry or director film is one click from your queue. Best-effort/additive. --- webui/static/video/video-discover.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/webui/static/video/video-discover.js b/webui/static/video/video-discover.js index d055c866..dd058cb3 100644 --- a/webui/static/video/video-discover.js +++ b/webui/static/video/video-discover.js @@ -273,6 +273,33 @@ .catch(function () { /* personalization is best-effort */ }); } + // ── "What am I missing?" gap rails — franchises you've started but not finished, + // and more from the directors/creators you own the most (prepended on top). ── + function loadGaps() { + fetch('/api/video/discover/gaps', { headers: { Accept: 'application/json' } }) + .then(function (r) { return r.ok ? r.json() : null; }) + .then(function (d) { + var rails = (d && d.rails) || []; + var host = $('[data-vdsc-shelves]'); + if (!rails.length || !host) return; + var html = rails.map(function (rl) { + return '
' + + '
' + + '

' + esc(rl.title) + '

' + + '
' + + '' + + '' + + '
' + + '
' + + '
' + (rl.items || []).map(card).join('') + '
' + + '
'; + }).join(''); + host.insertAdjacentHTML('afterbegin', html); + hydrateGet(host); + }) + .catch(function () { /* gaps are best-effort */ }); + } + // ── shelves (lazy rails) ────────────────────────────────────────────────── function renderShelves() { var host = $('[data-vdsc-shelves]'); if (!host) return; @@ -517,6 +544,7 @@ renderGenreChips(); renderShelves(); loadMoreLike(); // prepend personalized 'More like…' rails when ready + loadGaps(); // prepend 'what am I missing' (franchise + person) gap rails }); } function showEmpty() {