feature: Embed Frame Player
This commit is contained in:
@@ -7,7 +7,8 @@ namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
|
||||
public partial class AudioPlayerBar : ComponentBase, IAsyncDisposable
|
||||
{
|
||||
[CascadingParameter] public IStreamingPlayerService? PlayerService { get; set; }
|
||||
|
||||
[Parameter] public bool Fixed { get; set; } = false;
|
||||
|
||||
private bool _isMinimized = true;
|
||||
private bool _isSeeking = false;
|
||||
private double _seekPosition = 0;
|
||||
@@ -15,6 +16,15 @@ public partial class AudioPlayerBar : ComponentBase, IAsyncDisposable
|
||||
|
||||
private bool IsLoaded => PlayerService?.IsLoaded ?? false;
|
||||
private bool IsLoading => PlayerService?.IsLoading ?? false;
|
||||
|
||||
/// <summary>
|
||||
/// A track is staged when it has been selected as the current track but not yet loaded into
|
||||
/// the audio context (the embed's pre-gesture state). The first play click loads + plays it.
|
||||
/// </summary>
|
||||
private bool IsStaged => PlayerService is { IsLoaded: false, IsLoading: false, CurrentTrack: not null };
|
||||
|
||||
/// <summary>Play is available once a track is loaded, or staged and waiting for the first gesture.</summary>
|
||||
private bool CanPlay => IsLoaded || IsStaged;
|
||||
private bool IsStreaming => PlayerService?.CanStartStreaming ?? false;
|
||||
private bool IsStreamingMode => PlayerService?.IsStreamingMode ?? false;
|
||||
private double? Duration => PlayerService?.Duration;
|
||||
@@ -26,9 +36,15 @@ public partial class AudioPlayerBar : ComponentBase, IAsyncDisposable
|
||||
/// Display time - shows seek position while dragging, otherwise current playback time.
|
||||
/// </summary>
|
||||
private double DisplayTime => _isSeeking ? _seekPosition : (PlayerService?.CurrentTime ?? 0);
|
||||
private string PlayerModeClass => Fixed ? "player-fixed" : "player-docked";
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (Fixed)
|
||||
{
|
||||
_isMinimized = false;
|
||||
}
|
||||
|
||||
// PlayerService is cascaded by AudioPlayerProvider; once it arrives,
|
||||
// wire our track-selection handler. The provider owns OnStateChanged —
|
||||
// we intentionally do NOT wrap or replace it. Because the cascade is
|
||||
@@ -60,6 +76,15 @@ public partial class AudioPlayerBar : ComponentBase, IAsyncDisposable
|
||||
private async Task TogglePlayPause()
|
||||
{
|
||||
if (PlayerService == null) return;
|
||||
|
||||
// Gesture-gated start: a staged-but-unloaded track (the embed autoplay path) is loaded on
|
||||
// the first play click — the user gesture the browser requires before audio can start.
|
||||
if (IsStaged)
|
||||
{
|
||||
await PlayerService.SelectTrackStreaming(PlayerService.CurrentTrack!);
|
||||
return;
|
||||
}
|
||||
|
||||
await PlayerService.TogglePlayPause();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user