refactor(public): retire track-cardinal stack, fold Archive/Cuts cards into ReleaseGallery (P11 W3 §4)

This commit is contained in:
daniel-c-harvey
2026-06-16 11:31:02 -04:00
parent d98ead97c3
commit ef6d21b94e
32 changed files with 70 additions and 1353 deletions
@@ -1,9 +1,14 @@
@namespace DeepDrftPublic.Client.Controls
@* Card grid of releases that open their own detail page (/{DetailRoute}/{id}). Shared by the
Sessions and Mixes browse pages. Cuts intentionally do not use this they open the track
gallery filtered by album, a different navigation target. Fully controlled by the parent:
loading and item state are passed in. *@
@* The single release-card grid for every browse surface (Sessions, Mixes, Cuts, Archive). Cards
open a detail page; how a card computes its href is the only real divergence across surfaces, so
the parent supplies it one of two ways:
- DetailRoute (the simple default): every card links /{DetailRoute}/{id} (Sessions, Mixes).
- HrefResolver (per-card): each card links HrefResolver(release), so Archive routes each card by
its own medium through the one ReleaseRoutes table, and Cuts routes to /cuts/{id}.
HrefResolver wins when both are supplied. The card subtitle defaults to the artist; SubtitleResolver
overrides it (Cuts shows a track count instead). Fully controlled by the parent: loading and item
state are passed in. *@
<div>
<MudContainer MaxWidth="MaxWidth.Large" Class="release-gallery-container">
@@ -33,7 +38,7 @@
{
<MudItem xs="12" sm="6" md="4" lg="3" xl="3">
<div class="release-card-center">
<a href="@($"/{DetailRoute}/{release.Id}")" class="release-card-link">
<a href="@CardHref(release)" class="release-card-link">
<div class="release-card">
@if (!string.IsNullOrEmpty(release.ImagePath))
{
@@ -51,7 +56,7 @@
@release.Title
</MudText>
<MudText Typo="Typo.caption" Class="release-card-artist text-truncate">
@release.Artist
@(SubtitleResolver?.Invoke(release) ?? release.Artist)
</MudText>
</div>
</div>
@@ -68,8 +73,27 @@
[Parameter] public required IReadOnlyList<DeepDrftModels.DTOs.ReleaseDto> Releases { get; set; }
[Parameter] public bool Loading { get; set; }
/// <summary>Route segment for a card's detail page; a card links to /{DetailRoute}/{id}.</summary>
[Parameter] public required string DetailRoute { get; set; }
/// <summary>
/// Route segment for a card's detail page; a card links to /{DetailRoute}/{id}. The simple
/// fixed-route default used by Sessions/Mixes. Ignored when <see cref="HrefResolver"/> is supplied.
/// </summary>
[Parameter] public string? DetailRoute { get; set; }
/// <summary>
/// Per-card href resolver. When supplied, a card links to its result instead of the
/// <see cref="DetailRoute"/>-based href, letting Archive route each card by its own medium and
/// Cuts route to /cuts/{id} (both via <c>ReleaseRoutes.DetailHref</c>).
/// </summary>
[Parameter] public Func<DeepDrftModels.DTOs.ReleaseDto, string>? HrefResolver { get; set; }
/// <summary>
/// Optional override for a card's subtitle line (defaults to the release artist). Cuts pass a
/// track-count label here.
/// </summary>
[Parameter] public Func<DeepDrftModels.DTOs.ReleaseDto, string>? SubtitleResolver { get; set; }
[Parameter] public string EmptyMessage { get; set; } = "Nothing here yet";
private string CardHref(DeepDrftModels.DTOs.ReleaseDto release)
=> HrefResolver?.Invoke(release) ?? $"/{DetailRoute}/{release.Id}";
}