Reflect real playback state on gallery cards and toggle pause/resume
Add IsPaused/OnPause to TrackCard, make TracksGallery controlled, and drive the active track from PlayerService.CurrentTrack as the single source of truth.
This commit is contained in:
@@ -14,7 +14,6 @@ public partial class TracksView : ComponentBase, IDisposable
|
||||
[Inject] public required PersistentComponentState PersistentState { get; set; }
|
||||
[CascadingParameter] public required IStreamingPlayerService PlayerService { get; set; }
|
||||
|
||||
private TrackDto? _selectedTrack = null;
|
||||
private IStreamingPlayerService? _subscribedService;
|
||||
private PersistingComponentStateSubscription _persistingSubscription;
|
||||
|
||||
@@ -41,11 +40,11 @@ public partial class TracksView : ComponentBase, IDisposable
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
// The Stop/Close buttons on the player bar reset the player directly,
|
||||
// bypassing PlayTrack — so the gallery's selection must follow player
|
||||
// state rather than only its own clicks. Subscribe to the multicast
|
||||
// side-channel (the cascade is IsFixed, so provider re-renders don't
|
||||
// reach us) and clear the highlight when nothing is loaded.
|
||||
// The gallery's per-card icons read off the player's live state (CurrentTrack /
|
||||
// IsPlaying / IsPaused), which mutates outside this component's render path:
|
||||
// the player bar's play/pause/stop/close all change it directly. The cascade is
|
||||
// IsFixed, so the provider's re-render never reaches us — subscribe to the
|
||||
// multicast side-channel and re-render on every state change.
|
||||
if (PlayerService != null && !ReferenceEquals(PlayerService, _subscribedService))
|
||||
{
|
||||
if (_subscribedService != null)
|
||||
@@ -56,17 +55,7 @@ public partial class TracksView : ComponentBase, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayerStateChanged()
|
||||
{
|
||||
// Sync the gallery selection to the player. When the player is no longer
|
||||
// loaded (stopped/closed/ended) drop the highlight; guard against a
|
||||
// redundant re-render when nothing actually changed.
|
||||
if (!PlayerService.IsLoaded && _selectedTrack != null)
|
||||
{
|
||||
_selectedTrack = null;
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
private void OnPlayerStateChanged() => InvokeAsync(StateHasChanged);
|
||||
|
||||
private Task PersistTracks()
|
||||
{
|
||||
@@ -88,20 +77,25 @@ public partial class TracksView : ComponentBase, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PlayTrack(TrackDto? track)
|
||||
private async Task PlayTrack(TrackDto track)
|
||||
{
|
||||
if (track == null && _selectedTrack == null || track?.Id == _selectedTrack?.Id) return;
|
||||
|
||||
if (track is null)
|
||||
// Resume the current track if it's merely paused; otherwise stream the new selection.
|
||||
if (PlayerService.CurrentTrack?.Id == track.Id && PlayerService.IsPaused)
|
||||
{
|
||||
await PlayerService.Unload();
|
||||
await PlayerService.TogglePlayPause();
|
||||
}
|
||||
else
|
||||
{
|
||||
await PlayerService.SelectTrack(track);
|
||||
}
|
||||
}
|
||||
|
||||
_selectedTrack = track;
|
||||
private async Task PauseTrack(TrackDto track)
|
||||
{
|
||||
if (PlayerService.CurrentTrack?.Id == track.Id && PlayerService.IsPlaying)
|
||||
{
|
||||
await PlayerService.TogglePlayPause();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
Reference in New Issue
Block a user