af724ce570
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).
57 lines
2.4 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|