only show top 10 participants + total amount

This commit is contained in:
2025-08-13 16:14:07 +02:00
parent 4ea9068850
commit 6d021e8d6b
4 changed files with 90 additions and 17 deletions

View File

@@ -1,17 +1,17 @@
use crate::{
AppState, Backend, NameUpdateError,
language::language,
page::{MyMessage, Page},
AppState, Backend, NameUpdateError,
};
use axum::{
Form, Router,
extract::{Path, State},
http::HeaderMap,
response::{IntoResponse, Response},
routing::{get, post},
Form, Router,
};
use axum_extra::extract::{CookieJar, PrivateCookieJar};
use maud::{Markup, PreEscaped, html};
use maud::{html, Markup, PreEscaped};
use serde::Deserialize;
use std::sync::Arc;
use uuid::Uuid;
@@ -38,7 +38,8 @@ async fn retu(
let sightings = backend.sightings_for_client(&client).await;
let amount_total_cameras = backend.amount_total_cameras().await;
let highscore = backend.highscore().await;
let highscore = backend.highscore(&client).await;
let amount_participants = backend.amount_participants().await;
let mut page = Page::new(req.lang);
if let Some(message) = message {
@@ -85,6 +86,13 @@ async fn retu(
h2 { (t!("highscore_title")) }
ul.iterated {
@for rank in highscore {
@if rank.show_dots_above {
li.card {
span {
""
}
}
}
li.card {
span {
span.font-headline.rank.text-muted { (rank.rank) "." }
@@ -100,6 +108,7 @@ async fn retu(
}
}
}
(t!("amount_participants", amount = amount_participants))
}
});

View File

@@ -1,40 +1,102 @@
use crate::{Backend, model::client::Client};
use crate::{model::client::Client, Backend};
pub(crate) struct Rank {
pub(crate) rank: i64,
pub(crate) client: Client,
pub(crate) amount: i64,
pub(crate) show_dots_above: bool,
}
impl Backend {
pub(crate) async fn highscore(&self) -> Vec<Rank> {
pub(crate) async fn amount_participants(&self) -> i64 {
match self {
Backend::Sqlite(db) => {
let row = sqlx::query!("SELECT COUNT(*) as count FROM client")
.fetch_one(db)
.await
.unwrap();
row.count
}
}
}
pub(crate) async fn highscore(&self, client: &Client) -> Vec<Rank> {
match self {
Backend::Sqlite(db) => {
let rows = sqlx::query!(
"SELECT
DENSE_RANK() OVER (ORDER BY COUNT(s.client_uuid) DESC) as rank,
c.name,
c.uuid,
COUNT(s.client_uuid) as amount
FROM client c
LEFT JOIN sightings s ON c.uuid = s.client_uuid
GROUP BY c.uuid, c.name
ORDER BY amount DESC"
"WITH ranked_clients AS (
SELECT
DENSE_RANK() OVER (ORDER BY COUNT(s.client_uuid) DESC) as rank,
c.name,
c.uuid,
COUNT(s.client_uuid) as amount
FROM client c
LEFT JOIN sightings s ON c.uuid = s.client_uuid
GROUP BY c.uuid, c.name
)
SELECT rank, name, uuid, amount
FROM ranked_clients
WHERE rank <= (
SELECT rank
FROM ranked_clients
ORDER BY rank
LIMIT 1 OFFSET 9
)
ORDER BY rank, name"
)
.fetch_all(db)
.await
.unwrap_or_default();
rows.into_iter()
let mut ret: Vec<Rank> = rows
.into_iter()
.map(|row| Rank {
rank: row.rank.unwrap(),
client: Client {
uuid: row.uuid.unwrap(),
name: row.name,
},
amount: row.amount.unwrap(),
show_dots_above: false,
})
.collect();
let user_is_in_top = ret.iter().find(|x| &x.client == client).is_some();
if !user_is_in_top {
let row = sqlx::query!(
"WITH ranked_clients AS (
SELECT
DENSE_RANK() OVER (ORDER BY COUNT(s.client_uuid) DESC) as rank,
c.name,
c.uuid,
COUNT(s.client_uuid) as amount
FROM client c
LEFT JOIN sightings s ON c.uuid = s.client_uuid
GROUP BY c.uuid, c.name
)
SELECT rank, name, uuid, amount
FROM ranked_clients
WHERE uuid = ?
ORDER BY rank, name",
client.uuid
)
.fetch_one(db)
.await
.unwrap();
ret.push(Rank {
rank: row.rank,
client: Client {
uuid: row.uuid,
name: row.name,
},
amount: row.amount,
show_dots_above: true,
})
.collect()
}
ret
}
}
}