diff --git a/src/Koogle.Web/Components/Game/GameInputPanel.razor b/src/Koogle.Web/Components/Game/GameInputPanel.razor index 6dffcc3..d16e414 100644 --- a/src/Koogle.Web/Components/Game/GameInputPanel.razor +++ b/src/Koogle.Web/Components/Game/GameInputPanel.razor @@ -23,7 +23,7 @@ @if (GameState.Value.Participants.Mode == ParticipantsMode.FreeToChoose) { diff --git a/src/Koogle.Web/Components/Game/PlayerSelectorDialog.razor b/src/Koogle.Web/Components/Game/PlayerSelectorDialog.razor new file mode 100644 index 0000000..589f9ad --- /dev/null +++ b/src/Koogle.Web/Components/Game/PlayerSelectorDialog.razor @@ -0,0 +1,156 @@ +@using Koogle.Application.Games.DeathBox +@using Koogle.Domain.Enums + + + + + + Spieler auswählen + + + + @if (FilterByGameLogic && HasEliminatedPlayers) + { + + } + + + @foreach (var player in FilteredPlayers) + { + + + + + @player.Name[0] + + + @player.Name + + @if (player.IsCurrentPlayer) + { + + Aktuell + + } + @if (player.IsEliminated) + { + + Ausgeschieden + + } + + + + } + + + + Abbrechen + + + + + +@code { + /// + /// Player IDs in the game (in turn order). + /// + [Parameter] + public Guid[] PlayerIds { get; set; } = []; + + /// + /// Current player ID. + /// + [Parameter] + public Guid? CurrentPlayerId { get; set; } + + /// + /// Function to resolve player names by ID. + /// + [Parameter] + public Func? PlayerNameResolver { get; set; } + + /// + /// Game model for determining eliminated players. + /// + [Parameter] + public object? GameModel { get; set; } + + /// + /// Whether to filter by game logic (hide eliminated players by default). + /// + [Parameter] + public bool FilterByGameLogic { get; set; } = true; + + [CascadingParameter] + private IMudDialogInstance MudDialog { get; set; } = null!; + + private bool _showEliminatedPlayers; + + private record PlayerInfo(Guid Id, string Name, bool IsCurrentPlayer, bool IsEliminated); + + private HashSet EliminatedPlayerIds => GetEliminatedPlayerIds(); + + private bool HasEliminatedPlayers => EliminatedPlayerIds.Count > 0; + + private IEnumerable AllPlayers => PlayerIds.Select(id => new PlayerInfo( + id, + PlayerNameResolver?.Invoke(id) ?? "Unbekannt", + id == CurrentPlayerId, + EliminatedPlayerIds.Contains(id) + )); + + private IEnumerable FilteredPlayers => + FilterByGameLogic && !_showEliminatedPlayers + ? AllPlayers.Where(p => !p.IsEliminated) + : AllPlayers; + + private HashSet GetEliminatedPlayerIds() + { + return GameModel switch + { + DeathBoxGameModel deathBox => deathBox.EliminatedPlayers.ToHashSet(), + _ => [] + }; + } + + private string GetPlayerClass(PlayerInfo player) + { + return player.IsCurrentPlayer ? "current-player" : ""; + } + + private void SelectPlayer(PlayerInfo player) + { + if (player.IsEliminated && !_showEliminatedPlayers) + return; + + MudDialog.Close(DialogResult.Ok(player.Id)); + } + + private void Cancel() + { + MudDialog.Cancel(); + } +} diff --git a/src/Koogle.Web/Components/Pages/Days/DayDetails.razor b/src/Koogle.Web/Components/Pages/Days/DayDetails.razor index 153564d..c9f5136 100644 --- a/src/Koogle.Web/Components/Pages/Days/DayDetails.razor +++ b/src/Koogle.Web/Components/Pages/Days/DayDetails.razor @@ -862,9 +862,32 @@ else private async Task ShowPlayerSelector() { - // TODO: Implement player selector dialog - await Task.CompletedTask; - Snackbar.Add("Spieler-Auswahl noch nicht implementiert", Severity.Info); + if (!GameState.Value.IsGameActive) return; + + var parameters = new DialogParameters + { + { "PlayerIds", GameState.Value.Participants.PlayerIds }, + { "CurrentPlayerId", GameState.Value.Participants.CurrentPlayerId }, + { "PlayerNameResolver", (Func)GetPlayerName }, + { "GameModel", GameState.Value.GameModel }, + { "FilterByGameLogic", true } + }; + + var options = new DialogOptions + { + MaxWidth = MaxWidth.Small, + FullWidth = true, + CloseOnEscapeKey = true + }; + + var dialog = await DialogService.ShowAsync("Spieler auswählen", parameters, options); + var result = await dialog.Result; + + if (result != null && !result.Canceled && result.Data is Guid selectedPlayerId) + { + Dispatcher.Dispatch(new SetCurrentPlayerAction(selectedPlayerId)); + Snackbar.Add($"Spieler gewechselt zu {GetPlayerName(selectedPlayerId)}", Severity.Success); + } } private const int TimerDurationSeconds = 3;