Add React frontend and clean up legacy HTTP backend

This commit is contained in:
Tim
2026-06-15 22:20:56 +02:00
parent b8e2d15e27
commit beaf142ee4
40 changed files with 8328 additions and 437 deletions
+28 -21
View File
@@ -160,6 +160,19 @@ async def send_error(sid: str, message: str):
await sio.emit("error", {"error": message}, to=sid)
async def _mark_player_offline(game: "Game", player: "Player"):
"""Mark player disconnected, delete the game if everyone left, else notify the room."""
player.connected = False
if not any(p.connected for p in game.players):
del games[game.gid]
else:
await sio.emit(
"player_connection",
{"order": player.order, "connected": False},
room=game.gid,
)
def _active_game(sid: str) -> "tuple[Game, dict] | None":
"""Resolve the started game and seat for a connection, or None."""
sess = sessions.get(sid)
@@ -181,20 +194,12 @@ async def connect(sid, environ, auth=None):
@sio.event
async def disconnect(sid):
sessions.pop(sid, None)
game = next((g for g in games.values() if g.player_by_sid(sid)), None)
sess = sessions.pop(sid, None)
game = games.get(sess["gid"]) if sess else None
if game is not None:
player = game.player_by_sid(sid)
player.connected = False
if not any(p.connected for p in game.players):
# Everybody left — drop the game so it can't leak memory forever.
del games[game.gid]
else:
await sio.emit(
"player_connection",
{"order": player.order, "connected": False},
room=game.gid,
)
if player is not None:
await _mark_player_offline(game, player)
await broadcast_lobby()
@@ -256,14 +261,7 @@ async def leave_game(sid):
# Game in progress: keep the seat (reconnect via token still works),
# just mark the player offline.
if player is not None:
player.connected = False
await sio.emit(
"player_connection",
{"order": player.order, "connected": False},
room=game.gid,
)
if not any(p.connected for p in game.players):
del games[game.gid]
await _mark_player_offline(game, player)
else:
# Not started yet: free the seat entirely.
if player is not None:
@@ -275,6 +273,11 @@ async def leave_game(sid):
@sio.on("start_game")
async def start_game(sid, gid):
sess = sessions.get(sid)
if sess is None or sess["gid"] != gid:
return await send_error(sid, "Nie ste v tejto hre.")
if sess["order"] != 0:
return await send_error(sid, "Iba hostitel moze spustit hru.")
game = games.get(gid)
if game is None:
return await send_error(sid, "Hra neexistuje.")
@@ -299,6 +302,9 @@ async def reconnect_to_game(sid, gid, token):
if player is None:
return await send_error(sid, "Neplatny token pre pripojenie.")
old_sid = player.sid
if old_sid != sid:
sessions.pop(old_sid, None)
player.sid = sid
player.connected = True
sessions[sid] = {"gid": gid, "order": player.order}
@@ -371,4 +377,5 @@ async def play_card(sid, card_key):
except BridzikException as exc:
return await send_error(sid, str(exc))
await send_game_status(game.gid)
await send_player_cards(game.gid, sess["order"], sid)
for player in game.players:
await send_player_cards(game.gid, player.order, player.sid)