feat: implement cross-device reading progress synchronization using SignalR and remove legacy quiz generation services.

This commit is contained in:
2026-05-02 19:55:07 +02:00
parent e5611758f1
commit 94ecc7a404
22 changed files with 332 additions and 69 deletions
@@ -10,6 +10,7 @@
@inject IReaderNavigationService NavigationService
@inject KnowledgeCoordinator Coordinator
@inject IReaderInteractionService InteractionService
@inject ISyncService SyncService
<div class="reader-canvas @(ThemeService.IsLightMode ? "theme-light" : "theme-dark")">
@if (ViewModel == null)
@@ -77,6 +78,11 @@
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await SyncService.InitializeAsync();
}
if (ViewModel != null && !_isJsInitialized)
{
_isJsInitialized = true;
@@ -109,6 +115,23 @@
public void HandleBlockReached(string blockId, string content)
{
Coordinator.OnBlockReached(blockId, content);
// Debounce sync update (simple version: every 5 seconds or on a timer)
_ = SyncService.UpdateProgressAsync(blockId);
}
private void HandleSyncProgressReceived(string blockId, DateTime timestamp)
{
// For now, let's just scroll to the node if it's in the current view,
// or just log it. Usually, we should prompt the user.
Console.WriteLine($"[Sync] Received progress from another device: {blockId} at {timestamp}");
// Simple auto-scroll if it's newer than what we have (we don't track our own timestamp yet,
// but we can assume incoming syncs are from other active devices)
_ = InvokeAsync(async () => {
await ScrollToNodeAsync(blockId);
StateHasChanged();
});
}
[JSInvokable]
@@ -196,5 +219,6 @@
InteractionService.OnScrollToBlockRequested -= HandleScrollRequested;
InteractionService.OnHighlightBlockRequested -= HandleHighlightRequested;
InteractionService.OnTextSelected -= HandleTextSelected;
SyncService.OnProgressReceived -= HandleSyncProgressReceived;
}
}