Files
qbtmud/Lantean.QBTMudBlade/Pages/Search.razor.cs
2024-08-17 11:49:34 +01:00

185 lines
6.4 KiB
C#

using Lantean.QBitTorrentClient;
using Lantean.QBTMudBlade.Components.UI;
using Lantean.QBTMudBlade.Helpers;
using Lantean.QBTMudBlade.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using MudBlazor;
namespace Lantean.QBTMudBlade.Pages
{
public partial class Search : IDisposable
{
private IReadOnlyList<QBitTorrentClient.Models.SearchPlugin>? _plugins;
private int? _searchId;
private bool _disposedValue;
private readonly CancellationTokenSource _timerCancellationToken = new();
private int _refreshInterval = 1500;
private QBitTorrentClient.Models.SearchResults? _searchResults;
[Inject]
protected IApiClient ApiClient { get; set; } = default!;
[Inject]
protected IDialogService DialogService { get; set; } = default!;
[Inject]
protected NavigationManager NavigationManager { get; set; } = default!;
[CascadingParameter]
public MainData? MainData { get; set; }
[CascadingParameter(Name = "DrawerOpen")]
public bool DrawerOpen { get; set; }
[Parameter]
public string? Hash { get; set; }
protected SearchForm Model { get; set; } = new SearchForm();
protected Dictionary<string, string> Plugins => _plugins is null ? [] : _plugins.ToDictionary(a => a.Name, a => a.FullName);
protected Dictionary<string, string> Categories => GetCategories(Model.SelectedPlugin);
protected IEnumerable<QBitTorrentClient.Models.SearchResult>? Results => _searchResults?.Results;
protected DynamicTable<QBitTorrentClient.Models.SearchResult>? Table { get; set; }
protected override async Task OnInitializedAsync()
{
_plugins = await ApiClient.GetSearchPlugins();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
using (var timer = new PeriodicTimer(TimeSpan.FromMilliseconds(_refreshInterval)))
{
while (!_timerCancellationToken.IsCancellationRequested && await timer.WaitForNextTickAsync())
{
if (_searchId is not null)
{
try
{
_searchResults = await ApiClient.GetSearchResults(_searchId.Value);
if (_searchResults.Status == "Stopped")
{
await ApiClient.DeleteSearch(_searchId.Value);
_searchId = null;
}
}
catch (HttpRequestException)
{
if (MainData is not null)
{
MainData.LostConnection = true;
}
_searchId = null;
}
await InvokeAsync(StateHasChanged);
}
}
}
}
}
protected void NavigateBack()
{
NavigationManager.NavigateTo("/");
}
private Dictionary<string, string> GetCategories(string plugin)
{
if (_plugins is null)
{
return [];
}
if (plugin == "all")
{
return _plugins.SelectMany(i => i.SupportedCategories).Distinct().ToDictionary(a => a.Id, a => a.Name);
}
var pluginItem = _plugins.FirstOrDefault(p => p.Name == plugin);
if (pluginItem is null)
{
return [];
}
return pluginItem.SupportedCategories.ToDictionary(a => a.Id, a => a.Name);
}
protected async Task DoSearch(EditContext editContext)
{
if (_searchId is null)
{
if (string.IsNullOrEmpty(Model.SearchText))
{
return;
}
_searchResults = null;
_searchId = await ApiClient.StartSearch(Model.SearchText, [Model.SelectedPlugin], Model.SelectedCategory);
}
else
{
try
{
var status = await ApiClient.GetSearchStatus(_searchId.Value);
if (status is not null)
{
if (status.Status == "Running")
{
await ApiClient.StopSearch(_searchId.Value);
}
await ApiClient.DeleteSearch(_searchId.Value);
_searchId = null;
}
}
catch (HttpRequestException exception) when (exception.StatusCode == System.Net.HttpStatusCode.NotFound)
{
_searchId = null;
}
}
}
protected IEnumerable<ColumnDefinition<QBitTorrentClient.Models.SearchResult>> Columns => ColumnsDefinitions;
public static List<ColumnDefinition<QBitTorrentClient.Models.SearchResult>> ColumnsDefinitions { get; } =
[
new ColumnDefinition<QBitTorrentClient.Models.SearchResult>("Name", l => l.FileName),
new ColumnDefinition<QBitTorrentClient.Models.SearchResult>("Size", l => @DisplayHelpers.Size(l.FileSize)),
new ColumnDefinition<QBitTorrentClient.Models.SearchResult>("Seeders", l => l.Seeders),
new ColumnDefinition<QBitTorrentClient.Models.SearchResult>("Leechers", l => l.Leechers),
new ColumnDefinition<QBitTorrentClient.Models.SearchResult>("Search engine", l => l.SiteUrl),
];
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
_timerCancellationToken.Cancel();
_timerCancellationToken.Dispose();
}
_disposedValue = true;
}
}
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}