From 54ef4c038e3e7671a33a4a29ec5eadc05a71146b Mon Sep 17 00:00:00 2001 From: daniel-c-harvey Date: Wed, 17 Jun 2026 06:31:06 -0400 Subject: [PATCH] doc: MixVisualizerControls --- DeepDrftPublic.Client/CLAUDE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DeepDrftPublic.Client/CLAUDE.md b/DeepDrftPublic.Client/CLAUDE.md index 4288d4f..39b29ff 100644 --- a/DeepDrftPublic.Client/CLAUDE.md +++ b/DeepDrftPublic.Client/CLAUDE.md @@ -24,6 +24,7 @@ All interactive UI for the site. Blazor WebAssembly. Pages, controls, the stream - `AudioPlayerBar/LevelMeterFab.razor`: Floating-action button replacing the static FAB in the minimized dock. Renders a continuous vertical fill inside the music-note silhouette that tracks live audio level (0–100%), with fixed three-zone gradient (green 0–60%, yellow 60–85%, orange 85–100%). Note silhouette always visible at 25% opacity; idle when paused/stopped. Reuses spectrum-callback infrastructure. - `SpectrumVisualizer.razor`: Bar-graph spectrum display, driven by `getSpectrumData` JS callback. - `ReleaseHeroOverlay.razor`: Shared presentational overlay shell consumed by both `SessionDetail` and `MixDetail`. Renders a background-image hero region with genre/date/share overlaid at the top and title/artist/play at the bottom. Parameters: `HeroImageKey`, `PlaceholderIcon`, `CoverThumbKey` (optional cover thumb in bottom row), `Title`, `Artist`, `Genre`, `ReleaseDate`, `ShareContent` (slot), `PlayContent` (slot), `Class` (per-page aspect/sizing override). Owns no player logic or data fetch; each consuming page passes its own play and share slots. Overlay shell is plain `
`s; background-image surface is a `
` (no `MudPaper`). + - `MixVisualizerControls.razor`: Eight-knob RadialKnob control bar for the Mix detail lava-lamp visualizer. Controls (in order): waveform scroll speed, color gradient rotation speed, lava gravity, lava heat, fluid amount, fluid viscosity (cohesion), collision strength, waveform width. `[Parameter] bool Visible` — the host always renders this component and feeds the lava-lamp toggle into `Visible`; the knobs are `@if`-gated on `Visible` while the container holds a reserved `min-height` so content below never pops when the lamp toggles. Owns no JS interop: mutates the injected `MixVisualizerControlState` and raises `Changed`; the backdrop bridge (`MixWaveformVisualizer`) subscribes and pushes each changed dial to the WebGL module. No control is a seek surface (read-only contract). - `Helpers/`: Utilities and mapper functions. - `PlaybackIcons.cs`: Static `Resolve(isPlaying, isPaused, trackId, currentTrackId)` method — the sole glyph-mapping source for transport icons across all surfaces. Returns `(Icon, IsActive, IsPaused)` tuple. - `Services/`: Audio player + dark-mode services. @@ -32,6 +33,7 @@ All interactive UI for the site. Blazor WebAssembly. Pages, controls, the stream - `StreamingAudioPlayerService`: Production implementation. Chunked stream from `TrackMediaClient`, adaptive 16–64 KB buffer, early-playback, **seek-beyond-buffer** via offset request to the content API. - `AudioInteropService`: JS interop wrapper over `window.DeepDrftAudio`. Manages `DotNetObjectReference` lifetimes for progress, end-of-playback, spectrum callbacks. - Dark-mode services: `DarkModeServiceBase` (cookie name constant), `DarkModeCookieService` (JS cookie read/write). + - `MixVisualizerControlState`: Scoped session-persistent holder for the Mix visualizer's **eight** control positions: `ScrollSpeed`, `GradientRotationSpeed`, `LavaGravity`, `LavaHeat`, `FluidAmount` (wax count/volume), `FluidViscosity` (cohesion — the second half of the Phase 10 "bubbles" split; `BlobDensity` is gone), `CollisionStrength`, `WaveformWidth`. Each has a matching `Default*` const. `Changed` event is the decoupling seam — controls mutate state + raise `Changed`; the bridge (`MixWaveformVisualizer`) subscribes and pushes the affected uniform. Scoped DI so state survives SPA nav within a session and resets on fresh page load. - `Clients/`: HTTP API clients (both target DeepDrftAPI). - `TrackClient`: SQL metadata API. Uses named `IHttpClientFactory` client `"DeepDrft.API"`. Sends `page` param (not `pageNumber`). Deserializes response as bare `PagedResult` (not wrapped in ApiResultDto envelope). - `TrackMediaClient`: Content API. Uses named `IHttpClientFactory` client `"DeepDrft.Content"`. Methods like `GetAudioStreamAsync(trackId, byteOffset?)` → `Stream` with optional Range header support for seek-beyond-buffer.