Add final results modal, active rules display, and UI improvements

- Add big final results modal at game end with rankings and share button
- Add active rules bar showing enabled variants during gameplay
- Increase spacing between player cards and opponents row
- Add Wolfpack bonus rule (2 pairs of Jacks = -5 pts)
- Change joker options to radio buttons (None/Standard/Lucky Swing/Eagle-Eye)
- Update Eagle-Eye jokers: +2 pts unpaired, -4 pts paired
- Add card flip animation on discard pile
- Redesign waiting room layout with side-by-side columns
- Style card backs with red Bee-style diamond crosshatch pattern
- Compact standings panel to show top 4 per category
- Various CSS polish and responsive improvements

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Aaron D. Lee
2026-01-24 23:53:07 -05:00
parent f4275c7a7d
commit 39b78a2ba6
10 changed files with 1283 additions and 438 deletions

View File

@@ -184,17 +184,14 @@ async def websocket_endpoint(websocket: WebSocket):
# House Rules - Point Modifiers
lucky_swing=data.get("lucky_swing", False),
super_kings=data.get("super_kings", False),
lucky_sevens=data.get("lucky_sevens", False),
ten_penny=data.get("ten_penny", False),
# House Rules - Bonuses/Penalties
knock_bonus=data.get("knock_bonus", False),
underdog_bonus=data.get("underdog_bonus", False),
tied_shame=data.get("tied_shame", False),
blackjack=data.get("blackjack", False),
# House Rules - Gameplay Twists
queens_wild=data.get("queens_wild", False),
four_of_a_kind=data.get("four_of_a_kind", False),
eagle_eye=data.get("eagle_eye", False),
wolfpack=data.get("wolfpack", False),
)
# Validate settings
@@ -331,6 +328,37 @@ async def websocket_endpoint(websocket: WebSocket):
await handle_player_leave(current_room, player_id)
current_room = None
elif msg_type == "leave_game":
# Player leaves during an active game
if current_room:
await handle_player_leave(current_room, player_id)
current_room = None
elif msg_type == "end_game":
# Host ends the game for everyone
if not current_room:
continue
room_player = current_room.get_player(player_id)
if not room_player or not room_player.is_host:
await websocket.send_json({
"type": "error",
"message": "Only the host can end the game",
})
continue
# Notify all players that the game has ended
await current_room.broadcast({
"type": "game_ended",
"reason": "Host ended the game",
})
# Clean up the room
for cpu in list(current_room.get_cpu_players()):
current_room.remove_player(cpu.id)
room_manager.remove_room(current_room.code)
current_room = None
except WebSocketDisconnect:
if current_room:
await handle_player_leave(current_room, player_id)