Unify AudioPlayerBar to one responsive CSS layout and fix SpectrumVisualizer startup via StateChanged subscription

This commit is contained in:
daniel-c-harvey
2026-06-05 14:04:31 -04:00
parent 4887454911
commit 190d8d044f
5 changed files with 88 additions and 87 deletions
@@ -15,6 +15,7 @@ public partial class SpectrumVisualizer : ComponentBase, IAsyncDisposable
private double[] _spectrumData = Array.Empty<double>();
private bool _isAnimating = false;
private string? _playerId;
private IStreamingPlayerService? _subscribedService;
private bool IsVisible => (PlayerService?.IsPlaying ?? false) || (PlayerService?.IsPaused ?? false) || _isAnimating;
@@ -25,9 +26,20 @@ public partial class SpectrumVisualizer : ComponentBase, IAsyncDisposable
protected override async Task OnParametersSetAsync()
{
// Provider re-renders cascade down to children and re-run OnParametersSet.
// Pick up the player id once the cascade arrives, then drive animation
// state from the parent's current IsPlaying — no callback wrapping needed.
// The cascade is IsFixed, so the provider's re-renders do NOT re-run
// OnParametersSet here, and this component has no incoming parameters
// that change. Subscribe to the multicast StateChanged side-channel so
// animation state stays correct independent of parent re-renders —
// notably when the bar expands while a track is already playing.
if (PlayerService != null && !ReferenceEquals(PlayerService, _subscribedService))
{
if (_subscribedService != null)
_subscribedService.StateChanged -= OnPlayerStateChanged;
PlayerService.StateChanged += OnPlayerStateChanged;
_subscribedService = PlayerService;
}
if (_playerId == null && PlayerService is AudioPlayerService baseService)
{
_playerId = baseService.PlayerId;
@@ -36,6 +48,15 @@ public partial class SpectrumVisualizer : ComponentBase, IAsyncDisposable
await UpdateAnimationState();
}
private void OnPlayerStateChanged() => InvokeAsync(async () =>
{
if (_playerId == null && PlayerService is AudioPlayerService baseService)
{
_playerId = baseService.PlayerId;
}
await UpdateAnimationState();
});
private async Task UpdateAnimationState()
{
if (string.IsNullOrEmpty(_playerId) || PlayerService == null) return;
@@ -93,6 +114,11 @@ public partial class SpectrumVisualizer : ComponentBase, IAsyncDisposable
public async ValueTask DisposeAsync()
{
if (_subscribedService != null)
{
_subscribedService.StateChanged -= OnPlayerStateChanged;
_subscribedService = null;
}
await StopAnimation();
}
}