Added SearchPageBase class and implemented it on the voice works page and circles page. Turned off AOT compilation.
This commit is contained in:
122
JSMR.UI.Blazor/Shared/SearchPageBase.cs
Normal file
122
JSMR.UI.Blazor/Shared/SearchPageBase.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using JSMR.Application.Common.Search;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Routing;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace JSMR.UI.Blazor.Shared;
|
||||
|
||||
public abstract class SearchPageBase<TState, TItem> : ComponentBase, IAsyncDisposable
|
||||
where TState : notnull
|
||||
{
|
||||
[Inject]
|
||||
protected NavigationManager Nav { get; set; } = default!;
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JS { get; set; } = default!;
|
||||
|
||||
protected TState State { get; private set; } = default!;
|
||||
protected SearchResult<TItem>? Result { get; private set; }
|
||||
protected bool IsLoading { get; private set; }
|
||||
|
||||
private bool _suppressNextLocation;
|
||||
private bool _isAlive = true;
|
||||
private CancellationTokenSource _cancellationTokenSource = new();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Nav.LocationChanged += OnLocationChanged;
|
||||
State = ParseStateFromUri(Nav.Uri);
|
||||
|
||||
await RunSearchAsync();
|
||||
}
|
||||
|
||||
protected async Task UpdateAsync(TState next)
|
||||
{
|
||||
if (Equals(next, State))
|
||||
return;
|
||||
|
||||
State = next;
|
||||
NavigateToState(next);
|
||||
|
||||
_ = RunSearchAsync();
|
||||
}
|
||||
|
||||
private void NavigateToState(TState next)
|
||||
{
|
||||
string uri = BuildUri(next);
|
||||
_suppressNextLocation = true;
|
||||
Nav.NavigateTo(uri);
|
||||
}
|
||||
|
||||
private async void OnLocationChanged(object? sender, LocationChangedEventArgs e)
|
||||
{
|
||||
if (_suppressNextLocation)
|
||||
{
|
||||
_suppressNextLocation = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_isAlive)
|
||||
return;
|
||||
|
||||
if (!IsThisPage(e.Location))
|
||||
return;
|
||||
|
||||
TState next = ParseStateFromUri(e.Location);
|
||||
|
||||
if (Equals(next, State))
|
||||
return;
|
||||
|
||||
State = next;
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
_ = RunSearchAsync();
|
||||
}
|
||||
|
||||
private async Task RunSearchAsync()
|
||||
{
|
||||
await JS.InvokeVoidAsync("pageHelpers.scrollToTop");
|
||||
|
||||
try
|
||||
{
|
||||
IsLoading = true;
|
||||
//StateHasChanged();
|
||||
|
||||
_cancellationTokenSource.Cancel();
|
||||
_cancellationTokenSource = new();
|
||||
|
||||
Result = await ExecuteSearchAsync(State, _cancellationTokenSource.Token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_isAlive)
|
||||
{
|
||||
IsLoading = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract TState ParseStateFromUri(string absoluteUri);
|
||||
protected abstract string BuildUri(TState state);
|
||||
protected abstract bool IsThisPage(string absoluteUri);
|
||||
protected abstract Task<SearchResult<TItem>> ExecuteSearchAsync(TState state, CancellationToken cancellationToken);
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
_isAlive = false;
|
||||
|
||||
Nav.LocationChanged -= OnLocationChanged;
|
||||
|
||||
_cancellationTokenSource.Cancel();
|
||||
_cancellationTokenSource.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user