Files
ersatztv/ErsatzTV/Controllers/Api/Requests/ReplacePlaylistRequest.cs
T
timothy ffece01c32
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
style: #265 — normalize whitespace in the 11 touched files (format gate #311)
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
2026-07-12 23:21:00 +02:00

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();
}