Load campaign logs incrementally

This commit is contained in:
2026-04-02 00:03:54 +02:00
parent 6ea91ee565
commit e42c0fb9ba
12 changed files with 216 additions and 14 deletions

View File

@@ -171,15 +171,28 @@ public partial class Workspace : IAsyncDisposable
await EnsureSelectedCharacterActiveAsync();
}
private async Task RefreshCampaignLogAsync()
private async Task RefreshCampaignLogAsync(Guid? afterRollId = null)
{
if (!SelectedCampaignId.HasValue || !IsPlayScreen)
{
CampaignLog = [];
CampaignLogCursor = null;
return;
}
CampaignLog = (await WorkspaceQuery.GetCampaignLogAsync(SelectedCampaignId.Value)).ToList();
var page = await WorkspaceQuery.GetCampaignLogPageAsync(SelectedCampaignId.Value, afterRollId, CampaignLogWindowSize);
if (!afterRollId.HasValue || page.ResetRequired)
{
CampaignLog = page.Entries.ToList();
}
else if (page.Entries.Count > 0)
{
CampaignLog.AddRange(page.Entries);
if (CampaignLog.Count > CampaignLogWindowSize)
CampaignLog = CampaignLog.TakeLast(CampaignLogWindowSize).ToList();
}
CampaignLogCursor = page.Cursor ?? afterRollId;
}
private async Task RefreshCampaignScopeAsync()
@@ -193,6 +206,7 @@ public partial class Workspace : IAsyncDisposable
SelectedCharacterId = null;
ConnectionState = "offline";
CurrentCampaignState = null;
CampaignLogCursor = null;
return;
}
@@ -661,7 +675,7 @@ public partial class Workspace : IAsyncDisposable
{
LastRoll = await ApiClient.RequestAsync<RollResult>("POST", $"/api/skills/{skillId}/roll", new RollSkillRequest(RollVisibility));
await RefreshCampaignLogAsync();
await RefreshCampaignLogAsync(CampaignLogCursor);
ResetCampaignStateTracking();
SetStatus("Roll recorded.", false);
Announce("Roll result updated.");
@@ -760,7 +774,7 @@ public partial class Workspace : IAsyncDisposable
await RefreshSelectedCharacterSheetAsync();
if (logChanged)
await RefreshCampaignLogAsync();
await RefreshCampaignLogAsync(CampaignLogCursor);
CurrentCampaignState = state;
}
@@ -936,6 +950,7 @@ public partial class Workspace : IAsyncDisposable
SelectedCharacterSkills = [];
SelectedCharacterSkillGroups = [];
CampaignLog = [];
CampaignLogCursor = null;
SelectedCharacterId = null;
LastRoll = null;
KnownUsernames = [];
@@ -1059,6 +1074,7 @@ public partial class Workspace : IAsyncDisposable
private bool HasInteractiveRenderStarted { get; set; }
private DotNetObjectReference<Workspace>? DotNetRef { get; set; }
private CampaignStateSnapshot? CurrentCampaignState { get; set; }
private Guid? CampaignLogCursor { get; set; }
[Parameter]
public EventCallback<string?> LoggedOut { get; set; }
@@ -1194,6 +1210,7 @@ public partial class Workspace : IAsyncDisposable
private const string CampaignSessionKey = "campaign";
private const string MobilePanelSessionKey = "play-panel";
private const string RollVisibilitySessionKey = "roll-visibility";
private const int CampaignLogWindowSize = 100;
private const int ToastDurationMs = 3200;
private sealed record WorkspaceToast(Guid Id, string Message, bool IsError);