KoogleApp/src/GoodWood.Web/Components/Game/GameEventDialogHost.razor

133 lines
4.4 KiB
Plaintext

@using Fluxor
@using Fluxor.Blazor.Web.Components
@using GoodWood.Application.Games
@using GoodWood.Web.Store.GameState
@using GoodWood.Web.Store.DayState
@using MudBlazor
@inherits FluxorComponent
@implements IDisposable
@inject IState<DayState> DayState
@inject IActionSubscriber ActionSubscriber
@inject IDialogService DialogService
@inject IDispatcher Dispatcher
@code {
private bool _isShowingDialog;
private HashSet<Guid> _processedEventIds = [];
protected override void OnInitialized()
{
base.OnInitialized();
ActionSubscriber.SubscribeToAction<ShowGameEventDialogAction>(this, OnShowGameEventDialog);
}
private async void OnShowGameEventDialog(ShowGameEventDialogAction action)
{
if (_isShowingDialog) return;
if (action.Events.Count == 0) return;
// Filter out already processed events
var newEvents = action.Events
.Where(e => !_processedEventIds.Contains(e.EventId))
.ToList();
if (newEvents.Count == 0) return;
// Mark events as processed immediately
foreach (var evt in newEvents)
{
_processedEventIds.Add(evt.EventId);
}
_isShowingDialog = true;
// Collect info from events
var eliminatedPlayers = new List<(string Name, string? Message)>();
string? winnerName = null;
string? winnerMessage = null;
string? winningTeamName = null;
string? winningTeamMessage = null;
string? gameEndedMessage = null;
string? foxChangedMessage = null;
foreach (var evt in newEvents)
{
switch (evt)
{
case PlayerEliminatedEvent eliminated:
eliminatedPlayers.Add((GetPlayerName(eliminated.PlayerId), eliminated.Message));
break;
case PlayerWonEvent won:
winnerName = GetPlayerName(won.PlayerId);
winnerMessage = won.Message;
break;
case TeamWonEvent teamWon:
winningTeamName = teamWon.TeamName;
winningTeamMessage = teamWon.Message;
break;
case GameEndedEvent ended when ended.WinnerId == null && string.IsNullOrEmpty(ended.WinningTeamName):
gameEndedMessage = ended.Message ?? "Spiel beendet ohne Sieger";
break;
case FoxChangedEvent foxChanged:
foxChangedMessage = foxChanged.Message;
break;
}
}
// Only show dialog if there's something to show
if (eliminatedPlayers.Count == 0 && winnerName == null && winningTeamName == null && gameEndedMessage == null && foxChangedMessage == null)
{
_isShowingDialog = false;
return;
}
var parameters = new DialogParameters<GameEventDialog>
{
{ x => x.EliminatedPlayers, eliminatedPlayers },
{ x => x.IsGameOver, action.IsGameOver },
{ x => x.WinnerName, winnerName },
{ x => x.WinnerMessage, winnerMessage },
{ x => x.WinningTeamName, winningTeamName },
{ x => x.WinningTeamMessage, winningTeamMessage },
{ x => x.GameEndedMessage, gameEndedMessage },
{ x => x.FoxChangedMessage, foxChangedMessage }
};
var options = new DialogOptions
{
CloseButton = false,
CloseOnEscapeKey = false,
BackdropClick = false,
MaxWidth = MaxWidth.Small,
FullWidth = true
};
var title = (action.IsGameOver && (winnerName != null || winningTeamName != null)) || gameEndedMessage != null
? "Spiel beendet!"
: foxChangedMessage != null
? "Fuchswechsel!"
: "Spieler ausgeschieden!";
await InvokeAsync(async () =>
{
var dialog = await DialogService.ShowAsync<GameEventDialog>(title, parameters, options);
await dialog.Result;
_isShowingDialog = false;
Dispatcher.Dispatch(new GameEventDialogClosedAction());
});
}
private string GetPlayerName(Guid playerId)
{
var person = DayState.Value.AvailablePersons.FirstOrDefault(p => p.Id == playerId);
return person?.Name ?? "Unbekannt";
}
public void Dispose()
{
ActionSubscriber.UnsubscribeFromAllActions(this);
}
}