@inherits LayoutComponentBase @using NexusReader.Application.Abstractions.Services @using NexusReader.UI.Shared.Services @using NexusReader.UI.Shared.Components.Molecules @using NexusReader.UI.Shared.Components.Organisms @using NexusReader.Application.Queries.Graph @using Microsoft.Extensions.Logging @inject IPlatformService PlatformService @inject IFocusModeService FocusMode @inject IQuizStateService QuizService @inject IReaderInteractionService InteractionService @inject IKnowledgeGraphService GraphService @inject IJSRuntime JS @inject IIdentityService IdentityService @inject NavigationManager NavigationManager @inject Microsoft.Extensions.Logging.ILogger Logger @implements IDisposable
@Body
@if (!_isMobile) {
Asystent AI
@if (_activeTab == SidebarTab.Knowledge) {
Contextual Intelligence Panel
@if (_selectedNode != null) {
@(_selectedNode.Group.ToUpper())

@_selectedNode.Label

@if (!string.IsNullOrEmpty(_selectedNode.Description)) {

@_selectedNode.Description

} @if (!string.IsNullOrEmpty(_selectedNode.Summary)) {

Podsumowanie

@_selectedNode.Summary

} @if (_selectedNode.KeyTerms != null && _selectedNode.KeyTerms.Any()) {

Kluczowe Pojęcia

    @foreach (var term in _selectedNode.KeyTerms) {
  • @term
  • }
}
} else {

Wybierz węzeł na wykresie, aby wyświetlić szczegóły architektoniczne.

}
} else {
}
} else {
@if (_activeTab == SidebarTab.Knowledge) {
@if (_selectedNode != null) {
@(_selectedNode.Group.ToUpper())

@_selectedNode.Label

@if (!string.IsNullOrEmpty(_selectedNode.Description)) {

@_selectedNode.Description

} @if (!string.IsNullOrEmpty(_selectedNode.Summary)) {

Podsumowanie

@_selectedNode.Summary

} @if (_selectedNode.KeyTerms != null && _selectedNode.KeyTerms.Any()) {

Kluczowe Pojęcia

    @foreach (var term in _selectedNode.KeyTerms) {
  • @term
  • }
}
} else {

Wybierz pojęcie na wykresie, aby wyświetlić jego podsumowanie.

}
} else {
}
}
Weryfikacja...
An unhandled error has occurred. Reload 🗙
@code { private enum SidebarTab { Knowledge, Quiz } private enum MobileReaderTab { Reader, Graph, Insight } private SidebarTab _activeTab = SidebarTab.Knowledge; private MobileReaderTab _activeMobileTab = MobileReaderTab.Reader; private string? _selectedNodeId; private GraphNodeDto? _selectedNode; private string _platformClass = "platform-desktop"; private bool _isMobile = false; private DotNetObjectReference? _selfReference; protected override void OnInitialized() { FocusMode.OnFocusModeChanged += HandleUpdate; QuizService.OnQuizUpdated += HandleUpdate; QuizService.OnQuizRequested += HandleQuizRequestedAsync; InteractionService.OnNodeSelected += HandleNodeSelectedAsync; InteractionService.OnAssistantRequested += HandleAssistantRequestedAsync; GraphService.OnGraphUpdated += HandleGraphUpdatedAsync; var context = PlatformService.GetDeviceContext(); if (context.IsSuccess) { _isMobile = context.Value.DeviceType switch { DeviceType.Phone or DeviceType.Tablet => true, _ => false }; _platformClass = _isMobile ? "platform-mobile" : "platform-desktop"; } } private void SetActiveTab(SidebarTab tab) { _activeTab = tab; StateHasChanged(); } private void SetMobileTab(MobileReaderTab tab) { _activeMobileTab = tab; StateHasChanged(); } private async Task HandleQuizRequestedAsync(string blockId) { _activeTab = SidebarTab.Quiz; if (_isMobile) { _activeMobileTab = MobileReaderTab.Insight; } await InvokeAsync(StateHasChanged); } private async Task HandleAssistantRequestedAsync() { _activeMobileTab = MobileReaderTab.Insight; _activeTab = SidebarTab.Quiz; await InvokeAsync(StateHasChanged); } private async Task HandleNodeSelectedAsync(string nodeId) { _selectedNodeId = nodeId; if (GraphService.CurrentGraphData != null) { _selectedNode = GraphService.CurrentGraphData.Nodes.FirstOrDefault(n => n.Id == nodeId); } if (_isMobile) { _activeMobileTab = MobileReaderTab.Insight; _activeTab = SidebarTab.Knowledge; } await InvokeAsync(StateHasChanged); } private async Task HandleGraphUpdatedAsync() { _selectedNodeId = null; _selectedNode = null; await InvokeAsync(StateHasChanged); } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { try { var module = await JS.InvokeAsync("import", "./_content/NexusReader.UI.Shared/js/layoutResizer.js"); await module.InvokeVoidAsync("initResizer", ".app-container", "#sidebar-resizer", "--sidebar-width"); } catch (Exception ex) { Logger.LogError(ex, "Failed to initialize layout resizer JS module."); } await InitViewportDetectionAsync(); } } private async Task InitViewportDetectionAsync() { try { _selfReference = DotNetObjectReference.Create(this); var isMobileViewport = await JS.InvokeAsync("eval", "window.innerWidth < 768"); await OnViewportChanged(isMobileViewport); await JS.InvokeVoidAsync("eval", @" window.registerViewportObserver = (dotNetHelper) => { let currentIsMobile = window.innerWidth < 768; window.addEventListener('resize', () => { let isMobile = window.innerWidth < 768; if (isMobile !== currentIsMobile) { currentIsMobile = isMobile; dotNetHelper.invokeMethodAsync('OnViewportChanged', isMobile); } }); } "); await JS.InvokeVoidAsync("registerViewportObserver", _selfReference); } catch (Exception ex) { Logger.LogWarning(ex, "Failed to initialize viewport detection."); } } [JSInvokable] public async Task OnViewportChanged(bool isMobile) { if (_isMobile != isMobile) { _isMobile = isMobile; _platformClass = _isMobile ? "platform-mobile" : "platform-desktop"; await InvokeAsync(StateHasChanged); } } private Task HandleUpdate() => InvokeAsync(StateHasChanged); public void Dispose() { FocusMode.OnFocusModeChanged -= HandleUpdate; QuizService.OnQuizUpdated -= HandleUpdate; QuizService.OnQuizRequested -= HandleQuizRequestedAsync; InteractionService.OnNodeSelected -= HandleNodeSelectedAsync; InteractionService.OnAssistantRequested -= HandleAssistantRequestedAsync; GraphService.OnGraphUpdated -= HandleGraphUpdatedAsync; _selfReference?.Dispose(); } }