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.
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user