Add scoreboard with data to demo view
This commit is contained in:
@@ -22,6 +22,7 @@ where
|
||||
.layer(axum::extract::DefaultBodyLimit::max(500 * 1024 * 1024)),
|
||||
)
|
||||
.route("/:id/info", axum::routing::get(info))
|
||||
.route("/:id/analysis/scoreboard", axum::routing::get(scoreboard))
|
||||
.route("/:id/reanalyse", axum::routing::get(analyise))
|
||||
.with_state(Arc::new(DemoState {
|
||||
upload_folder: upload_folder.into(),
|
||||
@@ -178,3 +179,44 @@ async fn info(
|
||||
map: result.map,
|
||||
}))
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(session))]
|
||||
async fn scoreboard(session: UserSession, Path(demo_id): Path<i64>) -> Result<axum::response::Json<common::demo_analysis::ScoreBoard>, axum::http::StatusCode> {
|
||||
let query = crate::schema::demo_players::dsl::demo_players
|
||||
.inner_join(crate::schema::demo_player_stats::dsl::demo_player_stats.on(crate::schema::demo_players::dsl::demo_id.eq(crate::schema::demo_player_stats::dsl::demo_id).and(crate::schema::demo_players::dsl::steam_id.eq(crate::schema::demo_player_stats::dsl::steam_id))))
|
||||
.filter(crate::schema::demo_players::dsl::demo_id.eq(demo_id));
|
||||
|
||||
let mut db_con = crate::db_connection().await;
|
||||
|
||||
let response: Vec<(crate::models::DemoPlayer, crate::models::DemoPlayerStats)> = match query.load(&mut db_con).await {
|
||||
Ok(d) => d,
|
||||
Err(e) => {
|
||||
tracing::error!("Querying DB: {:?}", e);
|
||||
return Err(axum::http::StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
};
|
||||
|
||||
if response.is_empty() {
|
||||
tracing::error!("DB Response was empty");
|
||||
return Err(axum::http::StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
let team1_number: i16 = response.last().map(|(p, _)| p.team).unwrap();
|
||||
|
||||
let mut team1 = Vec::new();
|
||||
let mut team2 = Vec::new();
|
||||
for (player, stats) in response {
|
||||
let team_vec = if player.team == team1_number { &mut team1 } else { &mut team2 };
|
||||
|
||||
team_vec.push(common::demo_analysis::ScoreBoardPlayer {
|
||||
name: player.name,
|
||||
kills: stats.kills as usize,
|
||||
deaths: stats.deaths as usize,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(axum::Json(common::demo_analysis::ScoreBoard {
|
||||
team1,
|
||||
team2,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -15,3 +15,18 @@ pub struct DemoInfo {
|
||||
pub id: i64,
|
||||
pub map: String,
|
||||
}
|
||||
|
||||
pub mod demo_analysis {
|
||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ScoreBoard {
|
||||
pub team1: Vec<ScoreBoardPlayer>,
|
||||
pub team2: Vec<ScoreBoardPlayer>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ScoreBoardPlayer {
|
||||
pub name: String,
|
||||
pub kills: usize,
|
||||
pub deaths: usize,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,15 +70,52 @@ pub fn demo() -> impl leptos::IntoView {
|
||||
|
||||
#[leptos::component]
|
||||
pub fn scoreboard() -> impl leptos::IntoView {
|
||||
use leptos::Suspense;
|
||||
|
||||
let scoreboard_resource = create_resource(leptos_router::use_params_map(), |params| async move {
|
||||
let id = params.get("id").unwrap();
|
||||
|
||||
let res = reqwasm::http::Request::get(&format!("/api/demos/{}/analysis/scoreboard", id))
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
res.json::<common::demo_analysis::ScoreBoard>().await.unwrap()
|
||||
});
|
||||
|
||||
let team_display_func = |team: &[common::demo_analysis::ScoreBoardPlayer]| {
|
||||
team.iter().map(|player| {
|
||||
view! {
|
||||
<tr>
|
||||
<td> { player.name.clone() } </td>
|
||||
<td> { player.kills } </td>
|
||||
<td> { player.deaths } </td>
|
||||
</tr>
|
||||
}
|
||||
}).collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
view! {
|
||||
<h2>Scoreboard</h2>
|
||||
|
||||
<Suspense
|
||||
fallback=move || view! { <p>Loading Scoreboard data</p> }
|
||||
>
|
||||
<div>
|
||||
<h3>Team 1</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Kills</th>
|
||||
<th>Deaths</th>
|
||||
</tr>
|
||||
{
|
||||
move || {
|
||||
scoreboard_resource.get().map(|s| {
|
||||
let team = s.team1;
|
||||
team_display_func(&team)
|
||||
})
|
||||
}
|
||||
}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -88,8 +125,17 @@ pub fn scoreboard() -> impl leptos::IntoView {
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
</tr>
|
||||
{
|
||||
move || {
|
||||
scoreboard_resource.get().map(|s| {
|
||||
let team = s.team2;
|
||||
team_display_func(&team)
|
||||
})
|
||||
}
|
||||
}
|
||||
</table>
|
||||
</div>
|
||||
</Suspense>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user