add language
This commit is contained in:
148
src/game.rs
148
src/game.rs
@@ -1,6 +1,7 @@
|
|||||||
use crate::{page::new, Backend};
|
use crate::{language::language, page::new, Backend};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
|
http::HeaderMap,
|
||||||
response::{IntoResponse, Redirect, Response},
|
response::{IntoResponse, Redirect, Response},
|
||||||
routing::get,
|
routing::get,
|
||||||
Router,
|
Router,
|
||||||
@@ -10,77 +11,85 @@ use maud::{html, Markup, PreEscaped};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
async fn index(State(backend): State<Arc<Backend>>, cookies: CookieJar) -> Response {
|
async fn index(
|
||||||
let (cookies, client) = backend.client(cookies).await;
|
State(backend): State<Arc<Backend>>,
|
||||||
|
cookies: CookieJar,
|
||||||
|
headers: HeaderMap,
|
||||||
|
) -> Response {
|
||||||
|
let (cookies, req) = backend.client_full(cookies, &headers).await;
|
||||||
|
let client = req.client;
|
||||||
|
|
||||||
let sightings = backend.sightings_for_client(&client).await;
|
let sightings = backend.sightings_for_client(&client).await;
|
||||||
let amount_total_cameras = backend.amount_total_cameras().await;
|
let amount_total_cameras = backend.amount_total_cameras().await;
|
||||||
let highscore = backend.highscore().await;
|
let highscore = backend.highscore().await;
|
||||||
|
|
||||||
let markup = new(html! {
|
let markup = new(
|
||||||
hgroup {
|
html! {
|
||||||
h1 { "Who finds the most cameras?" }
|
hgroup {
|
||||||
}
|
h1 { "Who finds the most cameras?" }
|
||||||
p {
|
}
|
||||||
mark { "TODO: Explanation of AEF / digital shadows / search game" }
|
p {
|
||||||
}
|
mark { "TODO: Explanation of AEF / digital shadows / search game" }
|
||||||
p {
|
}
|
||||||
mark { "TODO: Show optional SUCC message" }
|
p {
|
||||||
}
|
mark { "TODO: Show optional SUCC message" }
|
||||||
|
|
||||||
div {
|
|
||||||
(client.get_display_name())
|
|
||||||
", do you want to be named something different? No worries, change here 👇"
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
|
||||||
fieldset role="group" {
|
|
||||||
input
|
|
||||||
name="name"
|
|
||||||
placeholder="✨ Your new name starts here ✨"
|
|
||||||
aria-label="Name";
|
|
||||||
input type="submit" value="Save";
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
div {
|
||||||
"You have found "
|
(client.get_display_name())
|
||||||
(sightings.len())
|
", do you want to be named something different? No worries, change here 👇"
|
||||||
"/"
|
}
|
||||||
(amount_total_cameras)
|
|
||||||
" cameras:"
|
form {
|
||||||
progress value=(sightings.len()) max=(amount_total_cameras);
|
fieldset role="group" {
|
||||||
}
|
input
|
||||||
p {
|
name="name"
|
||||||
ul.iterated {
|
placeholder="✨ Your new name starts here ✨"
|
||||||
@for (idx, sighting) in sightings.iter().enumerate() {
|
aria-label="Name";
|
||||||
li.card {
|
input type="submit" value="Save";
|
||||||
span {
|
}
|
||||||
span.font-headline.rank.text-muted { (idx+1) }
|
}
|
||||||
(sighting.camera.name)
|
|
||||||
|
p {
|
||||||
|
"You have found "
|
||||||
|
(sightings.len())
|
||||||
|
"/"
|
||||||
|
(amount_total_cameras)
|
||||||
|
" cameras:"
|
||||||
|
progress value=(sightings.len()) max=(amount_total_cameras);
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
ul.iterated {
|
||||||
|
@for (idx, sighting) in sightings.iter().enumerate() {
|
||||||
|
li.card {
|
||||||
|
span {
|
||||||
|
span.font-headline.rank.text-muted { (idx+1) }
|
||||||
|
(sighting.camera.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
h2 { "Highscore" }
|
||||||
|
ul.iterated {
|
||||||
|
@for rank in highscore {
|
||||||
|
li.card {
|
||||||
|
span {
|
||||||
|
span.font-headline.rank.text-muted { (rank.rank) "." }
|
||||||
|
@if rank.client == client { (PreEscaped("<mark>")) }
|
||||||
|
(rank.client.get_display_name())
|
||||||
|
@if rank.client == client { (PreEscaped("</mark>")) }
|
||||||
|
}
|
||||||
|
span.font-headline.font-lg { (rank.amount) (PreEscaped(" ")) "📸" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
}
|
req.lang,
|
||||||
p {
|
);
|
||||||
h2 { "Highscore" }
|
|
||||||
ul.iterated {
|
|
||||||
@for rank in highscore {
|
|
||||||
li.card {
|
|
||||||
span {
|
|
||||||
span.font-headline.rank.text-muted { (rank.rank) "." }
|
|
||||||
@if rank.client == client { (PreEscaped("<mark>")) }
|
|
||||||
(rank.client.get_display_name())
|
|
||||||
@if rank.client == client { (PreEscaped("</mark>")) }
|
|
||||||
}
|
|
||||||
span.font-headline.font-lg { (rank.amount) (PreEscaped(" ")) "📸" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
(cookies, markup).into_response()
|
(cookies, markup).into_response()
|
||||||
}
|
}
|
||||||
@@ -88,16 +97,17 @@ async fn index(State(backend): State<Arc<Backend>>, cookies: CookieJar) -> Respo
|
|||||||
async fn game(
|
async fn game(
|
||||||
State(backend): State<Arc<Backend>>,
|
State(backend): State<Arc<Backend>>,
|
||||||
cookies: CookieJar,
|
cookies: CookieJar,
|
||||||
|
headers: HeaderMap,
|
||||||
Path(uuid): Path<String>,
|
Path(uuid): Path<String>,
|
||||||
) -> Result<Redirect, Response> {
|
) -> Result<Redirect, Response> {
|
||||||
let (cookies, client) = backend.client(cookies).await;
|
let (cookies, client) = backend.client(cookies).await;
|
||||||
|
|
||||||
let Ok(uuid) = Uuid::parse_str(&uuid) else {
|
let Ok(uuid) = Uuid::parse_str(&uuid) else {
|
||||||
return Err(not_found().await.into_response());
|
return Err(not_found(cookies, headers).await.into_response());
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(camera) = backend.get_camera(&uuid).await else {
|
let Some(camera) = backend.get_camera(&uuid).await else {
|
||||||
return Err(not_found().await.into_response());
|
return Err(not_found(cookies, headers).await.into_response());
|
||||||
};
|
};
|
||||||
|
|
||||||
let succ = backend.client_found_camera(&client, &camera).await;
|
let succ = backend.client_found_camera(&client, &camera).await;
|
||||||
@@ -106,10 +116,14 @@ async fn game(
|
|||||||
Ok(Redirect::to("/game"))
|
Ok(Redirect::to("/game"))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn not_found() -> Markup {
|
async fn not_found(cookies: CookieJar, headers: HeaderMap) -> Markup {
|
||||||
new(html! {
|
let lang = language(&cookies, &headers);
|
||||||
h1 { "uups" }
|
new(
|
||||||
})
|
html! {
|
||||||
|
h1 { "uups" }
|
||||||
|
},
|
||||||
|
lang,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn routes() -> Router<Arc<Backend>> {
|
pub(super) fn routes() -> Router<Arc<Backend>> {
|
||||||
|
109
src/index.rs
109
src/index.rs
@@ -8,69 +8,72 @@ pub(super) async fn index(cookies: CookieJar, headers: HeaderMap) -> Markup {
|
|||||||
|
|
||||||
rust_i18n::set_locale(lang.to_locale());
|
rust_i18n::set_locale(lang.to_locale());
|
||||||
|
|
||||||
new(html! {
|
new(
|
||||||
h1 { (t!("digital_shadows")) }
|
html! {
|
||||||
hgroup {
|
h1 { (t!("digital_shadows")) }
|
||||||
h2 {
|
hgroup {
|
||||||
"Who owns your "
|
h2 {
|
||||||
mark { "data" }
|
"Who owns your "
|
||||||
"?"
|
mark { "data" }
|
||||||
|
"?"
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
"What happens when your digital shadow takes shape: tangible, interrogative, observant?"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
"What happens when your digital shadow takes shape: tangible, interrogative, observant?"
|
"Artists: René Mayrhofer (AT), Philipp Hofer (AT), Laura Poulbot (FR), Airan Berg (AT), Andrea Hummer (AT), Ilona Roth (DE/AT), Linda Huber (AT), Gisela Klammsteiner (AT), Sara Koniarek (AT), Simon Sharkey (GB), Valerio Iurato (IT), Doris Roth (DE), Alina Lugovskaya (UA/RU), Selina Nowak (AT), JeanClaude Grieco (AR/AT), Florian Böttcher (AT), Ethem Saygieder-Fischer (AT)"
|
||||||
|
span.easteregg {
|
||||||
|
", Marie Birner (Couch)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
blockquote {
|
||||||
p {
|
"Digital Shadows confronts visitors with their digital self – copied, measured, analyzed. An experiment on data power, visibility, and control in the digital age."
|
||||||
"Artists: René Mayrhofer (AT), Philipp Hofer (AT), Laura Poulbot (FR), Airan Berg (AT), Andrea Hummer (AT), Ilona Roth (DE/AT), Linda Huber (AT), Gisela Klammsteiner (AT), Sara Koniarek (AT), Simon Sharkey (GB), Valerio Iurato (IT), Doris Roth (DE), Alina Lugovskaya (UA/RU), Selina Nowak (AT), JeanClaude Grieco (AR/AT), Florian Böttcher (AT), Ethem Saygieder-Fischer (AT)"
|
footer {
|
||||||
span.easteregg {
|
cite { "— Digital Shadow Team" }
|
||||||
", Marie Birner (Couch)"
|
}
|
||||||
}
|
}
|
||||||
}
|
p {
|
||||||
blockquote {
|
"Digital Shadows invites the participants to experience questions of digital and physical identity, data security, and control. In immersive zones woven with choreographic elements, visitors encounter themselves mirrored, copied, measured and simultaneously lose themselves in a system that knows more about them than they intend to reveal. Between play and analysis, concealment and transparency, a reflection emerges on identity in the age of facial recognition, deepfakes, and algorithmic profiling. How does one fool a camera? How visible do I want to be? Who owns what I leave behind, and who profits from it? This experiment is a collaborative endeavor between science and art, making power, visibility, and self-determination in digital space tangible. Through an exploration of digital materiality and algorithmic intelligence, a sometimes absurd, always immediate reflection unfolds on our role in data-driven worlds until we face our digital dilemma, and the choice is still ours to make."
|
||||||
"Digital Shadows confronts visitors with their digital self – copied, measured, analyzed. An experiment on data power, visibility, and control in the digital age."
|
|
||||||
footer {
|
|
||||||
cite { "— Digital Shadow Team" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
"Digital Shadows invites the participants to experience questions of digital and physical identity, data security, and control. In immersive zones woven with choreographic elements, visitors encounter themselves mirrored, copied, measured and simultaneously lose themselves in a system that knows more about them than they intend to reveal. Between play and analysis, concealment and transparency, a reflection emerges on identity in the age of facial recognition, deepfakes, and algorithmic profiling. How does one fool a camera? How visible do I want to be? Who owns what I leave behind, and who profits from it? This experiment is a collaborative endeavor between science and art, making power, visibility, and self-determination in digital space tangible. Through an exploration of digital materiality and algorithmic intelligence, a sometimes absurd, always immediate reflection unfolds on our role in data-driven worlds until we face our digital dilemma, and the choice is still ours to make."
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
"What to do with this information?"
|
|
||||||
}
|
|
||||||
|
|
||||||
div.grid.gap-lg {
|
|
||||||
article {
|
|
||||||
header {
|
|
||||||
"Visit our booth"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"We will be delighted to see you at our booth in the Post City Linz, where our team will show you, what happens when your Digital Shadow becomes allmighty. "
|
h2 {
|
||||||
|
"What to do with this information?"
|
||||||
a href="https://www.jku.at/ars-electronica-2025-panic-yes-no/digital-shadows/" target="_blank" title="Go to JKU Information Page" {
|
|
||||||
"Find out more"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
div.grid.gap-lg {
|
||||||
"Where: Postcity Linz"
|
article {
|
||||||
}
|
header {
|
||||||
}
|
"Visit our booth"
|
||||||
article {
|
}
|
||||||
header {
|
|
||||||
"Play our game"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Ever wandered through Linz with the aim to find (hidden) cameras? Well, if you are that kind of person than our 'Discover cameras' game will be ideal for you! "
|
"We will be delighted to see you at our booth in the Post City Linz, where our team will show you, what happens when your Digital Shadow becomes allmighty. "
|
||||||
|
|
||||||
a href="/game" title="Go to Game Page" {
|
a href="https://www.jku.at/ars-electronica-2025-panic-yes-no/digital-shadows/" target="_blank" title="Go to JKU Information Page" {
|
||||||
"Find out more"
|
"Find out more"
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
"Where: all over Linz"
|
"Where: Postcity Linz"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
article {
|
||||||
|
header {
|
||||||
|
"Play our game"
|
||||||
|
}
|
||||||
|
|
||||||
|
"Ever wandered through Linz with the aim to find (hidden) cameras? Well, if you are that kind of person than our 'Discover cameras' game will be ideal for you! "
|
||||||
|
|
||||||
|
a href="/game" title="Go to Game Page" {
|
||||||
|
"Find out more"
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
"Where: all over Linz"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
lang,
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
|
use crate::Language;
|
||||||
use maud::{html, Markup, DOCTYPE};
|
use maud::{html, Markup, DOCTYPE};
|
||||||
|
|
||||||
// TODO: set dynamic meta lang attribute
|
// TODO: set dynamic meta lang attribute
|
||||||
|
|
||||||
pub fn new(content: Markup) -> Markup {
|
pub fn new(content: Markup, lang: Language) -> Markup {
|
||||||
html! {
|
html! {
|
||||||
(DOCTYPE)
|
(DOCTYPE)
|
||||||
head {
|
head {
|
||||||
|
Reference in New Issue
Block a user