76b828395d
This PR implements a comprehensive mobile-first design overhaul for the Reader, Dashboard, and Navigation layouts. ### Key Accomplishments 1. **Dynamic Viewport Synchronization**: Installed robust `ResizeObserver` listener on the client side with automatic reactive toggling of `platform-mobile`/`platform-desktop` CSS classes. 2. **Tab Controller & Visibility Fixes**: Refactored visibility constraints in `ReaderLayout.razor.css` to prevent layout clipping and DOM bloat. Standardized the mobile tab content selectors to ensure active views display perfectly. 3. **D3.js Graph Stabilization**: * Added checks to bypass resize callbacks when the graph container is hidden (`clientWidth <= 0` or `clientHeight <= 0`). * Guarded coordination ticks, node focus transformations, and zoom transitions against `NaN` parameters. 4. **Interactive Mobile UX Enhancements**: Optimized touch target sizing (44px target bounds) and interactive transitions for a state-of-the-art visual presentation. This has been successfully compiled and verified against the standard .NET 10 compilation gates. --------- Co-authored-by: Marek Jasiński <jasins.marek@gmail.com> Reviewed-on: #58 Co-authored-by: Antigravity <antigravity@google.com> Co-committed-by: Antigravity <antigravity@google.com>
42 lines
1.4 KiB
Plaintext
42 lines
1.4 KiB
Plaintext
@using Microsoft.AspNetCore.Components.Authorization
|
|
@inject PersistentComponentState ApplicationState
|
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
|
@implements IDisposable
|
|
|
|
@code {
|
|
private PersistingComponentStateSubscription _subscription;
|
|
|
|
protected override void OnInitialized()
|
|
{
|
|
_subscription = ApplicationState.RegisterOnPersisting(PersistAuthenticationStateAsync);
|
|
}
|
|
|
|
private async Task PersistAuthenticationStateAsync()
|
|
{
|
|
var authenticationState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
|
var principal = authenticationState.User;
|
|
|
|
if (principal.Identity?.IsAuthenticated == true)
|
|
{
|
|
var email = principal.FindFirst(System.Security.Claims.ClaimTypes.Email)?.Value ?? principal.Identity.Name;
|
|
var tenantId = principal.FindFirst("TenantId")?.Value ?? "global";
|
|
var roles = string.Join(",", principal.FindAll(System.Security.Claims.ClaimTypes.Role).Select(c => c.Value));
|
|
|
|
if (email != null)
|
|
{
|
|
ApplicationState.PersistAsJson("UserInfo", new UserInfo
|
|
{
|
|
Email = email,
|
|
TenantId = tenantId,
|
|
Roles = roles
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_subscription.Dispose();
|
|
}
|
|
}
|