ai generated solutions to our ai generated problems

This commit is contained in:
Heidi
2026-06-17 23:58:03 +01:00
parent 7572cfb0c3
commit 28e54cc261
2 changed files with 107 additions and 18 deletions
+73 -2
View File
@@ -242,6 +242,14 @@ struct GameParticipant {
result: String, result: String,
player_count: i64, player_count: i64,
stats: GameStats, stats: GameStats,
players: Vec<GamePlayer>,
}
#[derive(Serialize)]
struct GamePlayer {
uid: String,
nick: Option<String>,
stats: GameStats,
} }
#[derive(Serialize)] #[derive(Serialize)]
@@ -1423,7 +1431,7 @@ fn game_participants_for(
) )
.map_err(db_error)?; .map_err(db_error)?;
let rows = stmt let mut participants = stmt
.query_map(params![session_id], |row| { .query_map(params![session_id], |row| {
Ok(GameParticipant { Ok(GameParticipant {
team_name: row.get(0)?, team_name: row.get(0)?,
@@ -1440,13 +1448,76 @@ fn game_participants_for(
shell_interceptions: row.get(10)?, shell_interceptions: row.get(10)?,
team_kills_stat: row.get(11)?, team_kills_stat: row.get(11)?,
}, },
players: Vec::new(),
}) })
}) })
.map_err(db_error)? .map_err(db_error)?
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
.map_err(db_error)?; .map_err(db_error)?;
Ok(rows) for participant in &mut participants {
participant.players = game_players_for(conn, session_id, &participant.team_name)?;
}
Ok(participants)
}
fn game_players_for(
conn: &Connection,
session_id: &str,
team_name: &str,
) -> Result<Vec<GamePlayer>, ApiError> {
let mut stmt = conn
.prepare(
"SELECT
p.UID,
(SELECT pg.nick
FROM player_games_hist pg
WHERE pg.session_id = p.session_id
AND pg.UID = p.UID
AND pg.nick IS NOT NULL
AND pg.nick != ''
ORDER BY pg.endtime_unix DESC
LIMIT 1),
COALESCE(SUM(p.ground_kills), 0),
COALESCE(SUM(p.air_kills), 0),
COALESCE(SUM(p.assists), 0),
COALESCE(SUM(p.captures), 0),
COALESCE(SUM(p.deaths), 0),
COALESCE(SUM(p.score), 0),
COALESCE(SUM(p.missile_evades), 0),
COALESCE(SUM(p.shell_interceptions), 0),
COALESCE(SUM(p.team_kills_stat), 0)
FROM player_games_hist p
WHERE p.session_id = ?1 AND p.team_name = ?2 COLLATE NOCASE
GROUP BY p.UID
ORDER BY COALESCE(SUM(p.score), 0) DESC, p.UID",
)
.map_err(db_error)?;
let players = stmt
.query_map(params![session_id, team_name], |row| {
Ok(GamePlayer {
uid: row.get(0)?,
nick: row.get(1)?,
stats: GameStats {
ground_kills: row.get(2)?,
air_kills: row.get(3)?,
assists: row.get(4)?,
captures: row.get(5)?,
deaths: row.get(6)?,
score: row.get(7)?,
missile_evades: row.get(8)?,
shell_interceptions: row.get(9)?,
team_kills_stat: row.get(10)?,
},
})
})
.map_err(db_error)?
.collect::<Result<Vec<_>, _>>()
.map_err(db_error)?;
Ok(players)
} }
fn validate_team_name(name: &str) -> Result<&str, ApiError> { fn validate_team_name(name: &str) -> Result<&str, ApiError> {
+34 -16
View File
@@ -2786,10 +2786,9 @@ function GamePage({ gameId, navigate }) {
) : null} ) : null}
{game ? ( {game ? (
<div className="mt-6 grid gap-5 sm:grid-cols-2 xl:grid-cols-4"> <div className="mt-6 grid gap-5 sm:grid-cols-3">
<Stat label="Players" value={formatNumber(game.player_count)} /> <Stat label="Players" value={formatNumber(game.player_count)} />
<Stat label="Assists" value={formatNumber(game.stats?.assists)} /> <Stat label="Assists" value={formatNumber(game.stats?.assists)} />
<Stat label="Score" value={formatNumber(game.stats?.score)} />
<Stat label="Deaths" value={formatNumber(game.stats?.deaths)} /> <Stat label="Deaths" value={formatNumber(game.stats?.deaths)} />
</div> </div>
) : null} ) : null}
@@ -2807,20 +2806,39 @@ function GamePage({ gameId, navigate }) {
{participants.map((participant) => { {participants.map((participant) => {
const won = String(participant.result || '').toLowerCase() === 'win' const won = String(participant.result || '').toLowerCase() === 'win'
return ( return (
<button <div className="border-b border-surface" key={participant.team_name}>
className="grid w-full gap-4 border-b border-surface px-5 py-4 text-left transition hover:bg-surface md:grid-cols-[1fr_repeat(4,auto)] md:items-center" <button
key={participant.team_name} className="grid w-full gap-4 px-5 py-4 text-left transition hover:bg-surface md:grid-cols-[1fr_repeat(3,auto)] md:items-center"
onClick={() => navigate(teamPath(participant.team_name))} onClick={() => navigate(teamPath(participant.team_name))}
type="button" type="button"
> >
<p className={`truncate font-semibold ${won ? 'text-fury-violet' : 'text-text-soft'}`}> <p className={`truncate font-semibold ${won ? 'text-fury-violet' : 'text-text-soft'}`}>
{participant.team_name} {participant.team_name}
</p> </p>
<p className="text-sm">{formatNumber(participant.player_count)} players</p> <p className="text-sm">{formatNumber(participant.player_count)} players</p>
<p className="text-sm">{formatNumber(participant.stats?.assists)} assists</p> <p className="text-sm">{formatNumber(participant.stats?.assists)} assists</p>
<p className="text-sm">{formatNumber(participant.stats?.score)} score</p> <p className="text-sm">{formatNumber(participant.stats?.deaths)} deaths</p>
<p className="text-sm">{formatNumber(participant.stats?.deaths)} deaths</p> </button>
</button>
<div className="pb-3">
{(participant.players || []).map((player) => (
<button
className="grid w-full gap-3 px-5 py-2 pl-10 text-left text-sm transition hover:bg-surface md:grid-cols-[1fr_repeat(3,auto)] md:items-center sm:pl-14"
key={player.uid}
onClick={() => navigate(`/players/${encodeURIComponent(player.uid)}`)}
type="button"
>
<div className="min-w-0">
<p className="truncate font-semibold text-text">{player.nick || player.uid}</p>
<p className="text-xs text-text-soft">{player.uid}</p>
</div>
<p>{formatNumber(player.stats?.assists)} assists</p>
<p>{formatNumber(player.stats?.score)} score</p>
<p>{formatNumber(player.stats?.deaths)} deaths</p>
</button>
))}
</div>
</div>
) )
})} })}