@page "/voiceworks"
@using JSMR.Application.Common.Search
@using JSMR.Application.VoiceWorks.Queries.Search
@using JSMR.UI.Blazor.Components
@using JSMR.UI.Blazor.Filters
@using JSMR.UI.Blazor.Services
@using Microsoft.AspNetCore.WebUtilities
@inject VoiceWorksClient Client
@inject IJSRuntime JS
@inject NavigationManager NavigationManager
@implements IAsyncDisposable;
Voice Works
Voice Works
@if (searchResults is not null)
{
}
@code {
private bool _isAlive = true;
private CancellationTokenSource _cts = new();
VoiceWorkFilterState FilterState = new();
SearchResult? searchResults;
protected override async Task OnInitializedAsync()
{
NavigationManager.LocationChanged += OnLocationChanged;
FilterState = VoiceWorkFilterState.FromQuery(new Uri(NavigationManager.Uri).Query);
await RunSearchAsync();
}
private async void OnLocationChanged(object? sender, LocationChangedEventArgs e)
{
if (!_isAlive)
return;
if (!IsThisPage(e.Location))
return;
// Parse query from the new URL and update state if it actually changed.
string query = NavigationManager.ToAbsoluteUri(e.Location).Query;
VoiceWorkFilterState next = VoiceWorkFilterState.FromQuery(query);
if (next != FilterState)
{
FilterState = next;
await RunSearchAsync();
await InvokeAsync(StateHasChanged);
}
}
private bool IsThisPage(string absoluteUri)
{
string baseRelativePath = NavigationManager.ToBaseRelativePath(absoluteUri);
return baseRelativePath.StartsWith("voiceworks", StringComparison.OrdinalIgnoreCase);
}
async Task OnFilterStateChanged(VoiceWorkFilterState next)
{
if (next == FilterState)
return;
UpdateUrl(next, false);
}
void UpdateUrl(VoiceWorkFilterState next, bool replace)
{
string basePath = new Uri(NavigationManager.Uri).GetLeftPart(UriPartial.Path);
string uri = QueryHelpers.AddQueryString(basePath, next.ToQuery());
NavigationManager.NavigateTo(uri, replace: replace);
}
async Task RunSearchAsync()
{
await JS.InvokeVoidAsync("pageHelpers.scrollToTop");
try
{
_cts.Cancel();
_cts = new();
SearchVoiceWorksResponse? response = await Client.SearchAsync(FilterState.ToSearchRequest(), _cts.Token);
searchResults = response?.Results;
}
catch (OperationCanceledException)
{
}
}
public async ValueTask DisposeAsync()
{
_isAlive = false;
NavigationManager.LocationChanged -= OnLocationChanged;
_cts.Cancel();
_cts.Dispose();
await Task.CompletedTask;
}
}