Files
Moonlight/Moonlight.Client/UI/Layouts/MainLayout.razor
2025-01-08 00:33:09 +01:00

147 lines
3.4 KiB
Plaintext

@using MoonCore.Exceptions
@using Moonlight.Client.Interfaces
@using Moonlight.Client.Services
@using Moonlight.Client.UI.Partials
@using Moonlight.Shared.Misc
@using Moonlight.Client.UI.Components
@inherits LayoutComponentBase
@inject IdentityService IdentityService
@inject IServiceProvider ServiceProvider
@inject ILogger<MainLayout> Logger
@inject IAppLoader[] AppLoaders
@inject IAppScreen[] AppScreens
@inject FrontendConfiguration Configuration
<PageTitle>@Configuration.Title</PageTitle>
<ThemeLoader />
@if (IsLoading)
{
<div class="h-full w-full min-h-[100dvh] flex items-center justify-center">
<div id="loader"></div>
</div>
}
else if (CurrentScreen != null)
{
<CascadingValue Value="this" IsFixed="true">
@CurrentScreen
</CascadingValue>
}
else
{
<div>
<AppSidebar Layout="this"/>
<div class="lg:pl-72">
<AppHeader Layout="this"/>
<main class="py-10">
<div class="px-4 sm:px-6 lg:px-8">
<ErrorHandler>
<PermissionHandler CheckFunction="CheckPermission">
<CascadingValue Value="this" IsFixed="true">
@Body
</CascadingValue>
</PermissionHandler>
</ErrorHandler>
</div>
</main>
</div>
</div>
}
<ToastLauncher/>
<ModalLauncher/>
@code
{
// Mobile navigation
public event Func<Task> OnStateChanged;
public bool ShowMobileNavigation { get; private set; } = false;
public async Task ToggleMobileNavigation()
{
ShowMobileNavigation = !ShowMobileNavigation;
await OnStateChanged();
}
// App loaders & screens
private bool IsLoading = true;
private RenderFragment? CurrentScreen;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender)
return;
await Load();
}
public async Task Load()
{
IsLoading = true;
await InvokeAsync(StateHasChanged);
//
await RunLoaders();
// Screens
await RenderScreens();
//
IsLoading = false;
await InvokeAsync(StateHasChanged);
}
private async Task RunLoaders()
{
var appLoaders = AppLoaders
.OrderBy(x => x.Priority);
foreach (var loader in appLoaders) //TODO: Measure performance of every loader?
{
try
{
Logger.LogDebug("Running application loader '{name}'", loader.GetType().Name);
await loader.Load(ServiceProvider);
}
catch (HttpApiException)
{
throw;
}
catch (Exception e)
{
Logger.LogCritical("An app loader threw an unhandled exception: {e}", e);
}
}
}
public async Task RenderScreens()
{
CurrentScreen = null;
var appScreens = AppScreens
.OrderBy(x => x.Priority);
foreach (var screen in appScreens)
{
if (!await screen.ShouldRender(ServiceProvider))
continue;
CurrentScreen = screen.Render();
await InvokeAsync(StateHasChanged);
return;
}
await InvokeAsync(StateHasChanged);
}
private bool CheckPermission(string permission) => IdentityService.HasPermission(permission);
}