Merge commit '9919ae93c21395043f7f0eac6e54668a70cad146'
This commit is contained in:
34
src/game.rs
34
src/game.rs
@@ -29,29 +29,35 @@ async fn index(State(backend): State<Arc<Backend>>, cookies: CookieJar) -> Respo
|
|||||||
}
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
fieldset role="group" {
|
fieldset role="group" {
|
||||||
input name="name" placeholder=(format!("Rename {}", client.get_display_name())) aria-label="Name";
|
input
|
||||||
input type="submit" value="Save";
|
name="name"
|
||||||
}
|
placeholder=(format!("Rename {}", client.get_display_name()))
|
||||||
|
aria-label="Name";
|
||||||
|
input type="submit" value="Save";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p { "You have found " (sightings.len()) "/" (amount_total_cameras) " cameras." }
|
p {
|
||||||
|
"You have found "
|
||||||
|
(sightings.len())
|
||||||
|
"/"
|
||||||
|
(amount_total_cameras)
|
||||||
|
" cameras."
|
||||||
|
progress value=(sightings.len()) max=(amount_total_cameras);
|
||||||
|
}
|
||||||
p {
|
p {
|
||||||
h2 { "Highscore" }
|
h2 { "Highscore" }
|
||||||
ul.iterated {
|
ul.iterated {
|
||||||
@for rank in highscore {
|
@for rank in highscore {
|
||||||
li.card {
|
li.card {
|
||||||
span {
|
span {
|
||||||
span.font-headline.rank.text-muted {
|
span.font-headline.rank.text-muted { (rank.rank) "." }
|
||||||
(rank.rank)"."
|
@if rank.client == client { (PreEscaped("<mark>")) }
|
||||||
}
|
(rank.client.get_display_name())
|
||||||
@if rank.uuid == client.uuid { (PreEscaped("<mark>")) }
|
@if rank.client == client { (PreEscaped("</mark>")) }
|
||||||
(rank.name)
|
|
||||||
@if rank.uuid == client.uuid { (PreEscaped("</mark>")) }
|
|
||||||
}
|
|
||||||
span.font-headline.cam {
|
|
||||||
(rank.amount)(PreEscaped(" "))"📸"
|
|
||||||
}
|
}
|
||||||
|
span.font-headline.cam { (rank.amount) (PreEscaped(" ")) "📸" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,9 +3,7 @@ use maud::{html, Markup};
|
|||||||
|
|
||||||
pub(super) async fn index() -> Markup {
|
pub(super) async fn index() -> Markup {
|
||||||
new(html! {
|
new(html! {
|
||||||
h1 {
|
h1 { "Digital Shadows" }
|
||||||
"Digital Shadows"
|
|
||||||
}
|
|
||||||
hgroup {
|
hgroup {
|
||||||
h2 {
|
h2 {
|
||||||
"Who owns your "
|
"Who owns your "
|
||||||
@@ -22,9 +20,7 @@ pub(super) async fn index() -> Markup {
|
|||||||
blockquote {
|
blockquote {
|
||||||
"Digital Shadows confronts visitors with their digital self – copied, measured, analyzed. An experiment on data power, visibility, and control in the digital age."
|
"Digital Shadows confronts visitors with their digital self – copied, measured, analyzed. An experiment on data power, visibility, and control in the digital age."
|
||||||
footer {
|
footer {
|
||||||
cite {
|
cite { "— René Mayrhofer" }
|
||||||
"— René Mayrhofer"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
|
@@ -9,6 +9,12 @@ pub struct Client {
|
|||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Client {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.uuid == other.uuid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
pub(crate) fn get_display_name(&self) -> String {
|
pub(crate) fn get_display_name(&self) -> String {
|
||||||
match &self.name {
|
match &self.name {
|
||||||
|
@@ -1,56 +1,42 @@
|
|||||||
use crate::{random_names::get_name_by_uuid, Backend};
|
use crate::{model::client::Client, Backend};
|
||||||
|
|
||||||
struct RankDb {
|
|
||||||
pub(crate) rank: i64,
|
|
||||||
pub(crate) name: Option<String>,
|
|
||||||
pub(crate) uuid: String,
|
|
||||||
pub(crate) amount: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct Rank {
|
pub(crate) struct Rank {
|
||||||
pub(crate) rank: i64,
|
pub(crate) rank: i64,
|
||||||
pub(crate) name: String,
|
pub(crate) client: Client,
|
||||||
pub(crate) uuid: String,
|
|
||||||
pub(crate) amount: i64,
|
pub(crate) amount: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RankDb> for Rank {
|
|
||||||
fn from(value: RankDb) -> Self {
|
|
||||||
let name = match value.name {
|
|
||||||
Some(name) => name,
|
|
||||||
None => get_name_by_uuid(&value.uuid).to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
Self {
|
|
||||||
rank: value.rank,
|
|
||||||
name,
|
|
||||||
uuid: value.uuid,
|
|
||||||
amount: value.amount,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Backend {
|
impl Backend {
|
||||||
pub(crate) async fn highscore(&self) -> Vec<Rank> {
|
pub(crate) async fn highscore(&self) -> Vec<Rank> {
|
||||||
match self {
|
match self {
|
||||||
Backend::Sqlite(db) => sqlx::query_as!(
|
Backend::Sqlite(db) => {
|
||||||
RankDb,
|
let rows = sqlx::query!(
|
||||||
"SELECT
|
"SELECT
|
||||||
RANK() OVER (ORDER BY COUNT(s.client_uuid) DESC) as rank,
|
RANK() OVER (ORDER BY COUNT(s.client_uuid) DESC) as rank,
|
||||||
c.name,
|
c.name,
|
||||||
c.uuid,
|
c.uuid,
|
||||||
COUNT(s.client_uuid) as amount
|
COUNT(s.client_uuid) as amount
|
||||||
FROM client c
|
FROM client c
|
||||||
LEFT JOIN sightings s ON c.uuid = s.client_uuid
|
LEFT JOIN sightings s ON c.uuid = s.client_uuid
|
||||||
GROUP BY c.uuid, c.name
|
GROUP BY c.uuid, c.name
|
||||||
ORDER BY amount DESC"
|
ORDER BY amount DESC"
|
||||||
)
|
)
|
||||||
.fetch_all(db)
|
.fetch_all(db)
|
||||||
.await
|
.await
|
||||||
.unwrap_or_default()
|
.unwrap_or_default();
|
||||||
.into_iter()
|
|
||||||
.map(|r| r.into())
|
rows.into_iter()
|
||||||
.collect(),
|
.map(|row| Rank {
|
||||||
|
rank: row.rank,
|
||||||
|
client: Client {
|
||||||
|
uuid: row.uuid,
|
||||||
|
name: row.name,
|
||||||
|
},
|
||||||
|
amount: row.amount,
|
||||||
|
})
|
||||||
|
.map(|r| r.into())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
66
src/page.rs
66
src/page.rs
@@ -10,52 +10,50 @@ pub fn new(content: Markup) -> Markup {
|
|||||||
meta name="viewport" content="width=device-width, initial-scale=1.0";
|
meta name="viewport" content="width=device-width, initial-scale=1.0";
|
||||||
link rel="stylesheet" href="/static/pico.min.css";
|
link rel="stylesheet" href="/static/pico.min.css";
|
||||||
link rel="stylesheet" href="/static/style.css";
|
link rel="stylesheet" href="/static/style.css";
|
||||||
title {
|
title { "Digital Shadows" }
|
||||||
"Digital Shadows"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
header.container {
|
header.container {
|
||||||
nav {
|
nav {
|
||||||
ul {
|
ul {
|
||||||
li { a href="/" { strong { "Digital Shadows" } } }
|
li {
|
||||||
|
a href="/" {
|
||||||
|
strong { "Digital Shadows" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ul {
|
}
|
||||||
li {
|
ul {
|
||||||
a href="/"{
|
li {
|
||||||
span role="img" aria-label="home" {
|
a href="/" {
|
||||||
"🏠"
|
span role="img" aria-label="home" { "🏠" }
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
li {
|
}
|
||||||
a href="/game" {
|
li {
|
||||||
span role="img" aria-label="camera" {
|
a href="/game" {
|
||||||
"📸"
|
span role="img" aria-label="camera" { "📸" }
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
li { span id="theme_switcher" {} }
|
}
|
||||||
|
li {
|
||||||
|
span id="theme_switcher" {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
main.container {
|
main.container {
|
||||||
section {
|
section { (content) }
|
||||||
(content)
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer.container {
|
footer.container {
|
||||||
small {
|
small {
|
||||||
"Footer "
|
"Footer "
|
||||||
mark { "to be completed" }
|
mark { "to be completed" }
|
||||||
a href="#" { "with links" }
|
a href="#" { "with links" }
|
||||||
" • "
|
" • "
|
||||||
a target="_blank" href="https://www.digidow.eu/impressum/" { "Impressum" }
|
a target="_blank" href="https://www.digidow.eu/impressum/" { "Impressum" }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
script src="/static/theme.js" {}
|
}
|
||||||
|
script src="/static/theme.js" {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user