Files
ersatztv/ErsatzTV/Pages/TelevisionShowList.razor
T
Jason DoveandGitHub 245c4ec359 code analysis and cleanup (#1411)
* cleanup scanner project

* cleanup infrastructure projects

* cleanup ffmpeg project

* cleanup core project

* cleanup app project

* cleanup main project

* update dependencies

* code cleanup
2023-09-03 06:23:42 -05:00

183 lines
6.9 KiB
Plaintext

@page "/media/tv/shows"
@page "/media/tv/shows/page/{PageNumber:int}"
@inherits MultiSelectBase<TelevisionShowList>
@inject NavigationManager NavigationManager
@inject PersistentComponentState ApplicationState
@using ErsatzTV.Extensions
@using ErsatzTV.Application.MediaCards
@using ErsatzTV.Application.MediaCollections
@using ErsatzTV.Application.Search
@implements IDisposable
<MudPaper Square="true" Style="display: flex; height: 64px; left: 240px; padding: 0; position: fixed; right: 0; z-index: 100;">
<div style="display: flex; flex-direction: row; margin-bottom: auto; margin-top: auto; width: 100%" class="ml-6 mr-6">
@if (IsSelectMode())
{
<MudText Typo="Typo.h6" Color="Color.Primary">@SelectionLabel()</MudText>
<div style="margin-left: auto">
<MudButton Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.Add"
OnClick="@(_ => AddSelectionToCollection())">
Add To Collection
</MudButton>
<MudButton Class="ml-3"
Variant="Variant.Filled"
Color="Color.Secondary"
StartIcon="@Icons.Material.Filled.Check"
OnClick="@(_ => ClearSelection())">
Clear Selection
</MudButton>
</div>
}
else
{
<MudText Style="margin-bottom: auto; margin-top: auto; width: 33%">@_query</MudText>
<div style="max-width: 300px; width: 33%;">
<MudPaper Style="align-items: center; display: flex; justify-content: center;">
<MudIconButton Icon="@Icons.Material.Outlined.ChevronLeft"
OnClick="@PrevPage"
Disabled="@(PageNumber <= 1)">
</MudIconButton>
<MudText Style="flex-grow: 1"
Align="Align.Center">
@Math.Min((PageNumber - 1) * PageSize + 1, _data.Count)-@Math.Min(_data.Count, PageNumber * PageSize) of @_data.Count
</MudText>
<MudIconButton Icon="@Icons.Material.Outlined.ChevronRight"
OnClick="@NextPage" Disabled="@(PageNumber * PageSize >= _data.Count)">
</MudIconButton>
</MudPaper>
</div>
}
</div>
</MudPaper>
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8" Style="margin-top: 64px">
<MudContainer MaxWidth="MaxWidth.False" Class="media-card-grid">
<FragmentLetterAnchor TCard="TelevisionShowCardViewModel" Cards="@_data.Cards">
<MediaCard Data="@context"
Link="@($"media/tv/shows/{context.TelevisionShowId}")"
AddToCollectionClicked="@AddToCollection"
SelectClicked="@(e => SelectClicked(context, e))"
IsSelected="@IsSelected(context)"
IsSelectMode="@IsSelectMode()"/>
</FragmentLetterAnchor>
</MudContainer>
</MudContainer>
@if (_data.PageMap is not null)
{
<LetterBar PageMap="@_data.PageMap"
BaseUri="media/tv/shows"
Query="@_query"/>
}
@code {
private static int PageSize => 100;
[Parameter]
public int PageNumber { get; set; }
private TelevisionShowCardResultsViewModel _data = new(0, new List<TelevisionShowCardViewModel>(), null);
private string _query;
private PersistingComponentStateSubscription _persistingSubscription;
protected override Task OnInitializedAsync()
{
_persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
_query = NavigationManager.Uri.GetSearchQuery();
return base.OnInitializedAsync();
}
protected override async Task OnParametersSetAsync()
{
if (PageNumber == 0)
{
PageNumber = 1;
}
if (!ApplicationState.TryTakeFromJson("_data", out TelevisionShowCardResultsViewModel restored))
{
_data = await RefreshData();
}
else
{
_data = restored;
}
}
private Task PersistData()
{
ApplicationState.PersistAsJson("_data", _data);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
_persistingSubscription.Dispose();
base.Dispose();
}
protected override async Task<TelevisionShowCardResultsViewModel> RefreshData()
{
string searchQuery = string.IsNullOrWhiteSpace(_query) ? "type:show" : $"type:show AND ({_query})";
return await Mediator.Send(new QuerySearchIndexShows(searchQuery, PageNumber, PageSize), CancellationToken);
}
private void PrevPage()
{
var uri = $"media/tv/shows/page/{PageNumber - 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
uri = $"{uri}?{key}={value}";
}
NavigationManager.NavigateTo(uri);
}
private void NextPage()
{
var uri = $"media/tv/shows/page/{PageNumber + 1}";
if (!string.IsNullOrWhiteSpace(_query))
{
(string key, string value) = _query.EncodeQuery();
uri = $"{uri}?{key}={value}";
}
NavigationManager.NavigateTo(uri);
}
private void SelectClicked(MediaCardViewModel card, MouseEventArgs e)
{
List<MediaCardViewModel> GetSortedItems()
{
return _data.Cards.OrderBy(m => m.SortTitle).ToList<MediaCardViewModel>();
}
SelectClicked(GetSortedItems, card, e);
}
private async Task AddToCollection(MediaCardViewModel card)
{
if (card is TelevisionShowCardViewModel show)
{
var parameters = new DialogParameters { { "EntityType", "show" }, { "EntityName", show.Title } };
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall };
IDialogReference dialog = Dialog.Show<AddToCollectionDialog>("Add To Collection", parameters, options);
DialogResult result = await dialog.Result;
if (!result.Canceled && result.Data is MediaCollectionViewModel collection)
{
var request = new AddShowToCollection(collection.Id, show.TelevisionShowId);
Either<BaseError, Unit> addResult = await Mediator.Send(request, CancellationToken);
addResult.Match(
Left: error =>
{
Snackbar.Add($"Unexpected error adding show to collection: {error.Value}");
Logger.LogError("Unexpected error adding show to collection: {Error}", error.Value);
},
Right: _ => Snackbar.Add($"Added {show.Title} to collection {collection.Name}", Severity.Success));
}
}
}
}