diff --git a/app.py b/app.py index f2fd0e2..c08da9e 100644 --- a/app.py +++ b/app.py @@ -558,6 +558,7 @@ class FormationPlayerPayload(BaseModel): number: str = "" position: str = "" is_captain: bool = False + photo_enabled: bool = False x: float y: float @@ -575,6 +576,7 @@ class SquadEditorPlayerPayload(BaseModel): number: str = "" position: str = "" is_captain: bool = False + photo_enabled: bool = False class SquadEditorCoachPayload(BaseModel): diff --git a/repositories/match_lineup_repository.py b/repositories/match_lineup_repository.py index caa5d7e..850ee24 100644 --- a/repositories/match_lineup_repository.py +++ b/repositories/match_lineup_repository.py @@ -59,6 +59,7 @@ def _player_to_editor_dict(p: dict) -> dict: "number": str(p.get("number", "") or ""), "position": p.get("position", "") or "", "is_captain": bool(p.get("is_captain")), + "photo_enabled": bool(p.get("photo_enabled")), } @@ -90,7 +91,8 @@ def get_match_lineup_for_editor( COALESCE(p.first_name, '') AS first_name, COALESCE(mlp.number::text, '') AS number, COALESCE(p.position, '') AS position, - COALESCE(mlp.is_captain, FALSE) AS is_captain + COALESCE(mlp.is_captain, FALSE) AS is_captain, + COALESCE(p.photo_enabled, FALSE) AS photo_enabled FROM match_lineup_players mlp JOIN players p ON p.id = mlp.player_id @@ -141,6 +143,7 @@ def get_match_lineup_for_editor( "number": row[7] or "", "position": row[8] or "", "is_captain": bool(row[9]), + "photo_enabled": bool(row[10]), } side = row[0] @@ -232,11 +235,24 @@ def get_match_lineup_for_vmix( COALESCE(mlp.is_captain, FALSE) AS is_captain, COALESCE(p.position, '') AS pos, p.photo, - COALESCE(p.photo_enabled, FALSE) AS photo_enabled, - CASE WHEN mlp.side = 'home' THEN %s ELSE %s END AS team_id + COALESCE(p.photo_enabled, FALSE) AS photo_enabled FROM match_lineup_players mlp - LEFT JOIN players p - ON p.id = mlp.player_id + LEFT JOIN LATERAL ( + SELECT p.* + FROM players p + WHERE p.team_id = CASE WHEN mlp.side = 'home' THEN %s ELSE %s END + AND ( + p.id = mlp.player_id + OR ( + COALESCE(p.number::text, '') <> '' + AND COALESCE(p.number::text, '') = COALESCE(mlp.number::text, '') + ) + ) + ORDER BY + CASE WHEN p.id = mlp.player_id THEN 0 ELSE 1 END, + p.id + LIMIT 1 + ) p ON TRUE WHERE mlp.match_id = %s ORDER BY CASE @@ -298,7 +314,7 @@ def get_match_lineup_for_vmix( "pos": row[10] or "", "photo": row[11] or "", "photo_enabled": bool(row[12]), - "team_id": row[13], + "team_id": home_team_id if row[0] == "home" else away_team_id, } side = row[0] diff --git a/repositories/team_squad_repository.py b/repositories/team_squad_repository.py index 98a4848..7df54f2 100644 --- a/repositories/team_squad_repository.py +++ b/repositories/team_squad_repository.py @@ -22,7 +22,8 @@ def get_team_players_for_match_editor( COALESCE(p.first_name, '') AS first_name, COALESCE(p.number::text, '') AS number, COALESCE(p.position, '') AS position, - FALSE AS is_captain + FALSE AS is_captain, + COALESCE(p.photo_enabled, FALSE) AS photo_enabled FROM players p WHERE p.team_id = %s ORDER BY @@ -51,6 +52,7 @@ def get_team_players_for_match_editor( "number": row[4] or "", "position": row[5] or "", "is_captain": bool(row[6]), + "photo_enabled": bool(row[7]), } for row in rows ] diff --git a/services/vmix_json_service.py b/services/vmix_json_service.py index c9bede6..8f58b56 100644 --- a/services/vmix_json_service.py +++ b/services/vmix_json_service.py @@ -469,7 +469,48 @@ def get_vmix_team_formations(session_token: str, team_id: int): mf.team_id, COALESCE(mf.player_name, '') AS player_name FROM match_formations mf - LEFT JOIN players p ON p.id = mf.player_id + LEFT JOIN LATERAL ( + SELECT p.* + FROM players p + WHERE p.team_id = mf.team_id + AND ( + p.id = mf.player_id + OR ( + COALESCE(p.number::text, '') <> '' + AND COALESCE(p.number::text, '') = COALESCE(mf.number, '') + ) + OR ( + COALESCE(mf.player_name, '') <> '' + AND ( + LOWER(COALESCE(p.full_name, '')) = LOWER(TRIM(mf.player_name)) + OR LOWER(TRIM(COALESCE(p.last_name, '') || ' ' || COALESCE(p.first_name, ''))) = LOWER(TRIM(mf.player_name)) + OR LOWER(TRIM(COALESCE(p.first_name, '') || ' ' || COALESCE(p.last_name, ''))) = LOWER(TRIM(mf.player_name)) + ) + ) + ) + ORDER BY + CASE + WHEN p.id = mf.player_id + AND ( + COALESCE(mf.number, '') = '' + OR COALESCE(p.number::text, '') = COALESCE(mf.number, '') + OR LOWER(COALESCE(p.full_name, '')) = LOWER(TRIM(COALESCE(mf.player_name, ''))) + OR LOWER(TRIM(COALESCE(p.last_name, '') || ' ' || COALESCE(p.first_name, ''))) = LOWER(TRIM(COALESCE(mf.player_name, ''))) + OR LOWER(TRIM(COALESCE(p.first_name, '') || ' ' || COALESCE(p.last_name, ''))) = LOWER(TRIM(COALESCE(mf.player_name, ''))) + ) + THEN 0 + WHEN COALESCE(p.number::text, '') = COALESCE(mf.number, '') + AND COALESCE(mf.player_name, '') <> '' + THEN 1 + WHEN COALESCE(mf.player_name, '') <> '' + THEN 2 + WHEN COALESCE(p.number::text, '') = COALESCE(mf.number, '') + THEN 3 + ELSE 4 + END, + p.id + LIMIT 1 + ) p ON TRUE WHERE mf.match_id = %s and mf.team_id = %s ORDER BY mf.id """ diff --git a/static/script.js b/static/script.js index 4d3e720..bab42e6 100644 --- a/static/script.js +++ b/static/script.js @@ -2277,6 +2277,7 @@ function getRowPlayer(row) { number: row.dataset.playerNumber || "", position: row.dataset.playerPosition || "", isCaptain: row.dataset.playerCaptain === "1", + photoEnabled: row.dataset.playerPhotoEnabled === "1", disciplineType: row.dataset.disciplineType || "" }; } @@ -2289,6 +2290,7 @@ function setRowPlayer(row, player) { row.dataset.playerNumber = player.number ?? ""; row.dataset.playerPosition = player.position ?? ""; row.dataset.playerCaptain = player.isCaptain ? "1" : "0"; + row.dataset.playerPhotoEnabled = player.photoEnabled ? "1" : "0"; row.dataset.disciplineType = player.disciplineType ?? ""; } @@ -2380,6 +2382,9 @@ function renderLineupRow(row) { const idJs = JSON.stringify(player.id || player.number || ""); const nameJs = JSON.stringify(displayName); + const noPhotoIconHtml = player.photoEnabled + ? '' + : ''; let actionsHtml = ''; if (role === "starting") { @@ -2411,7 +2416,12 @@ function renderLineupRow(row) { } row.innerHTML = ` -