Files
daniel-c-harvey 912256d99a Add whole-release embeds to FramePlayer and un-gate the release embed share affordance
The queue gains an armed-but-idle state (Arm/Start) so a release embed stages track 0 prerender-safe, then queues the full release on first play and auto-advances.
2026-06-19 12:05:35 -04:00

53 lines
2.3 KiB
C#

using DeepDrftModels.DTOs;
using DeepDrftPublic.Client.Services;
namespace DeepDrftPublic.Client.ViewModels;
/// <summary>
/// Resolves the ordered track list for a release embed (<c>FramePlayer?ReleaseEntryKey=...</c>). Mirrors
/// <see cref="CutDetailViewModel"/>'s release-to-tracks resolution exactly (GetByEntryKey -> release.Id
/// -> releaseId-filtered track page sorted by TrackNumber) so an embedded release queues the same
/// ordered list the Cut detail page plays. Owns no playback or staging — the page stages the first
/// track and arms the queue; this VM only fetches. Scoped; <see cref="Tracks"/> is reset per
/// <see cref="Load"/> so a reused instance never bleeds across embeds.
/// </summary>
public class FramePlayerViewModel
{
private readonly IReleaseDataService _releaseData;
private readonly ITrackDataService _trackData;
// One page covers the whole release; the API caps PageSize at 100 regardless. Matches CutDetailViewModel.
private const int ReleasePageSize = 100;
public IReadOnlyList<TrackDto> Tracks { get; private set; } = [];
public FramePlayerViewModel(IReleaseDataService releaseData, ITrackDataService trackData)
{
_releaseData = releaseData;
_trackData = trackData;
}
/// <summary>
/// Resolves <paramref name="releaseEntryKey"/> to its ordered tracks. Leaves <see cref="Tracks"/>
/// empty when the release is not found or has no streamable tracks — the caller leaves the bar idle.
/// </summary>
public async Task Load(string releaseEntryKey)
{
Tracks = [];
var releaseResult = await _releaseData.GetByEntryKey(releaseEntryKey);
if (releaseResult is not { Success: true, Value: { } release }) return;
// The release's tracks via the releaseId-filtered page — the exact join the Cut page uses
// (internal int FK, not a title string), sorted by the explicit TrackNumber ordinal so the
// queue advances in saved order.
var trackResult = await _trackData.GetPage(
pageNumber: 1,
pageSize: ReleasePageSize,
sortColumn: "TrackNumber",
releaseId: release.Id);
if (trackResult is { Success: true, Value: { Items: { } items } })
Tracks = items.ToList();
}
}