Reveal face-down cards briefly (1s) before swap completes, using client-side state diffing instead of a separate server message. Local player reveals use existing card data; opponent reveals use server-sent card_revealed as a fallback. Defers incoming game_state updates during the reveal window to prevent overwrites. Also update YOUR TURN badge to cyan with suit symbols. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
84 lines
2.8 KiB
Python
84 lines
2.8 KiB
Python
"""Status bar showing phase, turn info, and action prompts."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from textual.widgets import Static
|
|
|
|
from tui_client.models import GameState
|
|
|
|
|
|
class StatusBarWidget(Static):
|
|
"""Top status bar with round, phase, and turn info."""
|
|
|
|
def __init__(self, **kwargs):
|
|
super().__init__(**kwargs)
|
|
self._state: GameState | None = None
|
|
self._player_id: str | None = None
|
|
self._extra: str = ""
|
|
|
|
def update_state(self, state: GameState, player_id: str | None = None) -> None:
|
|
self._state = state
|
|
self._player_id = player_id
|
|
self._refresh()
|
|
|
|
def set_extra(self, text: str) -> None:
|
|
self._extra = text
|
|
self._refresh()
|
|
|
|
def _refresh(self) -> None:
|
|
if not self._state:
|
|
self.update("Connecting...")
|
|
return
|
|
|
|
state = self._state
|
|
parts = []
|
|
|
|
# Round info
|
|
parts.append(f"⛳ {state.current_round}/{state.total_rounds}")
|
|
|
|
# Phase
|
|
phase_display = {
|
|
"waiting": "Waiting",
|
|
"initial_flip": "[bold white on #6a0dad] Flip Phase [/bold white on #6a0dad]",
|
|
"playing": "",
|
|
"final_turn": "[bold white on #c62828] FINAL TURN [/bold white on #c62828]",
|
|
"round_over": "[white on #555555] Hole Over [/white on #555555]",
|
|
"game_over": "[bold white on #b8860b] Game Over [/bold white on #b8860b]",
|
|
}.get(state.phase, state.phase)
|
|
parts.append(phase_display)
|
|
|
|
# Turn info (skip during initial flip - it's misleading)
|
|
if state.current_player_id and state.players and state.phase != "initial_flip":
|
|
if state.current_player_id == self._player_id:
|
|
parts.append(
|
|
"[on #00bcd4]"
|
|
" [bold #000000]♣[/bold #000000]"
|
|
"[bold #cc0000]♦[/bold #cc0000]"
|
|
" [bold #000000]YOUR TURN![/bold #000000] "
|
|
"[bold #000000]♠[/bold #000000]"
|
|
"[bold #cc0000]♥[/bold #cc0000]"
|
|
" [/on #00bcd4]"
|
|
)
|
|
else:
|
|
for p in state.players:
|
|
if p.id == state.current_player_id:
|
|
parts.append(f"[white on #555555] {p.name}'s Turn [/white on #555555]")
|
|
break
|
|
|
|
# Finisher indicator
|
|
if state.finisher_id:
|
|
for p in state.players:
|
|
if p.id == state.finisher_id:
|
|
parts.append(f"[bold white on #b8860b] {p.name} finished! [/bold white on #b8860b]")
|
|
break
|
|
|
|
# Active rules
|
|
if state.active_rules:
|
|
parts.append(f"Rules: {', '.join(state.active_rules)}")
|
|
|
|
text = " │ ".join(p for p in parts if p)
|
|
if self._extra:
|
|
text += f" {self._extra}"
|
|
|
|
self.update(text)
|