feat(cuts): wire PlayAlbum/PlayTrack to IQueueService.PlayRelease (§3.4 seam, P11 W1)
Header Play loads full album at index 0; row play loads at that row's index with same-track toggle preserved; null-safe cascade fallback to direct SelectTrackStreaming when queue absent.
This commit is contained in:
@@ -69,10 +69,8 @@ else
|
||||
}
|
||||
|
||||
<div class="cut-detail-actions">
|
||||
@* Header Play starts the album's first track. Wired to the single-slot player
|
||||
today; the §3.4 queue seam means a future swap to QueueService.PlayRelease
|
||||
is a one-line change inside PlayAlbum, not a markup edit. Disabled until a
|
||||
streamable track is resolved. *@
|
||||
@* Header Play loads the full album into the queue at index 0 (§3.4 seam,
|
||||
closed P11 W1). Disabled until at least one streamable track is resolved. *@
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Secondary"
|
||||
StartIcon="@Icons.Material.Filled.PlayArrow"
|
||||
@@ -112,15 +110,17 @@ else
|
||||
else
|
||||
{
|
||||
<div class="cut-detail-tracklist">
|
||||
@foreach (var track in ViewModel.Tracks)
|
||||
@for (var i = 0; i < ViewModel.Tracks.Count; i++)
|
||||
{
|
||||
var track = ViewModel.Tracks[i];
|
||||
var index = i;
|
||||
<div class="cut-detail-track-row">
|
||||
<span class="cut-detail-track-number">@track.TrackNumber</span>
|
||||
<div class="cut-detail-track-play">
|
||||
<PlayStateIcon Track="@track"
|
||||
Size="Size.Medium"
|
||||
Color="Color.Secondary"
|
||||
OnToggle="@(() => PlayTrack(track))" />
|
||||
OnToggle="@(() => PlayTrack(track, index))" />
|
||||
</div>
|
||||
<span class="cut-detail-track-name text-truncate">@track.TrackName</span>
|
||||
</div>
|
||||
@@ -133,20 +133,23 @@ else
|
||||
|
||||
@code {
|
||||
[CascadingParameter] public IStreamingPlayerService? PlayerService { get; set; }
|
||||
[CascadingParameter] public IQueueService? Queue { get; set; }
|
||||
|
||||
// Header Play: start the album's first track. The §3.4 queue seam lives here — swapping this body
|
||||
// to `Queue.PlayRelease(ViewModel.Tracks)` once IQueueService (track 11.F) lands is a one-line
|
||||
// change with no other edit to this page. The queue type is not referenced here because it does
|
||||
// not exist in this worktree.
|
||||
// Header Play: load the full album into the queue starting at track 0.
|
||||
private Task PlayAlbum()
|
||||
{
|
||||
var first = ViewModel.Tracks.Count > 0 ? ViewModel.Tracks[0] : null;
|
||||
return first is null ? Task.CompletedTask : PlayTrack(first);
|
||||
if (ViewModel.Tracks.Count == 0) return Task.CompletedTask;
|
||||
if (Queue is not null) return Queue.PlayRelease(ViewModel.Tracks, 0);
|
||||
|
||||
// Queue cascade absent (prerender or non-interactive): fall back to direct single-track play.
|
||||
return PlayerService is not null
|
||||
? PlayerService.SelectTrackStreaming(ViewModel.Tracks[0])
|
||||
: Task.CompletedTask;
|
||||
}
|
||||
|
||||
// Row play: toggle if this track is already active, otherwise start a fresh stream. Mirrors the
|
||||
// scaffold's own PlayTrack wiring (SessionDetail uses the same idiom for its diverged layout).
|
||||
private async Task PlayTrack(TrackDto track)
|
||||
// Row play: toggle if this track is already playing/paused, otherwise load the album at this
|
||||
// row's index so playback continues to the end from the chosen track.
|
||||
private async Task PlayTrack(TrackDto track, int index)
|
||||
{
|
||||
if (PlayerService is null) return;
|
||||
|
||||
@@ -154,9 +157,16 @@ else
|
||||
if (isThisTrack && (PlayerService.IsPlaying || PlayerService.IsPaused))
|
||||
{
|
||||
await PlayerService.TogglePlayPause();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Queue is not null)
|
||||
{
|
||||
await Queue.PlayRelease(ViewModel.Tracks, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Queue cascade absent: fall back to direct single-track play.
|
||||
await PlayerService.SelectTrackStreaming(track);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user