forked from Keelrleek/SoulStream
navigation: one glass bar for the app's life, not one per page
The bar was rendered by each view, so `<CurrentView />` swapping on every
navigation destroyed it and built a new one. Measured: the `.glassbar`
element is not the same node on either side of an artist -> album move, and
the old one is disconnected.
That broke the crumb entrance animation, which is what this was noticed
from. The `seen` set exists so only a genuinely ARRIVING crumb slides in,
and it is component state -- so it was empty on every mount and every crumb
looked new. Instrumenting Element.animate across one navigation:
AC/DC -> Highway to Hell should animate: the album
actually animated: all three crumbs
Back to AC/DC should animate: nothing
actually animated: both crumbs
So the whole trail re-flew in from the right on every page change, and Back
animated crumbs that had never left -- the exact opposite of the
direction-of-travel cue the animation was written for.
The bar is app chrome, not part of a page, so App.svelte now mounts it once
as the scroll pane's first child and pages no longer carry it. Views that
do not show it yet hide it with `display: none` rather than an {#if}: the
element leaves the layout and measures zero -- scrollbar.js reads this
bar's height to start the thumb below it, and correctly gets 0 -- while the
component stays alive and keeps its crumb memory across the round trip.
Geometry is unchanged, which the negative-margin bleed made easy to get
wrong: the bar's net flow height is zero either way, so moving it from
first-child-of-the-page to previous-sibling-of-the-page leaves the page's
top exactly where it was. Verified against the live pane -- bar top/left/
width flush with the pane and 46 high, page top at pane + 24, z-index 40
and elementFromPoint at the bar's centre still returning the bar rather
than the hero underneath.
After: arriving at an album animates only the album's own crumb, Back
animates nothing, and a trip out to Library and back animates nothing. The
backdrop-filter layer is no longer recomposited on every page change, and a
bar element can now transition between pages at all, which was impossible
when each side was a different node.
Two consequences worth stating. The resolver pulse takes the GLOBAL accent
everywhere now; on the album page it used to inherit that page's extracted
palette, because the bar sat inside `.album-page`. The artist page always
gave it the global accent, so the two now agree rather than disagreeing.
And putting the bar on the remaining pages is now widening BAR_VIEWS plus
deciding how it sits against each page's existing header -- the mounting
question is settled.
85 JS tests pass.
This commit is contained in:
1 parent
98d11a2228
commit
8017c0d877
4 files changed
+42
-10
No files matched your search
@@ -7,6 +7,7 @@
|
||||
import LoginModal from "./components/LoginModal.svelte";
|
||||
import PreviewOverlay from "./components/PreviewOverlay.svelte";
|
||||
import DebugOverlay from "./components/DebugOverlay.svelte";
|
||||
import GlassBar from "./components/GlassBar.svelte";
|
||||
import { previewUi } from "./lib/preview/previewSession.svelte.js";
|
||||
import Home from "./views/Home.svelte";
|
||||
import Search from "./views/Search.svelte";
|
||||
@@ -39,6 +40,13 @@
|
||||
};
|
||||
const CurrentView = $derived(views[ui.view] ?? Home);
|
||||
|
||||
/* The glass bar is app chrome, not part of a page, so it is mounted ONCE
|
||||
here and lives above whichever view is current — see the note at the top
|
||||
of GlassBar.svelte for what a per-view instance cost. Views that do not
|
||||
show it yet hide it; the component is never unmounted, so its crumb
|
||||
memory survives every navigation, including out to Home and back. */
|
||||
const BAR_VIEWS = new Set(["catalogArtist", "catalogAlbum"]);
|
||||
|
||||
initEvents();
|
||||
autoConnect();
|
||||
refreshLibrary();
|
||||
@@ -62,6 +70,11 @@
|
||||
The titlebar stays live for window chrome. -->
|
||||
<Sidebar />
|
||||
<main class="content" use:floatScroll inert={previewUi.open || undefined}>
|
||||
<!-- First child of the scroll pane: the bar's sticky pin and its
|
||||
negative bleed margins are measured against THIS element's
|
||||
padding, and its net flow height is zero, so the page below still
|
||||
starts exactly where it did when each view carried its own. -->
|
||||
<GlassBar hidden={!BAR_VIEWS.has(ui.view)} />
|
||||
<CurrentView />
|
||||
</main>
|
||||
<NowPlaying />
|
||||
|
||||
Reference in new issue
Block a user