dd4f8ddded
Centered tinted MudOverlay (NowPlayingCard chrome) replaces the anchored popover; eight dials become a deterministic three-row LAVA/WAVE layout; lava + waveform lamp toggles drive a genuine per-subsystem draw-skip; scroll/zoom becomes a slider; playful tooltips; green=interactive/light=static.
68 lines
2.6 KiB
Plaintext
68 lines
2.6 KiB
Plaintext
@using DeepDrftPublic.Client.Services
|
|
@implements IDisposable
|
|
|
|
@* Hero-right panel (owns the navy backdrop + clipping, formerly Home.razor's .hero-right wrapper). *@
|
|
<div class="now-playing-panel">
|
|
@* Full-bleed waveform background. The visualizer mounts with Fill="true" (position:absolute; inset:0),
|
|
so .np-visualizer-bg is the positioned, sized ancestor that lets the lava fill the whole hero-right
|
|
panel. Driven by the live cascaded player — keyed on the current track via ReleaseEntryKey/TrackId/
|
|
TrackEntryKey so it scrolls to the real signal and sits at-rest when nothing plays. Read-only: the
|
|
background visualizes, it never seeks. Sits behind the rings + content (z-order via stacking below). *@
|
|
<div class="np-visualizer-bg">
|
|
<WaveformVisualizer Fill="true"
|
|
ReleaseEntryKey="@(Player?.CurrentTrack?.Release?.EntryKey ?? string.Empty)"
|
|
TrackId="@Player?.CurrentTrack?.Id"
|
|
TrackEntryKey="@Player?.CurrentTrack?.EntryKey" />
|
|
</div>
|
|
|
|
@* The lava-lamp trigger lands in the panel's top-right corner (full parity, §8e). Above the canvas
|
|
and pointer-enabled so the icon is clickable even though the visualizer layer is
|
|
pointer-events:none. The panel itself opens screen-centered (Phase 15 §4 — no per-host anchor),
|
|
so only the icon size is host-specific now. *@
|
|
<div class="np-visualizer-controls">
|
|
<WaveformVisualizerControlPopover IconSize="Size.Small" />
|
|
</div>
|
|
|
|
@* Pulsing rings *@
|
|
<div class="circle-deco"></div>
|
|
<div class="circle-deco"></div>
|
|
<div class="circle-deco"></div>
|
|
|
|
<div class="now-playing-content">
|
|
<NowPlayingCard />
|
|
|
|
@* Stat row - hard-coded for now. TODO Phase 2: wire to real track count / identity model. *@
|
|
<NowPlayingStats />
|
|
</div>
|
|
</div>
|
|
|
|
|
|
@code {
|
|
[CascadingParameter] public IStreamingPlayerService? Player { get; set; }
|
|
|
|
private IStreamingPlayerService? _subscribedPlayer;
|
|
|
|
protected override void OnParametersSet()
|
|
{
|
|
if (Player != null && !ReferenceEquals(Player, _subscribedPlayer))
|
|
{
|
|
if (_subscribedPlayer != null)
|
|
_subscribedPlayer.StateChanged -= OnPlayerStateChanged;
|
|
|
|
Player.StateChanged += OnPlayerStateChanged;
|
|
_subscribedPlayer = Player;
|
|
}
|
|
}
|
|
|
|
private void OnPlayerStateChanged() => InvokeAsync(StateHasChanged);
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_subscribedPlayer != null)
|
|
{
|
|
_subscribedPlayer.StateChanged -= OnPlayerStateChanged;
|
|
_subscribedPlayer = null;
|
|
}
|
|
}
|
|
}
|