feature: Track Meta Labels on Player
This commit is contained in:
@@ -19,14 +19,15 @@ else
|
||||
IsLoading="IsLoading"
|
||||
IsStreaming="IsStreaming"
|
||||
LoadProgress="LoadProgress"
|
||||
DisplayTime="DisplayTime"
|
||||
Duration="Duration"
|
||||
TogglePlayPause="@TogglePlayPause"
|
||||
Stop="@Stop"
|
||||
Class="transport-zone"/>
|
||||
|
||||
<VolumeZone Volume="@Volume" VolumeChanged="@OnVolumeChange"/>
|
||||
|
||||
<PlayerSeekZone DisplayTime="DisplayTime"
|
||||
Duration="Duration"
|
||||
<PlayerSeekZone CurrentTrack="CurrentTrack"
|
||||
OnSeekStart="@OnSeekStart"
|
||||
OnSeekEnd="@OnSeekEnd"
|
||||
OnSeekChange="@OnSeekChange"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using DeepDrftModels.DTOs;
|
||||
using DeepDrftPublic.Client.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MudBlazor;
|
||||
@@ -28,6 +29,7 @@ public partial class AudioPlayerBar : ComponentBase, IAsyncDisposable
|
||||
private bool IsStreaming => PlayerService?.CanStartStreaming ?? false;
|
||||
private bool IsStreamingMode => PlayerService?.IsStreamingMode ?? false;
|
||||
private double? Duration => PlayerService?.Duration;
|
||||
private TrackDto? CurrentTrack => PlayerService?.CurrentTrack;
|
||||
private double Volume => PlayerService?.Volume ?? 0;
|
||||
private double LoadProgress => PlayerService?.LoadProgress ?? 0;
|
||||
private string? ErrorMessage => PlayerService?.ErrorMessage;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
|
||||
|
||||
<MudStack Row="false" Spacing="0" Class="@Class">
|
||||
<MudStack Row="false" Spacing="1" Class="@Class">
|
||||
<WaveformSeeker OnSeekStart="OnSeekStart"
|
||||
OnSeekChange="OnSeekChange"
|
||||
OnSeekEnd="OnSeekEnd"
|
||||
Class="seek-waveform"/>
|
||||
<TimestampLabel CurrentTime="DisplayTime" Duration="@Duration"/>
|
||||
<TrackMetaLabel Track="CurrentTrack"/>
|
||||
</MudStack>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
using DeepDrftModels.DTOs;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
|
||||
|
||||
/// <summary>
|
||||
/// Centre zone of the player: the <see cref="WaveformSeeker"/> over a timestamp label.
|
||||
/// The seeker owns the pointer-gesture seek logic and reads playback 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.
|
||||
/// Centre zone of the player: the <see cref="WaveformSeeker"/> over the now-playing metadata row
|
||||
/// (<see cref="TrackMetaLabel"/>). The seeker owns the pointer-gesture seek logic and reads playback
|
||||
/// 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 current track's metadata.
|
||||
/// </summary>
|
||||
public partial class PlayerSeekZone : ComponentBase
|
||||
{
|
||||
[Parameter] public double DisplayTime { get; set; }
|
||||
[Parameter] public double? Duration { get; set; }
|
||||
[Parameter] public TrackDto? CurrentTrack { get; set; }
|
||||
[Parameter] public EventCallback OnSeekStart { get; set; }
|
||||
[Parameter] public EventCallback<double> OnSeekEnd { get; set; }
|
||||
[Parameter] public EventCallback<double> OnSeekChange { get; set; }
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
|
||||
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1" Class="@Class">
|
||||
<PlayerControls IsLoaded="IsLoaded"
|
||||
CanPlay="CanPlay"
|
||||
TogglePlayPause="TogglePlayPause"
|
||||
Stop="Stop"/>
|
||||
@if (IsLoading && !IsStreaming)
|
||||
{
|
||||
<MudProgressCircular Color="Color.Tertiary"
|
||||
Size="Size.Small"
|
||||
Max="1D"
|
||||
Value="@LoadProgress"
|
||||
Indeterminate="@(LoadProgress == 0)"/>
|
||||
}
|
||||
<MudStack Row="false" AlignItems="AlignItems.Center" Spacing="1" Class="@Class">
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
|
||||
<PlayerControls IsLoaded="IsLoaded"
|
||||
CanPlay="CanPlay"
|
||||
TogglePlayPause="TogglePlayPause"
|
||||
Stop="Stop"/>
|
||||
@if (IsLoading && !IsStreaming)
|
||||
{
|
||||
<MudProgressCircular Color="Color.Tertiary"
|
||||
Size="Size.Small"
|
||||
Max="1D"
|
||||
Value="@LoadProgress"
|
||||
Indeterminate="@(LoadProgress == 0)"/>
|
||||
}
|
||||
</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 IsStreaming { 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 Stop { 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