using DeepDrftModels.DTOs; using DeepDrftPublic.Client.Services; namespace DeepDrftPublic.Client.ViewModels; /// /// State for a single-release detail page (Session, Mix). Loads the release and resolves its /// playable track. The release read surface exposes no track entry directly, so the playable track /// is resolved through the existing track gallery filtered by the release's album title — for /// Session/Mix that yields the single track. Scoped; reset every flag per so a /// reused instance never bleeds across navigations (mirrors TrackDetailViewModel). /// public class ReleaseDetailViewModel { private readonly IReleaseDataService _releaseData; private readonly ITrackDataService _trackData; public ReleaseDto? Release { get; private set; } public TrackDto? Track { get; private set; } public bool IsLoading { get; private set; } = true; public bool NotFound { get; private set; } public ReleaseDetailViewModel(IReleaseDataService releaseData, ITrackDataService trackData) { _releaseData = releaseData; _trackData = trackData; } /// Seed state directly from a bridged prerender payload — no fetch. public void Restore(ReleaseDto release, TrackDto? track) { Release = release; Track = track; NotFound = false; IsLoading = false; } public async Task Load(long releaseId) { IsLoading = true; NotFound = false; Release = null; Track = null; try { var releaseResult = await _releaseData.GetById(releaseId); if (releaseResult is not { Success: true, Value: { } release }) { NotFound = true; return; } Release = release; // Resolve the playable track via the album-filtered track page. Session/Mix releases // carry a single track; take the first. A release with no streamable track simply // leaves Track null (the detail page hides the play affordance). var trackResult = await _trackData.GetPage( pageNumber: 1, pageSize: 1, album: release.Title); if (trackResult is { Success: true, Value: { Items: { } items } }) Track = items.FirstOrDefault(); } finally { IsLoading = false; } } }