Persist roll visibility preference across workspace reloads

This commit is contained in:
2026-02-26 13:16:45 +01:00
parent 15c046bcac
commit bf3a6fa645
4 changed files with 15 additions and 5 deletions

1
FAQ.md
View File

@@ -94,6 +94,7 @@ Skills now use inline row chip actions:
- a final `+` dummy row styled like a skill row to create a new skill - a final `+` dummy row styled like a skill row to create a new skill
Roll visibility remains controlled in the skills header row. Roll visibility remains controlled in the skills header row.
The selected visibility is remembered per browser tab via session storage.
## Why was the "Last Roll" card removed from the character panel? ## Why was the "Last Roll" card removed from the character panel?

View File

@@ -28,7 +28,7 @@ Tracking against `UX.md` tasks and decisions.
| 9.1 App load + session restore | Implemented | Health check on load, rulesets/session load, unauthorized session reset, API unhealthy retry banner. | | 9.1 App load + session restore | Implemented | Health check on load, rulesets/session load, unauthorized session reset, API unhealthy retry banner. |
| 9.2 Authentication view | Implemented | Register/login cards, required validation, register password length check, server-error display. | | 9.2 Authentication view | Implemented | Register/login cards, required validation, register password length check, server-error display. |
| 9.3 Shared authenticated header | Implemented | Compact single-row header with user/campaign context, growing connection-status cell, right-aligned hamburger screen switch, and link-style logout. | | 9.3 Shared authenticated header | Implemented | Compact single-row header with user/campaign context, growing connection-status cell, right-aligned hamburger screen switch, and link-style logout. |
| 9.4 Play screen character column | Implemented | Compact character picker, merged character+skills header row, modal edit/create flows, inline per-skill edit/roll chips, d6 skill options (wild/fumble), and no separate last-roll panel. | | 9.4 Play screen character column | Implemented | Compact character picker, merged character+skills header row, modal edit/create flows, inline per-skill edit/roll chips, d6 skill options (wild/fumble), remembered roll-visibility preference, and no separate last-roll panel. |
| 9.5 Play screen log column | Implemented | Chronological feed, private/public badges, private perspective styles (roller vs GM), per-entry dice visualization with die-state flags, local time + ISO tooltip. | | 9.5 Play screen log column | Implemented | Chronological feed, private/public badges, private perspective styles (roller vs GM), per-entry dice visualization with die-state flags, local time + ISO tooltip. |
| 9.6 Campaign management screen | Implemented | Campaign selector and details are merged into one card, campaign create moved behind an inline `Add campaign` row opening a modal, and character management sits beneath with chip-style edit actions plus an inline `Add character` row. | | 9.6 Campaign management screen | Implemented | Campaign selector and details are merged into one card, campaign create moved behind an inline `Add campaign` row opening a modal, and character management sits beneath with chip-style edit actions plus an inline `Add character` row. |
| 9.7 Tablet/mobile bottom bar | Implemented | `Character` / `Log` panel switch in play screen and per-tab session persistence. | | 9.7 Tablet/mobile bottom bar | Implemented | `Character` / `Log` panel switch in play screen and per-tab session persistence. |

View File

@@ -46,7 +46,7 @@
</h3> </h3>
<div class="chip-toolbar"> <div class="chip-toolbar">
<label class="visibility-control" for="roll-visibility">Visibility</label> <label class="visibility-control" for="roll-visibility">Visibility</label>
<select id="roll-visibility" value="@RollVisibility" @onchange="OnRollVisibilityChangedAsync"> <select id="roll-visibility" value="@(RollVisibility == "private" ? "private" : "public")" @onchange="OnRollVisibilityChangedAsync">
<option value="public">Public</option> <option value="public">Public</option>
<option value="private">Private</option> <option value="private">Private</option>
</select> </select>

View File

@@ -28,6 +28,9 @@ public partial class Workspace : IAsyncDisposable
if (string.Equals(storedPanel, "log", StringComparison.OrdinalIgnoreCase)) if (string.Equals(storedPanel, "log", StringComparison.OrdinalIgnoreCase))
MobilePanel = "log"; MobilePanel = "log";
var storedRollVisibility = await JS.InvokeAsync<string?>("rpgRollerApi.getSessionValue", RollVisibilitySessionKey);
RollVisibility = NormalizeRollVisibility(storedRollVisibility);
Guid? preferredCampaignId = null; Guid? preferredCampaignId = null;
var storedCampaignId = await JS.InvokeAsync<string?>("rpgRollerApi.getSessionValue", CampaignSessionKey); var storedCampaignId = await JS.InvokeAsync<string?>("rpgRollerApi.getSessionValue", CampaignSessionKey);
if (Guid.TryParse(storedCampaignId, out var parsedCampaignId)) if (Guid.TryParse(storedCampaignId, out var parsedCampaignId))
@@ -412,10 +415,15 @@ public partial class Workspace : IAsyncDisposable
} }
} }
private Task OnRollVisibilityChanged(string visibility) private async Task OnRollVisibilityChanged(string visibility)
{ {
RollVisibility = string.Equals(visibility, "private", StringComparison.OrdinalIgnoreCase) ? "private" : "public"; RollVisibility = NormalizeRollVisibility(visibility);
return Task.CompletedTask; await JS.InvokeVoidAsync("rpgRollerApi.setSessionValue", RollVisibilitySessionKey, RollVisibility);
}
private static string NormalizeRollVisibility(string? visibility)
{
return string.Equals(visibility, "private", StringComparison.OrdinalIgnoreCase) ? "private" : "public";
} }
private bool CanEditSkill(SkillSummary skill) private bool CanEditSkill(SkillSummary skill)
@@ -743,6 +751,7 @@ public partial class Workspace : IAsyncDisposable
private const string ScreenSessionKey = "screen"; private const string ScreenSessionKey = "screen";
private const string CampaignSessionKey = "campaign"; private const string CampaignSessionKey = "campaign";
private const string MobilePanelSessionKey = "play-panel"; private const string MobilePanelSessionKey = "play-panel";
private const string RollVisibilitySessionKey = "roll-visibility";
private const int ToastDurationMs = 3200; private const int ToastDurationMs = 3200;
private sealed record WorkspaceToast(Guid Id, string Message, bool IsError); private sealed record WorkspaceToast(Guid Id, string Message, bool IsError);