TrackCard, TracksGallery, DDIcons, DeepDrftPalettes (Default+Cms), DeepDrftFontLinks,
and palette CSS tokens extracted. Both hosts and DeepDrftCms reference the shared RCL.
Public host is now auth-free: no AuthBlocks, no DeepDrftCms ref, no stealth routing.
MainLayout restored to full chrome. DeepDrft.Content/.Cms HttpClients wired on Manager.
Routes moves to InteractiveServer so the server router always sees all
assemblies (including AuthBlocksWeb). MainLayout declares
@rendermode InteractiveWebAssembly — the single source of WASM
interactivity for all public pages. CmsLayout in DeepDrftCms provides
a server-rendered admin shell without the audio dock. Assembly-level
_Imports.razor files set the default layout for each group; no per-page
rendermode declarations needed. Routes.razor moves to the server host
(its correct home) carrying the full AdditionalAssemblies list.
AuthBlocksWeb pages live in a server-only assembly not bundled in the WASM
client. When InteractiveAuto switches routing to WASM, /account/login has
no matching component and shows NotFound. Routes.razor now intercepts
NotFound for /account/* paths and forces a full-page reload to the server
router, which knows the real login page via AddAdditionalAssemblies.
- SeekBeyondBuffer and LoadTrackStreaming assign _activeStreamingTask before
awaiting; DrainActiveStreamingTaskAsync awaits previous task before new
stream starts, closing the concurrent-seek race on the JS StreamDecoder
- Always slice ArrayPool buffer to currentBytes before sending to JS interop;
eliminates stale bytes from prior rentals reaching the audio decoder
- getSampleAlignedChunkSize accepts streamComplete flag; bypasses minimum
chunk guard on final tail so trailing bytes are decoded, not dropped
- StreamDecoder accumulates headerSearchChunks until parseHeader succeeds,
with 256 KB MAX_HEADER_SEARCH_BYTES bound; handles fragmented first chunks
and extended WAV headers with LIST/INFO/JUNK chunks
- markStreamComplete early-returns when streamComplete already set to prevent
double-drain and incorrect streamingCompleted flag after partial failure
- processedBytes advances only after successful decode; failed segments leave
cursor in place rather than permanently skipping audio
- AudioInteropService.MarkStreamCompleteAsync wires C# loop exit to JS decoder
ensuring tail drain fires even when Content-Length header is absent
- Redesigned audio player bar to be mobile-friendly
- Added unloading for track switching (needs to be fixed)
- Added IsLoading status so loading spinner isn't hanging around when it shouldn't be
- Normalized styles with scoped files (will further reduce)
- Layout Cleanup
- EF fixes (migrations now function for deployment)
- deploy script updates (new dedicated host)
- Redesign component wiring for audio playback
- Removed playback logic from the player control and moved it to injectable audio player engine service
- Chunked/buffered stream loading from Content API passed to Web Audio API playback in 8K blocks
Content API:
- Enabling CORS for access from Blazor app
Web Server:
- Content API URL environment config
- Web Audio API JS Interop layer in TypeScript
- HttpClient configs
Web Client:
- Audio Tack player controls
- Audio Player example page
- Audio Interop Service Layer
- Named HttpClients