mirror of https://github.com/ErsatzTV/ErsatzTV.git
13 changed files with 102 additions and 88 deletions
@ -0,0 +1,9 @@ |
|||||||
|
namespace ErsatzTV.Application |
||||||
|
{ |
||||||
|
public interface IMediaCard |
||||||
|
{ |
||||||
|
string Title { get; } |
||||||
|
string SortTitle { get; } |
||||||
|
string Subtitle { get; } |
||||||
|
} |
||||||
|
} |
||||||
@ -1,4 +1,13 @@ |
|||||||
namespace ErsatzTV.Application.MediaItems |
namespace ErsatzTV.Application.MediaItems |
||||||
{ |
{ |
||||||
public record AggregateMediaItemViewModel(string Source, string Title, int Count, string Duration); |
public record AggregateMediaItemViewModel( |
||||||
|
string Source, |
||||||
|
string Title, |
||||||
|
string Subtitle, |
||||||
|
int Count, |
||||||
|
string Duration) : IMediaCard |
||||||
|
{ |
||||||
|
public string SortTitle => |
||||||
|
Title.ToLowerInvariant().StartsWith("the ") ? Title.Substring(4) : Title; |
||||||
|
} |
||||||
} |
} |
||||||
|
|||||||
@ -1,17 +0,0 @@ |
|||||||
@page "/media/items" |
|
||||||
|
|
||||||
<MudTabs Elevation="1"> |
|
||||||
<MudTabPanel Text="TV Shows"> |
|
||||||
<MediaItemTable MediaType="@MediaType.TvShow"/> |
|
||||||
</MudTabPanel> |
|
||||||
<MudTabPanel Text="Movies"> |
|
||||||
<MediaItemTable MediaType="@MediaType.Movie"/> |
|
||||||
</MudTabPanel> |
|
||||||
<MudTabPanel Text="Other"> |
|
||||||
<MediaItemTable MediaType="@MediaType.Other"/> |
|
||||||
</MudTabPanel> |
|
||||||
</MudTabs> |
|
||||||
|
|
||||||
@code { |
|
||||||
|
|
||||||
} |
|
||||||
@ -0,0 +1,8 @@ |
|||||||
|
@page "/media/movies/items" |
||||||
|
@inject IMediator Mediator |
||||||
|
|
||||||
|
<MediaItemsGrid MediaType="@MediaType.Movie"/> |
||||||
|
|
||||||
|
@code { |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
@page "/media/other/items" |
||||||
|
@inject IMediator Mediator |
||||||
|
|
||||||
|
<MediaItemsGrid MediaType="@MediaType.Other"/> |
||||||
|
|
||||||
|
@code { |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
@page "/media/tv/items" |
||||||
|
@inject IMediator Mediator |
||||||
|
|
||||||
|
<MediaItemsGrid MediaType="@MediaType.TvShow"/> |
||||||
|
|
||||||
|
@code { |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
<div style="width: 152px" class="mx-3 pb-3"> |
||||||
|
<MudPaper Style="display: flex; flex-direction: column; height: 220px; justify-content: center; width: 152px;"> |
||||||
|
<MudText Align="Align.Center" |
||||||
|
Typo="Typo.h1" |
||||||
|
Style="font-weight: bold" |
||||||
|
Class="mud-text-disabled"> |
||||||
|
@Data.SortTitle.Substring(0, 1) |
||||||
|
</MudText> |
||||||
|
</MudPaper> |
||||||
|
<MudText Align="Align.Center" |
||||||
|
UserAttributes="@(new Dictionary<string, object> { { "title", Data.Title } })" |
||||||
|
Style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;"> |
||||||
|
@Data.Title |
||||||
|
</MudText> |
||||||
|
<MudText Typo="Typo.body2" |
||||||
|
Align="Align.Center" |
||||||
|
Style="text-overflow: ellipsis" |
||||||
|
Class="mud-text-secondary"> |
||||||
|
@Data.Subtitle |
||||||
|
</MudText> |
||||||
|
</div> |
||||||
|
|
||||||
|
@code { |
||||||
|
|
||||||
|
[Parameter] |
||||||
|
public IMediaCard Data { get; set; } |
||||||
|
|
||||||
|
} |
||||||
@ -1,66 +0,0 @@ |
|||||||
@using ErsatzTV.Application.MediaItems |
|
||||||
@using ErsatzTV.Application.MediaItems.Queries |
|
||||||
@inject IMediator Mediator |
|
||||||
|
|
||||||
<MudTable @ref="_table" Hover="true" ServerData="@(new Func<TableState, Task<TableData<AggregateMediaItemViewModel>>>(ServerReload))"> |
|
||||||
<ToolBarContent> |
|
||||||
<MudText Typo="Typo.h6">Media Items</MudText> |
|
||||||
<MudToolBarSpacer/> |
|
||||||
<MudTextField T="string" ValueChanged="@OnSearch" Placeholder="Search" Adornment="Adornment.Start" |
|
||||||
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"> |
|
||||||
</MudTextField> |
|
||||||
</ToolBarContent> |
|
||||||
<HeaderContent> |
|
||||||
<MudTh>Source</MudTh> |
|
||||||
<MudTh>Title</MudTh> |
|
||||||
<MudTh>Count</MudTh> |
|
||||||
<MudTh>Duration</MudTh> |
|
||||||
</HeaderContent> |
|
||||||
<RowTemplate> |
|
||||||
<MudTd DataLabel="Source">@context.Source</MudTd> |
|
||||||
<MudTd DataLabel="Title">@context.Title</MudTd> |
|
||||||
<MudTd DataLabel="Count">@context.Count</MudTd> |
|
||||||
<MudTd DataLabel="Duration">@context.Duration</MudTd> |
|
||||||
</RowTemplate> |
|
||||||
<PagerContent> |
|
||||||
<MudTablePager/> |
|
||||||
</PagerContent> |
|
||||||
</MudTable> |
|
||||||
|
|
||||||
@code { |
|
||||||
|
|
||||||
[Parameter] |
|
||||||
public MediaType MediaType { get; set; } |
|
||||||
|
|
||||||
private IEnumerable<AggregateMediaItemViewModel> _pagedData; |
|
||||||
private MudTable<AggregateMediaItemViewModel> _table; |
|
||||||
|
|
||||||
private int _totalItems; |
|
||||||
private string _searchString; |
|
||||||
|
|
||||||
private async Task<TableData<AggregateMediaItemViewModel>> ServerReload(TableState state) |
|
||||||
{ |
|
||||||
List<AggregateMediaItemViewModel> aggregateData = |
|
||||||
await Mediator.Send(new GetAggregateMediaItems(MediaType, _searchString)); |
|
||||||
|
|
||||||
_totalItems = aggregateData.Count; |
|
||||||
|
|
||||||
_pagedData = aggregateData.Skip(state.Page * state.PageSize).Take(state.PageSize); |
|
||||||
return new TableData<AggregateMediaItemViewModel> { TotalItems = _totalItems, Items = _pagedData }; |
|
||||||
} |
|
||||||
|
|
||||||
private async Task OnSearch(string text) |
|
||||||
{ |
|
||||||
_searchString = text; |
|
||||||
await _table.ReloadServerData(); |
|
||||||
} |
|
||||||
|
|
||||||
private class MediaItemAggregate |
|
||||||
{ |
|
||||||
public string Source { get; set; } |
|
||||||
public string Title { get; set; } |
|
||||||
public int Count { get; set; } |
|
||||||
public string Duration { get; set; } |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -0,0 +1,22 @@ |
|||||||
|
@using ErsatzTV.Application.MediaItems |
||||||
|
@using ErsatzTV.Application.MediaItems.Queries |
||||||
|
@inject IMediator Mediator |
||||||
|
|
||||||
|
<MudContainer MaxWidth="MaxWidth.False" Style="display: flex; flex-direction: row; flex-wrap: wrap"> |
||||||
|
@foreach (AggregateMediaItemViewModel item in _data.OrderBy(i => i.SortTitle)) |
||||||
|
{ |
||||||
|
<MediaCard Data="@item"/> |
||||||
|
} |
||||||
|
</MudContainer> |
||||||
|
|
||||||
|
@code { |
||||||
|
|
||||||
|
[Parameter] |
||||||
|
public MediaType MediaType { get; set; } |
||||||
|
|
||||||
|
private List<AggregateMediaItemViewModel> _data; |
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync() => |
||||||
|
_data = await Mediator.Send(new GetAggregateMediaItems(MediaType, string.Empty)); |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue