mirror of https://github.com/ErsatzTV/ErsatzTV.git
25 changed files with 261 additions and 26 deletions
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Application.Libraries |
||||
{ |
||||
public record LocalLibraryPathViewModel(int Id, string Path); |
||||
} |
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Application.Libraries |
||||
{ |
||||
public record LocalLibraryViewModel(int Id, string Name, string MediaKind); |
||||
} |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
using ErsatzTV.Core.Domain; |
||||
|
||||
namespace ErsatzTV.Application.Libraries |
||||
{ |
||||
internal static class Mapper |
||||
{ |
||||
public static LocalLibraryViewModel ProjectToViewModel(LocalLibrary library) => |
||||
new(library.Id, library.Name, library.MediaKind.ToString()); |
||||
|
||||
public static LocalLibraryPathViewModel ProjectToViewModel(LibraryPath libraryPath) => |
||||
new(libraryPath.Id, libraryPath.Path); |
||||
} |
||||
} |
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
using System.Collections.Generic; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.Libraries.Queries |
||||
{ |
||||
public record GetLocalLibraries : IRequest<List<LocalLibraryViewModel>>; |
||||
} |
||||
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
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.Libraries.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.Libraries.Queries |
||||
{ |
||||
public class GetLocalLibrariesHandler : IRequestHandler<GetLocalLibraries, List<LocalLibraryViewModel>> |
||||
{ |
||||
private readonly ILibraryRepository _libraryRepository; |
||||
|
||||
public GetLocalLibrariesHandler(ILibraryRepository libraryRepository) => _libraryRepository = libraryRepository; |
||||
|
||||
public Task<List<LocalLibraryViewModel>> |
||||
Handle(GetLocalLibraries request, CancellationToken cancellationToken) => |
||||
_libraryRepository.GetAllLocal().Map(list => list.Map(ProjectToViewModel).ToList()); |
||||
} |
||||
} |
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
using System.Collections.Generic; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.Libraries.Queries |
||||
{ |
||||
public record GetLocalLibraryPaths(int LocalLibraryId) : IRequest<List<LocalLibraryPathViewModel>>; |
||||
} |
||||
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
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.Libraries.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.Libraries.Queries |
||||
{ |
||||
public class GetLocalLibraryPathsHandler : IRequestHandler<GetLocalLibraryPaths, List<LocalLibraryPathViewModel>> |
||||
{ |
||||
private readonly ILibraryRepository _libraryRepository; |
||||
|
||||
public GetLocalLibraryPathsHandler(ILibraryRepository libraryRepository) => |
||||
_libraryRepository = libraryRepository; |
||||
|
||||
public Task<List<LocalLibraryPathViewModel>> Handle( |
||||
GetLocalLibraryPaths request, |
||||
CancellationToken cancellationToken) => |
||||
_libraryRepository.GetLocalPaths(request.LocalLibraryId) |
||||
.Map(list => list.Map(ProjectToViewModel).ToList()); |
||||
} |
||||
} |
||||
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
@page "/media/libraries" |
||||
@using ErsatzTV.Application.Libraries |
||||
@using ErsatzTV.Application.Libraries.Queries |
||||
@implements IDisposable |
||||
@inject IMediator Mediator |
||||
@inject IEntityLocker Locker |
||||
|
||||
<MudContainer MaxWidth="MaxWidth.ExtraLarge"> |
||||
<MudTable Hover="true" Items="_libraries" Dense="true"> |
||||
<ToolBarContent> |
||||
<MudText Typo="Typo.h6">Libraries</MudText> |
||||
</ToolBarContent> |
||||
<ColGroup> |
||||
<col/> |
||||
<col/> |
||||
<col/> |
||||
<col style="width: 120px;"/> |
||||
</ColGroup> |
||||
<HeaderContent> |
||||
<MudTh>Library Kind</MudTh> |
||||
<MudTh>Name</MudTh> |
||||
<MudTh>Media Kind</MudTh> |
||||
<MudTh/> |
||||
</HeaderContent> |
||||
<RowTemplate> |
||||
<MudTd DataLabel="Library Kind">Local</MudTd> |
||||
<MudTd DataLabel="Name">@context.Name</MudTd> |
||||
<MudTd DataLabel="Media Kind">@context.MediaKind</MudTd> |
||||
<MudTd> |
||||
<div style="align-items: center; display: flex;"> |
||||
@if (Locker.IsLibraryLocked(context.Id)) |
||||
{ |
||||
<div style="align-items: center; display: flex; height: 48px; justify-content: center; width: 48px;"> |
||||
<MudProgressCircular Color="Color.Primary" Size="Size.Small" Indeterminate="true"/> |
||||
</div> |
||||
} |
||||
else |
||||
{ |
||||
<MudTooltip Text="Scan Library"> |
||||
<MudIconButton Icon="@Icons.Material.Filled.Refresh" |
||||
Disabled="@Locker.IsLibraryLocked(context.Id)" |
||||
OnClick="@(_ => ScanLibrary(context))"> |
||||
</MudIconButton> |
||||
</MudTooltip> |
||||
} |
||||
@if (context is LocalLibraryViewModel) |
||||
{ |
||||
<MudTooltip Text="Edit Library"> |
||||
<MudIconButton Icon="@Icons.Material.Filled.Edit" |
||||
Disabled="@Locker.IsLibraryLocked(context.Id)" |
||||
Link="@($"/media/libraries/local/{context.Id}")"> |
||||
</MudIconButton> |
||||
</MudTooltip> |
||||
} |
||||
</div> |
||||
</MudTd> |
||||
</RowTemplate> |
||||
</MudTable> |
||||
</MudContainer> |
||||
|
||||
@code { |
||||
private IList<LocalLibraryViewModel> _libraries; |
||||
|
||||
protected override void OnInitialized() => |
||||
Locker.OnLibraryChanged += LockChanged; |
||||
|
||||
protected override async Task OnParametersSetAsync() => await LoadLibraries(); |
||||
|
||||
private async Task LoadLibraries() => |
||||
_libraries = await Mediator.Send(new GetLocalLibraries()); |
||||
|
||||
private Task ScanLibrary(LocalLibraryViewModel library) |
||||
{ |
||||
return Task.CompletedTask; |
||||
} |
||||
|
||||
private void LockChanged(object sender, EventArgs e) => |
||||
InvokeAsync(StateHasChanged); |
||||
|
||||
void IDisposable.Dispose() => Locker.OnLibraryChanged -= LockChanged; |
||||
|
||||
} |
||||
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
@page "/media/libraries/local/{Id:int}" |
||||
@using ErsatzTV.Application.Libraries |
||||
@using ErsatzTV.Application.Libraries.Queries |
||||
@inject IMediator Mediator |
||||
|
||||
<MudContainer MaxWidth="MaxWidth.ExtraLarge"> |
||||
<MudTable Hover="true" Items="_libraryPaths" Dense="true"> |
||||
<ToolBarContent> |
||||
<MudText Typo="Typo.h6">Library Paths</MudText> |
||||
</ToolBarContent> |
||||
<ColGroup> |
||||
<col/> |
||||
<col style="width: 60px;"/> |
||||
</ColGroup> |
||||
<HeaderContent> |
||||
<MudTh>Path</MudTh> |
||||
<MudTh/> |
||||
</HeaderContent> |
||||
<RowTemplate> |
||||
<MudTd DataLabel="Path">@context.Path</MudTd> |
||||
<MudTd> |
||||
<div style="align-items: center; display: flex;"> |
||||
<MudTooltip Text="Delete Library Path"> |
||||
<MudIconButton Icon="@Icons.Material.Filled.Delete" |
||||
OnClick="@(() => DeleteLibraryPath(context))"> |
||||
</MudIconButton> |
||||
</MudTooltip> |
||||
</div> |
||||
</MudTd> |
||||
</RowTemplate> |
||||
</MudTable> |
||||
</MudContainer> |
||||
|
||||
@code { |
||||
|
||||
[Parameter] |
||||
public int Id { get; set; } |
||||
|
||||
private IList<LocalLibraryPathViewModel> _libraryPaths; |
||||
|
||||
protected override async Task OnParametersSetAsync() => await LoadLibraryPaths(); |
||||
|
||||
private async Task LoadLibraryPaths() => |
||||
_libraryPaths = await Mediator.Send(new GetLocalLibraryPaths(Id)); |
||||
|
||||
private Task DeleteLibraryPath(LocalLibraryPathViewModel libraryPath) => Task.CompletedTask; |
||||
|
||||
} |
||||
Loading…
Reference in new issue