Overhaul workspace UX for denser play workflow
This commit is contained in:
@@ -145,7 +145,6 @@ public partial class Workspace : IAsyncDisposable
|
||||
SelectedCampaign = null;
|
||||
CampaignLog = [];
|
||||
SelectedCharacterId = null;
|
||||
SelectedSkillId = null;
|
||||
ConnectionState = "offline";
|
||||
return;
|
||||
}
|
||||
@@ -157,7 +156,6 @@ public partial class Workspace : IAsyncDisposable
|
||||
SelectedCampaign = await ApiClient.RequestAsync<CampaignDetails>("GET", $"/api/campaigns/{campaignId}");
|
||||
CampaignLog = (await ApiClient.RequestAsync<IReadOnlyList<CampaignLogEntry>>("GET", $"/api/campaigns/{campaignId}/log")).ToList();
|
||||
SyncSelectedCharacter();
|
||||
SyncSelectedSkill();
|
||||
await EnsureSelectedCharacterActiveAsync();
|
||||
}
|
||||
catch (ApiRequestException ex) when (ex.StatusCode == 401)
|
||||
@@ -226,6 +224,7 @@ public partial class Workspace : IAsyncDisposable
|
||||
private async Task SwitchScreenAsync(string screen)
|
||||
{
|
||||
CurrentScreen = string.Equals(screen, "management", StringComparison.OrdinalIgnoreCase) ? "management" : "play";
|
||||
IsScreenMenuOpen = false;
|
||||
await JS.InvokeVoidAsync("rpgRollerApi.setSessionValue", ScreenSessionKey, CurrentScreen);
|
||||
}
|
||||
|
||||
@@ -264,6 +263,7 @@ public partial class Workspace : IAsyncDisposable
|
||||
await JS.InvokeVoidAsync("rpgRollerApi.setSessionValue", CampaignSessionKey, campaignId.ToString());
|
||||
await RefreshCampaignScopeAsync();
|
||||
await SyncStateEventsAsync();
|
||||
IsScreenMenuOpen = false;
|
||||
}
|
||||
|
||||
private async Task OnCampaignCreatedAsync(Guid campaignId)
|
||||
@@ -327,7 +327,6 @@ public partial class Workspace : IAsyncDisposable
|
||||
private async Task SelectCharacterAsync(Guid characterId)
|
||||
{
|
||||
SelectedCharacterId = characterId;
|
||||
SyncSelectedSkill();
|
||||
await EnsureSelectedCharacterActiveAsync();
|
||||
}
|
||||
|
||||
@@ -367,25 +366,37 @@ public partial class Workspace : IAsyncDisposable
|
||||
SetStatus("Skill created.", false);
|
||||
}
|
||||
|
||||
private async Task OnSkillUpdatedAsync(Guid skillId)
|
||||
private async Task OnSkillUpdatedAsync(Guid _)
|
||||
{
|
||||
SelectedSkillId = skillId;
|
||||
await RefreshCampaignScopeAsync();
|
||||
SetStatus("Skill updated.", false);
|
||||
}
|
||||
|
||||
private async Task RollSelectedSkillAsync()
|
||||
private async Task RollSkillAsync(Guid skillId)
|
||||
{
|
||||
if (SelectedSkill is null)
|
||||
if (SelectedCampaign is null)
|
||||
{
|
||||
SetStatus("Select a skill to roll.", true);
|
||||
SetStatus("No campaign selected.", true);
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedSkill = SelectedCampaign.Skills.FirstOrDefault(skill => skill.Id == skillId);
|
||||
if (selectedSkill is null)
|
||||
{
|
||||
SetStatus("Skill is no longer available. Refresh campaign data.", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanRollSkill(selectedSkill))
|
||||
{
|
||||
SetStatus("You are not allowed to roll this skill.", true);
|
||||
return;
|
||||
}
|
||||
|
||||
IsMutating = true;
|
||||
try
|
||||
{
|
||||
LastRoll = await ApiClient.RequestAsync<RollResult>("POST", $"/api/skills/{SelectedSkill.Id}/roll", new RollSkillRequest(RollVisibility));
|
||||
LastRoll = await ApiClient.RequestAsync<RollResult>("POST", $"/api/skills/{selectedSkill.Id}/roll", new RollSkillRequest(RollVisibility));
|
||||
|
||||
await RefreshCampaignScopeAsync();
|
||||
SetStatus("Roll recorded.", false);
|
||||
@@ -407,11 +418,6 @@ public partial class Workspace : IAsyncDisposable
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void SelectSkill(Guid skillId)
|
||||
{
|
||||
SelectedSkillId = skillId;
|
||||
}
|
||||
|
||||
private bool CanEditSkill(SkillSummary skill)
|
||||
{
|
||||
if (SelectedCampaign is null)
|
||||
@@ -526,21 +532,6 @@ public partial class Workspace : IAsyncDisposable
|
||||
SelectedCharacterId = SelectedCampaign.Characters[0].Id;
|
||||
}
|
||||
|
||||
private void SyncSelectedSkill()
|
||||
{
|
||||
var skills = SelectedCharacterSkills;
|
||||
if (skills.Count == 0)
|
||||
{
|
||||
SelectedSkillId = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (SelectedSkillId.HasValue && skills.Any(skill => skill.Id == SelectedSkillId.Value))
|
||||
return;
|
||||
|
||||
SelectedSkillId = skills[0].Id;
|
||||
}
|
||||
|
||||
private string OwnerLabel(Guid ownerUserId)
|
||||
{
|
||||
if (User is not null && ownerUserId == User.Id)
|
||||
@@ -624,7 +615,6 @@ public partial class Workspace : IAsyncDisposable
|
||||
Campaigns = [];
|
||||
CampaignLog = [];
|
||||
SelectedCharacterId = null;
|
||||
SelectedSkillId = null;
|
||||
LastRoll = null;
|
||||
ShowCreateCharacterModal = false;
|
||||
ShowEditCharacterModal = false;
|
||||
@@ -646,6 +636,11 @@ public partial class Workspace : IAsyncDisposable
|
||||
LiveAnnouncement = message;
|
||||
}
|
||||
|
||||
private void ToggleScreenMenu()
|
||||
{
|
||||
IsScreenMenuOpen = !IsScreenMenuOpen;
|
||||
}
|
||||
|
||||
[Inject]
|
||||
private IJSRuntime JS { get; set; } = null!;
|
||||
|
||||
@@ -660,7 +655,6 @@ public partial class Workspace : IAsyncDisposable
|
||||
private List<CampaignLogEntry> CampaignLog { get; set; } = [];
|
||||
private List<RulesetDefinition> Rulesets { get; set; } = [];
|
||||
private Guid? SelectedCharacterId { get; set; }
|
||||
private Guid? SelectedSkillId { get; set; }
|
||||
private RollResult? LastRoll { get; set; }
|
||||
private string RollVisibility { get; set; } = "public";
|
||||
|
||||
@@ -674,6 +668,7 @@ public partial class Workspace : IAsyncDisposable
|
||||
private string MobilePanel { get; set; } = "character";
|
||||
private string ConnectionState { get; set; } = "offline";
|
||||
private string LiveAnnouncement { get; set; } = string.Empty;
|
||||
private bool IsScreenMenuOpen { get; set; }
|
||||
|
||||
private bool ShowCreateCharacterModal { get; set; }
|
||||
private bool ShowEditCharacterModal { get; set; }
|
||||
@@ -694,12 +689,6 @@ public partial class Workspace : IAsyncDisposable
|
||||
private CharacterSummary? SelectedCharacter =>
|
||||
SelectedCampaign?.Characters.FirstOrDefault(c => c.Id == SelectedCharacterId);
|
||||
|
||||
private SkillSummary? SelectedSkill =>
|
||||
SelectedCampaign?.Skills.FirstOrDefault(s => s.Id == SelectedSkillId);
|
||||
|
||||
private string? ActiveCharacterName =>
|
||||
SelectedCampaign?.Characters.FirstOrDefault(c => c.Id == SelectedCharacterId)?.Name;
|
||||
|
||||
private bool IsCurrentUserGm =>
|
||||
SelectedCampaign is not null && User is not null && SelectedCampaign.Gm.Id == User.Id;
|
||||
|
||||
@@ -711,6 +700,7 @@ public partial class Workspace : IAsyncDisposable
|
||||
|
||||
private bool IsPlayScreen => string.Equals(CurrentScreen, "play", StringComparison.OrdinalIgnoreCase);
|
||||
private bool IsManagementScreen => !IsPlayScreen;
|
||||
private string CurrentScreenLabel => IsPlayScreen ? "Play" : "Campaign Management";
|
||||
|
||||
private string ConnectionStateLabel => ConnectionState switch
|
||||
{
|
||||
@@ -731,4 +721,4 @@ public partial class Workspace : IAsyncDisposable
|
||||
private const string ScreenSessionKey = "screen";
|
||||
private const string CampaignSessionKey = "campaign";
|
||||
private const string MobilePanelSessionKey = "play-panel";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user