Support character unlinking and global campaign options

This commit is contained in:
2026-02-26 17:50:08 +01:00
parent 6f94b1ba95
commit ac5acd77f0
12 changed files with 176 additions and 31 deletions

View File

@@ -118,6 +118,7 @@ public partial class Workspace : IAsyncDisposable
ActiveCharacterId = me.ActiveCharacterId;
await ReloadCampaignsAsync(preferredCampaignId ?? me.CurrentCampaignId);
await ReloadCharacterCampaignOptionsAsync();
await RefreshCampaignScopeAsync();
await SyncStateEventsAsync();
return true;
@@ -156,6 +157,12 @@ public partial class Workspace : IAsyncDisposable
await JS.InvokeVoidAsync("rpgRollerApi.setSessionValue", CampaignSessionKey, SelectedCampaignId?.ToString());
}
private async Task ReloadCharacterCampaignOptionsAsync()
{
var campaignOptions = await ApiClient.RequestAsync<IReadOnlyList<CampaignOption>>("GET", "/api/campaigns/options");
CharacterCampaignOptions = campaignOptions.OrderBy(campaign => campaign.Name, StringComparer.OrdinalIgnoreCase).ToList();
}
private async Task RefreshCampaignScopeAsync()
{
if (!SelectedCampaignId.HasValue)
@@ -269,6 +276,7 @@ public partial class Workspace : IAsyncDisposable
private async Task OnCampaignCreatedAsync(Guid campaignId)
{
await ReloadCampaignsAsync(campaignId);
await ReloadCharacterCampaignOptionsAsync();
await RefreshCampaignScopeAsync();
await SyncStateEventsAsync();
SetStatus("Campaign created.", false);
@@ -279,7 +287,7 @@ public partial class Workspace : IAsyncDisposable
CreateCharacterInitialModel = new()
{
Name = string.Empty,
CampaignId = SelectedCampaignId?.ToString() ?? string.Empty,
CampaignId = SelectedCampaignId?.ToString() ?? CharacterCampaignOptions.FirstOrDefault()?.Id.ToString() ?? string.Empty,
OwnerUsername = string.Empty
};
@@ -290,7 +298,7 @@ public partial class Workspace : IAsyncDisposable
private async Task OpenEditCharacterModal(CharacterSummary character)
{
if (IsCurrentUserGm)
if (IsCurrentUserGm || IsCurrentUserAdmin)
await LoadKnownUsernamesAsync();
EditingCharacterId = character.Id;
@@ -302,7 +310,7 @@ public partial class Workspace : IAsyncDisposable
};
EditCharacterFormVersion++;
CanEditCharacterOwner = IsCurrentUserGm;
CanEditCharacterOwner = IsCurrentUserGm || IsCurrentUserAdmin;
ShowEditCharacterModal = true;
}
@@ -314,22 +322,24 @@ public partial class Workspace : IAsyncDisposable
EditingCharacterId = null;
}
private async Task OnCharacterCreatedAsync(Guid campaignId)
private async Task OnCharacterCreatedAsync(Guid? campaignId)
{
CloseCharacterModals();
await ReloadCampaignsAsync(campaignId);
await ReloadCharacterCampaignOptionsAsync();
await RefreshCampaignScopeAsync();
await SyncStateEventsAsync();
SetStatus("Character created.", false);
}
private async Task OnCharacterUpdatedAsync(Guid campaignId)
private async Task OnCharacterUpdatedAsync(Guid? campaignId)
{
CloseCharacterModals();
await ReloadCampaignsAsync(campaignId);
await ReloadCharacterCampaignOptionsAsync();
await RefreshCampaignScopeAsync();
await SyncStateEventsAsync();
SetStatus("Character updated.", false);
SetStatus(campaignId.HasValue ? "Character updated." : "Character unlinked from campaign.", false);
}
private async Task DeleteSelectedCampaignAsync()
@@ -346,6 +356,7 @@ public partial class Workspace : IAsyncDisposable
{
_ = await ApiClient.RequestAsync<bool>("DELETE", $"/api/campaigns/{SelectedCampaign.Id}");
await ReloadCampaignsAsync(null);
await ReloadCharacterCampaignOptionsAsync();
await RefreshCampaignScopeAsync();
await SyncStateEventsAsync();
SetStatus("Campaign deleted.", false);
@@ -368,7 +379,7 @@ public partial class Workspace : IAsyncDisposable
private bool CanEditCharacter(CharacterSummary character)
{
return User is not null && (character.OwnerUserId == User.Id || IsCurrentUserGm);
return User is not null && (character.OwnerUserId == User.Id || IsCurrentUserGm || IsCurrentUserAdmin);
}
private static bool CanActivateCharacter(CharacterSummary character, UserSummary? user)
@@ -674,6 +685,7 @@ public partial class Workspace : IAsyncDisposable
SelectedCampaignId = null;
SelectedCampaign = null;
Campaigns = [];
CharacterCampaignOptions = [];
CampaignLog = [];
SelectedCharacterId = null;
LastRoll = null;
@@ -738,6 +750,7 @@ public partial class Workspace : IAsyncDisposable
private Guid? SelectedCampaignId { get; set; }
private CampaignDetails? SelectedCampaign { get; set; }
private List<CampaignDetails> Campaigns { get; set; } = [];
private List<CampaignOption> CharacterCampaignOptions { get; set; } = [];
private List<CampaignLogEntry> CampaignLog { get; set; } = [];
private List<RulesetDefinition> Rulesets { get; set; } = [];
private Guid? SelectedCharacterId { get; set; }