added ParticipantsMode.FreeToChoose:
Neue Datei erstellt: - src/Koogle.Web/Components/Game/PlayerSelectorDialog.razor - Dialog zur manuellen Spielerauswahl Geändert: - src/Koogle.Web/Components/Pages/Days/DayDetails.razor:863-891 - ShowPlayerSelector implementiert Funktionsweise: 1. Bei ParticipantsMode.FreeToChoose zeigt GameInputPanel.razor:23-32 den Button "Spieler wechseln" 2. Der neue Dialog listet alle Spieler aus Participants.PlayerIds 3. Bei DeathBox werden ausgeschiedene Spieler standardmäßig ausgeblendet (Toggle verfügbar) 4. Bei Spielerauswahl wird SetCurrentPlayerAction dispatcht Features: - Aktueller Spieler ist markiert (grün) - Ausgeschiedene Spieler sind durchgestrichen mit "Ausgeschieden"-Badge - Optional können ausgeschiedene Spieler eingeblendet werden (falls nötig) - Funktioniert mit allen Game-Typen (DeathBox, Shit, Training)
This commit is contained in:
parent
39d4629e72
commit
587b92409d
|
|
@ -23,7 +23,7 @@
|
|||
@if (GameState.Value.Participants.Mode == ParticipantsMode.FreeToChoose)
|
||||
{
|
||||
<MudButton Variant="Variant.Outlined"
|
||||
Color="Color.Primary"
|
||||
Color="Color.Warning"
|
||||
Size="Size.Small"
|
||||
OnClick="ShowPlayerSelector"
|
||||
StartIcon="@Icons.Material.Filled.SwapHoriz">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
@using Koogle.Application.Games.DeathBox
|
||||
@using Koogle.Domain.Enums
|
||||
|
||||
<MudDialog>
|
||||
<TitleContent>
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2">
|
||||
<MudIcon Icon="@Icons.Material.Filled.Person" />
|
||||
<MudText Typo="Typo.h6">Spieler auswählen</MudText>
|
||||
</MudStack>
|
||||
</TitleContent>
|
||||
<DialogContent>
|
||||
@if (FilterByGameLogic && HasEliminatedPlayers)
|
||||
{
|
||||
<MudSwitch @bind-Value="_showEliminatedPlayers"
|
||||
Color="Color.Secondary"
|
||||
Label="Ausgeschiedene anzeigen"
|
||||
Class="mb-3" />
|
||||
}
|
||||
|
||||
<MudList T="PlayerInfo" Dense="false" Class="player-selector-list">
|
||||
@foreach (var player in FilteredPlayers)
|
||||
{
|
||||
<MudListItem T="PlayerInfo"
|
||||
Class="@GetPlayerClass(player)"
|
||||
OnClick="@(() => SelectPlayer(player))"
|
||||
Disabled="@(player.IsEliminated && !_showEliminatedPlayers)">
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Justify="Justify.SpaceBetween" Style="width: 100%">
|
||||
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2">
|
||||
<MudAvatar Size="Size.Medium"
|
||||
Color="@(player.IsCurrentPlayer ? Color.Success : (player.IsEliminated ? Color.Default : Color.Primary))">
|
||||
@player.Name[0]
|
||||
</MudAvatar>
|
||||
<MudText Style="@(player.IsEliminated ? "text-decoration: line-through; opacity: 0.6" : "")">
|
||||
@player.Name
|
||||
</MudText>
|
||||
@if (player.IsCurrentPlayer)
|
||||
{
|
||||
<MudChip T="string" Size="Size.Small" Color="Color.Success" Variant="Variant.Outlined">
|
||||
Aktuell
|
||||
</MudChip>
|
||||
}
|
||||
@if (player.IsEliminated)
|
||||
{
|
||||
<MudChip T="string" Size="Size.Small" Color="Color.Error" Variant="Variant.Outlined">
|
||||
Ausgeschieden
|
||||
</MudChip>
|
||||
}
|
||||
</MudStack>
|
||||
</MudStack>
|
||||
</MudListItem>
|
||||
}
|
||||
</MudList>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<MudButton OnClick="Cancel" Color="Color.Default">Abbrechen</MudButton>
|
||||
</DialogActions>
|
||||
</MudDialog>
|
||||
|
||||
<style>
|
||||
.player-selector-list .mud-list-item {
|
||||
border-radius: 8px;
|
||||
margin-bottom: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.player-selector-list .mud-list-item:hover:not(.mud-list-item-disabled) {
|
||||
background-color: var(--mud-palette-action-default-hover);
|
||||
}
|
||||
|
||||
.player-selector-list .current-player {
|
||||
border: 2px solid var(--mud-palette-success);
|
||||
background-color: var(--mud-palette-success-lighten);
|
||||
}
|
||||
</style>
|
||||
|
||||
@code {
|
||||
/// <summary>
|
||||
/// Player IDs in the game (in turn order).
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Guid[] PlayerIds { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Current player ID.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Guid? CurrentPlayerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Function to resolve player names by ID.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Func<Guid, string>? PlayerNameResolver { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Game model for determining eliminated players.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public object? GameModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to filter by game logic (hide eliminated players by default).
|
||||
/// </summary>
|
||||
[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<Guid> EliminatedPlayerIds => GetEliminatedPlayerIds();
|
||||
|
||||
private bool HasEliminatedPlayers => EliminatedPlayerIds.Count > 0;
|
||||
|
||||
private IEnumerable<PlayerInfo> AllPlayers => PlayerIds.Select(id => new PlayerInfo(
|
||||
id,
|
||||
PlayerNameResolver?.Invoke(id) ?? "Unbekannt",
|
||||
id == CurrentPlayerId,
|
||||
EliminatedPlayerIds.Contains(id)
|
||||
));
|
||||
|
||||
private IEnumerable<PlayerInfo> FilteredPlayers =>
|
||||
FilterByGameLogic && !_showEliminatedPlayers
|
||||
? AllPlayers.Where(p => !p.IsEliminated)
|
||||
: AllPlayers;
|
||||
|
||||
private HashSet<Guid> 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Guid, string>)GetPlayerName },
|
||||
{ "GameModel", GameState.Value.GameModel },
|
||||
{ "FilterByGameLogic", true }
|
||||
};
|
||||
|
||||
var options = new DialogOptions
|
||||
{
|
||||
MaxWidth = MaxWidth.Small,
|
||||
FullWidth = true,
|
||||
CloseOnEscapeKey = true
|
||||
};
|
||||
|
||||
var dialog = await DialogService.ShowAsync<PlayerSelectorDialog>("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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue