Files
deepdrft/DeepDrftPublic.Client/Controls/ReleaseHeroOverlay.razor
T

111 lines
4.7 KiB
Plaintext

@namespace DeepDrftPublic.Client.Controls
@* Shared background-image hero with all release metadata overlaid: top row (genre/date + share),
bottom row (optional cover thumb + title/artist + play). Single source of truth for the overlay
composition consumed by both Session and Mix detail. Purely presentational — owns no data fetch
and no player wiring; play/share ride in as slots so each page keeps its own toggle. Per-page
aspect/sizing variance rides the Class parameter (e.g. Mix's square `mix-hero`), never a fork. *@
@{
var hasGenre = !string.IsNullOrEmpty(Genre);
var hasDate = ReleaseDate is not null;
// Show the cover thumbnail only when it differs from the hero background — otherwise it would
// duplicate the same image. Mix passes CoverThumbKey=null, so this is false there for free.
var showCover = !string.IsNullOrEmpty(CoverThumbKey) && CoverThumbKey != HeroImageKey;
}
@* The hero is the positioning context for every overlay row; the gradient shim and the
top/bottom overlays are absolutely positioned children of this wrapper. *@
<div class="release-hero @Class">
@if (!string.IsNullOrEmpty(HeroImageKey))
{
<div class="release-hero-img"
style="@($"background-image: url('api/image/{Uri.EscapeDataString(HeroImageKey)}');")"></div>
}
else
{
<div class="release-hero-placeholder deepdrft-gradient-soft-secondary">
<MudIcon Icon="@PlaceholderIcon" Color="Color.Primary" />
</div>
}
@* Darkening shim so overlaid text/controls stay legible over any image. *@
<div class="release-hero-shim"></div>
@* Top overlay: secondary details (genre, release date) and the share affordance. *@
<div class="release-hero-top">
<MudStack Row AlignItems="AlignItems.Center" Spacing="3" Class="release-hero-meta">
@if (hasGenre)
{
<MudChip T="string" Variant="Variant.Outlined" Class="release-overlay-chip">
@Genre
</MudChip>
}
@if (hasDate)
{
<div class="release-overlay-date">
<span class="release-overlay-label">Released</span>
<span class="release-overlay-value">@ReleaseDate!.Value.ToString("MMMM yyyy")</span>
</div>
}
</MudStack>
@if (ShareContent is not null)
{
<div class="release-hero-share">
@ShareContent
</div>
}
</div>
@* Bottom overlay: cover thumbnail, title/artist, and the play affordance in one row. *@
<div class="release-hero-bottom">
<MudStack Row AlignItems="AlignItems.Center" Spacing="4" Class="release-hero-bottom-row">
@if (showCover)
{
<div class="release-cover-thumb">
<div class="deepdrft-track-detail-cover-art"
style="@($"background-image: url('api/image/{Uri.EscapeDataString(CoverThumbKey!)}');")"></div>
</div>
}
<div class="release-hero-titles">
<div class="release-overlay-title">@Title</div>
<div class="release-overlay-artist">@Artist</div>
</div>
@if (PlayContent is not null)
{
<div class="release-hero-play">
@PlayContent
</div>
}
</MudStack>
</div>
</div>
@code {
/// <summary>Background image entry key. Null renders the placeholder treatment.</summary>
[Parameter] public string? HeroImageKey { get; set; }
/// <summary>Material icon for the no-image placeholder (Session: Piano; Mix: Album).</summary>
[Parameter] public required string PlaceholderIcon { get; set; }
/// <summary>
/// Optional small cover thumbnail in the bottom row. Shown only when it differs from
/// <see cref="HeroImageKey"/> (otherwise it would duplicate the background). Mix passes null.
/// </summary>
[Parameter] public string? CoverThumbKey { get; set; }
[Parameter] public required string Title { get; set; }
[Parameter] public string? Artist { get; set; }
[Parameter] public string? Genre { get; set; }
[Parameter] public DateOnly? ReleaseDate { get; set; }
/// <summary>Share affordance slot — each page passes its own SharePopover with the right params.</summary>
[Parameter] public RenderFragment? ShareContent { get; set; }
/// <summary>Play affordance slot — each page passes its PlayStateIcon wired to its own toggle.</summary>
[Parameter] public RenderFragment? PlayContent { get; set; }
/// <summary>Extra class for per-page aspect/sizing variance (e.g. Mix's square `mix-hero`).</summary>
[Parameter] public string? Class { get; set; }
}