Phase 2C WIP: PreviewOverlay modal + root integration (reel centering bug)
Working: - PreviewOverlay.svelte mounted at app root; opens over a fixture manifest (window.__previewFixture(n) in dev), inert background, player bar hidden, focus trap, keyboard nav, F3 rail, T3 swaps, R1b capsule, accent extraction. - previewSession.svelte.js: store + service wiring (production + fixture). - Root integration in App.svelte; revision-gateway bumps + notePlaybackGeneration threaded through state.svelte.js player entry points; api.win guarded so plain vite browser mounts. - Launcher on the artist page builds a real artist manifest and opens the modal with a play-full starter. - 70 JS tests still green. Two bugs found and fixed during bring-up: - effect_update_depth_exceeded: bleed-crossfade and bump effects read AND wrote the same $state; wrapped writes in untrack(). This loop was breaking Svelte's scheduler globally (even ui.* stopped reacting). - accentFromImage now sets crossOrigin for remote covers. KNOWN BROKEN (handoff): reel vertical centering. The active card stays centred at index 0 but drifts by one stride per step. Root cause isolated — see TODO-Feature-Docs/scrollable-track-previews/HANDOFF-PHASE2C.md.
This commit is contained in:
1 parent
8cb3cd593b
commit
d051f0db28
7 files changed
+1492
-16
No files matched your search
+36
-3
@@ -5,6 +5,8 @@
|
||||
import NowPlaying from "./components/NowPlaying.svelte";
|
||||
import ArtworkViewer from "./components/ArtworkViewer.svelte";
|
||||
import LoginModal from "./components/LoginModal.svelte";
|
||||
import PreviewOverlay from "./components/PreviewOverlay.svelte";
|
||||
import { previewUi, openPreviewFixture } from "./lib/preview/previewSession.svelte.js";
|
||||
import Home from "./views/Home.svelte";
|
||||
import Search from "./views/Search.svelte";
|
||||
import Library from "./views/Library.svelte";
|
||||
@@ -40,16 +42,38 @@
|
||||
autoConnect();
|
||||
refreshLibrary();
|
||||
refreshPlaylists();
|
||||
|
||||
// Dev-only hook for the Phase 2 exit-gate check (500-item fixture in a
|
||||
// plain browser) and for driving the modal without a Tauri backend.
|
||||
if (import.meta.env.DEV && typeof window !== "undefined") {
|
||||
window.__previewFixture = (n = 12) => openPreviewFixture(n);
|
||||
window.__previewUi = previewUi; // debug: the app's own store instance
|
||||
window.__ui = ui; // debug: known-good reactive store, same instance
|
||||
window.__togglePv = () => (previewUi.open = !previewUi.open);
|
||||
window.__toggleNp = () => (ui.nowPlaying = !ui.nowPlaying);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="app" class:np-open={ui.nowPlaying} class:sidebar-collapsed={ui.sidebarCollapsed}>
|
||||
<div
|
||||
class="app"
|
||||
class:np-open={ui.nowPlaying}
|
||||
class:sidebar-collapsed={ui.sidebarCollapsed}
|
||||
class:preview-open={previewUi.open}
|
||||
>
|
||||
<TitleBar />
|
||||
<!-- Previews take over the whole window (decision 2026-07-22): while the
|
||||
modal is open the page and the player bar are inert/not rendered —
|
||||
there is deliberately NO UI path to command main audio behind the
|
||||
focus coordinator's back. The titlebar stays live for window chrome. -->
|
||||
<Sidebar />
|
||||
<main class="content" use:floatScroll>
|
||||
<main class="content" use:floatScroll inert={previewUi.open || undefined}>
|
||||
<CurrentView />
|
||||
</main>
|
||||
<NowPlaying />
|
||||
<PlayerBar />
|
||||
{#if !previewUi.open}
|
||||
<PlayerBar />
|
||||
{/if}
|
||||
<PreviewOverlay />
|
||||
<ArtworkViewer />
|
||||
<LoginModal />
|
||||
</div>
|
||||
@@ -57,6 +81,15 @@
|
||||
<style>
|
||||
/* Frameless window: the titlebar row is part of the app background —
|
||||
no separate chrome color, the panels float beneath it. */
|
||||
/* While the preview modal is open: keyboard is contained by the dialog's
|
||||
focus trap and aria-modal, the content pane is `inert`, and the flanking
|
||||
panels stop taking pointer input here. (The player bar is simply not
|
||||
rendered — see the markup note above.) */
|
||||
.app.preview-open :global(.sidebar),
|
||||
.app.preview-open :global(.nowplaying) {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.app {
|
||||
display: grid;
|
||||
grid-template-columns: var(--sidebar-width) 1fr var(--nowplaying-width);
|
||||
|
||||
Reference in new issue
Block a user