Build ErsatzTV Image / Docs update reminder (pull_request) Successful in 13s
Build ErsatzTV Image / decisions.md append-only (pull_request) Successful in 13s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 1m29s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 2m56s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 8m21s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 10m21s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
The fix-as-you-touch format gate requires every .cs this PR touches to fully conform to .editorconfig, including pre-existing whitespace on lines the change didn't edit. dotnet format (whitespace) applied to the 11 touched files; legacy files left untouched (no big-bang reformat). Whitespace/layout only — no behavior change. Refs #265
88 lines
3.0 KiB
C#
88 lines
3.0 KiB
C#
#nullable enable
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using ErsatzTV.Application.MediaCollections;
|
|
using ErsatzTV.Core.Domain;
|
|
using LanguageExt;
|
|
|
|
namespace ErsatzTV.Controllers.Api.Requests;
|
|
|
|
public record PlaylistItemRequest(
|
|
int Index,
|
|
CollectionType CollectionType,
|
|
int? CollectionId,
|
|
int? MultiCollectionId,
|
|
int? SmartCollectionId,
|
|
int? MediaItemId,
|
|
PlaybackOrder PlaybackOrder,
|
|
int? Count,
|
|
bool PlayAll,
|
|
bool IncludeInProgramGuide)
|
|
{
|
|
public ReplacePlaylistItem ToReplaceCommand(int index) =>
|
|
new(
|
|
index,
|
|
CollectionType,
|
|
CollectionId,
|
|
MultiCollectionId,
|
|
SmartCollectionId,
|
|
MediaItemId,
|
|
PlaybackOrder,
|
|
Count,
|
|
PlayAll,
|
|
IncludeInProgramGuide);
|
|
|
|
// Mirrors ReplacePlaylistItemsHandler.CollectionTypeMustBeValid: the id required for the
|
|
// item's collection type must be present. Kept in sync with that handler so the PUT and
|
|
// preview endpoints enforce the same rule (the handler operates on the command type in the
|
|
// Application layer and cannot reference this request DTO, hence the parallel logic).
|
|
public bool HasRequiredId() =>
|
|
CollectionType switch
|
|
{
|
|
CollectionType.Collection => CollectionId is not null,
|
|
CollectionType.MultiCollection => MultiCollectionId is not null,
|
|
CollectionType.SmartCollection => SmartCollectionId is not null,
|
|
CollectionType.TelevisionShow
|
|
or CollectionType.TelevisionSeason
|
|
or CollectionType.Artist
|
|
or CollectionType.Movie
|
|
or CollectionType.Episode
|
|
or CollectionType.MusicVideo
|
|
or CollectionType.OtherVideo
|
|
or CollectionType.Song
|
|
or CollectionType.Image => MediaItemId is not null,
|
|
_ => false
|
|
};
|
|
}
|
|
|
|
public record ReplacePlaylistRequest(string? Name, List<PlaylistItemRequest>? Items)
|
|
{
|
|
public ReplacePlaylistItems ToCommand(int id, Option<Seq<int>> expectedVersions = default) =>
|
|
new(id, Name ?? string.Empty, BuildItems(), expectedVersions);
|
|
|
|
// Preview operates on the posted draft, so there is no persisted playlist id (0).
|
|
public ReplacePlaylistItems ToReplaceCommand() =>
|
|
new(0, Name ?? string.Empty, BuildItems());
|
|
|
|
// Array indexes of draft items missing the id required for their collection type.
|
|
public List<int> ItemsMissingRequiredId()
|
|
{
|
|
List<PlaylistItemRequest> items = Items ?? new List<PlaylistItemRequest>();
|
|
var invalid = new List<int>();
|
|
for (int i = 0; i < items.Count; i++)
|
|
{
|
|
if (!items[i].HasRequiredId())
|
|
{
|
|
invalid.Add(i);
|
|
}
|
|
}
|
|
|
|
return invalid;
|
|
}
|
|
|
|
private List<ReplacePlaylistItem> BuildItems() =>
|
|
(Items ?? new List<PlaylistItemRequest>())
|
|
.Select((item, index) => item.ToReplaceCommand(index))
|
|
.ToList();
|
|
}
|