@ -2,17 +2,16 @@
@@ -2,17 +2,16 @@
@using ErsatzTV.Application.MediaCollections
@using ErsatzTV.Application.MediaItems
@using ErsatzTV.Application.ProgramSchedules
@using ErsatzTV.Application.Television
@using ErsatzTV.Application.Watermarks
@using ErsatzTV.Application.Filler
@using System.Globalization
@using ErsatzTV.Core.Domain.Filler
@using ErsatzTV.Application.Artists
@using ErsatzTV.Application.Search
@implements IDisposable
@inject NavigationManager _n avigationManager
@inject ILogger<ScheduleItemsEditor> _l ogger
@inject ISnackbar _s nackbar
@inject IMediator _m ediator
@inject NavigationManager N avigationManager
@inject ILogger<ScheduleItemsEditor> L ogger
@inject ISnackbar S nackbar
@inject IMediator M ediator
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<MudTable Hover="true" Items="_schedule.Items.OrderBy(i => i.Index)" Dense="true" @bind-SelectedItem="_selectedItem">
@ -104,82 +103,86 @@
@@ -104,82 +103,86 @@
</MudSelect>
<MudTimePicker Class="mt-3" Label="Start Time" @bind-Time="@_selectedItem.StartTime" For="@(() => _selectedItem.StartTime)" Disabled="@(_selectedItem.StartType == StartType.Dynamic)"/>
<MudSelect Class="mt-3" Label="Collection Type" @bind-Value="_selectedItem.CollectionType" For="@(() => _selectedItem.CollectionType)">
@foreach (ProgramScheduleItemCollectionType collectionType in Enum.GetValues<ProgramScheduleItemCollectionType>())
{
<MudSelectItem Value="@collectionType">@collectionType</MudSelectItem>
}
<MudSelectItem Value="ProgramScheduleItemCollectionType.Collection">Collection</MudSelectItem>
<MudSelectItem Value="ProgramScheduleItemCollectionType.TelevisionShow">Television Show</MudSelectItem>
<MudSelectItem Value="ProgramScheduleItemCollectionType.TelevisionSeason">Television Season</MudSelectItem>
<MudSelectItem Value="ProgramScheduleItemCollectionType.Artist">Artist</MudSelectItem>
<MudSelectItem Value="ProgramScheduleItemCollectionType.MultiCollection">Multi Collection</MudSelectItem>
<MudSelectItem Value="ProgramScheduleItemCollectionType.SmartCollection">Smart Collection</MudSelectItem>
</MudSelect>
@if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.Collection)
{
<MudSelect Class="mt-3 "
T="MediaCollectionViewModel "
Label="Collection"
@bind-value="_selectedItem.Collection" >
@foreach (MediaCollectionViewModel collection in _mediaCollections)
{
<MudSelectItem Value="@collection">@collection.Name</MudSelectItem >
}
</MudSelect >
<MudAutocomplete Class="mt-3" T="MediaCollectionViewModel" Label="Collection "
@bind-Value="_selectedItem.Collection" SearchFunc="@SearchCollections "
ToStringFunc="@(c=> c.Name)" Placeholder="Type to search...">
<MoreItemsTemplate >
<MudText Align="Align.Center" Class="px-4 py-1">
Only the first 10 items are shown
</MudText >
</MoreItemsTemplate>
</MudAutocomplete >
}
@if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.MultiCollection)
{
<MudSelect Class="mt-3 "
T="MultiCollectionViewModel "
Label="Multi Collection"
@bind-value="_selectedItem.MultiCollection" >
@foreach (MultiCollectionViewModel collection in _multiCollections)
{
<MudSelectItem Value="@collection">@collection.Name</MudSelectItem >
}
</MudSelect >
<MudAutocomplete Class="mt-3" T="MultiCollectionViewModel" Label="Multi Collection "
@bind-Value="_selectedItem.MultiCollection" SearchFunc="@SearchMultiCollections "
ToStringFunc="@(c=> c.Name)" Placeholder="Type to search...">
<MoreItemsTemplate >
<MudText Align="Align.Center" Class="px-4 py-1">
Only the first 10 items are shown
</MudText >
</MoreItemsTemplate>
</MudAutocomplete >
}
@if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.SmartCollection)
{
<MudSelect Class="mt-3 "
T="SmartCollectionViewModel "
Label="Smart Collection"
@bind-value="_selectedItem.SmartCollection" >
@foreach (SmartCollectionViewModel collection in _smartCollections)
{
<MudSelectItem Value="@collection">@collection.Name</MudSelectItem >
}
</MudSelect >
<MudAutocomplete Class="mt-3" T="SmartCollectionViewModel" Label="Smart Collection "
@bind-Value="_selectedItem.SmartCollection" SearchFunc="@SearchSmartCollections "
ToStringFunc="@(c=> c.Name)" Placeholder="Type to search...">
<MoreItemsTemplate >
<MudText Align="Align.Center" Class="px-4 py-1">
Only the first 10 items are shown
</MudText >
</MoreItemsTemplate>
</MudAutocomplete >
}
@if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.TelevisionShow)
{
<MudSelect Class="mt-3 "
T="NamedMediaItemViewModel "
Label="Television Show"
@bind-value="_selectedItem.MediaItem" >
@foreach (NamedMediaItemViewModel show in _televisionShows)
{
<MudSelectItem Value="@show">@show.Name</MudSelectItem >
}
</MudSelect >
<MudAutocomplete Class="mt-3" T="NamedMediaItemViewModel" Label="Television Show "
@bind-Value="_selectedItem.MediaItem" SearchFunc="@SearchTelevisionShows "
ToStringFunc="@(c=> c.Name)" Placeholder="Type to search...">
<MoreItemsTemplate >
<MudText Align="Align.Center" Class="px-4 py-1">
Only the first 10 items are shown
</MudText >
</MoreItemsTemplate>
</MudAutocomplete >
}
@if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.TelevisionSeason)
{
<MudSelect Class="mt-3"
T="NamedMediaItemViewModel"
Label="Television Season"
@bind-value="_selectedItem.MediaItem">
@foreach (NamedMediaItemViewModel season in _televisionSeasons)
{
<MudSelectItem Value="@season">@season.Name</MudSelectItem>
}
</MudSelect>
<MudAutocomplete Class="mt-3" T="NamedMediaItemViewModel" Label="Television Season"
@bind-Value="_selectedItem.MediaItem" SearchFunc="@SearchTelevisionSeasons"
ToStringFunc="@(c=> c.Name)" Placeholder="Type to search..."
MaxItems="20">
<MoreItemsTemplate>
<MudText Align="Align.Center" Class="px-4 py-1">
Only the first 20 items are shown
</MudText>
</MoreItemsTemplate>
</MudAutocomplete>
}
@if (_selectedItem.CollectionType == ProgramScheduleItemCollectionType.Artist)
{
<MudSelect Class="mt-3"
T="NamedMediaItemViewModel"
Label="Artist"
@bind-value="_selectedItem.MediaItem">
@foreach (NamedMediaItemViewModel artist in _artists)
{
<MudSelectItem Value="@artist">@artist.Name</MudSelectItem>
}
</MudSelect>
<MudAutocomplete Class="mt-3" T="NamedMediaItemViewModel" Label="Artist"
@bind-Value="_selectedItem.MediaItem" SearchFunc="@SearchArtists"
ToStringFunc="@(c=> c.Name)" Placeholder="Type to search..."
MaxItems="10">
<MoreItemsTemplate>
<MudText Align="Align.Center" Class="px-4 py-1">
Only the first 10 items are shown
</MudText>
</MoreItemsTemplate>
</MudAutocomplete>
}
<MudSelect Class="mt-3" Label="Playback Order" @bind-Value="@_selectedItem.PlaybackOrder" For="@(() => _selectedItem.PlaybackOrder)">
@switch (_selectedItem.CollectionType)
@ -338,12 +341,6 @@
@@ -338,12 +341,6 @@
public int Id { get; set; }
private ProgramScheduleItemsEditViewModel _schedule;
private List<MediaCollectionViewModel> _mediaCollections;
private List<MultiCollectionViewModel> _multiCollections;
private List<SmartCollectionViewModel> _smartCollections;
private List<NamedMediaItemViewModel> _televisionShows;
private List<NamedMediaItemViewModel> _televisionSeasons;
private List<NamedMediaItemViewModel> _artists;
private List<FillerPresetViewModel> _fillerPresets;
private List<WatermarkViewModel> _watermarks;
private List<CultureInfo> _availableCultures;
@ -361,34 +358,23 @@
@@ -361,34 +358,23 @@
private async Task LoadScheduleItems()
{
// TODO: fix performance
_mediaCollections = await _mediator.Send(new GetAllCollections(), _cts.Token)
.Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList());
_multiCollections = await _mediator.Send(new GetAllMultiCollections(), _cts.Token)
.Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList());
_smartCollections = await _mediator.Send(new GetAllSmartCollections(), _cts.Token)
.Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList());
_televisionShows = await _mediator.Send(new GetAllTelevisionShows(), _cts.Token)
.Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList());
_televisionSeasons = await _mediator.Send(new GetAllTelevisionSeasons(), _cts.Token)
.Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList());
_artists = await _mediator.Send(new GetAllArtists(), _cts.Token)
_fillerPresets = await Mediator.Send(new GetAllFillerPresets(), _cts.Token)
.Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList());
_fillerPresets = await _mediator.Send(new GetAllFillerPreset s(), _cts.Token)
_watermarks = await Mediator.Send(new GetAllWatermarks(), _cts.Token)
.Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList());
_watermarks = await _mediator.Send(new GetAllWatermarks(), _cts.Token)
.Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList());
_availableCultures = await _mediator.Send(new GetAllLanguageCodes(), _cts.Token);
_availableCultures = await Mediator.Send(new GetAllLanguageCodes(), _cts.Token);
string name = string.Empty;
var shuffleScheduleItems = false;
Option<ProgramScheduleViewModel> maybeSchedule = await _m ediator.Send(new GetProgramScheduleById(Id), _cts.Token);
Option<ProgramScheduleViewModel> maybeSchedule = await Mediator.Send(new GetProgramScheduleById(Id), _cts.Token);
foreach (ProgramScheduleViewModel schedule in maybeSchedule)
{
name = schedule.Name;
shuffleScheduleItems = schedule.ShuffleScheduleItems;
}
Option<IEnumerable<ProgramScheduleItemViewModel>> maybeResults = await _mediator.Send(new GetProgramScheduleItems(Id), _cts.Token);
Option<IEnumerable<ProgramScheduleItemViewModel>> maybeResults =
await Mediator.Send(new GetProgramScheduleItems(Id), _cts.Token);
foreach (IEnumerable<ProgramScheduleItemViewModel> items in maybeResults)
{
_schedule = new ProgramScheduleItemsEditViewModel
@ -405,6 +391,66 @@
@@ -405,6 +391,66 @@
}
}
private async Task<IEnumerable<MediaCollectionViewModel>> SearchCollections(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return new List<MediaCollectionViewModel>();
}
return await Mediator.Send(new SearchCollections(value), _cts.Token);
}
private async Task<IEnumerable<MultiCollectionViewModel>> SearchMultiCollections(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return new List<MultiCollectionViewModel>();
}
return await Mediator.Send(new SearchMultiCollections(value), _cts.Token);
}
private async Task<IEnumerable<SmartCollectionViewModel>> SearchSmartCollections(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return new List<SmartCollectionViewModel>();
}
return await Mediator.Send(new SearchSmartCollections(value), _cts.Token);
}
private async Task<IEnumerable<NamedMediaItemViewModel>> SearchTelevisionShows(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return new List<NamedMediaItemViewModel>();
}
return await Mediator.Send(new SearchTelevisionShows(value), _cts.Token);
}
private async Task<IEnumerable<NamedMediaItemViewModel>> SearchTelevisionSeasons(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return new List<NamedMediaItemViewModel>();
}
return await Mediator.Send(new SearchTelevisionSeasons(value), _cts.Token);
}
private async Task<IEnumerable<NamedMediaItemViewModel>> SearchArtists(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return new List<NamedMediaItemViewModel>();
}
return await Mediator.Send(new SearchArtists(value), _cts.Token);
}
private ProgramScheduleItemEditViewModel ProjectToEditViewModel(ProgramScheduleItemViewModel item)
{
var result = new ProgramScheduleItemEditViewModel
@ -512,15 +558,15 @@
@@ -512,15 +558,15 @@
item.PreferredSubtitleLanguageCode,
item.SubtitleMode)).ToList();
Seq<BaseError> errorMessages = await _m ediator.Send(new ReplaceProgramScheduleItems(Id, items), _cts.Token).Map(e => e.LeftToSeq());
Seq<BaseError> errorMessages = await M ediator.Send(new ReplaceProgramScheduleItems(Id, items), _cts.Token).Map(e => e.LeftToSeq());
errorMessages.HeadOrNone().Match(
error =>
{
_s nackbar.Add($"Unexpected error saving schedule: {error.Value}", Severity.Error);
_l ogger.LogError("Unexpected error saving schedule: {Error}", error.Value);
S nackbar.Add($"Unexpected error saving schedule: {error.Value}", Severity.Error);
L ogger.LogError("Unexpected error saving schedule: {Error}", error.Value);
},
() => _n avigationManager.NavigateTo("/schedules"));
() => N avigationManager.NavigateTo("/schedules"));
}
}