improve schedule editor performance (#1240)
* rename * async cleanup * use autocomplete fields in schedule items editor
This commit is contained in:
@@ -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 _navigationManager
|
||||
@inject ILogger<ScheduleItemsEditor> _logger
|
||||
@inject ISnackbar _snackbar
|
||||
@inject IMediator _mediator
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject ILogger<ScheduleItemsEditor> Logger
|
||||
@inject ISnackbar Snackbar
|
||||
@inject IMediator Mediator
|
||||
|
||||
<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 @@
|
||||
</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 @@
|
||||
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 @@
|
||||
private async Task LoadScheduleItems()
|
||||
{
|
||||
// TODO: fix performance
|
||||
_mediaCollections = await _mediator.Send(new GetAllCollections(), _cts.Token)
|
||||
_fillerPresets = await Mediator.Send(new GetAllFillerPresets(), _cts.Token)
|
||||
.Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList());
|
||||
_multiCollections = await _mediator.Send(new GetAllMultiCollections(), _cts.Token)
|
||||
_watermarks = await Mediator.Send(new GetAllWatermarks(), _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)
|
||||
.Map(list => list.OrderBy(vm => vm.Name, StringComparer.CurrentCultureIgnoreCase).ToList());
|
||||
_fillerPresets = await _mediator.Send(new GetAllFillerPresets(), _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 _mediator.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
|
||||
@@ -404,6 +390,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)
|
||||
{
|
||||
@@ -512,15 +558,15 @@
|
||||
item.PreferredSubtitleLanguageCode,
|
||||
item.SubtitleMode)).ToList();
|
||||
|
||||
Seq<BaseError> errorMessages = await _mediator.Send(new ReplaceProgramScheduleItems(Id, items), _cts.Token).Map(e => e.LeftToSeq());
|
||||
Seq<BaseError> errorMessages = await Mediator.Send(new ReplaceProgramScheduleItems(Id, items), _cts.Token).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);
|
||||
Snackbar.Add($"Unexpected error saving schedule: {error.Value}", Severity.Error);
|
||||
Logger.LogError("Unexpected error saving schedule: {Error}", error.Value);
|
||||
},
|
||||
() => _navigationManager.NavigateTo("/schedules"));
|
||||
() => NavigationManager.NavigateTo("/schedules"));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user