55cc3ae10d
This PR introduces a major optimization of graph dynamics, immersive reading experience, and architectural stabilization. ### 🚀 Key Improvements - **Knowledge Graph (Fix #16)**: - Implemented smooth D3.js transitions using the General Update Pattern. - Added "Neon Flash" entry animations and dynamic node dimming for better focus. - **Immersive Reader (Fix #12)**: - Standardized centered layout (`max-width: 800px`) with **Merriweather** typography. - Optimized line-height and letter-spacing for premium readability. - **Technical Code Blocks (Fix #20)**: - High-contrast dark containers for code snippets. - **JetBrains Mono** integration and neon-accented scrollbars. - **Architectural Stabilization**: - Enforced a strict **'no async void'** policy in UI services using `Func<Task>`. - Resolved WASM runtime DI errors by implementing dummy service proxies for server-side dependencies. - Replaced generic 'Not Found' message with a branded Nexus preloader. Fixes #7, Fixes #12, Fixes #16, Fixes #20. Reviewed-on: #19 Co-authored-by: Marek Jasiński <jasins.marek@gmail.com> Co-committed-by: Marek Jasiński <jasins.marek@gmail.com>
82 lines
2.5 KiB
Plaintext
82 lines
2.5 KiB
Plaintext
@page "/"
|
|
@attribute [Authorize]
|
|
@using NexusReader.UI.Shared.Services
|
|
@implements IAsyncDisposable
|
|
@inject IQuizStateService QuizState
|
|
@inject IFocusModeService FocusMode
|
|
@inject IJSRuntime JS
|
|
<PageTitle>Nexus E-Reader</PageTitle>
|
|
|
|
<div class="home-reader-container">
|
|
<ReaderCanvas @ref="readerCanvas" />
|
|
</div>
|
|
|
|
|
|
@code {
|
|
private ReaderCanvas? readerCanvas;
|
|
private string? _activeQuizBlockId;
|
|
|
|
private IJSObjectReference? _interopModule;
|
|
private IJSObjectReference? _keydownHandler;
|
|
private DotNetObjectReference<Home>? _dotNetRef;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
QuizState.OnQuizRequested += HandleQuizRequestedAsync;
|
|
FocusMode.OnFocusModeChanged += HandleUpdate;
|
|
await FocusMode.InitializeAsync();
|
|
}
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
if (firstRender)
|
|
{
|
|
try {
|
|
_interopModule = await JS.InvokeAsync<IJSObjectReference>("import", "./_content/NexusReader.UI.Shared/js/focusInterop.js");
|
|
_dotNetRef = DotNetObjectReference.Create(this);
|
|
_keydownHandler = await _interopModule.InvokeAsync<IJSObjectReference>("attachKeyboardListener", _dotNetRef);
|
|
} catch { } /* ignored dynamically */
|
|
}
|
|
}
|
|
|
|
[JSInvokable]
|
|
public async Task OnFocusKeypressed()
|
|
{
|
|
await FocusMode.ToggleAsync();
|
|
StateHasChanged();
|
|
}
|
|
|
|
private async Task HandleNodeSelected(string nodeId)
|
|
{
|
|
if (readerCanvas != null)
|
|
{
|
|
await readerCanvas.ScrollToNodeAsync(nodeId);
|
|
}
|
|
}
|
|
|
|
private async Task HandleQuizRequestedAsync(string blockId)
|
|
{
|
|
_activeQuizBlockId = blockId;
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
private Task HandleUpdate() => InvokeAsync(StateHasChanged);
|
|
|
|
public async ValueTask DisposeAsync()
|
|
{
|
|
QuizState.OnQuizRequested -= HandleQuizRequestedAsync;
|
|
FocusMode.OnFocusModeChanged -= HandleUpdate;
|
|
|
|
if (_interopModule != null && _keydownHandler != null)
|
|
{
|
|
try {
|
|
await _interopModule.InvokeVoidAsync("detachKeyboardListener", _keydownHandler);
|
|
await _interopModule.DisposeAsync();
|
|
await _keydownHandler.DisposeAsync();
|
|
} catch { } // Circuit disconnected catch explicitly
|
|
}
|
|
|
|
_dotNetRef?.Dispose();
|
|
}
|
|
}
|