@page "/mixes/{EntryKey}" @using DeepDrftPublic.Client.Controls @using DeepDrftPublic.Client.Services @inherits ReleaseDetailBase @(ViewModel.Release?.Title ?? "Mix") - DeepDrft @if (ViewModel.IsLoading) {
} else if (ViewModel.NotFound || ViewModel.Release is null) {
Mix not found.
All mixes
} else { var release = ViewModel.Release; @* Full-page waveform sits behind the scaffold content. The scaffold's container is positioned above it via the mix-detail-foreground stacking context. TrackId lets the visualizer couple to playback only when the player is on this mix's track; TrackEntryKey is the datum to render at rest (before playback) — the mix's single track, so the lava shows immediately on page load (§4). *@
@* Mix keeps the scaffold solely for the Phase 10 top row (back link | controls | lava-lamp). Title/artist/genre/date/share/play all move into the overlaid hero, so the scaffold's default header and meta regions are suppressed (ShowHeader/ShowMeta=false) and the share row stays off (ShowShareRow=false). *@ @* Lava-lamp icon → popover panel, top-right across from the back link (Phase 12 §3d-revised). Replaces the former inline TopContent knob-bar: the icon IS the toggle and the popover IS the panel. Mix takes the cleanest anchor case (§8e) — the popover's default bottom-right anchor opens down over the full-bleed field. *@ @* Cover-as-background hero with all metadata overlaid, square `mix-hero` sizing. The cover art IS the background, so no separate cover thumbnail (CoverThumbKey defaults to null). Share and play ride in as slots, matching Sessions. *@ @* Release-mode share: copies the canonical /mixes/{entryKey} URL, not a single track (§3b). *@ @if (ViewModel.Track is not null) { @* Append-only: queues the mix's single track without starting playback. *@ } @* Blurb sits below the hero, inside the scaffold's foreground stacking context. *@
} @code { protected override string PersistKey => "mix-detail"; [CascadingParameter] public IStreamingPlayerService? PlayerService { get; set; } // The hero now carries the play affordance (the scaffold's header is suppressed), so the // play-toggle is wired here directly — mirroring SessionDetail. Toggle if this track is already // active, otherwise start a fresh stream. private async Task PlayTrack() { var track = ViewModel.Track; if (track is null || PlayerService is null) return; var isThisTrack = PlayerService.CurrentTrack?.Id == track.Id; if (isThisTrack && (PlayerService.IsPlaying || PlayerService.IsPaused)) { await PlayerService.TogglePlayPause(); } else { await PlayerService.SelectTrackStreaming(track); } } }