Files
deepdrft/DeepDrftPublic.Client/Controls/ReleaseDetailScaffold.razor.cs
T
daniel-c-harvey af724ce570 Phase 9 Wave 4: ARCHIVE nav + Cuts/Sessions/Mixes pages + MixWaveformVisualizer
Replaces flat RELEASES/SESSIONS/MIXES nav with ARCHIVE dropdown (PageRoute.Children,
one-level cap, dual-role node). Adds /archive overview, /cuts (AlbumsView + medium
filter; /albums redirects), /sessions + /sessions/{id} (hero-dominant), /mixes +
/mixes/{id} (MixWaveformVisualizer full-page background). Extracts ReleaseDetailScaffold
from TrackDetail (invariant trio). PersistentComponentState bridge on all new pages.
Click-to-seek seam designed on MixWaveformVisualizer (inert until wired).
2026-06-12 23:05:25 -04:00

57 lines
2.4 KiB
C#

using DeepDrftModels.DTOs;
using DeepDrftPublic.Client.Services;
using Microsoft.AspNetCore.Components;
namespace DeepDrftPublic.Client.Controls;
/// <summary>
/// Shared detail-page chrome for any release medium: back link, masthead, play/share affordance,
/// and hero/meta slots. Owns the play-toggle wiring against the cascaded streaming player so each
/// detail page supplies only its data and medium-specific visuals. Extracted from the original
/// TrackDetail page, which is now a thin consumer of this scaffold.
/// </summary>
public partial class ReleaseDetailScaffold : ComponentBase
{
[CascadingParameter] public IStreamingPlayerService? PlayerService { get; set; }
[Parameter] public required string Title { get; set; }
[Parameter] public string? Artist { get; set; }
// The playable track for this release. Null while unresolved (or when a release has no
// streamable track yet) — the play/share row is hidden in that case.
[Parameter] public TrackDto? Track { get; set; }
[Parameter] public string BackHref { get; set; } = "/archive";
[Parameter] public string BackLabel { get; set; } = "Archive";
/// <summary>Medium-specific hero visual (cover art, hero image, or waveform background).</summary>
[Parameter] public RenderFragment? Hero { get; set; }
/// <summary>Optional medium-specific metadata block, rendered under a divider when present.</summary>
[Parameter] public RenderFragment? MetaContent { get; set; }
/// <summary>
/// Gate for the metadata block. Lets a consumer supply a <see cref="MetaContent"/> fragment but
/// suppress the divider + block when its data is empty (slot fragments cannot be conditionally
/// attached inline). Defaults to shown.
/// </summary>
[Parameter] public bool ShowMeta { get; set; } = true;
private async Task PlayTrack()
{
if (Track is null || PlayerService is null) return;
// Toggle if this track is already active (playing or paused); otherwise start a fresh
// stream. SelectTrackStreaming is the live entry point — the buffered path is dead.
var isThisTrack = PlayerService.CurrentTrack?.Id == Track.Id;
if (isThisTrack && (PlayerService.IsPlaying || PlayerService.IsPaused))
{
await PlayerService.TogglePlayPause();
}
else
{
await PlayerService.SelectTrackStreaming(Track);
}
}
}