video discover: language preference UI (multi-select chips)
A 🌐 multi-select chip row in the Discover toolbar (EN/KO/JA/ES/FR/HI/DE/IT) to pick which
original languages appear in the general/curated rails. Loads the current preference from
/discover/languages, toggling a chip POSTs the new set and rebuilds the rails (never empty —
at least one stays on). Extracted reloadRails() (now shared by the hide-owned toggle + language
chips). Default EN, so the rails are English unless you opt more in.
This commit is contained in:
parent
28fe3d2b0b
commit
f1b6fd5e31
3 changed files with 53 additions and 6 deletions
|
|
@ -1051,6 +1051,17 @@
|
|||
<input type="checkbox" data-vdsc-hideowned>
|
||||
<span>Hide owned</span>
|
||||
</label>
|
||||
<div class="vdsc-langs" data-vdsc-langs aria-label="Rail languages" title="Which original languages show in the general rails">
|
||||
<span class="vdsc-langs-label">🌐</span>
|
||||
<button class="vdsc-lang vdsc-lang--on" type="button" data-lang="en">EN</button>
|
||||
<button class="vdsc-lang" type="button" data-lang="ko">KO</button>
|
||||
<button class="vdsc-lang" type="button" data-lang="ja">JA</button>
|
||||
<button class="vdsc-lang" type="button" data-lang="es">ES</button>
|
||||
<button class="vdsc-lang" type="button" data-lang="fr">FR</button>
|
||||
<button class="vdsc-lang" type="button" data-lang="hi">HI</button>
|
||||
<button class="vdsc-lang" type="button" data-lang="de">DE</button>
|
||||
<button class="vdsc-lang" type="button" data-lang="it">IT</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vdsc-chips" data-vdsc-chipset="genre" aria-label="Genre">
|
||||
<button class="vdsc-chip vdsc-chip--on" type="button" data-val="">All genres</button>
|
||||
|
|
|
|||
|
|
@ -333,6 +333,14 @@
|
|||
.catch(function () { /* best-effort */ });
|
||||
}
|
||||
|
||||
// Rebuild the whole rail stack (genre/curated shelves + the prepended personalized rows).
|
||||
function reloadRails() {
|
||||
renderShelves();
|
||||
loadMoreLike();
|
||||
loadGaps();
|
||||
loadForYou();
|
||||
}
|
||||
|
||||
// ── shelves (lazy rails) ──────────────────────────────────────────────────
|
||||
function renderShelves() {
|
||||
var host = $('[data-vdsc-shelves]'); if (!host) return;
|
||||
|
|
@ -546,12 +554,30 @@
|
|||
hide.addEventListener('change', function () {
|
||||
page.classList.toggle('vdsc-hide-owned', hide.checked);
|
||||
try { localStorage.setItem('vdsc_hideowned', hide.checked ? '1' : '0'); } catch (e) { /* ignore */ }
|
||||
// The rails are now server-filtered for owned (and page deeper), so rebuild
|
||||
// them with the new state instead of just CSS-hiding cards in place.
|
||||
renderShelves();
|
||||
loadMoreLike();
|
||||
loadGaps();
|
||||
loadForYou();
|
||||
reloadRails(); // rails are server-filtered now (owned + paged deeper) — rebuild
|
||||
});
|
||||
}
|
||||
// Rail language preference — multi-select chips, persisted server-side; rebuilds the rails.
|
||||
var langWrap = $('[data-vdsc-langs]');
|
||||
if (langWrap) {
|
||||
fetch('/api/video/discover/languages', { headers: { Accept: 'application/json' } })
|
||||
.then(function (r) { return r.ok ? r.json() : null; })
|
||||
.then(function (d) {
|
||||
var set = {}; ((d && d.languages) || ['en']).forEach(function (c) { set[c] = 1; });
|
||||
langWrap.querySelectorAll('.vdsc-lang').forEach(function (b) {
|
||||
b.classList.toggle('vdsc-lang--on', !!set[b.getAttribute('data-lang')]);
|
||||
});
|
||||
}).catch(function () { /* default chip state stands */ });
|
||||
langWrap.addEventListener('click', function (e) {
|
||||
var btn = e.target.closest('.vdsc-lang'); if (!btn) return;
|
||||
btn.classList.toggle('vdsc-lang--on');
|
||||
var langs = Array.prototype.map.call(langWrap.querySelectorAll('.vdsc-lang--on'),
|
||||
function (b) { return b.getAttribute('data-lang'); });
|
||||
if (!langs.length) { btn.classList.add('vdsc-lang--on'); return; } // never allow empty
|
||||
fetch('/api/video/discover/languages', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ languages: langs }),
|
||||
}).then(function () { reloadRails(); }).catch(function () { /* ignore */ });
|
||||
});
|
||||
}
|
||||
// Infinite scroll: a sentinel near the grid bottom pulls the next page.
|
||||
|
|
|
|||
|
|
@ -2354,6 +2354,16 @@ body[data-side="video"] #soulsync-toggle { display: none; }
|
|||
.vdsc-toggle input { accent-color: rgb(var(--accent-rgb, 88 101 242)); width: 16px; height: 16px; cursor: pointer; }
|
||||
.vdsc-hide-owned .vsr-card--owned { display: none; }
|
||||
|
||||
/* rail-language preference chips — which original languages show in the general rails */
|
||||
.vdsc-langs { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-left: 14px; }
|
||||
.vdsc-langs-label { font-size: 13px; opacity: 0.6; }
|
||||
.vdsc-lang { font-size: 11px; font-weight: 700; letter-spacing: 0.3px; padding: 3px 8px; border-radius: 999px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.12); background: rgba(255, 255, 255, 0.04);
|
||||
color: rgba(255, 255, 255, 0.5); cursor: pointer;
|
||||
transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease; }
|
||||
.vdsc-lang:hover { color: rgba(255, 255, 255, 0.85); }
|
||||
.vdsc-lang--on { color: #fff; background: rgba(var(--accent-rgb, 88 101 242), 0.85); border-color: transparent; }
|
||||
|
||||
/* rails: a gentle fade-in when filled + per-title hue on hover */
|
||||
.vdsc-shelf--in .vdsc-rail { animation: vdscFade 0.45s ease both; }
|
||||
@keyframes vdscFade { from { opacity: 0.35; } to { opacity: 1; } }
|
||||
|
|
|
|||
Loading…
Reference in a new issue