video discover: stop duplicate 'Recommended for you' rows stacking on rail rebuild
Toggling service/language chips calls reloadRails(), which clears the shelves synchronously but the personalized loaders (foryou/gaps/morelike) fetch async and insertAdjacentHTML afterbegin. Rapid re-toggles let superseded in-flight fetches prepend anyway -> N 'Recommended for you' rows piled up. Each rebuild now bumps state.railGen and every loader bails if its captured gen is stale before prepending; chip-driven rebuilds are also debounced (350ms) so multi-select coalesces into one rebuild. The 'On your streaming services' rail itself was building fine - it was just buried under the duplicates.
This commit is contained in:
parent
cd29239b2f
commit
4f24ac2733
1 changed files with 17 additions and 2 deletions
|
|
@ -383,9 +383,11 @@
|
|||
|
||||
// ── "More like <owned title>" rails (pre-filled, prepended above the stack) ─
|
||||
function loadMoreLike() {
|
||||
var gen = state.railGen || 0;
|
||||
fetch('/api/video/discover/morelike', { headers: { Accept: 'application/json' } })
|
||||
.then(function (r) { return r.ok ? r.json() : null; })
|
||||
.then(function (d) {
|
||||
if (gen !== (state.railGen || 0)) return; // a newer rebuild superseded this
|
||||
var rails = (d && d.rails) || [];
|
||||
var host = $('[data-vdsc-shelves]');
|
||||
if (!rails.length || !host) return;
|
||||
|
|
@ -411,9 +413,11 @@
|
|||
// ── "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() {
|
||||
var gen = state.railGen || 0;
|
||||
fetch('/api/video/discover/gaps', { headers: { Accept: 'application/json' } })
|
||||
.then(function (r) { return r.ok ? r.json() : null; })
|
||||
.then(function (d) {
|
||||
if (gen !== (state.railGen || 0)) return; // a newer rebuild superseded this
|
||||
var rails = (d && d.rails) || [];
|
||||
var host = $('[data-vdsc-shelves]');
|
||||
if (!rails.length || !host) return;
|
||||
|
|
@ -438,9 +442,11 @@
|
|||
|
||||
// ── "Recommended for you" — one wall blended from across your library, prepended on top ─
|
||||
function loadForYou() {
|
||||
var gen = state.railGen || 0;
|
||||
fetch('/api/video/discover/foryou', { headers: { Accept: 'application/json' } })
|
||||
.then(function (r) { return r.ok ? r.json() : null; })
|
||||
.then(function (d) {
|
||||
if (gen !== (state.railGen || 0)) return; // a newer rebuild superseded this
|
||||
var items = (d && d.items) || [];
|
||||
var host = $('[data-vdsc-shelves]');
|
||||
if (items.length < 6 || !host) return;
|
||||
|
|
@ -462,12 +468,21 @@
|
|||
}
|
||||
|
||||
// Rebuild the whole rail stack (genre/curated shelves + the prepended personalized rows).
|
||||
// Each rebuild bumps railGen; in-flight personalized loaders from a superseded rebuild check
|
||||
// it before prepending, so rapid re-toggles can't stack duplicate "Recommended for you" rows.
|
||||
function reloadRails() {
|
||||
state.railGen = (state.railGen || 0) + 1;
|
||||
renderShelves();
|
||||
loadMoreLike();
|
||||
loadGaps();
|
||||
loadForYou();
|
||||
}
|
||||
// Coalesce rapid chip toggles (e.g. picking 3 services) into a single rebuild.
|
||||
var _reloadTimer;
|
||||
function reloadRailsSoon() {
|
||||
clearTimeout(_reloadTimer);
|
||||
_reloadTimer = setTimeout(reloadRails, 350);
|
||||
}
|
||||
|
||||
// ── shelves (lazy rails) ──────────────────────────────────────────────────
|
||||
function renderShelves() {
|
||||
|
|
@ -727,7 +742,7 @@
|
|||
fetch('/api/video/discover/languages', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ languages: langs }),
|
||||
}).then(function () { reloadRails(); }).catch(function () { /* ignore */ });
|
||||
}).then(function () { reloadRailsSoon(); }).catch(function () { /* ignore */ });
|
||||
});
|
||||
}
|
||||
// 'My streaming services' preference — multi-select; drives the 'On your services' rail.
|
||||
|
|
@ -752,7 +767,7 @@
|
|||
fetch('/api/video/discover/providers-pref', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ providers: provs }),
|
||||
}).then(function () { reloadRails(); }).catch(function () { /* ignore */ });
|
||||
}).then(function () { reloadRailsSoon(); }).catch(function () { /* ignore */ });
|
||||
});
|
||||
}
|
||||
// Infinite scroll: a sentinel near the grid bottom pulls the next page.
|
||||
|
|
|
|||
Loading…
Reference in a new issue