Added app loaders and screen for the ui. Added identity service. Started auth screens
This commit is contained in:
27
Moonlight.Client/Implementations/AuthenticationUiHandler.cs
Normal file
27
Moonlight.Client/Implementations/AuthenticationUiHandler.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MoonCore.Blazor.Helpers;
|
||||
using Moonlight.Client.Interfaces;
|
||||
using Moonlight.Client.Services;
|
||||
using Moonlight.Client.UI.Screens;
|
||||
|
||||
namespace Moonlight.Client.Implementations;
|
||||
|
||||
public class AuthenticationUiHandler : IAppLoader, IAppScreen
|
||||
{
|
||||
public int Priority => 0;
|
||||
|
||||
public Task<bool> ShouldRender(IServiceProvider serviceProvider)
|
||||
{
|
||||
var identityService = serviceProvider.GetRequiredService<IdentityService>();
|
||||
|
||||
return Task.FromResult(identityService.IsLoggedIn);
|
||||
}
|
||||
|
||||
public RenderFragment Render() => ComponentHelper.FromType<AuthenticationScreen>();
|
||||
|
||||
public async Task Load(IServiceProvider serviceProvider)
|
||||
{
|
||||
var identityService = serviceProvider.GetRequiredService<IdentityService>();
|
||||
await identityService.Check();
|
||||
}
|
||||
}
|
||||
7
Moonlight.Client/Interfaces/IAppLoader.cs
Normal file
7
Moonlight.Client/Interfaces/IAppLoader.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Moonlight.Client.Interfaces;
|
||||
|
||||
public interface IAppLoader
|
||||
{
|
||||
public int Priority { get; }
|
||||
public Task Load(IServiceProvider serviceProvider);
|
||||
}
|
||||
10
Moonlight.Client/Interfaces/IAppScreen.cs
Normal file
10
Moonlight.Client/Interfaces/IAppScreen.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Moonlight.Client.Interfaces;
|
||||
|
||||
public interface IAppScreen
|
||||
{
|
||||
public int Priority { get; }
|
||||
public Task<bool> ShouldRender(IServiceProvider serviceProvider);
|
||||
public RenderFragment Render();
|
||||
}
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Helpers\" />
|
||||
<Folder Include="Services\" />
|
||||
<Folder Include="UI\Components\" />
|
||||
<Folder Include="wwwroot\css\" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -55,6 +55,10 @@ var implementationService = new ImplementationService();
|
||||
|
||||
implementationService.Register<ISidebarItemProvider, DefaultSidebarItemProvider>();
|
||||
|
||||
var authUiHandler = new AuthenticationUiHandler();
|
||||
implementationService.Register<IAppScreen>(authUiHandler);
|
||||
implementationService.Register<IAppLoader>(authUiHandler);
|
||||
|
||||
builder.Services.AddSingleton(implementationService);
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
57
Moonlight.Client/Services/IdentityService.cs
Normal file
57
Moonlight.Client/Services/IdentityService.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using MoonCore.Blazor.Tailwind.Services;
|
||||
using MoonCore.Exceptions;
|
||||
using MoonCore.Helpers;
|
||||
using Moonlight.Shared.Http.Responses.Auth;
|
||||
|
||||
namespace Moonlight.Client.Services;
|
||||
|
||||
public class IdentityService
|
||||
{
|
||||
public string Username { get; private set; }
|
||||
public string Email { get; private set; }
|
||||
public string[] Permissions { get; private set; }
|
||||
public bool IsLoggedIn { get; private set; }
|
||||
|
||||
public event Func<Task> OnStateChanged;
|
||||
|
||||
private readonly CookieService CookieService;
|
||||
private readonly HttpApiClient ApiClient;
|
||||
|
||||
public IdentityService(CookieService cookieService, HttpApiClient apiClient)
|
||||
{
|
||||
CookieService = cookieService;
|
||||
ApiClient = apiClient;
|
||||
}
|
||||
|
||||
public async Task Check()
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await ApiClient.GetJson<CheckResponse>("api/auth/check");
|
||||
|
||||
Username = response.Username;
|
||||
Email = response.Email;
|
||||
Permissions = response.Permissions;
|
||||
|
||||
IsLoggedIn = true;
|
||||
}
|
||||
catch (HttpApiException)
|
||||
{
|
||||
IsLoggedIn = false;
|
||||
}
|
||||
|
||||
await OnStateChanged();
|
||||
}
|
||||
|
||||
public async Task Login(string token)
|
||||
{
|
||||
await CookieService.SetValue("token", token, 30);
|
||||
await Check();
|
||||
}
|
||||
|
||||
public async Task Logout()
|
||||
{
|
||||
await CookieService.SetValue("token", "", 30);
|
||||
await Check();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,26 @@
|
||||
@using MoonCore.Helpers
|
||||
@using MoonCore.PluginFramework.Services
|
||||
@using Moonlight.Client.Interfaces
|
||||
@using Moonlight.Client.UI.Partials
|
||||
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
@inject ImplementationService ImplementationService
|
||||
@inject IServiceProvider ServiceProvider
|
||||
@inject ILogger<MainLayout> Logger
|
||||
|
||||
@if (IsLoading)
|
||||
{
|
||||
<LazyLoader Load="Load">
|
||||
|
||||
</LazyLoader>
|
||||
}
|
||||
else if (CurrentScreen != null)
|
||||
{
|
||||
@CurrentScreen
|
||||
}
|
||||
else
|
||||
{
|
||||
<div>
|
||||
<AppSidebar Layout="this"/>
|
||||
|
||||
@@ -12,18 +30,23 @@
|
||||
<ErrorHandler>
|
||||
<main class="py-10">
|
||||
<div class="px-4 sm:px-6 lg:px-8">
|
||||
<CascadingValue Value="this" IsFixed="true">
|
||||
@Body
|
||||
</CascadingValue>
|
||||
</div>
|
||||
</main>
|
||||
</ErrorHandler>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<ToastLauncher/>
|
||||
<ModalLauncher/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@code
|
||||
{
|
||||
// Mobile navigation
|
||||
public event Func<Task> OnStateChanged;
|
||||
public bool ShowMobileNavigation { get; private set; } = false;
|
||||
|
||||
@@ -32,4 +55,64 @@
|
||||
ShowMobileNavigation = !ShowMobileNavigation;
|
||||
await OnStateChanged();
|
||||
}
|
||||
|
||||
// App loaders & screens
|
||||
private bool IsLoading = true;
|
||||
private RenderFragment? CurrentScreen;
|
||||
|
||||
private async Task Load(LazyLoader lazyLoader)
|
||||
{
|
||||
await lazyLoader.UpdateText("Retrieving data");
|
||||
await RunLoaders();
|
||||
|
||||
await RenderScreens();
|
||||
|
||||
IsLoading = false;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
public async Task Reload()
|
||||
{
|
||||
IsLoading = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async Task RunLoaders()
|
||||
{
|
||||
var appLoaders = ImplementationService
|
||||
.Get<IAppLoader>()
|
||||
.OrderBy(x => x.Priority);
|
||||
|
||||
foreach (var loader in appLoaders) //TODO: Measure performance of every loader?
|
||||
{
|
||||
try
|
||||
{
|
||||
await loader.Load(ServiceProvider);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogCritical("An app loader threw an unhandled exception: {e}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RenderScreens()
|
||||
{
|
||||
CurrentScreen = null;
|
||||
|
||||
var appScreens = ImplementationService
|
||||
.Get<IAppScreen>()
|
||||
.OrderBy(x => x.Priority);
|
||||
|
||||
foreach (var screen in appScreens)
|
||||
{
|
||||
if (!await screen.ShouldRender(ServiceProvider))
|
||||
continue;
|
||||
|
||||
CurrentScreen = screen.Render();
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Moonlight.Client/UI/Screens/AuthenticationScreen.razor
Normal file
18
Moonlight.Client/UI/Screens/AuthenticationScreen.razor
Normal file
@@ -0,0 +1,18 @@
|
||||
@page "/auth/register"
|
||||
@page "/auth/login"
|
||||
|
||||
@inject NavigationManager Navigation
|
||||
|
||||
@{
|
||||
var url = new Uri(Navigation.Uri);
|
||||
var isRegister = url.LocalPath.StartsWith("/auth/register");
|
||||
}
|
||||
|
||||
@if (isRegister)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user