feat(intelligence): implement Global AI Q&A screen and paywall blocker

- Implemented standard empty and active chat conversation states for the `/intelligence` page
- Created interactive `AiResponseRenderer` with AOT-compliant sentence splitting and payment gateway simulation
- Added scoped `LibraryStateService` to synchronize book ownership and updates across the application
- Obfuscated paywalled content in DOM to prevent inspection bypass
- Fixed local port connection mismatch by updating API configurations to use port 5104
This commit is contained in:
2026-06-06 10:41:48 +02:00
parent bcd5daa3a0
commit faf6ec826e
15 changed files with 932 additions and 318 deletions
@@ -1,5 +1,6 @@
@page "/catalog"
@attribute [Authorize]
@implements IDisposable
@using NexusReader.UI.Shared.Components.Organisms
@using NexusReader.Application.DTOs.User
@using NexusReader.UI.Shared.Services
@@ -7,6 +8,7 @@
@inject HttpClient Http
@inject IReaderNavigationService ReaderNavigation
@inject NavigationManager NavigationManager
@inject ILibraryStateService LibraryStateService
<div class="catalog-page">
<header class="catalog-header">
@@ -189,6 +191,11 @@
private bool _isLoading = true;
private List<LastReadBookDto>? _books;
protected override void OnInitialized()
{
LibraryStateService.OnBooksChanged += HandleBooksChanged;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
@@ -197,6 +204,11 @@
}
}
private void HandleBooksChanged()
{
_ = InvokeAsync(LoadBooksAsync);
}
private async Task LoadBooksAsync()
{
_isLoading = true;
@@ -231,4 +243,9 @@
// Showcase callback
NavigationManager.NavigateTo("/profile");
}
public void Dispose()
{
LibraryStateService.OnBooksChanged -= HandleBooksChanged;
}
}