[CHANGE] Channel & Account list to view models
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
@page "/Accounts"
|
@page "/Accounts"
|
||||||
|
@using Manager.App.Controllers
|
||||||
@using Manager.App.Models.Settings
|
@using Manager.App.Models.Settings
|
||||||
@using Manager.App.Services.System
|
@using Manager.App.Services.System
|
||||||
@using Microsoft.Extensions.Options
|
@using Microsoft.Extensions.Options
|
||||||
@@ -26,14 +27,18 @@
|
|||||||
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
|
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
|
||||||
</ToolBarContent>
|
</ToolBarContent>
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
|
<MudTh></MudTh>
|
||||||
<MudTh>Name</MudTh>
|
<MudTh>Name</MudTh>
|
||||||
<MudTh>Handle</MudTh>
|
<MudTh>Handle</MudTh>
|
||||||
<MudTh>ID</MudTh>
|
<MudTh>ID</MudTh>
|
||||||
|
<MudTh>Cookies</MudTh>
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
<MudTd>@context.Channel?.Name</MudTd>
|
<MudTd><MudImage Src="@(FileController.CreateProvideUrl(context.AvatarFileId))" Height="40"/></MudTd>
|
||||||
<MudTd>@context.Channel?.Handle</MudTd>
|
<MudTd>@context.Name</MudTd>
|
||||||
|
<MudTd>@context.Handle</MudTd>
|
||||||
<MudTd>@context.Id</MudTd>
|
<MudTd>@context.Id</MudTd>
|
||||||
|
<MudTd>@context.HasCookies</MudTd>
|
||||||
</RowTemplate>
|
</RowTemplate>
|
||||||
<NoRecordsContent>
|
<NoRecordsContent>
|
||||||
<MudText>No channels found</MudText>
|
<MudText>No channels found</MudText>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Manager.App.Components.Dialogs;
|
using Manager.App.Components.Dialogs;
|
||||||
using Manager.App.Models.Library;
|
using Manager.App.Models.Library;
|
||||||
using Manager.Data.Entities.LibraryContext;
|
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using MudBlazor;
|
using MudBlazor;
|
||||||
|
|
||||||
@@ -8,14 +7,14 @@ namespace Manager.App.Components.Pages;
|
|||||||
|
|
||||||
public partial class Accounts : ComponentBase
|
public partial class Accounts : ComponentBase
|
||||||
{
|
{
|
||||||
private MudTable<ClientAccountEntity>? _table;
|
private MudTable<AccountListView>? _table;
|
||||||
private readonly DialogOptions _dialogOptions = new() { BackdropClick = false, CloseButton = true, FullWidth = true, MaxWidth = MaxWidth.ExtraLarge };
|
private readonly DialogOptions _dialogOptions = new() { BackdropClick = false, CloseButton = true, FullWidth = true, MaxWidth = MaxWidth.ExtraLarge };
|
||||||
private string _search = "";
|
private string _search = "";
|
||||||
|
|
||||||
private async Task<TableData<ClientAccountEntity>> ServerReload(TableState state, CancellationToken token)
|
private async Task<TableData<AccountListView>> ServerReload(TableState state, CancellationToken token)
|
||||||
{
|
{
|
||||||
var results = await LibraryService.GetAccountsAsync(_search, state.Page * state.PageSize, state.PageSize, token);
|
var results = await LibraryService.GetAccountsAsync(_search, state.Page * state.PageSize, state.PageSize, token);
|
||||||
return !results.IsSuccess ? new TableData<ClientAccountEntity>() : new TableData<ClientAccountEntity>() { Items = results.Value, TotalItems = results.Total };
|
return !results.IsSuccess ? new TableData<AccountListView>() : new TableData<AccountListView> { Items = results.Value, TotalItems = results.Total };
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSearch(string text)
|
private void OnSearch(string text)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@page "/Channels"
|
@page "/Channels"
|
||||||
|
@using Manager.App.Controllers
|
||||||
|
|
||||||
@inject ILibraryService LibraryService
|
@inject ILibraryService LibraryService
|
||||||
|
|
||||||
@@ -13,11 +14,13 @@
|
|||||||
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
|
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
|
||||||
</ToolBarContent>
|
</ToolBarContent>
|
||||||
<HeaderContent>
|
<HeaderContent>
|
||||||
|
<MudTh></MudTh>
|
||||||
<MudTh>Name</MudTh>
|
<MudTh>Name</MudTh>
|
||||||
<MudTh>Handle</MudTh>
|
<MudTh>Handle</MudTh>
|
||||||
<MudTh>Channel id</MudTh>
|
<MudTh>Channel id</MudTh>
|
||||||
</HeaderContent>
|
</HeaderContent>
|
||||||
<RowTemplate>
|
<RowTemplate>
|
||||||
|
<MudTd><MudImage Src="@(FileController.CreateProvideUrl(context.AvatarFileId))" Height="40"/></MudTd>
|
||||||
<MudTd>@context.Name</MudTd>
|
<MudTd>@context.Name</MudTd>
|
||||||
<MudTd>@context.Handle</MudTd>
|
<MudTd>@context.Handle</MudTd>
|
||||||
<MudTd>@context.Id</MudTd>
|
<MudTd>@context.Id</MudTd>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Manager.Data.Entities.LibraryContext;
|
using Manager.App.Models.Library;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using MudBlazor;
|
using MudBlazor;
|
||||||
|
|
||||||
@@ -6,13 +6,13 @@ namespace Manager.App.Components.Pages;
|
|||||||
|
|
||||||
public partial class Channels : ComponentBase
|
public partial class Channels : ComponentBase
|
||||||
{
|
{
|
||||||
private MudTable<ChannelEntity>? _table;
|
private MudTable<ChannelListView>? _table;
|
||||||
private string _search = "";
|
private string _search = "";
|
||||||
|
|
||||||
private async Task<TableData<ChannelEntity>> ServerReload(TableState state, CancellationToken token)
|
private async Task<TableData<ChannelListView>> ServerReload(TableState state, CancellationToken token)
|
||||||
{
|
{
|
||||||
var results = await LibraryService.GetChannelsAsync(_search, state.Page * state.PageSize, state.PageSize, token);
|
var results = await LibraryService.GetChannelsAsync(_search, state.Page * state.PageSize, state.PageSize, token);
|
||||||
return !results.IsSuccess ? new TableData<ChannelEntity>() : new TableData<ChannelEntity> { Items = results.Value, TotalItems = results.Total };
|
return !results.IsSuccess ? new TableData<ChannelListView>() : new TableData<ChannelListView> { Items = results.Value, TotalItems = results.Total };
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSearch(string text)
|
private void OnSearch(string text)
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ namespace Manager.App.Controllers;
|
|||||||
[Route("api/v1/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
public class FileController(ILibraryService libraryService) : ControllerBase
|
public class FileController(ILibraryService libraryService) : ControllerBase
|
||||||
{
|
{
|
||||||
|
public static string CreateProvideUrl(Guid? id) => id == null ? "" : $"/api/v1/file/provide?id={id}";
|
||||||
|
|
||||||
[HttpGet("provide")]
|
[HttpGet("provide")]
|
||||||
public async Task<IActionResult> ProvideFile([FromQuery(Name = "id")] Guid id, CancellationToken cancellationToken)
|
public async Task<IActionResult> ProvideFile([FromQuery(Name = "id")] Guid id, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,6 +14,6 @@ public interface ILibraryService
|
|||||||
public Task<Result<ChannelEntity>> GetChannelByIdAsync(string id, CancellationToken cancellationToken = default);
|
public Task<Result<ChannelEntity>> GetChannelByIdAsync(string id, CancellationToken cancellationToken = default);
|
||||||
public Task<Result> SaveChannelAsync(InnertubeChannel innertubeChannel, CancellationToken cancellationToken = default);
|
public Task<Result> SaveChannelAsync(InnertubeChannel innertubeChannel, CancellationToken cancellationToken = default);
|
||||||
public Task<Result<LibraryInformation>> GetLibraryInfoAsync(CancellationToken cancellationToken = default);
|
public Task<Result<LibraryInformation>> GetLibraryInfoAsync(CancellationToken cancellationToken = default);
|
||||||
public Task<ListResult<ClientAccountEntity>> GetAccountsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default);
|
public Task<ListResult<AccountListView>> GetAccountsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default);
|
||||||
public Task<ListResult<ChannelEntity>> GetChannelsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default);
|
public Task<ListResult<ChannelListView>> GetChannelsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ public class LibraryService : ILibraryService
|
|||||||
return ResultError.Fail($"File with id {id} not found.");
|
return ResultError.Fail($"File with id {id} not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var fs = new FileStream(Path.Combine(_libraryDirectory.FullName, file.RelativePath), FileMode.Open, FileAccess.Read, FileShare.Read);
|
var fs = new FileStream(Path.Combine(_libraryDirectory.FullName, LibraryConstants.Directories.SubDirChannels, file.RelativePath), FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
return new LibraryFile { DataStream = fs, SizeBytes = file.SizeBytes, FileName = file.OriginalFileName ?? file.Id.ToString(), MimeType = file.MimeType ?? MediaTypeNames.Application.Octet };
|
return new LibraryFile { DataStream = fs, SizeBytes = file.SizeBytes, FileName = file.OriginalFileName ?? file.Id.ToString(), MimeType = file.MimeType ?? MediaTypeNames.Application.Octet };
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -268,7 +268,7 @@ public class LibraryService : ILibraryService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ListResult<ClientAccountEntity>> GetAccountsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default)
|
public async Task<ListResult<AccountListView>> GetAccountsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (total == 0)
|
if (total == 0)
|
||||||
{
|
{
|
||||||
@@ -278,16 +278,16 @@ public class LibraryService : ILibraryService
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
await using var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||||
var accounts = context.ClientAccounts
|
var accountsQuery = context.ClientAccounts
|
||||||
.Include(ca => ca.Channel)
|
.Include(ca => ca.Channel)
|
||||||
.Include(ca => ca.HttpCookies)
|
.Include(ca => ca.HttpCookies)
|
||||||
.OrderByDescending(ca => ca.Id);
|
.OrderByDescending(ca => ca.Id).AsQueryable();
|
||||||
var totalAccounts = accounts.Count();
|
var totalAccounts = accountsQuery.Count();
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(search) && totalAccounts != 0)
|
if (!string.IsNullOrWhiteSpace(search) && totalAccounts != 0)
|
||||||
{
|
{
|
||||||
var normalizedSearch = $"%{search.ToLower()}%";
|
var normalizedSearch = $"%{search.ToLower()}%";
|
||||||
var searched = accounts
|
accountsQuery = accountsQuery
|
||||||
.Where(ca =>
|
.Where(ca =>
|
||||||
EF.Functions.Like(
|
EF.Functions.Like(
|
||||||
(
|
(
|
||||||
@@ -298,11 +298,20 @@ public class LibraryService : ILibraryService
|
|||||||
normalizedSearch
|
normalizedSearch
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
totalAccounts = searched.Count();
|
totalAccounts = accountsQuery.Count();
|
||||||
accounts = searched.OrderByDescending(ca => ca.Id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ListResultReturn<ClientAccountEntity>(totalAccounts == 0 ? [] : accounts.Skip(offset).Take(total).ToList(), totalAccounts);
|
var accountViews = accountsQuery.Skip(offset).Take(total).Select(account => new AccountListView
|
||||||
|
{
|
||||||
|
Id = account.Id,
|
||||||
|
Name = account.Channel != null ? account.Channel.Name : "",
|
||||||
|
Handle = account.Channel != null ? account.Channel.Handle : "",
|
||||||
|
HasCookies = account.HttpCookies.Count != 0,
|
||||||
|
AvatarFileId = account.Files == null ? null
|
||||||
|
: account.Files.Where(f => f.FileType == LibraryConstants.FileTypes.ChannelAvatar).OrderBy(x => x.Id).Select(f => f.Id).FirstOrDefault()
|
||||||
|
});
|
||||||
|
|
||||||
|
return new ListResultReturn<AccountListView>(totalAccounts == 0 ? [] : accountViews.ToList(), totalAccounts);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -310,21 +319,26 @@ public class LibraryService : ILibraryService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ListResult<ChannelEntity>> GetChannelsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default)
|
public async Task<ListResult<ChannelListView>> GetChannelsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
|
if (total == 0)
|
||||||
|
{
|
||||||
|
total = 20;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
await using var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||||
var orderedAccounts = context.Channels.OrderBy(x => x.Id);
|
|
||||||
|
|
||||||
var totalChannels = orderedAccounts.Count();
|
var channelQuery = context.Channels.OrderByDescending(c => c.Id).AsQueryable();
|
||||||
if (!string.IsNullOrWhiteSpace(search) && orderedAccounts.Any())
|
|
||||||
|
var totalChannels = channelQuery.Count();
|
||||||
|
if (!string.IsNullOrWhiteSpace(search) && totalChannels != 0)
|
||||||
{
|
{
|
||||||
var normalizedSearch = $"%{search.ToLower()}%";
|
var normalizedSearch = $"%{search.ToLower()}%";
|
||||||
var searched = orderedAccounts
|
channelQuery = channelQuery
|
||||||
.Where(ca =>
|
.Where(ca =>
|
||||||
EF.Functions.Like(
|
EF.Functions.Like((
|
||||||
(
|
|
||||||
ca.Id.ToString() + " " +
|
ca.Id.ToString() + " " +
|
||||||
ca.Name + " " +
|
ca.Name + " " +
|
||||||
ca.Handle
|
ca.Handle
|
||||||
@@ -332,11 +346,19 @@ public class LibraryService : ILibraryService
|
|||||||
normalizedSearch
|
normalizedSearch
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
totalChannels = searched.Count();
|
totalChannels = channelQuery.Count();
|
||||||
orderedAccounts = searched.OrderByDescending(ca => ca.Id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ListResultReturn<ChannelEntity>(totalChannels == 0 ? [] : orderedAccounts.Skip(offset).Take(total).ToList(), totalChannels);
|
var channelViews = channelQuery.Skip(offset).Take(total).Select(channel => new ChannelListView
|
||||||
|
{
|
||||||
|
Id = channel.Id,
|
||||||
|
Name = channel.Name,
|
||||||
|
Handle = channel.Handle,
|
||||||
|
AvatarFileId = channel.Files == null ? null
|
||||||
|
: channel.Files.Where(f => f.FileType == LibraryConstants.FileTypes.ChannelAvatar).OrderBy(x => x.Id).Select(f => f.Id).FirstOrDefault()
|
||||||
|
});
|
||||||
|
|
||||||
|
return new ListResultReturn<ChannelListView>(totalChannels == 0 ? [] : channelViews.ToList(), totalChannels);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -366,6 +388,6 @@ public class LibraryService : ILibraryService
|
|||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogError(exception, "Service error");
|
_logger.LogError(exception, "Service error");
|
||||||
return ResultError.Fail("Failed to get library information");
|
return ResultError.Error(exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user