rework media layout (#22)

* replace media items tables with card grids

* style cleanup

* add basic paging

* sort and page in the db

* optimize sql for movies

* support movie posters

* resize movie posters and store in cache with channel logos

* fix bug preventing folders with more than 50 chars as local media sources

* support tv posters
This commit is contained in:
Jason Dove
2021-02-14 00:15:18 +00:00
committed by GitHub
parent 0b5a6f9dcd
commit 9d40caebd6
48 changed files with 2386 additions and 178 deletions
@@ -1,9 +1,8 @@
using System.Collections.Generic;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Domain;
using MediatR;
namespace ErsatzTV.Application.MediaItems.Queries
{
public record GetAggregateMediaItems
(MediaType MediaType, string SearchString) : IRequest<List<AggregateMediaItemViewModel>>;
(MediaType MediaType, int PageNumber, int PageSize) : IRequest<AggregateMediaItemResults>;
}
@@ -1,46 +1,42 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.AggregateModels;
using ErsatzTV.Core.Interfaces.Repositories;
using MediatR;
namespace ErsatzTV.Application.MediaItems.Queries
{
public class
GetAggregateMediaItemsHandler : IRequestHandler<GetAggregateMediaItems, List<AggregateMediaItemViewModel>>
GetAggregateMediaItemsHandler : IRequestHandler<GetAggregateMediaItems, AggregateMediaItemResults>
{
private readonly IMediaItemRepository _mediaItemRepository;
public GetAggregateMediaItemsHandler(IMediaItemRepository mediaItemRepository) =>
_mediaItemRepository = mediaItemRepository;
public async Task<List<AggregateMediaItemViewModel>> Handle(
public async Task<AggregateMediaItemResults> Handle(
GetAggregateMediaItems request,
CancellationToken cancellationToken)
{
IEnumerable<MediaItem> allItems = await _mediaItemRepository.GetAll(request.MediaType);
int count = await _mediaItemRepository.GetCountByType(request.MediaType);
if (!string.IsNullOrEmpty(request.SearchString))
{
allItems = allItems.Filter(
i => i.Metadata?.Title.Contains(request.SearchString, StringComparison.OrdinalIgnoreCase) ==
true);
}
IEnumerable<MediaItemSummary> allItems = await _mediaItemRepository.GetPageByType(
request.MediaType,
request.PageNumber,
request.PageSize);
return allItems.GroupBy(c => new { c.Source.Name, c.Metadata.Title }).Map(
group => new AggregateMediaItemViewModel(
group.Key.Name,
group.Key.Title,
group.Count(),
group.Count() == 1 ? DisplayDuration(group.Head()) : string.Empty))
var results = allItems
.Map(
s => new AggregateMediaItemViewModel(
s.Title,
s.Subtitle,
s.SortTitle,
s.Poster))
.ToList();
}
private static string DisplayDuration(MediaItem mediaItem) => string.Format(
mediaItem.Metadata?.Duration.TotalHours >= 1 ? @"{0:h\:mm\:ss}" : @"{0:mm\:ss}",
mediaItem.Metadata?.Duration);
return new AggregateMediaItemResults(count, results);
}
}
}