@page "/schedules/{Id:int}/items" @using ErsatzTV.Application.MediaCollections @using ErsatzTV.Application.MediaCollections.Queries @using ErsatzTV.Application.MediaItems @using ErsatzTV.Application.ProgramSchedules @using ErsatzTV.Application.ProgramSchedules.Commands @using ErsatzTV.Application.ProgramSchedules.Queries @using ErsatzTV.Application.Television.Queries @using ErsatzTV.Application.Artists.Queries @using ErsatzTV.Application.Filler @using ErsatzTV.Application.Filler.Queries @using ErsatzTV.Core.Domain.Filler @inject NavigationManager _navigationManager @inject ILogger _logger @inject ISnackbar _snackbar @inject IMediator _mediator @_schedule.Name Items Start Time Collection Playout Mode @(context.StartType == StartType.Fixed ? context.StartTime == null ? string.Empty : DateTime.Today.Add(context.StartTime.Value).ToShortTimeString() : "Dynamic") @context.CollectionName @context.PlayoutMode @if (context.PlayoutMode == PlayoutMode.Multiple && context.MultipleCount.HasValue) { @($" ({context.MultipleCount})") } Add Schedule Item Save Changes @if (_selectedItem is not null) {
@foreach (StartType startType in Enum.GetValues()) { @startType } @foreach (ProgramScheduleItemCollectionType collectionType in Enum.GetValues()) { @collectionType } @if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.Collection) { @foreach (MediaCollectionViewModel collection in _mediaCollections) { @collection.Name } } @if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.MultiCollection) { @foreach (MultiCollectionViewModel collection in _multiCollections) { @collection.Name } } @if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.SmartCollection) { @foreach (SmartCollectionViewModel collection in _smartCollections) { @collection.Name } } @if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.TelevisionShow) { @foreach (NamedMediaItemViewModel show in _televisionShows) { @show.Name } } @if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.TelevisionSeason) { @foreach (NamedMediaItemViewModel season in _televisionSeasons) { @season.Name } } @if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.Artist) { @foreach (NamedMediaItemViewModel artist in _artists) { @artist.Name } } @switch (_selectedItem.CollectionType) { case ProgramScheduleItemCollectionType.MultiCollection: Shuffle Shuffle In Order break; case ProgramScheduleItemCollectionType.Collection: case ProgramScheduleItemCollectionType.SmartCollection: Chronological Random Shuffle Shuffle In Order break; default: Chronological Random Shuffle break; } @foreach (PlayoutMode playoutMode in Enum.GetValues()) { @playoutMode } (none) Offline Filler Normal Filler
@foreach (FillerPresetViewModel filler in _fillerPresets.Where(f => f.FillerKind == FillerKind.PreRoll)) { @filler.Name } @foreach (FillerPresetViewModel filler in _fillerPresets.Where(f => f.FillerKind == FillerKind.MidRoll)) { @filler.Name } @foreach (FillerPresetViewModel filler in _fillerPresets.Where(f => f.FillerKind == FillerKind.PostRoll)) { @filler.Name } @foreach (FillerPresetViewModel filler in _fillerPresets.Where(f => f.FillerKind == FillerKind.Tail)) { @filler.Name } @foreach (FillerPresetViewModel filler in _fillerPresets.Where(f => f.FillerKind == FillerKind.Fallback)) { @filler.Name }
}
@code { [Parameter] public int Id { get; set; } private ProgramScheduleItemsEditViewModel _schedule; private List _mediaCollections; private List _multiCollections; private List _smartCollections; private List _televisionShows; private List _televisionSeasons; private List _artists; private List _fillerPresets; private ProgramScheduleItemEditViewModel _selectedItem; protected override Task OnParametersSetAsync() => LoadScheduleItems(); private async Task LoadScheduleItems() { // TODO: fix performance _mediaCollections = await _mediator.Send(new GetAllCollections()) .Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList()); _multiCollections = await _mediator.Send(new GetAllMultiCollections()) .Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList()); _smartCollections = await _mediator.Send(new GetAllSmartCollections()) .Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList()); _televisionShows = await _mediator.Send(new GetAllTelevisionShows()) .Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList()); _televisionSeasons = await _mediator.Send(new GetAllTelevisionSeasons()) .Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList()); _artists = await _mediator.Send(new GetAllArtists()) .Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList()); _fillerPresets = await _mediator.Send(new GetAllFillerPresets()) .Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList()); string name = string.Empty; Option maybeSchedule = await _mediator.Send(new GetProgramScheduleById(Id)); maybeSchedule.IfSome(vm => name = vm.Name); Option> maybeResults = await _mediator.Send(new GetProgramScheduleItems(Id)); foreach (IEnumerable items in maybeResults) { _schedule = new ProgramScheduleItemsEditViewModel { Name = name, Items = items.Map(ProjectToEditViewModel).ToList() }; if (_schedule.Items.Count == 1) { _selectedItem = _schedule.Items.Head(); } } } private ProgramScheduleItemEditViewModel ProjectToEditViewModel(ProgramScheduleItemViewModel item) { var result = new ProgramScheduleItemEditViewModel { Id = item.Id, Index = item.Index, StartType = item.StartType, StartTime = item.StartTime, PlayoutMode = item.PlayoutMode, CollectionType = item.CollectionType, Collection = item.Collection, MultiCollection = item.MultiCollection, SmartCollection = item.SmartCollection, MediaItem = item.MediaItem, PlaybackOrder = item.PlaybackOrder, CustomTitle = item.CustomTitle, GuideMode = item.GuideMode, PreRollFiller = item.PreRollFiller, MidRollFiller = item.MidRollFiller, PostRollFiller = item.PostRollFiller, TailFiller = item.TailFiller, FallbackFiller = item.FallbackFiller }; switch (item) { case ProgramScheduleItemMultipleViewModel multiple: result.MultipleCount = multiple.Count; break; case ProgramScheduleItemDurationViewModel duration: result.PlayoutDuration = duration.PlayoutDuration; result.TailMode = duration.TailMode; break; } return result; } private void AddScheduleItem() { var item = new ProgramScheduleItemEditViewModel { Index = _schedule.Items.Map(i => i.Index).DefaultIfEmpty().Max() + 1, StartType = StartType.Dynamic, PlayoutMode = PlayoutMode.One, PlaybackOrder = PlaybackOrder.Shuffle, CollectionType = ProgramScheduleItemCollectionType.Collection }; _schedule.Items.Add(item); _selectedItem = item; } private void RemoveScheduleItem(ProgramScheduleItemEditViewModel item) { _selectedItem = null; _schedule.Items.Remove(item); } private void MoveItemUp(ProgramScheduleItemEditViewModel item) { // swap with lower index ProgramScheduleItemEditViewModel toSwap = _schedule.Items.OrderByDescending(x => x.Index).First(x => x.Index < item.Index); (toSwap.Index, item.Index) = (item.Index, toSwap.Index); } private void MoveItemDown(ProgramScheduleItemEditViewModel item) { // swap with higher index ProgramScheduleItemEditViewModel toSwap = _schedule.Items.OrderBy(x => x.Index).First(x => x.Index > item.Index); (toSwap.Index, item.Index) = (item.Index, toSwap.Index); } private Task> SearchFillerPresets(FillerKind fillerKind, string value) => _fillerPresets.Filter(p => p.FillerKind == fillerKind && p.Name.Contains(value ?? string.Empty, StringComparison.OrdinalIgnoreCase)).AsTask(); private async Task SaveChanges() { var items = _schedule.Items.Map(item => new ReplaceProgramScheduleItem( item.Index, item.StartType, item.StartTime, item.PlayoutMode, item.CollectionType, item.Collection?.Id, item.MultiCollection?.Id, item.SmartCollection?.Id, item.MediaItem?.MediaItemId, item.PlaybackOrder, item.MultipleCount, item.PlayoutDuration, item.TailMode, item.CustomTitle, item.GuideMode, item.PreRollFiller?.Id, item.MidRollFiller?.Id, item.PostRollFiller?.Id, item.TailFiller?.Id, item.FallbackFiller?.Id)).ToList(); Seq errorMessages = await _mediator.Send(new ReplaceProgramScheduleItems(Id, items)).Map(e => e.LeftToSeq()); errorMessages.HeadOrNone().Match( error => { _snackbar.Add($"Unexpected error saving schedule: {error.Value}", Severity.Error); _logger.LogError("Unexpected error saving schedule: {Error}", error.Value); }, () => _navigationManager.NavigateTo("/schedules")); } }