Files

63 lines
2.4 KiB
C#

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.
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;
}
}
}