mirror of https://github.com/ErsatzTV/ErsatzTV.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
6.6 KiB
151 lines
6.6 KiB
@page "/media/tv/seasons/{SeasonId:int}" |
|
@using ErsatzTV.Application.Television |
|
@using ErsatzTV.Application.Television.Queries |
|
@using ErsatzTV.Application.MediaCards |
|
@using ErsatzTV.Application.MediaCards.Queries |
|
@using ErsatzTV.Application.MediaCollections |
|
@using ErsatzTV.Application.MediaCollections.Commands |
|
@using ErsatzTV.Application.ProgramSchedules |
|
@using ErsatzTV.Application.ProgramSchedules.Commands |
|
@using Unit = LanguageExt.Unit |
|
@inject IMediator Mediator |
|
@inject ILogger<TelevisionEpisodeList> Logger |
|
@inject ISnackbar Snackbar |
|
@inject IDialogService Dialog |
|
@inject NavigationManager NavigationManager |
|
@inject ChannelWriter<IBackgroundServiceRequest> Channel |
|
|
|
<MudContainer MaxWidth="MaxWidth.Large"> |
|
<MudBreadcrumbs Items="_breadcrumbs" Class="mb-6"></MudBreadcrumbs> |
|
<MudCard Class="mb-6"> |
|
<div style="display: flex; flex-direction: row;"> |
|
@if (!string.IsNullOrWhiteSpace(_season.Poster)) |
|
{ |
|
<MudPaper Style="flex-shrink: 0;"> |
|
<MudCardMedia Image="@($"/artwork/posters/{_season.Poster}")" Style="height: 440px; width: 304px;"/> |
|
</MudPaper> |
|
} |
|
<MudCardContent Class="mx-3 my-3"> |
|
<div style="display: flex; flex-direction: column; height: 100%"> |
|
<MudText Typo="Typo.h3">@_season.Title</MudText> |
|
<MudText Typo="Typo.subtitle1" Class="mb-6 mud-text-secondary">@_season.Year</MudText> |
|
<MudText Style="flex-grow: 1">@_season.Plot</MudText> |
|
<div class="mt-6"> |
|
<MudButton Variant="Variant.Filled" |
|
Color="Color.Primary" |
|
StartIcon="@Icons.Material.Filled.Add" |
|
OnClick="@AddToCollection"> |
|
Add To Collection |
|
</MudButton> |
|
<MudButton Class="ml-3" |
|
Variant="Variant.Filled" |
|
Color="Color.Primary" |
|
StartIcon="@Icons.Material.Filled.Schedule" |
|
OnClick="@AddToSchedule"> |
|
Add To Schedule |
|
</MudButton> |
|
</div> |
|
</div> |
|
</MudCardContent> |
|
</div> |
|
</MudCard> |
|
</MudContainer> |
|
|
|
<MudContainer MaxWidth="MaxWidth.Large" Class="media-card-grid"> |
|
@foreach (TelevisionEpisodeCardViewModel card in _data.Cards) |
|
{ |
|
<MediaCard Data="@card" |
|
Placeholder="@card.Placeholder" |
|
Link="@($"/media/tv/episodes/{card.EpisodeId}")" |
|
AddToCollectionClicked="@AddEpisodeToCollection" |
|
ContainerClass="media-card-episode-container mx-2" |
|
CardClass="media-card-episode" |
|
ArtworkKind="@ArtworkKind.Thumbnail"/> |
|
} |
|
</MudContainer> |
|
|
|
@code { |
|
|
|
[Parameter] |
|
public int SeasonId { get; set; } |
|
|
|
private TelevisionSeasonViewModel _season; |
|
|
|
private int _pageSize => 100; |
|
private readonly int _pageNumber = 1; |
|
|
|
private TelevisionEpisodeCardResultsViewModel _data; |
|
|
|
private List<BreadcrumbItem> _breadcrumbs; |
|
|
|
protected override Task OnParametersSetAsync() => RefreshData(); |
|
|
|
private async Task RefreshData() |
|
{ |
|
await Mediator.Send(new GetTelevisionSeasonById(SeasonId)) |
|
.IfSomeAsync(vm => _season = vm); |
|
|
|
_data = await Mediator.Send(new GetTelevisionEpisodeCards(SeasonId, _pageNumber, _pageSize)); |
|
|
|
_breadcrumbs = new List<BreadcrumbItem> |
|
{ |
|
new("TV Shows", "/media/tv/shows"), |
|
new($"{_season.Title} ({_season.Year})", $"/media/tv/shows/{_season.ShowId}"), |
|
new(_season.Plot, null, true) |
|
}; |
|
} |
|
|
|
private async Task AddToCollection() |
|
{ |
|
var parameters = new DialogParameters { { "EntityType", "season" }, { "EntityName", $"{_season.Title} - {_season.Plot}" } }; |
|
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.Cancelled && result.Data is MediaCollectionViewModel collection) |
|
{ |
|
await Mediator.Send(new AddSeasonToCollection(collection.Id, SeasonId)); |
|
NavigationManager.NavigateTo($"/media/collections/{collection.Id}"); |
|
} |
|
} |
|
|
|
|
|
private async Task AddToSchedule() |
|
{ |
|
var parameters = new DialogParameters { { "EntityType", "season" }, { "EntityName", $"{_season.Title} - {_season.Plot}" } }; |
|
var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall }; |
|
|
|
IDialogReference dialog = Dialog.Show<AddToScheduleDialog>("Add To Schedule", parameters, options); |
|
DialogResult result = await dialog.Result; |
|
if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule) |
|
{ |
|
await Mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.TelevisionSeason, null, SeasonId, null, null, null)); |
|
NavigationManager.NavigateTo($"/schedules/{schedule.Id}/items"); |
|
} |
|
} |
|
|
|
private async Task AddEpisodeToCollection(MediaCardViewModel card) |
|
{ |
|
if (card is TelevisionEpisodeCardViewModel episode) |
|
{ |
|
var parameters = new DialogParameters { { "EntityType", "episode" }, { "EntityName", episode.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.Cancelled && result.Data is MediaCollectionViewModel collection) |
|
{ |
|
var request = new AddEpisodeToCollection(collection.Id, episode.EpisodeId); |
|
Either<BaseError, Unit> addResult = await Mediator.Send(request); |
|
addResult.Match( |
|
Left: error => |
|
{ |
|
Snackbar.Add($"Unexpected error adding episode to collection: {error.Value}"); |
|
Logger.LogError("Unexpected error adding episode to collection: {Error}", error.Value); |
|
}, |
|
Right: _ => Snackbar.Add($"Added {episode.Title} to collection {collection.Name}", Severity.Success)); |
|
} |
|
} |
|
} |
|
|
|
} |