Files
deepdrft/DeepDrftManager/Services/CmsTrackBrowserViewModel.cs
T
daniel-c-harvey 2f47efeb46 CMS Phase 9 Wave 3: Release Archive tab, medium selector, Session/Mix browsers
Renames Genre tab to Release Archive with switch-free medium card group
(Enum.GetValues-driven). Adds MediumFields single dispatch + CutFields/SessionFields/
MixFields per-medium sections embedded by all five upload/edit forms. BatchUpload
enforces single-track invariant for Session/Mix. Adds CmsSessionBrowser (hero-image
upload) and CmsMixBrowser (waveform status + per-row Generate trigger).
ICmsReleaseService/CmsReleaseService wraps api/release endpoints.
Note: medium selector is forward-compat only — API write path pending.
2026-06-12 23:07:15 -04:00

86 lines
3.0 KiB
C#

using DeepDrftModels.DTOs;
namespace DeepDrftManager.Services;
/// <summary>The browse dimensions for the /tracks page.</summary>
public enum BrowseMode
{
Tracks,
Albums,
Archive,
Genres,
}
/// <summary>
/// Holds the /tracks browser's current mode plus the album- and genre-mode datasets. Scoped per
/// circuit. Album and genre lists are fetched lazily on first switch into their mode and cached for
/// the circuit's lifetime; Track mode owns its own paging inside <c>CmsTrackGrid</c> and needs no
/// state here.
/// </summary>
public class CmsTrackBrowserViewModel
{
private readonly ICmsTrackService _trackService;
public CmsTrackBrowserViewModel(ICmsTrackService trackService)
{
_trackService = trackService;
}
public BrowseMode Mode { get; private set; } = BrowseMode.Tracks;
// Album mode.
public IReadOnlyList<ReleaseDto> Albums { get; private set; } = Array.Empty<ReleaseDto>();
public bool AlbumsLoading { get; private set; }
// Genre mode.
public IReadOnlyList<GenreSummaryDto> Genres { get; private set; } = Array.Empty<GenreSummaryDto>();
public bool GenresLoading { get; private set; }
public string? ExpandedGenre { get; private set; }
/// <summary>
/// Switch the active mode, lazily loading the album or genre dataset on first entry. Collapses
/// any expanded genre row. The grid in Track mode owns its own data, so no fetch happens there.
/// </summary>
public async Task SwitchModeAsync(BrowseMode mode)
{
Mode = mode;
ExpandedGenre = null; // collapse on mode switch
if (mode == BrowseMode.Albums && Albums.Count == 0 && !AlbumsLoading)
{
AlbumsLoading = true;
var result = await _trackService.GetReleasesAsync();
Albums = result.Success && result.Value is not null
? result.Value
: Array.Empty<ReleaseDto>();
AlbumsLoading = false;
}
else if (mode == BrowseMode.Genres && Genres.Count == 0 && !GenresLoading)
{
GenresLoading = true;
var result = await _trackService.GetGenreSummariesAsync();
Genres = result.Success && result.Value is not null
? result.Value
: Array.Empty<GenreSummaryDto>();
GenresLoading = false;
}
}
/// <summary>Toggle the expanded genre row. Selecting the already-expanded genre collapses it.</summary>
public void SetExpandedGenre(string? genre)
{
ExpandedGenre = ExpandedGenre == genre ? null : genre;
}
/// <summary>
/// Drop the cached album and genre datasets so the next <see cref="SwitchModeAsync"/> into
/// either mode re-fetches from the API. Call after a track or release mutation (edit, delete)
/// since both datasets are derived from the catalogue and go stale on any such change.
/// </summary>
public void Invalidate()
{
Albums = Array.Empty<ReleaseDto>();
Genres = Array.Empty<GenreSummaryDto>();
}
}