feature: Track Meta Labels on Player
This commit is contained in:
@@ -19,14 +19,15 @@ else
|
|||||||
IsLoading="IsLoading"
|
IsLoading="IsLoading"
|
||||||
IsStreaming="IsStreaming"
|
IsStreaming="IsStreaming"
|
||||||
LoadProgress="LoadProgress"
|
LoadProgress="LoadProgress"
|
||||||
|
DisplayTime="DisplayTime"
|
||||||
|
Duration="Duration"
|
||||||
TogglePlayPause="@TogglePlayPause"
|
TogglePlayPause="@TogglePlayPause"
|
||||||
Stop="@Stop"
|
Stop="@Stop"
|
||||||
Class="transport-zone"/>
|
Class="transport-zone"/>
|
||||||
|
|
||||||
<VolumeZone Volume="@Volume" VolumeChanged="@OnVolumeChange"/>
|
<VolumeZone Volume="@Volume" VolumeChanged="@OnVolumeChange"/>
|
||||||
|
|
||||||
<PlayerSeekZone DisplayTime="DisplayTime"
|
<PlayerSeekZone CurrentTrack="CurrentTrack"
|
||||||
Duration="Duration"
|
|
||||||
OnSeekStart="@OnSeekStart"
|
OnSeekStart="@OnSeekStart"
|
||||||
OnSeekEnd="@OnSeekEnd"
|
OnSeekEnd="@OnSeekEnd"
|
||||||
OnSeekChange="@OnSeekChange"
|
OnSeekChange="@OnSeekChange"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using DeepDrftModels.DTOs;
|
||||||
using DeepDrftPublic.Client.Services;
|
using DeepDrftPublic.Client.Services;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using MudBlazor;
|
using MudBlazor;
|
||||||
@@ -28,6 +29,7 @@ public partial class AudioPlayerBar : ComponentBase, IAsyncDisposable
|
|||||||
private bool IsStreaming => PlayerService?.CanStartStreaming ?? false;
|
private bool IsStreaming => PlayerService?.CanStartStreaming ?? false;
|
||||||
private bool IsStreamingMode => PlayerService?.IsStreamingMode ?? false;
|
private bool IsStreamingMode => PlayerService?.IsStreamingMode ?? false;
|
||||||
private double? Duration => PlayerService?.Duration;
|
private double? Duration => PlayerService?.Duration;
|
||||||
|
private TrackDto? CurrentTrack => PlayerService?.CurrentTrack;
|
||||||
private double Volume => PlayerService?.Volume ?? 0;
|
private double Volume => PlayerService?.Volume ?? 0;
|
||||||
private double LoadProgress => PlayerService?.LoadProgress ?? 0;
|
private double LoadProgress => PlayerService?.LoadProgress ?? 0;
|
||||||
private string? ErrorMessage => PlayerService?.ErrorMessage;
|
private string? ErrorMessage => PlayerService?.ErrorMessage;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
|
@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
|
||||||
|
|
||||||
<MudStack Row="false" Spacing="0" Class="@Class">
|
<MudStack Row="false" Spacing="1" Class="@Class">
|
||||||
<WaveformSeeker OnSeekStart="OnSeekStart"
|
<WaveformSeeker OnSeekStart="OnSeekStart"
|
||||||
OnSeekChange="OnSeekChange"
|
OnSeekChange="OnSeekChange"
|
||||||
OnSeekEnd="OnSeekEnd"
|
OnSeekEnd="OnSeekEnd"
|
||||||
Class="seek-waveform"/>
|
Class="seek-waveform"/>
|
||||||
<TimestampLabel CurrentTime="DisplayTime" Duration="@Duration"/>
|
<TrackMetaLabel Track="CurrentTrack"/>
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
|
using DeepDrftModels.DTOs;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
|
namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Centre zone of the player: the <see cref="WaveformSeeker"/> over a timestamp label.
|
/// Centre zone of the player: the <see cref="WaveformSeeker"/> over the now-playing metadata row
|
||||||
/// The seeker owns the pointer-gesture seek logic and reads playback state off the cascaded
|
/// (<see cref="TrackMetaLabel"/>). The seeker owns the pointer-gesture seek logic and reads playback
|
||||||
/// player service directly; this zone just forwards the seek callbacks up to
|
/// state off the cascaded player service directly; this zone just forwards the seek callbacks up to
|
||||||
/// <see cref="AudioPlayerBar"/> (whose wiring is unchanged) and renders the timestamp.
|
/// <see cref="AudioPlayerBar"/> (whose wiring is unchanged) and renders the current track's metadata.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class PlayerSeekZone : ComponentBase
|
public partial class PlayerSeekZone : ComponentBase
|
||||||
{
|
{
|
||||||
[Parameter] public double DisplayTime { get; set; }
|
[Parameter] public TrackDto? CurrentTrack { get; set; }
|
||||||
[Parameter] public double? Duration { get; set; }
|
|
||||||
[Parameter] public EventCallback OnSeekStart { get; set; }
|
[Parameter] public EventCallback OnSeekStart { get; set; }
|
||||||
[Parameter] public EventCallback<double> OnSeekEnd { get; set; }
|
[Parameter] public EventCallback<double> OnSeekEnd { get; set; }
|
||||||
[Parameter] public EventCallback<double> OnSeekChange { get; set; }
|
[Parameter] public EventCallback<double> OnSeekChange { get; set; }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
|
@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
|
||||||
|
|
||||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1" Class="@Class">
|
<MudStack Row="false" AlignItems="AlignItems.Center" Spacing="1" Class="@Class">
|
||||||
|
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
|
||||||
<PlayerControls IsLoaded="IsLoaded"
|
<PlayerControls IsLoaded="IsLoaded"
|
||||||
CanPlay="CanPlay"
|
CanPlay="CanPlay"
|
||||||
TogglePlayPause="TogglePlayPause"
|
TogglePlayPause="TogglePlayPause"
|
||||||
@@ -14,3 +15,5 @@
|
|||||||
Indeterminate="@(LoadProgress == 0)"/>
|
Indeterminate="@(LoadProgress == 0)"/>
|
||||||
}
|
}
|
||||||
</MudStack>
|
</MudStack>
|
||||||
|
<TimestampLabel CurrentTime="DisplayTime" Duration="@Duration"/>
|
||||||
|
</MudStack>
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ public partial class PlayerTransportZone : ComponentBase
|
|||||||
[Parameter] public bool IsLoading { get; set; }
|
[Parameter] public bool IsLoading { get; set; }
|
||||||
[Parameter] public bool IsStreaming { get; set; }
|
[Parameter] public bool IsStreaming { get; set; }
|
||||||
[Parameter] public double LoadProgress { get; set; }
|
[Parameter] public double LoadProgress { get; set; }
|
||||||
|
[Parameter] public double DisplayTime { get; set; }
|
||||||
|
[Parameter] public double? Duration { get; set; }
|
||||||
[Parameter] public EventCallback TogglePlayPause { get; set; }
|
[Parameter] public EventCallback TogglePlayPause { get; set; }
|
||||||
[Parameter] public EventCallback Stop { get; set; }
|
[Parameter] public EventCallback Stop { get; set; }
|
||||||
[Parameter] public string? Class { get; set; }
|
[Parameter] public string? Class { get; set; }
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
|
||||||
|
|
||||||
|
@if (Track is not null)
|
||||||
|
{
|
||||||
|
<div class="track-meta-row">
|
||||||
|
<div class="track-meta-identity">
|
||||||
|
<MudText Typo="Typo.subtitle2" Class="track-meta-title text-truncate">
|
||||||
|
@Track.TrackName
|
||||||
|
</MudText>
|
||||||
|
<MudText Typo="Typo.subtitle2"> - </MudText>
|
||||||
|
<MudText Typo="Typo.caption" Class="track-meta-artist text-truncate">
|
||||||
|
@Track.Artist
|
||||||
|
</MudText>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="track-meta-accents">
|
||||||
|
@if (!string.IsNullOrEmpty(Track.Genre))
|
||||||
|
{
|
||||||
|
<MudChip T="string"
|
||||||
|
Size="Size.Small"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Color="Color.Tertiary"
|
||||||
|
Class="deepdrft-genre-chip">
|
||||||
|
@Track.Genre
|
||||||
|
</MudChip>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (Track.ReleaseDate.HasValue)
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.caption" Class="track-meta-year">
|
||||||
|
@Track.ReleaseDate.Value.Year
|
||||||
|
</MudText>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using DeepDrftModels.DTOs;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The now-playing metadata row beneath the <see cref="WaveformSeeker"/>: track title + artist on
|
||||||
|
/// the left, genre chip + release year on the right. Reads nothing from the player service itself —
|
||||||
|
/// the current <see cref="TrackDto"/> is passed in by <see cref="PlayerSeekZone"/>.
|
||||||
|
/// </summary>
|
||||||
|
public partial class TrackMetaLabel : ComponentBase
|
||||||
|
{
|
||||||
|
[Parameter] public TrackDto? Track { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/* Single space-between row under the waveform: identity on the left, accents on the right.
|
||||||
|
Colours come from the MudBlazor theme (the dock surface is theme-aware), so unlike the
|
||||||
|
always-dark TrackCard glass we do not hard-code green-accent overrides here. */
|
||||||
|
.track-meta-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 2px 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Left group shrinks and truncates so a long title never pushes the chip off-screen. */
|
||||||
|
.track-meta-identity {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 8px;
|
||||||
|
min-width: 0;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
::deep .track-meta-title {
|
||||||
|
font-family: var(--deepdrft-font-mono);
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::deep .track-meta-artist {
|
||||||
|
opacity: 0.75;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right group keeps its natural size and never shrinks. */
|
||||||
|
.track-meta-accents {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
::deep .track-meta-year {
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user