Refactor campaign payload loading

This commit is contained in:
2026-04-01 23:06:46 +02:00
parent 1c8cb71cb4
commit 8561c6643a
19 changed files with 246 additions and 152 deletions

View File

@@ -143,7 +143,7 @@ public partial class Workspace : IAsyncDisposable
private async Task ReloadCampaignsAsync(Guid? preferredCampaignId)
{
var campaigns = await ApiClient.RequestAsync<IReadOnlyList<CampaignDetails>>("GET", "/api/campaigns");
var campaigns = await ApiClient.RequestAsync<IReadOnlyList<CampaignSummary>>("GET", "/api/campaigns");
Campaigns = campaigns.OrderBy(c => c.Name, StringComparer.OrdinalIgnoreCase).ToList();
if (Campaigns.Count == 0)
@@ -173,6 +173,8 @@ public partial class Workspace : IAsyncDisposable
if (!SelectedCampaignId.HasValue)
{
SelectedCampaign = null;
SelectedCharacterSkills = [];
SelectedCharacterSkillGroups = [];
CampaignLog = [];
SelectedCharacterId = null;
ConnectionState = "offline";
@@ -183,9 +185,18 @@ public partial class Workspace : IAsyncDisposable
try
{
var campaignId = SelectedCampaignId.Value;
SelectedCampaign = await ApiClient.RequestAsync<CampaignDetails>("GET", $"/api/campaigns/{campaignId}");
CampaignLog = (await ApiClient.RequestAsync<IReadOnlyList<CampaignLogEntry>>("GET", $"/api/campaigns/{campaignId}/log")).ToList();
SelectedCampaign = await ApiClient.RequestAsync<CampaignRoster>("GET", $"/api/campaigns/{campaignId}");
SyncSelectedCharacter();
if (IsPlayScreen && PlaySelectedCharacterId.HasValue && SelectedCharacterId != PlaySelectedCharacterId)
SelectedCharacterId = PlaySelectedCharacterId;
await RefreshSelectedCharacterSheetAsync();
CampaignLog = IsPlayScreen
? (await ApiClient.RequestAsync<IReadOnlyList<CampaignLogEntry>>("GET", $"/api/campaigns/{campaignId}/log")).ToList()
: [];
await EnsureSelectedCharacterActiveAsync();
}
catch (ApiRequestException ex) when (ex.StatusCode == 401)
@@ -238,6 +249,12 @@ public partial class Workspace : IAsyncDisposable
await PersistScreenPreferenceAsync(CurrentScreen);
await InvokeAsync(StateHasChanged);
if (User is not null)
{
await RefreshCampaignScopeAsync();
await SyncStateEventsAsync();
}
if (IsAdminScreen)
{
await EnsureAdminUsersLoadedAsync();
@@ -521,6 +538,7 @@ public partial class Workspace : IAsyncDisposable
private async Task SelectCharacterAsync(Guid characterId)
{
SelectedCharacterId = characterId;
await RefreshSelectedCharacterSheetAsync();
await EnsureSelectedCharacterActiveAsync();
}
@@ -559,6 +577,24 @@ public partial class Workspace : IAsyncDisposable
}
}
private async Task RefreshSelectedCharacterSheetAsync()
{
if (!SelectedCharacterId.HasValue || SelectedCampaign is null || !IsPlayScreen)
{
SelectedCharacterSkills = [];
SelectedCharacterSkillGroups = [];
return;
}
var sheet = await ApiClient.RequestAsync<CharacterSheet>("GET", $"/api/characters/{SelectedCharacterId.Value}/sheet");
SelectedCharacterSkillGroups = sheet.SkillGroups
.OrderBy(group => group.Name, StringComparer.OrdinalIgnoreCase)
.ToList();
SelectedCharacterSkills = sheet.Skills
.OrderBy(skill => skill.Name, StringComparer.OrdinalIgnoreCase)
.ToList();
}
private async Task OnSkillCreatedAsync(Guid _)
{
await RefreshCampaignScopeAsync();
@@ -715,7 +751,7 @@ public partial class Workspace : IAsyncDisposable
private async Task SyncStateEventsAsync()
{
if (User is null || !SelectedCampaignId.HasValue)
if (User is null || !SelectedCampaignId.HasValue || IsAdminScreen)
{
await StopStateEventsAsync();
ConnectionState = "offline";
@@ -795,16 +831,6 @@ public partial class Workspace : IAsyncDisposable
return string.IsNullOrWhiteSpace(ownerDisplayName) ? "Unknown owner" : ownerDisplayName;
}
private string CharacterLabel(Guid characterId)
{
return SelectedCampaign?.Characters.FirstOrDefault(c => c.Id == characterId)?.Name ?? "Hidden character";
}
private string SkillLabel(Guid skillId)
{
return SelectedCampaign?.Skills.FirstOrDefault(s => s.Id == skillId)?.Name ?? "Hidden skill";
}
private string SkillDefinitionLabel(SkillSummary skill)
{
if (!string.Equals(SelectedCampaign?.RulesetId, "d6", StringComparison.OrdinalIgnoreCase))
@@ -822,7 +848,7 @@ public partial class Workspace : IAsyncDisposable
if (SelectedCampaign is not null && entry.RollerUserId == SelectedCampaign.Gm.Id)
return "GM";
return "Participant";
return entry.RollerDisplayName;
}
private string VisibilityLabel(CampaignLogEntry entry)
@@ -866,6 +892,8 @@ public partial class Workspace : IAsyncDisposable
SelectedCampaign = null;
Campaigns = [];
CharacterCampaignOptions = [];
SelectedCharacterSkills = [];
SelectedCharacterSkillGroups = [];
CampaignLog = [];
SelectedCharacterId = null;
LastRoll = null;
@@ -934,9 +962,11 @@ public partial class Workspace : IAsyncDisposable
private UserSummary? User { get; set; }
private Guid? ActiveCharacterId { get; set; }
private Guid? SelectedCampaignId { get; set; }
private CampaignDetails? SelectedCampaign { get; set; }
private List<CampaignDetails> Campaigns { get; set; } = [];
private CampaignRoster? SelectedCampaign { get; set; }
private List<CampaignSummary> Campaigns { get; set; } = [];
private List<CampaignOption> CharacterCampaignOptions { get; set; } = [];
private List<SkillSummary> SelectedCharacterSkills { get; set; } = [];
private List<SkillGroupSummary> SelectedCharacterSkillGroups { get; set; } = [];
private List<CampaignLogEntry> CampaignLog { get; set; } = [];
private List<RulesetDefinition> Rulesets { get; set; } = [];
private List<AdminUserSummary> AdminUsers { get; set; } = [];
@@ -973,12 +1003,12 @@ public partial class Workspace : IAsyncDisposable
[Parameter]
public EventCallback<string?> LoggedOut { get; set; }
private string? SelectedCampaignName => SelectedCampaign?.Name;
private string? SelectedCampaignName => SelectedCampaign?.Name ?? Campaigns.FirstOrDefault(campaign => campaign.Id == SelectedCampaignId)?.Name;
private CharacterSummary? SelectedCharacter =>
SelectedCampaign?.Characters.FirstOrDefault(c => c.Id == SelectedCharacterId);
private CampaignDetails? PlaySelectedCampaign
private CampaignRoster? PlaySelectedCampaign
{
get
{
@@ -986,27 +1016,18 @@ public partial class Workspace : IAsyncDisposable
return null;
if (User is null)
return new CampaignDetails(SelectedCampaign.Id, SelectedCampaign.Name, SelectedCampaign.RulesetId, SelectedCampaign.Gm, [], [], []);
return new CampaignRoster(SelectedCampaign.Id, SelectedCampaign.Name, SelectedCampaign.RulesetId, SelectedCampaign.Gm, []);
var ownedCharacters = SelectedCampaign.Characters
.Where(character => character.OwnerUserId == User.Id)
.ToList();
var ownedCharacterIds = ownedCharacters.Select(character => character.Id).ToHashSet();
var ownedSkillGroups = SelectedCampaign.SkillGroups
.Where(group => ownedCharacterIds.Contains(group.CharacterId))
.ToList();
var ownedSkills = SelectedCampaign.Skills
.Where(skill => ownedCharacterIds.Contains(skill.CharacterId))
.ToList();
return new CampaignDetails(
return new CampaignRoster(
SelectedCampaign.Id,
SelectedCampaign.Name,
SelectedCampaign.RulesetId,
SelectedCampaign.Gm,
ownedCharacters,
ownedSkillGroups,
ownedSkills);
ownedCharacters);
}
}
@@ -1038,20 +1059,10 @@ public partial class Workspace : IAsyncDisposable
private Guid? PlaySelectedCharacterId => PlaySelectedCharacter?.Id;
private List<SkillSummary> PlaySelectedCharacterSkills =>
PlaySelectedCampaign is null || !PlaySelectedCharacterId.HasValue
? []
: PlaySelectedCampaign.Skills
.Where(skill => skill.CharacterId == PlaySelectedCharacterId.Value)
.OrderBy(skill => skill.Name, StringComparer.OrdinalIgnoreCase)
.ToList();
PlaySelectedCampaign is null || !PlaySelectedCharacterId.HasValue ? [] : SelectedCharacterSkills;
private List<SkillGroupSummary> PlaySelectedCharacterSkillGroups =>
PlaySelectedCampaign is null || !PlaySelectedCharacterId.HasValue
? []
: PlaySelectedCampaign.SkillGroups
.Where(group => group.CharacterId == PlaySelectedCharacterId.Value)
.OrderBy(group => group.Name, StringComparer.OrdinalIgnoreCase)
.ToList();
PlaySelectedCampaign is null || !PlaySelectedCharacterId.HasValue ? [] : SelectedCharacterSkillGroups;
private List<CampaignLogEntry> PlayVisibleCampaignLog =>
User is null
@@ -1079,12 +1090,6 @@ public partial class Workspace : IAsyncDisposable
return user.Roles.Contains(UserRoles.Admin, StringComparer.OrdinalIgnoreCase);
}
private List<SkillSummary> SelectedCharacterSkills =>
SelectedCampaign is null || !SelectedCharacterId.HasValue ? [] : SelectedCampaign.Skills.Where(skill => skill.CharacterId == SelectedCharacterId.Value).OrderBy(skill => skill.Name, StringComparer.OrdinalIgnoreCase).ToList();
private List<SkillGroupSummary> SelectedCharacterSkillGroups =>
SelectedCampaign is null || !SelectedCharacterId.HasValue ? [] : SelectedCampaign.SkillGroups.Where(group => group.CharacterId == SelectedCharacterId.Value).OrderBy(group => group.Name, StringComparer.OrdinalIgnoreCase).ToList();
private bool IsPlayScreen => string.Equals(CurrentScreen, ScreenPlay, StringComparison.OrdinalIgnoreCase);
private bool IsManagementScreen => string.Equals(CurrentScreen, ScreenManagement, StringComparison.OrdinalIgnoreCase);
private bool IsAdminScreen => string.Equals(CurrentScreen, ScreenAdmin, StringComparison.OrdinalIgnoreCase);