From 530995dd025cf09940b13e912b3c9c9670f31398 Mon Sep 17 00:00:00 2001 From: Byron Gamatos Date: Mon, 22 Jun 2026 11:26:52 +0200 Subject: [PATCH] fix(v3): scope song search to the library + keep it above the toolbar on scroll (#560) The topbar search (#v3-search) rendered on every screen and, on the library screen, was hidden behind the filter toolbar while scrolling (both were sticky top-0 z-20 in the #v3-main scroller). - shell.js: wrap the search in #v3-search-wrap (hidden by default) and toggle it in syncActive() so it only shows on #v3-songs; bump the topbar to z-30 so it always sits above the toolbar. - songs.js: drop the toolbar's top-0 and pin it beneath the topbar by measuring the topbar height (positionToolbar). A ResizeObserver on #v3-topbar keeps the offset correct as the topbar height changes (viewport width, search show/hide) and fixes the initial position regardless of render()/syncActive() ordering. Fixes #559 Co-authored-by: Claude Opus 4.8 (1M context) --- static/v3/shell.js | 11 +++++++++-- static/v3/songs.js | 31 ++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/static/v3/shell.js b/static/v3/shell.js index f6ba206..582fb42 100644 --- a/static/v3/shell.js +++ b/static/v3/shell.js @@ -112,6 +112,10 @@ el.classList.toggle('text-fb-textDim', !on); }); setTopbarTitle(titleFor(screenId)); + // Show the song search only on the library screen. Everywhere else the + // box is irrelevant (and would silently no-op against v3Songs.search). + const searchWrap = document.getElementById('v3-search-wrap'); + if (searchWrap) searchWrap.classList.toggle('hidden', screenId !== 'v3-songs'); // NOTE: we deliberately do NOT reflect the screen into location.hash on // every navigation. app.js's audio 'error' handler suppresses empty-src // errors only when `audio.src === window.location.href`; a `#/...` @@ -173,13 +177,16 @@ function renderTopbar() { const bar = document.getElementById('v3-topbar'); if (!bar) return; - bar.className = 'sticky top-0 z-20 bg-fb-sidebar/80 backdrop-blur'; + bar.className = 'sticky top-0 z-30 bg-fb-sidebar/80 backdrop-blur'; bar.innerHTML = // Row 1 — top utility bar: search. '
' + '' + - '
' + + // Search is scoped to the library — syncActive() toggles `hidden` on + // this wrapper so it only shows on the v3-songs screen. It lives in + // the sticky topbar, so it stays put while the song grid scrolls. + '