Minor design improvements
This commit is contained in:
@@ -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<_>>(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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<_>>()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user