Files
ersatztv/ErsatzTV.Application/ProgramSchedules/ProgramScheduleItemViewModel.cs
T
timothyandClaude Fable 5 d0652d4adb wip: partial implementation salvaged from interrupted workflow run
Untrusted draft — no build/test had run yet. Review before building on it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 23:41:57 +02:00

98 lines
4.2 KiB
C#

using ErsatzTV.Application.Filler;
using ErsatzTV.Application.Graphics;
using ErsatzTV.Application.MediaCollections;
using ErsatzTV.Application.MediaItems;
using ErsatzTV.Application.Watermarks;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Scheduling;
namespace ErsatzTV.Application.ProgramSchedules;
public abstract record ProgramScheduleItemViewModel(
int Id,
int Index,
StartType StartType,
TimeSpan? StartTime,
FixedStartTimeBehavior? FixedStartTimeBehavior,
PlayoutMode PlayoutMode,
CollectionType CollectionType,
MediaCollectionViewModel Collection,
MultiCollectionViewModel MultiCollection,
SmartCollectionViewModel SmartCollection,
RerunCollectionViewModel RerunCollection,
PlaylistViewModel Playlist,
NamedMediaItemViewModel MediaItem,
string SearchTitle,
string SearchQuery,
PlaybackOrder PlaybackOrder,
MarathonGroupBy MarathonGroupBy,
bool MarathonShuffleGroups,
bool MarathonShuffleItems,
int? MarathonBatchSize,
FillWithGroupMode FillWithGroupMode,
string CustomTitle,
GuideMode GuideMode,
FillerPresetViewModel PreRollFiller,
FillerPresetViewModel MidRollFiller,
FillerPresetViewModel PostRollFiller,
FillerPresetViewModel TailFiller,
FillerPresetViewModel FallbackFiller,
List<WatermarkViewModel> Watermarks,
List<GraphicsElementViewModel> GraphicsElements,
string PreferredAudioLanguageCode,
string PreferredAudioTitle,
string PreferredSubtitleLanguageCode,
ChannelSubtitleMode? SubtitleMode)
{
/// <summary>
/// A rough estimate, in wall-clock time, of how long a single pass of this schedule item will play,
/// derived from the aggregated runtimes (<c>MediaVersion.Duration</c>) of the referenced content.
/// <para>
/// Semantics by <see cref="PlayoutMode" />:
/// <list type="bullet">
/// <item><b>One</b> — the average runtime of one item in the referenced collection.</item>
/// <item>
/// <b>Multiple</b> — the average item runtime multiplied by the configured count
/// (<see cref="MultipleMode.Count" />), or the whole collection runtime for
/// <see cref="MultipleMode.CollectionSize" />.
/// </item>
/// <item><b>Flood</b> — always <c>null</c>: a flood item fills the remaining time and is unbounded.</item>
/// <item>
/// <b>Duration</b> — always <c>null</c>: its runtime is the explicit
/// <c>playoutDuration</c> setting already present on the item, so it is not re-derived here.
/// </item>
/// </list>
/// </para>
/// <para>
/// <c>null</c> whenever a bounded estimate cannot be produced — an unbounded mode (Flood/Duration),
/// a referenced collection with no items that have a known non-zero duration, a Multiple mode other
/// than Count/CollectionSize, or a collection type other than <see cref="CollectionType.Collection" />
/// (smart/multi/playlist/search/rerun/show/season/artist references are not aggregated in this pass).
/// Callers should treat a <c>null</c> as "unknown", never as zero.
/// </para>
/// </summary>
public TimeSpan? DurationEstimate { get; init; }
public string Name => CollectionType switch
{
CollectionType.Collection => Collection?.Name,
CollectionType.TelevisionShow =>
MediaItem?.Name, // $"{TelevisionShow?.Title} ({TelevisionShow?.Year})",
CollectionType.TelevisionSeason =>
MediaItem?.Name, // $"{TelevisionSeason?.Title} ({TelevisionSeason?.Plot})",
CollectionType.Artist =>
MediaItem?.Name,
CollectionType.MultiCollection =>
MultiCollection?.Name,
CollectionType.SmartCollection =>
SmartCollection?.Name,
CollectionType.SearchQuery =>
string.IsNullOrWhiteSpace(SearchTitle) ? SearchQuery : SearchTitle,
CollectionType.Playlist =>
Playlist?.Name,
CollectionType.RerunFirstRun or CollectionType.RerunRerun =>
RerunCollection?.Name,
_ => string.Empty
};
}