Implement milestone 2 route navigation
This commit is contained in:
@@ -3,18 +3,31 @@ using RpgRoller.Contracts;
|
||||
|
||||
namespace RpgRoller.Components.Pages;
|
||||
|
||||
public sealed class WorkspaceSessionCoordinator(WorkspaceState state, WorkspaceFeedbackService feedback, IJSRuntime js, RpgRollerApiClient apiClient, WorkspaceQueryService workspaceQuery, Func<Guid?, Task> reloadCampaignsAsync, Func<Task> reloadCharacterCampaignOptionsAsync, Func<Task> refreshCampaignScopeAsync, Func<Task> syncStateEventsAsync, Func<Task> stopStateEventsAsync, Func<Task> ensureAdminUsersLoadedAsync, Action resetCampaignLogDetailState, Func<Task> requestRefreshAsync, Func<string?, Task> onLoggedOutAsync)
|
||||
public sealed class WorkspaceSessionCoordinator(
|
||||
WorkspaceState state,
|
||||
WorkspaceFeedbackService feedback,
|
||||
IJSRuntime js,
|
||||
RpgRollerApiClient apiClient,
|
||||
WorkspaceQueryService workspaceQuery,
|
||||
Func<bool> isAdminRoute,
|
||||
Func<Task> redirectToPlayAsync,
|
||||
Func<Guid?, Task> reloadCampaignsAsync,
|
||||
Func<Task> reloadCharacterCampaignOptionsAsync,
|
||||
Func<Task> refreshCampaignScopeAsync,
|
||||
Func<Task> syncStateEventsAsync,
|
||||
Func<Task> stopStateEventsAsync,
|
||||
Func<Task> ensureAdminUsersLoadedAsync,
|
||||
Action resetCampaignLogDetailState,
|
||||
Func<string?, Task> onLoggedOutAsync)
|
||||
{
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
var storedScreen = await js.InvokeAsync<string?>("rpgRollerApi.getSessionValue", ScreenSessionKey);
|
||||
state.CurrentScreen = NormalizeRequestedScreen(storedScreen) ?? ScreenPlay;
|
||||
|
||||
var storedPanel = await js.InvokeAsync<string?>("rpgRollerApi.getSessionValue", MobilePanelSessionKey);
|
||||
if (string.Equals(storedPanel, "log", StringComparison.OrdinalIgnoreCase))
|
||||
state.MobilePanel = "log";
|
||||
|
||||
var storedRollVisibility = await js.InvokeAsync<string?>("rpgRollerApi.getSessionValue", RollVisibilitySessionKey);
|
||||
var storedRollVisibility =
|
||||
await js.InvokeAsync<string?>("rpgRollerApi.getSessionValue", RollVisibilitySessionKey);
|
||||
state.RollVisibility = NormalizeRollVisibility(storedRollVisibility);
|
||||
|
||||
Guid? preferredCampaignId = null;
|
||||
@@ -78,30 +91,6 @@ public sealed class WorkspaceSessionCoordinator(WorkspaceState state, WorkspaceF
|
||||
await onLoggedOutAsync("Logged out.");
|
||||
}
|
||||
|
||||
public async Task SwitchScreenAsync(string screen)
|
||||
{
|
||||
var targetScreen = NormalizeRequestedScreen(screen) ?? ScreenPlay;
|
||||
if (string.Equals(targetScreen, ScreenAdmin, StringComparison.OrdinalIgnoreCase) && !state.IsCurrentUserAdmin)
|
||||
targetScreen = ScreenPlay;
|
||||
|
||||
state.CurrentScreen = targetScreen;
|
||||
state.IsScreenMenuOpen = false;
|
||||
await PersistScreenPreferenceAsync(state.CurrentScreen);
|
||||
await requestRefreshAsync();
|
||||
|
||||
if (state.User is not null)
|
||||
{
|
||||
await refreshCampaignScopeAsync();
|
||||
await syncStateEventsAsync();
|
||||
}
|
||||
|
||||
if (state.IsAdminScreen)
|
||||
{
|
||||
await ensureAdminUsersLoadedAsync();
|
||||
await requestRefreshAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task OnRollVisibilityChangedAsync(string visibility)
|
||||
{
|
||||
state.RollVisibility = NormalizeRollVisibility(visibility);
|
||||
@@ -168,14 +157,15 @@ public sealed class WorkspaceSessionCoordinator(WorkspaceState state, WorkspaceF
|
||||
|
||||
state.User = me.User;
|
||||
state.ActiveCharacterId = me.ActiveCharacterId;
|
||||
await EnsureScreenAccessAsync();
|
||||
if (!await EnsureRouteAccessAsync())
|
||||
return true;
|
||||
|
||||
await reloadCampaignsAsync(preferredCampaignId ?? me.CurrentCampaignId);
|
||||
await reloadCharacterCampaignOptionsAsync();
|
||||
await refreshCampaignScopeAsync();
|
||||
await syncStateEventsAsync();
|
||||
|
||||
if (state.IsAdminScreen)
|
||||
if (isAdminRoute())
|
||||
await ensureAdminUsersLoadedAsync();
|
||||
|
||||
return true;
|
||||
@@ -193,33 +183,17 @@ public sealed class WorkspaceSessionCoordinator(WorkspaceState state, WorkspaceF
|
||||
}
|
||||
}
|
||||
|
||||
private async Task EnsureScreenAccessAsync()
|
||||
private async Task<bool> EnsureRouteAccessAsync()
|
||||
{
|
||||
if (state.IsCurrentUserAdmin)
|
||||
return;
|
||||
if (state.IsCurrentUserAdmin || !isAdminRoute())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
state.AdminUsers = [];
|
||||
state.HasLoadedAdminUsers = false;
|
||||
|
||||
if (!state.IsAdminScreen)
|
||||
return;
|
||||
|
||||
state.CurrentScreen = ScreenPlay;
|
||||
await PersistScreenPreferenceAsync(state.CurrentScreen);
|
||||
}
|
||||
|
||||
private async Task PersistScreenPreferenceAsync(string screen)
|
||||
{
|
||||
try
|
||||
{
|
||||
await js.InvokeVoidAsync("rpgRollerApi.setSessionValue", ScreenSessionKey, screen);
|
||||
}
|
||||
catch (JSDisconnectedException)
|
||||
{
|
||||
}
|
||||
catch (InvalidOperationException ex) when (IsStaticRenderInteropException(ex))
|
||||
{
|
||||
}
|
||||
await redirectToPlayAsync();
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string NormalizeRollVisibility(string? visibility)
|
||||
@@ -227,29 +201,6 @@ public sealed class WorkspaceSessionCoordinator(WorkspaceState state, WorkspaceF
|
||||
return string.Equals(visibility, "private", StringComparison.OrdinalIgnoreCase) ? "private" : "public";
|
||||
}
|
||||
|
||||
private static string? NormalizeRequestedScreen(string? screen)
|
||||
{
|
||||
if (string.Equals(screen, ScreenAdmin, StringComparison.OrdinalIgnoreCase))
|
||||
return ScreenAdmin;
|
||||
|
||||
if (string.Equals(screen, ScreenManagement, StringComparison.OrdinalIgnoreCase))
|
||||
return ScreenManagement;
|
||||
|
||||
if (string.Equals(screen, ScreenPlay, StringComparison.OrdinalIgnoreCase))
|
||||
return ScreenPlay;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool IsStaticRenderInteropException(InvalidOperationException exception)
|
||||
{
|
||||
return exception.Message.Contains("JavaScript interop calls cannot be issued", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private const string ScreenPlay = "play";
|
||||
private const string ScreenManagement = "management";
|
||||
private const string ScreenAdmin = "admin";
|
||||
private const string ScreenSessionKey = "screen";
|
||||
private const string CampaignSessionKey = "campaign";
|
||||
private const string MobilePanelSessionKey = "play-panel";
|
||||
private const string RollVisibilitySessionKey = "roll-visibility";
|
||||
|
||||
Reference in New Issue
Block a user