Minor design improvements

This commit is contained in:
Lol3rrr
2024-11-01 21:47:25 +01:00
parent 1d6b6555b1
commit 101833d0d8
5 changed files with 87 additions and 40 deletions

View File

@@ -46,7 +46,8 @@ async fn list(
) )
.inner_join( .inner_join(
crate::schema::demo_players::table crate::schema::demo_players::table
.on(crate::schema::demos::dsl::demo_id.eq(crate::schema::demo_players::dsl::demo_id)) .on(crate::schema::demos::dsl::demo_id
.eq(crate::schema::demo_players::dsl::demo_id)),
) )
.select(( .select((
crate::models::Demo::as_select(), crate::models::Demo::as_select(),
@@ -54,7 +55,11 @@ async fn list(
crate::models::DemoTeam::as_select(), crate::models::DemoTeam::as_select(),
crate::models::DemoPlayer::as_select(), crate::models::DemoPlayer::as_select(),
)) ))
.filter(crate::schema::demos::dsl::steam_id.eq(steam_id.to_string()).and(crate::schema::demo_players::dsl::steam_id.eq(steam_id.to_string()))); .filter(
crate::schema::demos::dsl::steam_id
.eq(steam_id.to_string())
.and(crate::schema::demo_players::dsl::steam_id.eq(steam_id.to_string())),
);
let pending_query = crate::schema::demos::dsl::demos let pending_query = crate::schema::demos::dsl::demos
.inner_join(crate::schema::processing_status::table.on( .inner_join(crate::schema::processing_status::table.on(
crate::schema::demos::dsl::demo_id.eq(crate::schema::processing_status::dsl::demo_id), crate::schema::demos::dsl::demo_id.eq(crate::schema::processing_status::dsl::demo_id),
@@ -294,18 +299,34 @@ async fn scoreboard(
), ),
), ),
) )
.filter(crate::schema::demo_players::dsl::demo_id.eq(demo_id)); .filter(crate::schema::demo_players::dsl::demo_id.eq(demo_id.clone()));
let team_query = crate::schema::demo_teams::dsl::demo_teams
.filter(crate::schema::demo_teams::dsl::demo_id.eq(demo_id));
let mut db_con = crate::db_connection().await; let mut db_con = crate::db_connection().await;
let response: Vec<(crate::models::DemoPlayer, crate::models::DemoPlayerStats)> = let db_result = db_con
match query.load(&mut db_con).await { .build_transaction()
Ok(d) => d, .read_only()
Err(e) => { .run::<_, diesel::result::Error, _>(|con| {
tracing::error!("Querying DB: {:?}", e); Box::pin(async move {
return Err(axum::http::StatusCode::INTERNAL_SERVER_ERROR); let players: Vec<(crate::models::DemoPlayer, crate::models::DemoPlayerStats)> =
} query.load(con).await?;
}; let teams: Vec<crate::models::DemoTeam> = team_query.load(con).await?;
Ok((players, teams))
})
})
.await;
let (response, team_response) = match db_result {
Ok(d) => d,
Err(e) => {
tracing::error!("Querying DB {:?}", e);
return Err(axum::http::StatusCode::INTERNAL_SERVER_ERROR);
}
};
if response.is_empty() { if response.is_empty() {
tracing::error!("DB Response was empty"); tracing::error!("DB Response was empty");
@@ -314,9 +335,16 @@ async fn scoreboard(
let mut teams = std::collections::BTreeMap::new(); let mut teams = std::collections::BTreeMap::new();
for (player, stats) in response { for (player, stats) in response {
let team = teams.entry(player.team as u32).or_insert(Vec::new()); let team =
teams
.entry(player.team as u32)
.or_insert(common::demo_analysis::ScoreBoardTeam {
number: player.team as u32,
players: Vec::new(),
score: 0,
});
team.push(common::demo_analysis::ScoreBoardPlayer { team.players.push(common::demo_analysis::ScoreBoardPlayer {
name: player.name, name: player.name,
kills: stats.kills as usize, kills: stats.kills as usize,
deaths: stats.deaths as usize, deaths: stats.deaths as usize,
@@ -325,8 +353,15 @@ async fn scoreboard(
}); });
} }
for team in team_response {
let number = team.team as u32;
if let Some(entry) = teams.get_mut(&number) {
entry.score = team.end_score;
}
}
Ok(axum::Json(common::demo_analysis::ScoreBoard { Ok(axum::Json(common::demo_analysis::ScoreBoard {
teams: teams.into_iter().collect::<Vec<_>>(), teams: teams.into_values().collect::<Vec<_>>(),
})) }))
} }

View File

@@ -1,6 +1,13 @@
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct ScoreBoard { pub struct ScoreBoard {
pub teams: Vec<(u32, Vec<ScoreBoardPlayer>)>, pub teams: Vec<ScoreBoardTeam>,
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct ScoreBoardTeam {
pub number: u32,
pub score: i16,
pub players: Vec<ScoreBoardPlayer>,
} }
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]

View File

@@ -25,9 +25,9 @@ pub fn scoreboard() -> impl leptos::IntoView {
.get() .get()
.into_iter() .into_iter()
.flat_map(|v| v.teams.into_iter()) .flat_map(|v| v.teams.into_iter())
.map(|(team, players)| { .map(|team| {
view! { view! {
<TeamScoreboard value=players team_name=format!("Team {}", team) /> <TeamScoreboard value=team.players team_name=format!("Team {} - {}", team.number, team.score) />
} }
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()

View File

@@ -3,9 +3,7 @@ use leptos::*;
#[leptos::component] #[leptos::component]
pub fn homepage(get_notification: ReadSignal<u8>) -> impl leptos::IntoView { pub fn homepage(get_notification: ReadSignal<u8>) -> impl leptos::IntoView {
let demo_data = create_resource( let demo_data = create_resource(
move || { move || get_notification.get(),
get_notification.get()
},
|_| async move { |_| async move {
let res = reqwasm::http::Request::get("/api/demos/list") let res = reqwasm::http::Request::get("/api/demos/list")
.send() .send()
@@ -16,11 +14,17 @@ pub fn homepage(get_notification: ReadSignal<u8>) -> impl leptos::IntoView {
}, },
); );
let pending_display = move || demo_data.get().map(|d| d.pending).filter(|p| p.len() > 0).map(|pending| { let pending_display = move || {
view! { demo_data
<p>{pending.len()} demos are pending/waiting for analysis</p> .get()
} .map(|d| d.pending)
}); .filter(|p| p.len() > 0)
.map(|pending| {
view! {
<p>{pending.len()} demos are pending/waiting for analysis</p>
}
})
};
view! { view! {
<div> <div>
@@ -117,8 +121,8 @@ fn demo_list_entry(demo: common::BaseDemoInfo, idx: usize) -> impl leptos::IntoV
view! { view! {
class=style, class=style,
<span <span
class="score" class="score"
style=format!("grid-row: {};", idx + 1) style=format!("grid-row: {};", idx + 1)
class:won=won class:won=won
class:lost=lost class:lost=lost

View File

@@ -112,23 +112,24 @@ pub fn upload_demo(
let uploading = RwSignal::new(false); let uploading = RwSignal::new(false);
let handle_resp: std::rc::Rc<dyn Fn(&leptos::web_sys::Response)> = std::rc::Rc::new(move |resp: &leptos::web_sys::Response| { let handle_resp: std::rc::Rc<dyn Fn(&leptos::web_sys::Response)> =
if resp.status() != 200 { std::rc::Rc::new(move |resp: &leptos::web_sys::Response| {
// TODO if resp.status() != 200 {
// Display error somehow // TODO
return; // Display error somehow
} return;
}
uploading.set(false); uploading.set(false);
// Remove the Upload popup // Remove the Upload popup
update_shown.set(DemoUploadStatus::Hidden); update_shown.set(DemoUploadStatus::Hidden);
// Reload the demo list // Reload the demo list
reload_demos.update(|v| { reload_demos.update(|v| {
*v = v.wrapping_add(1); *v = v.wrapping_add(1);
});
}); });
});
let on_submit: std::rc::Rc<dyn Fn(&leptos::web_sys::FormData)> = std::rc::Rc::new(move |_| { let on_submit: std::rc::Rc<dyn Fn(&leptos::web_sys::FormData)> = std::rc::Rc::new(move |_| {
uploading.set(true); uploading.set(true);