Fix player UI: sports Highlights pane, scrubber knob, volume knob, description + save-to-playlist

Player/UI fixes:
- Sports (match) Highlights pane: move the toggle click-handler script out of
  the always-false @if(false ...) legacy block so the "Highlights" button opens,
  and emit videoId/isOwner with @json instead of {{ json_encode() }} (escaped
  quotes crashed the data/tab/CRUD block once route keys became hashid strings).
- Progress scrubber knob (video + audio players): center on the track line with
  translate(-50%, -50%); drop the margin-top hack that floated it above the line.
- Music player volume: give the slider wrap height so overflow:hidden no longer
  crops the knob; add a subtle thumb shadow for visibility.
- Music language menu: cap height to available space above the header, sticky
  header, internal scroll; keep controls from auto-hiding while the menu is open.
- Description box: re-check "Show more" overflow at every settle point (fonts,
  images, rAF, tab reopen) so SPA autonext keeps the expand button.

Also bundles pending work: save-to-playlist button component, playlist/channel
views, PlaylistController + NasSyncService, and component-usage tracker updates.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
ghassanandClaude Opus 4.8 committed 2026-07-28 22:12:58 +03:00
1 parent 80948efff7
commit 6b43a7060a
14 files changed
+236 -136

No files matched your search

@@ -95,6 +95,9 @@ function switchVdbTab(panelId, btn) {
document.querySelectorAll('.vdb-panel').forEach(p => p.classList.remove('active'));
btn.classList.add('active');
document.getElementById(panelId).classList.add('active');
// About just became visible — re-measure now that its panel is laid out, since
// a measurement taken while it was display:none would have read 0.
if (panelId === 'vdb-about' && window._vdbScheduleOverflowCheck) window._vdbScheduleOverflowCheck();
if (panelId === 'vdb-insights') {
const panel = document.getElementById('vdb-insights');
const currentUrl = panel && panel.dataset.insightsBase;
@@ -128,7 +131,13 @@ function _vdbApplyActiveTab() {
(function _vdbWatchSwaps() {
const wrap = document.getElementById('vdbWrap');
if (!wrap || wrap._vdbTabObserver) return;
const obs = new MutationObserver(() => _vdbApplyActiveTab());
const obs = new MutationObserver(() => {
_vdbApplyActiveTab();
// The swap replaced the description markup — re-evaluate the "Show more"
// button once layout/fonts/images settle. Central here so every SPA swap
// path is covered, not just the ones that remember to call it themselves.
if (window._vdbScheduleOverflowCheck) window._vdbScheduleOverflowCheck();
});
obs.observe(wrap, { childList: true, subtree: false });
wrap._vdbTabObserver = obs;
})();
@@ -147,9 +156,25 @@ function _vdbCheckOverflow() {
const d = document.getElementById('vdbDescShort'), b = document.getElementById('vdbShowMore');
if (!d || !b) return;
if (d.classList.contains('vdb-expanded')) { b.style.display = 'flex'; return; }
// If the About panel isn't laid out yet (e.g. Insights tab active, or mid-swap),
// scrollHeight reads 0 — don't hide the button on a bogus zero measurement.
if (d.scrollHeight === 0) return;
b.style.display = (d.scrollHeight > 138) ? 'flex' : 'none';
}
document.addEventListener('DOMContentLoaded', _vdbCheckOverflow);
window.addEventListener('load', _vdbCheckOverflow);
// A single measurement right after an SPA swap is unreliable: web-fonts, images
// inside the description, and panel layout can all change the height a beat later,
// each of which flips whether the clamp overflows. Re-check at every settling point.
window._vdbScheduleOverflowCheck = window._vdbScheduleOverflowCheck || function () {
requestAnimationFrame(_vdbCheckOverflow);
setTimeout(_vdbCheckOverflow, 120);
setTimeout(_vdbCheckOverflow, 400);
if (document.fonts && document.fonts.ready) document.fonts.ready.then(_vdbCheckOverflow);
const d = document.getElementById('vdbDescShort');
if (d) d.querySelectorAll('img').forEach(function (img) {
if (!img.complete) img.addEventListener('load', _vdbCheckOverflow, { once: true });
});
};
document.addEventListener('DOMContentLoaded', window._vdbScheduleOverflowCheck);
window.addEventListener('load', window._vdbScheduleOverflowCheck);
</script>
@endif