using Blazored.LocalStorage; using Lantean.QBitTorrentClient; using Lantean.QBitTorrentClient.Models; using Lantean.QBTMud.Components.UI; using Lantean.QBTMud.Helpers; using Lantean.QBTMud.Models; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; using MudBlazor; using System.Net; namespace Lantean.QBTMud.Pages { public partial class Blocks : IAsyncDisposable { private readonly bool _refreshEnabled = true; private const string _selectedTypesStorageKey = "Blocks.SelectedTypes"; private readonly CancellationTokenSource _timerCancellationToken = new(); private bool _disposedValue; [Inject] protected IApiClient ApiClient { get; set; } = default!; [Inject] protected IDialogService DialogService { get; set; } = default!; [Inject] protected NavigationManager NavigationManager { get; set; } = default!; [Inject] protected ILocalStorageService LocalStorage { get; set; } = default!; [CascadingParameter(Name = "DrawerOpen")] public bool DrawerOpen { get; set; } protected LogForm Model { get; set; } = new LogForm(); protected List? Results { get; private set; } protected MudSelect? CategoryMudSelect { get; set; } protected DynamicTable? Table { get; set; } protected override async Task OnInitializedAsync() { var selectedTypes = await LocalStorage.GetItemAsync>(_selectedTypesStorageKey); if (selectedTypes is not null) { Model.SelectedTypes = selectedTypes; } else { Model.SelectedTypes = ["Normal"]; } await DoSearch(); } protected void NavigateBack() { NavigationManager.NavigateTo("/"); } protected async Task SelectedValuesChanged(IEnumerable values) { Model.SelectedTypes = values; await LocalStorage.SetItemAsync(_selectedTypesStorageKey, Model.SelectedTypes); } protected static string GenerateSelectedText(List values) { if (values.Count == 4) { return "All"; } return $"{values.Count} selected"; } protected Task Submit(EditContext editContext) { return DoSearch(); } private async Task DoSearch() { var results = await ApiClient.GetPeerLog(Model.LastKnownId); if (results.Count > 0) { Results ??= []; Results.AddRange(results); Model.LastKnownId = results[^1].Id; } } protected static string RowClass(PeerLog log, int index) { return $"log-{(log.Blocked ? "critical" : "normal")}"; } public async ValueTask DisposeAsync() { // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method await DisposeAsync(disposing: true); GC.SuppressFinalize(this); } protected virtual async Task DisposeAsync(bool disposing) { if (!_disposedValue) { if (disposing) { _timerCancellationToken.Cancel(); _timerCancellationToken.Dispose(); await Task.CompletedTask; } _disposedValue = true; } } protected override async Task OnAfterRenderAsync(bool firstRender) { if (!_refreshEnabled) { return; } if (!firstRender) { return; } using (var timer = new PeriodicTimer(TimeSpan.FromMilliseconds(1500))) { while (!_timerCancellationToken.IsCancellationRequested && await timer.WaitForNextTickAsync()) { try { await DoSearch(); } catch (HttpRequestException exception) when (exception.StatusCode == HttpStatusCode.Forbidden || exception.StatusCode == HttpStatusCode.NotFound) { _timerCancellationToken.CancelIfNotDisposed(); return; } await InvokeAsync(StateHasChanged); } } } protected IEnumerable> Columns => ColumnsDefinitions; public static List> ColumnsDefinitions { get; } = [ new ColumnDefinition("Id", l => l.Id), new ColumnDefinition("Message", l => l.IPAddress), new ColumnDefinition("Timestamp", l => l.Timestamp, l => @DisplayHelpers.DateTime(l.Timestamp)), new ColumnDefinition("Blocked", l => l.Blocked ? "Blocked" : "Banned"), new ColumnDefinition("Reason", l => l.Reason), ]; } }