mirror of https://github.com/ErsatzTV/ErsatzTV.git
32 changed files with 471 additions and 64 deletions
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
using ErsatzTV.Core.Domain; |
||||
|
||||
namespace ErsatzTV.Application.MediaCards |
||||
{ |
||||
internal static class Mapper |
||||
{ |
||||
internal static TelevisionShowCardViewModel ProjectToViewModel(TelevisionShow televisionShow) => |
||||
new( |
||||
televisionShow.Id, |
||||
televisionShow.Metadata.Title, |
||||
televisionShow.Metadata.Year.ToString(), |
||||
televisionShow.Metadata.SortTitle, |
||||
televisionShow.Poster); |
||||
|
||||
internal static TelevisionSeasonCardViewModel ProjectToViewModel(TelevisionSeason televisionSeason) => |
||||
new( |
||||
televisionSeason.Id, |
||||
GetSeasonName(televisionSeason.Number), |
||||
string.Empty, |
||||
GetSeasonName(televisionSeason.Number), |
||||
televisionSeason.Poster); |
||||
|
||||
internal static MovieCardViewModel ProjectToViewModel(MovieMediaItem movie) => |
||||
new( |
||||
movie.Id, |
||||
movie.Metadata.Title, |
||||
movie.Metadata.Year.ToString(), |
||||
movie.Metadata.SortTitle, |
||||
movie.Poster); |
||||
|
||||
private static string GetSeasonName(int number) => |
||||
number == 0 ? "Specials" : $"Season {number}"; |
||||
} |
||||
} |
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Application.MediaCards |
||||
{ |
||||
public record MediaCardViewModel(string Title, string Subtitle, string SortTitle, string Poster); |
||||
} |
||||
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
using System.Collections.Generic; |
||||
|
||||
namespace ErsatzTV.Application.MediaCards |
||||
{ |
||||
public record MovieCardResultsViewModel(int Count, List<MovieCardViewModel> Cards); |
||||
} |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
namespace ErsatzTV.Application.MediaCards |
||||
{ |
||||
public record MovieCardViewModel |
||||
(int MovieId, string Title, string Subtitle, string SortTitle, string Poster) : MediaCardViewModel( |
||||
Title, |
||||
Subtitle, |
||||
SortTitle, |
||||
Poster) |
||||
{ |
||||
} |
||||
} |
||||
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaCards.Queries |
||||
{ |
||||
public record GetMovieCards(int PageNumber, int PageSize) : IRequest<MovieCardResultsViewModel>; |
||||
} |
||||
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.MediaCards.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.MediaCards.Queries |
||||
{ |
||||
public class |
||||
GetMovieCardsHandler : IRequestHandler<GetMovieCards, MovieCardResultsViewModel> |
||||
{ |
||||
private readonly IMovieRepository _movieRepository; |
||||
|
||||
public GetMovieCardsHandler(IMovieRepository movieRepository) |
||||
{ |
||||
_movieRepository = movieRepository; |
||||
} |
||||
|
||||
public async Task<MovieCardResultsViewModel> Handle( |
||||
GetMovieCards request, |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
int count = await _movieRepository.GetMovieCount(); |
||||
|
||||
List<MovieCardViewModel> results = await _movieRepository |
||||
.GetPagedMovies(request.PageNumber, request.PageSize) |
||||
.Map(list => list.Map(ProjectToViewModel).ToList()); |
||||
|
||||
return new MovieCardResultsViewModel(count, results); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaCards.Queries |
||||
{ |
||||
public record GetTelevisionSeasonCards |
||||
(int TelevisionShowId, int PageNumber, int PageSize) : IRequest<TelevisionSeasonCardResultsViewModel>; |
||||
} |
||||
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.MediaCards.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.MediaCards.Queries |
||||
{ |
||||
public class |
||||
GetTelevisionSeasonCardsHandler : IRequestHandler<GetTelevisionSeasonCards, TelevisionSeasonCardResultsViewModel |
||||
> |
||||
{ |
||||
private readonly ITelevisionRepository _televisionRepository; |
||||
|
||||
public GetTelevisionSeasonCardsHandler(ITelevisionRepository televisionRepository) => |
||||
_televisionRepository = televisionRepository; |
||||
|
||||
public async Task<TelevisionSeasonCardResultsViewModel> Handle( |
||||
GetTelevisionSeasonCards request, |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
int count = await _televisionRepository.GetSeasonCount(request.TelevisionShowId); |
||||
|
||||
List<TelevisionSeasonCardViewModel> results = await _televisionRepository |
||||
.GetPagedSeasons(request.TelevisionShowId, request.PageNumber, request.PageSize) |
||||
.Map(list => list.Map(ProjectToViewModel).ToList()); |
||||
|
||||
return new TelevisionSeasonCardResultsViewModel(count, results); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaCards.Queries |
||||
{ |
||||
public record GetTelevisionShowCards(int PageNumber, int PageSize) : IRequest<TelevisionShowCardResultsViewModel>; |
||||
} |
||||
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.MediaCards.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.MediaCards.Queries |
||||
{ |
||||
public class |
||||
GetTelevisionShowCardsHandler : IRequestHandler<GetTelevisionShowCards, TelevisionShowCardResultsViewModel> |
||||
{ |
||||
private readonly ITelevisionRepository _televisionRepository; |
||||
|
||||
public GetTelevisionShowCardsHandler(ITelevisionRepository televisionRepository) => |
||||
_televisionRepository = televisionRepository; |
||||
|
||||
public async Task<TelevisionShowCardResultsViewModel> Handle( |
||||
GetTelevisionShowCards request, |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
int count = await _televisionRepository.GetShowCount(); |
||||
|
||||
List<TelevisionShowCardViewModel> results = await _televisionRepository |
||||
.GetPagedShows(request.PageNumber, request.PageSize) |
||||
.Map(list => list.Map(ProjectToViewModel).ToList()); |
||||
|
||||
return new TelevisionShowCardResultsViewModel(count, results); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
namespace ErsatzTV.Application.MediaCards |
||||
{ |
||||
public record TelevisionEpisodeCardViewModel |
||||
(string Title, string Subtitle, string SortTitle, string Poster) : MediaCardViewModel( |
||||
Title, |
||||
Subtitle, |
||||
SortTitle, |
||||
Poster) |
||||
{ |
||||
} |
||||
} |
||||
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
using System.Collections.Generic; |
||||
|
||||
namespace ErsatzTV.Application.MediaCards |
||||
{ |
||||
public record TelevisionSeasonCardResultsViewModel(int Count, List<TelevisionSeasonCardViewModel> Cards); |
||||
} |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
namespace ErsatzTV.Application.MediaCards |
||||
{ |
||||
public record TelevisionSeasonCardViewModel |
||||
(int TelevisionSeasonId, string Title, string Subtitle, string SortTitle, string Poster) : MediaCardViewModel( |
||||
Title, |
||||
Subtitle, |
||||
SortTitle, |
||||
Poster) |
||||
{ |
||||
} |
||||
} |
||||
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
using System.Collections.Generic; |
||||
|
||||
namespace ErsatzTV.Application.MediaCards |
||||
{ |
||||
public record TelevisionShowCardResultsViewModel(int Count, List<TelevisionShowCardViewModel> Cards); |
||||
} |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
namespace ErsatzTV.Application.MediaCards |
||||
{ |
||||
public record TelevisionShowCardViewModel |
||||
(int TelevisionShowId, string Title, string Subtitle, string SortTitle, string Poster) : MediaCardViewModel( |
||||
Title, |
||||
Subtitle, |
||||
SortTitle, |
||||
Poster) |
||||
{ |
||||
} |
||||
} |
||||
@ -1,8 +1,8 @@
@@ -1,8 +1,8 @@
|
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Core.AggregateModels; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaItems.Queries |
||||
{ |
||||
public record GetAggregateMediaItems |
||||
(MediaType MediaType, int PageNumber, int PageSize) : IRequest<AggregateMediaItemResults>; |
||||
(AggregateMediaItemType ItemType, int PageNumber, int PageSize) : IRequest<AggregateMediaItemResults>; |
||||
} |
||||
|
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
namespace ErsatzTV.Core.AggregateModels |
||||
{ |
||||
public enum AggregateMediaItemType |
||||
{ |
||||
TelevisionShows, |
||||
TelevisionSeasons, |
||||
TelevisionEpisodes, |
||||
Movies |
||||
} |
||||
} |
||||
@ -1,8 +0,0 @@
@@ -1,8 +0,0 @@
|
||||
@page "/media/movies/items" |
||||
@inject IMediator Mediator |
||||
|
||||
<MediaItemsGrid MediaType="@MediaType.Movie"/> |
||||
|
||||
@code { |
||||
|
||||
} |
||||
@ -1,8 +0,0 @@
@@ -1,8 +0,0 @@
|
||||
@page "/media/tv/items" |
||||
@inject IMediator Mediator |
||||
|
||||
<MediaItemsGrid MediaType="@MediaType.TvShow"/> |
||||
|
||||
@code { |
||||
|
||||
} |
||||
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
@page "/media/tv/shows/{ShowId:int}" |
||||
@using ErsatzTV.Application.MediaCards |
||||
@using ErsatzTV.Application.MediaCards.Queries |
||||
@inject IMediator Mediator |
||||
|
||||
<MudContainer MaxWidth="MaxWidth.False" Class="media-card-grid"> |
||||
@foreach (TelevisionSeasonCardViewModel card in _data.Cards) |
||||
{ |
||||
<MediaCard Data="@card" Link="@($"/media/tv/shows/{ShowId}/seasons/{card.TelevisionSeasonId}")" DataRefreshed="@(() => RefreshData())"/> |
||||
} |
||||
</MudContainer> |
||||
|
||||
@code { |
||||
|
||||
[Parameter] |
||||
public int ShowId { get; set; } |
||||
|
||||
private int PageSize => 100; |
||||
private int _pageNumber = 1; |
||||
|
||||
private TelevisionSeasonCardResultsViewModel _data; |
||||
|
||||
protected override Task OnParametersSetAsync() => RefreshData(); |
||||
|
||||
private async Task RefreshData() => |
||||
_data = await Mediator.Send(new GetTelevisionSeasonCards(ShowId, _pageNumber, PageSize)); |
||||
|
||||
} |
||||
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
@page "/media/tv/shows" |
||||
@using ErsatzTV.Application.MediaCards |
||||
@using ErsatzTV.Application.MediaCards.Queries |
||||
@inject IMediator Mediator |
||||
|
||||
<MudContainer MaxWidth="MaxWidth.Small" Class="mb-6" Style="max-width: 300px"> |
||||
<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> |
||||
</MudContainer> |
||||
|
||||
<MudContainer MaxWidth="MaxWidth.False" Class="media-card-grid"> |
||||
@foreach (TelevisionShowCardViewModel card in _data.Cards) |
||||
{ |
||||
<MediaCard Data="@card" Link="@($"/media/tv/shows/{card.TelevisionShowId}")" DataRefreshed="@(() => RefreshData())"/> |
||||
} |
||||
</MudContainer> |
||||
|
||||
@code { |
||||
private int PageSize => 100; |
||||
private int _pageNumber = 1; |
||||
|
||||
private TelevisionShowCardResultsViewModel _data; |
||||
|
||||
protected override Task OnParametersSetAsync() => RefreshData(); |
||||
|
||||
private async Task RefreshData() => |
||||
_data = await Mediator.Send(new GetTelevisionShowCards(_pageNumber, PageSize)); |
||||
|
||||
private async Task PrevPage() |
||||
{ |
||||
_pageNumber -= 1; |
||||
await RefreshData(); |
||||
} |
||||
|
||||
private async Task NextPage() |
||||
{ |
||||
_pageNumber += 1; |
||||
await RefreshData(); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue