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">
|
<div class="cut-detail-actions">
|
||||||
@* Header Play starts the album's first track. Wired to the single-slot player
|
@* Header Play loads the full album into the queue at index 0 (§3.4 seam,
|
||||||
today; the §3.4 queue seam means a future swap to QueueService.PlayRelease
|
closed P11 W1). Disabled until at least one streamable track is resolved. *@
|
||||||
is a one-line change inside PlayAlbum, not a markup edit. Disabled until a
|
|
||||||
streamable track is resolved. *@
|
|
||||||
<MudButton Variant="Variant.Filled"
|
<MudButton Variant="Variant.Filled"
|
||||||
Color="Color.Secondary"
|
Color="Color.Secondary"
|
||||||
StartIcon="@Icons.Material.Filled.PlayArrow"
|
StartIcon="@Icons.Material.Filled.PlayArrow"
|
||||||
@@ -112,15 +110,17 @@ else
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="cut-detail-tracklist">
|
<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">
|
<div class="cut-detail-track-row">
|
||||||
<span class="cut-detail-track-number">@track.TrackNumber</span>
|
<span class="cut-detail-track-number">@track.TrackNumber</span>
|
||||||
<div class="cut-detail-track-play">
|
<div class="cut-detail-track-play">
|
||||||
<PlayStateIcon Track="@track"
|
<PlayStateIcon Track="@track"
|
||||||
Size="Size.Medium"
|
Size="Size.Medium"
|
||||||
Color="Color.Secondary"
|
Color="Color.Secondary"
|
||||||
OnToggle="@(() => PlayTrack(track))" />
|
OnToggle="@(() => PlayTrack(track, index))" />
|
||||||
</div>
|
</div>
|
||||||
<span class="cut-detail-track-name text-truncate">@track.TrackName</span>
|
<span class="cut-detail-track-name text-truncate">@track.TrackName</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -133,20 +133,23 @@ else
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
[CascadingParameter] public IStreamingPlayerService? PlayerService { get; set; }
|
[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
|
// Header Play: load the full album into the queue starting at track 0.
|
||||||
// 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.
|
|
||||||
private Task PlayAlbum()
|
private Task PlayAlbum()
|
||||||
{
|
{
|
||||||
var first = ViewModel.Tracks.Count > 0 ? ViewModel.Tracks[0] : null;
|
if (ViewModel.Tracks.Count == 0) return Task.CompletedTask;
|
||||||
return first is null ? Task.CompletedTask : PlayTrack(first);
|
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
|
// Row play: toggle if this track is already playing/paused, otherwise load the album at this
|
||||||
// scaffold's own PlayTrack wiring (SessionDetail uses the same idiom for its diverged layout).
|
// row's index so playback continues to the end from the chosen track.
|
||||||
private async Task PlayTrack(TrackDto track)
|
private async Task PlayTrack(TrackDto track, int index)
|
||||||
{
|
{
|
||||||
if (PlayerService is null) return;
|
if (PlayerService is null) return;
|
||||||
|
|
||||||
@@ -154,9 +157,16 @@ else
|
|||||||
if (isThisTrack && (PlayerService.IsPlaying || PlayerService.IsPaused))
|
if (isThisTrack && (PlayerService.IsPlaying || PlayerService.IsPaused))
|
||||||
{
|
{
|
||||||
await PlayerService.TogglePlayPause();
|
await PlayerService.TogglePlayPause();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Queue is not null)
|
||||||
|
{
|
||||||
|
await Queue.PlayRelease(ViewModel.Tracks, index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Queue cascade absent: fall back to direct single-track play.
|
||||||
await PlayerService.SelectTrackStreaming(track);
|
await PlayerService.SelectTrackStreaming(track);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user