Files
Nexus.Reader/src/NexusReader.UI.Shared/Components/Organisms/CurrentReadingWidget.razor
T
Antigravity 541e9e1fb5 feat(ai-ux): deduplicate AI queries, handle ServiceUnavailable retries, and optimize reader canvas graph prerendering (#44)
This Pull Request encapsulates all outstanding AI, Blazor InteractiveAuto lifecycle, pgvector, and Firefox authorization/session compatibility fixes.

### Key Accomplishments:
1. **Concurrent Request Deduplication (Option B):** Implemented a thread-safe active task registry in `KnowledgeService` that groups concurrent graph extraction queries for the same content, preventing duplicate AI calls completely.
2. **Resilience Strategy for Downstream Demands:** Extended the `ai-retry` resilience pipeline to automatically intercept and retry on temporary Google API `503 ServiceUnavailable` / `high demand` spikes.
3. **Interactive Graph Generation Guard (Option A):** Prevented server-side prerender-phase graph requests in the reader canvas component.
4. **Firefox Compatibility & Cookie Handler:** Implemented an authentication endpoint and hybrid hidden-form submission flow to solve login, registration, and logout redirections and cookies securely.
5. **Autoscrolling & Graph Exclusions:** Added concept-to-block smooth scrolling, active block badging, and filtered out markdown code blocks from being extracted as nodes.

All unit tests compiled and passed 100% cleanly.

---------

Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Reviewed-on: #44
Co-authored-by: Antigravity <antigravity@google.com>
Co-committed-by: Antigravity <antigravity@google.com>
2026-05-18 17:53:36 +00:00

80 lines
2.8 KiB
Plaintext

@using NexusReader.Application.DTOs.User
@using NexusReader.UI.Shared.Components.Atoms
@inject NavigationManager NavigationManager
<section class="current-reading-card glass-panel">
@if (Book != null)
{
<div class="card-layout">
<div class="book-cover">
<img src="@(Book.CoverUrl ?? "https://via.placeholder.com/120x180?text=No+Cover")" alt="@Book.Title" />
</div>
<div class="book-details">
<div class="header-info">
<h3 class="book-title">@Book.Title</h3>
<span class="author-name">by @Book.Author.Name</span>
</div>
<div class="chapter-progress">
<div class="progress-header">
<span class="chapter-name">@Book.LastChapter</span>
<span class="percentage">@(Book.Progress.ToString("F0"))%</span>
</div>
<div class="progress-bar-container">
<div class="progress-bar-fill" style="width: @(Book.Progress.ToString("F0"))%"></div>
</div>
</div>
@if (!string.IsNullOrEmpty(Book.Description))
{
<p class="book-excerpt">
@Book.Description
</p>
}
else
{
<p class="book-excerpt empty">
Kontynuuj odkrywanie wiedzy w książce "@Book.Title".
Twój cyfrowy asystent Nexus jest gotowy do analizy kolejnych rozdziałów i generowania interaktywnych map myśli.
</p>
}
<div class="actions">
<button class="btn-nexus outline" @onclick="HandleContinueReading">
Continue Reading
<NexusIcon Name="arrow-right" Size="16" />
</button>
</div>
</div>
</div>
}
else
{
<div class="empty-state">
<div class="empty-icon">
<NexusIcon Name="book-open" Size="48" />
</div>
<div class="empty-text">
<h3>Brak aktywnych lektur</h3>
<p>Przejdź do biblioteki, aby rozpocząć przygodę z Nexus Reader.</p>
</div>
<button class="btn-nexus primary" @onclick='() => NavigationManager.NavigateTo("/library")'>
Przejdź do Biblioteki
</button>
</div>
}
</section>
@code {
[Parameter] public LastReadBookDto? Book { get; set; }
private void HandleContinueReading()
{
if (Book != null)
{
NavigationManager.NavigateTo($"/reader/{Book.Id}?chapter={Book.LastChapterIndex}");
}
}
}