Consolidate play/pause icon logic into PlaybackIcons mapper and PlayStateIcon component
Add Disabled parameter to PlayStateIcon; forward to MudIconButton; pass Disabled="!IsLoaded" from PlayerControls to match Stop button parity.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
using DeepDrftModels.DTOs;
|
||||
using DeepDrftPublic.Client.Helpers;
|
||||
using DeepDrftPublic.Client.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MudBlazor;
|
||||
|
||||
namespace DeepDrftPublic.Client.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Renders the play/pause transport glyph for either a specific track or global playback,
|
||||
/// reading live state off the cascaded <see cref="IStreamingPlayerService"/>. The icon is
|
||||
/// always resolved through <see cref="PlaybackIcons.Resolve"/>.
|
||||
/// </summary>
|
||||
public partial class PlayStateIcon : ComponentBase, IDisposable
|
||||
{
|
||||
[CascadingParameter] public IStreamingPlayerService? PlayerService { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When non-null, the icon reflects this track's playback state (active only when it is the
|
||||
/// current track). When null, it reflects global playback state.
|
||||
/// </summary>
|
||||
[Parameter] public TrackDto? Track { get; set; }
|
||||
|
||||
[Parameter] public Size Size { get; set; } = Size.Medium;
|
||||
[Parameter] public Color Color { get; set; } = Color.Primary;
|
||||
[Parameter] public bool Disabled { get; set; } = false;
|
||||
[Parameter] public EventCallback OnToggle { get; set; }
|
||||
|
||||
private IStreamingPlayerService? _subscribedService;
|
||||
|
||||
private bool IsActive => Track is null || PlayerService?.CurrentTrack?.Id == Track.Id;
|
||||
private bool IsPlaying => IsActive && (PlayerService?.IsPlaying ?? false);
|
||||
private bool IsPaused => IsActive && (PlayerService?.IsPaused ?? false);
|
||||
|
||||
private string Icon => PlaybackIcons.Resolve(IsPlaying, IsPaused);
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
// The cascade is IsFixed, so the provider's re-render never reaches us; subscribe to the
|
||||
// multicast side-channel to re-render on every player state change. Reference-guarded so
|
||||
// re-parametering is idempotent. Mirrors AudioPlayerBar / TracksView.
|
||||
if (PlayerService != null && !ReferenceEquals(PlayerService, _subscribedService))
|
||||
{
|
||||
if (_subscribedService != null)
|
||||
_subscribedService.StateChanged -= OnPlayerStateChanged;
|
||||
|
||||
PlayerService.StateChanged += OnPlayerStateChanged;
|
||||
_subscribedService = PlayerService;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayerStateChanged() => InvokeAsync(StateHasChanged);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_subscribedService != null)
|
||||
{
|
||||
_subscribedService.StateChanged -= OnPlayerStateChanged;
|
||||
_subscribedService = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user