diff --git a/Manager.App/Components/Pages/Accounts.razor b/Manager.App/Components/Pages/Accounts.razor
index f693a25..0fa1d66 100644
--- a/Manager.App/Components/Pages/Accounts.razor
+++ b/Manager.App/Components/Pages/Accounts.razor
@@ -1,4 +1,5 @@
@page "/Accounts"
+@using Manager.App.Controllers
@using Manager.App.Models.Settings
@using Manager.App.Services.System
@using Microsoft.Extensions.Options
@@ -26,14 +27,18 @@
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0">
+
Name
Handle
ID
+ Cookies
- @context.Channel?.Name
- @context.Channel?.Handle
+
+ @context.Name
+ @context.Handle
@context.Id
+ @context.HasCookies
No channels found
diff --git a/Manager.App/Components/Pages/Accounts.razor.cs b/Manager.App/Components/Pages/Accounts.razor.cs
index f46ab89..7c25e66 100644
--- a/Manager.App/Components/Pages/Accounts.razor.cs
+++ b/Manager.App/Components/Pages/Accounts.razor.cs
@@ -1,6 +1,5 @@
using Manager.App.Components.Dialogs;
using Manager.App.Models.Library;
-using Manager.Data.Entities.LibraryContext;
using Microsoft.AspNetCore.Components;
using MudBlazor;
@@ -8,14 +7,14 @@ namespace Manager.App.Components.Pages;
public partial class Accounts : ComponentBase
{
- private MudTable? _table;
+ private MudTable? _table;
private readonly DialogOptions _dialogOptions = new() { BackdropClick = false, CloseButton = true, FullWidth = true, MaxWidth = MaxWidth.ExtraLarge };
private string _search = "";
- private async Task> ServerReload(TableState state, CancellationToken token)
+ private async Task> ServerReload(TableState state, CancellationToken token)
{
var results = await LibraryService.GetAccountsAsync(_search, state.Page * state.PageSize, state.PageSize, token);
- return !results.IsSuccess ? new TableData() : new TableData() { Items = results.Value, TotalItems = results.Total };
+ return !results.IsSuccess ? new TableData() : new TableData { Items = results.Value, TotalItems = results.Total };
}
private void OnSearch(string text)
diff --git a/Manager.App/Components/Pages/Channels.razor b/Manager.App/Components/Pages/Channels.razor
index 38d7ab9..e60b2bf 100644
--- a/Manager.App/Components/Pages/Channels.razor
+++ b/Manager.App/Components/Pages/Channels.razor
@@ -1,4 +1,5 @@
@page "/Channels"
+@using Manager.App.Controllers
@inject ILibraryService LibraryService
@@ -13,11 +14,13 @@
AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0">
+
Name
Handle
Channel id
+
@context.Name
@context.Handle
@context.Id
diff --git a/Manager.App/Components/Pages/Channels.razor.cs b/Manager.App/Components/Pages/Channels.razor.cs
index bc47493..3705465 100644
--- a/Manager.App/Components/Pages/Channels.razor.cs
+++ b/Manager.App/Components/Pages/Channels.razor.cs
@@ -1,4 +1,4 @@
-using Manager.Data.Entities.LibraryContext;
+using Manager.App.Models.Library;
using Microsoft.AspNetCore.Components;
using MudBlazor;
@@ -6,13 +6,13 @@ namespace Manager.App.Components.Pages;
public partial class Channels : ComponentBase
{
- private MudTable? _table;
+ private MudTable? _table;
private string _search = "";
- private async Task> ServerReload(TableState state, CancellationToken token)
+ private async Task> ServerReload(TableState state, CancellationToken token)
{
var results = await LibraryService.GetChannelsAsync(_search, state.Page * state.PageSize, state.PageSize, token);
- return !results.IsSuccess ? new TableData() : new TableData { Items = results.Value, TotalItems = results.Total };
+ return !results.IsSuccess ? new TableData() : new TableData { Items = results.Value, TotalItems = results.Total };
}
private void OnSearch(string text)
diff --git a/Manager.App/Controllers/FileController.cs b/Manager.App/Controllers/FileController.cs
index 3a81545..a2b154f 100644
--- a/Manager.App/Controllers/FileController.cs
+++ b/Manager.App/Controllers/FileController.cs
@@ -7,6 +7,8 @@ namespace Manager.App.Controllers;
[Route("api/v1/[controller]")]
public class FileController(ILibraryService libraryService) : ControllerBase
{
+ public static string CreateProvideUrl(Guid? id) => id == null ? "" : $"/api/v1/file/provide?id={id}";
+
[HttpGet("provide")]
public async Task ProvideFile([FromQuery(Name = "id")] Guid id, CancellationToken cancellationToken)
{
diff --git a/Manager.App/Services/ILibraryService.cs b/Manager.App/Services/ILibraryService.cs
index f1ad57e..b4f5038 100644
--- a/Manager.App/Services/ILibraryService.cs
+++ b/Manager.App/Services/ILibraryService.cs
@@ -14,6 +14,6 @@ public interface ILibraryService
public Task> GetChannelByIdAsync(string id, CancellationToken cancellationToken = default);
public Task SaveChannelAsync(InnertubeChannel innertubeChannel, CancellationToken cancellationToken = default);
public Task> GetLibraryInfoAsync(CancellationToken cancellationToken = default);
- public Task> GetAccountsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default);
- public Task> GetChannelsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default);
+ public Task> GetAccountsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default);
+ public Task> GetChannelsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default);
}
\ No newline at end of file
diff --git a/Manager.App/Services/LibraryService.cs b/Manager.App/Services/LibraryService.cs
index a42b006..50df9ba 100644
--- a/Manager.App/Services/LibraryService.cs
+++ b/Manager.App/Services/LibraryService.cs
@@ -150,7 +150,7 @@ public class LibraryService : ILibraryService
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 };
}
catch (Exception e)
@@ -268,7 +268,7 @@ public class LibraryService : ILibraryService
}
}
- public async Task> GetAccountsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default)
+ public async Task> GetAccountsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default)
{
if (total == 0)
{
@@ -278,16 +278,16 @@ public class LibraryService : ILibraryService
try
{
await using var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
- var accounts = context.ClientAccounts
+ var accountsQuery = context.ClientAccounts
.Include(ca => ca.Channel)
.Include(ca => ca.HttpCookies)
- .OrderByDescending(ca => ca.Id);
- var totalAccounts = accounts.Count();
+ .OrderByDescending(ca => ca.Id).AsQueryable();
+ var totalAccounts = accountsQuery.Count();
if (!string.IsNullOrWhiteSpace(search) && totalAccounts != 0)
{
var normalizedSearch = $"%{search.ToLower()}%";
- var searched = accounts
+ accountsQuery = accountsQuery
.Where(ca =>
EF.Functions.Like(
(
@@ -298,11 +298,20 @@ public class LibraryService : ILibraryService
normalizedSearch
)
);
- totalAccounts = searched.Count();
- accounts = searched.OrderByDescending(ca => ca.Id);
+ totalAccounts = accountsQuery.Count();
}
- return new ListResultReturn(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(totalAccounts == 0 ? [] : accountViews.ToList(), totalAccounts);
}
catch (Exception e)
{
@@ -310,21 +319,26 @@ public class LibraryService : ILibraryService
}
}
- public async Task> GetChannelsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default)
+ public async Task> GetChannelsAsync(string? search, int offset = 0, int total = 20, CancellationToken cancellationToken = default)
{
+ if (total == 0)
+ {
+ total = 20;
+ }
+
try
{
await using var context = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
- var orderedAccounts = context.Channels.OrderBy(x => x.Id);
- var totalChannels = orderedAccounts.Count();
- if (!string.IsNullOrWhiteSpace(search) && orderedAccounts.Any())
+ var channelQuery = context.Channels.OrderByDescending(c => c.Id).AsQueryable();
+
+ var totalChannels = channelQuery.Count();
+ if (!string.IsNullOrWhiteSpace(search) && totalChannels != 0)
{
var normalizedSearch = $"%{search.ToLower()}%";
- var searched = orderedAccounts
+ channelQuery = channelQuery
.Where(ca =>
- EF.Functions.Like(
- (
+ EF.Functions.Like((
ca.Id.ToString() + " " +
ca.Name + " " +
ca.Handle
@@ -332,11 +346,19 @@ public class LibraryService : ILibraryService
normalizedSearch
)
);
- totalChannels = searched.Count();
- orderedAccounts = searched.OrderByDescending(ca => ca.Id);
+ totalChannels = channelQuery.Count();
}
+
+ 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(totalChannels == 0 ? [] : orderedAccounts.Skip(offset).Take(total).ToList(), totalChannels);
+ return new ListResultReturn(totalChannels == 0 ? [] : channelViews.ToList(), totalChannels);
}
catch (Exception e)
{
@@ -366,6 +388,6 @@ public class LibraryService : ILibraryService
}
_logger.LogError(exception, "Service error");
- return ResultError.Fail("Failed to get library information");
+ return ResultError.Error(exception);
}
}
\ No newline at end of file