summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Hafskjold Thoresen <martin@vind.ai>2025-01-10 18:25:19 +0100
committerMartin Hafskjold Thoresen <martin@vind.ai>2025-01-10 18:25:19 +0100
commited791666b2575fd1e60934f0a178441e063bdfca (patch)
tree9717dfb23b44e7f7338cd5f73db320b506483522 /src
parente249e3003b569c7e3b270c06e02b87cad86ea2fb (diff)
downloadmusicgame-ed791666b2575fd1e60934f0a178441e063bdfca.tar.gz
musicgame-ed791666b2575fd1e60934f0a178441e063bdfca.zip
The game works!
Diffstat (limited to 'src')
-rw-r--r--src/main.rs47
1 files changed, 44 insertions, 3 deletions
diff --git a/src/main.rs b/src/main.rs
index 3c98db2..2f8d5a5 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -20,7 +20,7 @@ use axum::{
use axum_extra::extract::CookieJar;
use maud::{html, Markup, PreEscaped, DOCTYPE};
use rand::random;
-use serde::Deserialize;
+use serde::{Deserialize, Serialize};
use tokio::sync::{
broadcast::{self, Receiver, Sender},
Mutex,
@@ -50,7 +50,7 @@ fn handle_panic(err: Box<dyn std::any::Any + Send + 'static>) -> Response {
#[derive(Hash, Eq, PartialEq, Copy, Clone, Debug, PartialOrd, Ord, Deserialize)]
struct UserId(u64);
-#[derive(Deserialize, Debug, Clone)]
+#[derive(Serialize, Deserialize, Debug, Clone)]
struct NoteDatum {
// Epoch time in ms
time: u64,
@@ -239,6 +239,18 @@ impl Game {
};
let gid = self.id;
+ let Some(notes) = self.submissions.get(&r.author) else {
+ return html! {
+ h1 { "No song!" }
+ p { "This user didn't submit anything!" }
+ };
+ };
+
+ let notes_json = serde_json::to_value(&notes.notes)
+ .context("Convert to json should work")
+ .unwrap()
+ .to_string();
+
html! {
h1 { (format!("Round {i}/{n}"))}
p { "Author was " (r.author.0)}
@@ -246,6 +258,35 @@ impl Game {
input placeholder="Your guess..." name="guess" {};
input type="submit" hx-post=(format!("/game/{gid}/guess")) hx-target="#form-guess" {};
}
+
+ script { (PreEscaped(format!(r#"
+const notes = {notes_json};
+{}"#, r#"
+const context = new AudioContext();
+
+function loadSample(url) {
+ return fetch(url)
+ .then(response => response.arrayBuffer())
+ .then(buffer => context.decodeAudioData(buffer));
+}
+
+function playSoundSample(sample, sampleNote, noteToPlay) {
+ const source = context.createBufferSource();
+ source.buffer = sample;
+ source.playbackRate.value = 2 ** ((noteToPlay - sampleNote) / 12);
+ source.connect(context.destination);
+ source.start(0);
+}
+
+const soundUrl = "/static/dog.mp3";
+loadSample(soundUrl).then((sample) => {
+ const t0 = notes[0].time - 1_000;
+ notes.forEach(({time, y}) => {
+ const pitch = 60 + 12 * y;
+ setTimeout(() => playSoundSample(sample, 60, pitch), time - t0);
+ });
+});
+"#)))}
}
}
@@ -275,7 +316,7 @@ impl Game {
data-accept=(accept)
hx-post=(post)
hx-swap="outerHTML"
- { (g) }
+ { (g) " (click to toggle)"}
}
}