99 lines
3.6 KiB
C#
99 lines
3.6 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
using RpgRoller.Contracts;
|
|
|
|
namespace RpgRoller.Components.Pages;
|
|
|
|
[ExcludeFromCodeCoverage]
|
|
public sealed class WorkspaceLiveStateController(WorkspaceState state, WorkspaceFeedbackService feedback, Func<Guid, Task> startStateEventsAsync, Func<Task> stopStateEventsCoreAsync, Func<Task> refreshCampaignRosterAsync, Func<Task> refreshSelectedCharacterSheetAsync, Func<Guid?, Task> refreshCampaignLogAsync, Func<Task> requestRefreshAsync)
|
|
{
|
|
public async Task OnStateEventReceivedAsync(CampaignStateSnapshot state1)
|
|
{
|
|
if (state.StateRefreshInProgress)
|
|
return;
|
|
|
|
if (!state.SelectedCampaignId.HasValue || state1.CampaignId != state.SelectedCampaignId.Value)
|
|
return;
|
|
|
|
state.StateRefreshInProgress = true;
|
|
try
|
|
{
|
|
if (state.CurrentCampaignState is null)
|
|
{
|
|
state.CurrentCampaignState = state1;
|
|
return;
|
|
}
|
|
|
|
var previousState = state.CurrentCampaignState;
|
|
var previousSelectedCharacterId = state.SelectedCharacterId;
|
|
var previousSelectedCharacterVersion = GetCharacterVersion(previousState, previousSelectedCharacterId);
|
|
var rosterChanged = state1.RosterVersion != previousState.RosterVersion;
|
|
var logChanged = state.IsPlayScreen && state1.LogVersion != previousState.LogVersion;
|
|
|
|
if (rosterChanged)
|
|
await refreshCampaignRosterAsync();
|
|
|
|
var selectedCharacterChanged = previousSelectedCharacterId != state.SelectedCharacterId;
|
|
var selectedCharacterVersionChanged = state.IsPlayScreen && !selectedCharacterChanged && GetCharacterVersion(state1, state.SelectedCharacterId) != previousSelectedCharacterVersion;
|
|
|
|
if (state.IsPlayScreen && (selectedCharacterChanged || selectedCharacterVersionChanged))
|
|
await refreshSelectedCharacterSheetAsync();
|
|
|
|
if (logChanged)
|
|
await refreshCampaignLogAsync(state.CampaignLogCursor);
|
|
|
|
state.CurrentCampaignState = state1;
|
|
}
|
|
finally
|
|
{
|
|
state.StateRefreshInProgress = false;
|
|
await requestRefreshAsync();
|
|
}
|
|
}
|
|
|
|
public async Task OnConnectionStateChangedAsync(string state1)
|
|
{
|
|
state.ConnectionState = state1 switch
|
|
{
|
|
"connected" => "connected",
|
|
"reconnecting" => "reconnecting",
|
|
_ => "offline"
|
|
};
|
|
|
|
if (state.ConnectionState == "reconnecting")
|
|
feedback.Announce("Reconnecting to live updates.");
|
|
|
|
if (state.ConnectionState == "offline")
|
|
feedback.Announce("Live updates offline. Use manual refresh.");
|
|
|
|
await requestRefreshAsync();
|
|
}
|
|
|
|
public async Task SyncStateEventsAsync()
|
|
{
|
|
if (state.User is null || !state.SelectedCampaignId.HasValue || state.IsAdminScreen)
|
|
{
|
|
await StopStateEventsAsync();
|
|
state.ConnectionState = "offline";
|
|
return;
|
|
}
|
|
|
|
await startStateEventsAsync(state.SelectedCampaignId.Value);
|
|
state.ConnectionState = "reconnecting";
|
|
}
|
|
|
|
public async Task StopStateEventsAsync()
|
|
{
|
|
if (!state.HasInteractiveRenderStarted)
|
|
return;
|
|
|
|
await stopStateEventsCoreAsync();
|
|
}
|
|
|
|
private static long GetCharacterVersion(CampaignStateSnapshot snapshot, Guid? characterId)
|
|
{
|
|
if (!characterId.HasValue)
|
|
return 0;
|
|
|
|
return snapshot.CharacterVersions.FirstOrDefault(version => version.CharacterId == characterId.Value)?.Version ?? 0;
|
|
}
|
|
} |