feat: implement mobile reader header and navigation components with updated icon support
This commit is contained in:
@@ -15,9 +15,31 @@
|
||||
@inject AuthenticationStateProvider AuthStateProvider
|
||||
@inject IQuizStateService QuizService
|
||||
@inject IPlatformService PlatformService
|
||||
@inject NavigationManager Navigation
|
||||
@inject ILogger<ReaderCanvas> Logger
|
||||
|
||||
<div class="reader-canvas @(ThemeService.IsLightMode ? "theme-light" : "theme-dark")">
|
||||
@if (_isMobile && ViewModel != null)
|
||||
{
|
||||
<header class="nexus-mobile-reader-header">
|
||||
<button class="nexus-mobile-escape-btn" @onclick="HandleEscape" aria-label="Powrót do pulpitu">
|
||||
<NexusIcon Name="chevron-left" Size="18" />
|
||||
<span>Pulpit</span>
|
||||
</button>
|
||||
<div class="nexus-mobile-chapter-navigation">
|
||||
<button class="nexus-chapter-nav-btn prev" @onclick="NavigationService.GoToPreviousChapter" disabled="@(NavigationService.CurrentChapterIndex == 0)" aria-label="Poprzedni rozdział">
|
||||
<NexusIcon Name="chevron-left" Size="14" />
|
||||
</button>
|
||||
<div class="nexus-mobile-chapter-title">
|
||||
@ViewModel.ChapterTitle
|
||||
</div>
|
||||
<button class="nexus-chapter-nav-btn next" @onclick="NavigationService.GoToNextChapter" disabled="@(NavigationService.CurrentChapterIndex >= NavigationService.TotalChapters - 1)" aria-label="Następny rozdział">
|
||||
<NexusIcon Name="chevron-right" Size="14" />
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
}
|
||||
|
||||
@if (ViewModel == null)
|
||||
{
|
||||
<div class="loading-state full-page">
|
||||
@@ -56,16 +78,7 @@
|
||||
Coordinates="@_selectionCoords"
|
||||
FullPageContent="@GetFullPageContent()" />
|
||||
|
||||
@if (_isMobile)
|
||||
{
|
||||
<button class="nexus-mobile-assistant-fab @(QuizService.HasNewQuiz ? "has-new-quiz" : "")" @onclick="HandleAssistantFabClick" aria-label="Asystent AI">
|
||||
<NexusIcon Name="robot" Size="24" Class="neon-glow" />
|
||||
@if (QuizService.HasNewQuiz)
|
||||
{
|
||||
<span class="fab-badge"></span>
|
||||
}
|
||||
</button>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
@@ -194,12 +207,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
private IJSObjectReference? _scrollListenerReference;
|
||||
|
||||
private async Task InitializeObserverAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var module = await JS.InvokeAsync<IJSObjectReference>("import", "./_content/NexusReader.UI.Shared/js/readerObserver.js");
|
||||
await module.InvokeVoidAsync("initObserver", DotNetObjectReference.Create(this), ".reader-flow-container", ".block-wrapper");
|
||||
_scrollListenerReference = await module.InvokeAsync<IJSObjectReference>("initScrollListener", DotNetObjectReference.Create(this), ".reader-flow-container");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -207,10 +223,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
[JSInvokable]
|
||||
public async Task HandleScrollPercentChanged(int percent)
|
||||
{
|
||||
await InteractionService.NotifyScrollPercentChanged(percent);
|
||||
}
|
||||
|
||||
[JSInvokable]
|
||||
public async Task HandleBlockReached(string blockId, string content)
|
||||
{
|
||||
_currentActiveBlockId = blockId;
|
||||
await InteractionService.NotifyBlockReached(blockId);
|
||||
await Coordinator.OnBlockReachedAsync(blockId, content);
|
||||
|
||||
if (ViewModel != null)
|
||||
@@ -310,6 +333,13 @@
|
||||
ViewModel = result.Value;
|
||||
await NavigationService.UpdateMetadataAsync(ViewModel.CurrentChapterIndex, ViewModel.TotalChapters, ViewModel.ChapterTitle);
|
||||
|
||||
// Populate checkpoints!
|
||||
var checkpoints = ViewModel.Blocks
|
||||
.Where(b => !string.IsNullOrEmpty(b.Id) && b.Id.Contains("seg"))
|
||||
.Select(b => b.Id)
|
||||
.ToList();
|
||||
InteractionService.CurrentCheckpoints = checkpoints;
|
||||
|
||||
if (_isInteractive)
|
||||
{
|
||||
await Coordinator.ProcessFullPageAsync(GetFullPageContent(), ebookId: ViewModel.EbookId);
|
||||
@@ -352,6 +382,14 @@
|
||||
|
||||
private Task HandleUpdate() => InvokeAsync(StateHasChanged);
|
||||
|
||||
private void HandleEscape()
|
||||
{
|
||||
if (ViewModel != null)
|
||||
{
|
||||
Navigation.NavigateTo("/");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleAssistantFabClick()
|
||||
{
|
||||
await InteractionService.RequestAssistant();
|
||||
@@ -368,5 +406,14 @@
|
||||
InteractionService.OnTextSelected -= HandleTextSelected;
|
||||
SyncService.OnProgressReceived -= HandleSyncProgressReceived;
|
||||
_selfReference?.Dispose();
|
||||
|
||||
try
|
||||
{
|
||||
if (_scrollListenerReference != null)
|
||||
{
|
||||
_ = _scrollListenerReference.DisposeAsync();
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user