Fix bugs, add number buttons, add easter egg

This commit is contained in:
Amanda Graven 2025-12-11 20:34:58 +01:00
parent 972d18afbe
commit 80865ace7d
6 changed files with 2184 additions and 1261 deletions

3314
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -7,8 +7,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
dioxus = { version = "0.6.0", features = [] } dioxus = { version = "0.7.2", features = [] }
getrandom = { version = "0.2" } getrandom = "0.2"
rand = "0.8" rand = "0.8"
[features] [features]

BIN
assets/daniel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View file

@ -5,51 +5,63 @@ html, body, #main {
height: 100%; height: 100%;
} }
body { body {
background-color: #efeffc; background-color: #efeffc;
color: #000000; color: #000000;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
} }
main { main {
margin: auto; margin: auto;
max-width: 40rem; max-width: 40rem;
justify-content: space-between; justify-content: space-between;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
} }
table { table {
border-collapse: collapse; border-collapse: collapse;
border-spacing: 0; border-spacing: 0;
margin: 3rem 0; margin: 3rem 0;
} }
tr { tr {
border: 1px solid gray; border: 1px solid gray;
} }
td { td {
border: 1px solid gray; border: 1px solid gray;
text-align: center; text-align: center;
padding: 2px; padding: 2px;
} }
#controls { .controls {
margin: 3rem 0; margin: 3rem 0;
display: flex; display: flex;
flex-direction: column;
justify-items: stretch;
gap: 1rem;
}
.controls button {
flex: 1 1 auto;
font-size: larger;
font-weight: bold;
} }
#controls > * { .controls .number-buttons {
flex: 1 1 auto; display: flex;
justify-content: stretch;
gap: 1rem;
} }
.number { .number {
width: 1rem; width: 1rem;
animation: 1s ease-in-out 1s backwards number-scale; animation: 1s ease-in-out 1s backwards number-scale;
} }
@keyframes number-scale { @keyframes number-scale {
from { font-size: xx-large; } from { font-size: xx-large; }
to { font-size: initial; } to { font-size: initial; }
} }

View file

@ -6,6 +6,10 @@
text-shadow: 0 0 5px #000; text-shadow: 0 0 5px #000;
} }
.snowflake img {
width: 64px;
}
.snowflake, .snowflake,
.snowflake .inner { .snowflake .inner {
animation-iteration-count: infinite; animation-iteration-count: infinite;
@ -81,6 +85,7 @@
animation-delay: 6s animation-delay: 6s
} }
.snowflake:nth-of-type(12) .inner,
.snowflake:nth-of-type(3) { .snowflake:nth-of-type(3) {
left: 30%; left: 30%;
animation-delay: 2s animation-delay: 2s
@ -147,3 +152,12 @@
left: 65%; left: 65%;
animation-delay: 2.5s animation-delay: 2.5s
} }
.snowflake:nth-of-type(12) {
left: 5%;
animation-delay: 3.5s;
}
.snowflake:nth-of-type(13) {
left: -5%;
}

View file

@ -1,13 +1,16 @@
use std::cmp::max;
use dioxus::prelude::*; use dioxus::prelude::*;
use rand::Rng; use rand::Rng;
const FAVICON: Asset = asset!("/assets/icon.svg"); const FAVICON: Asset = asset!("/assets/icon.svg");
const MAIN_CSS: Asset = asset!("/assets/main.css"); const MAIN_CSS: Asset = asset!("/assets/main.css");
const SNOW_CSS: Asset = asset!("/assets/snow.css"); const SNOW_CSS: Asset = asset!("/assets/snow.css");
const DANIEL: Asset = asset!("/assets/daniel.png");
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
struct State { struct State {
pub rows: Vec<Vec<u8>>, pub rows: Vec<Vec<u16>>,
} }
impl State { impl State {
@ -19,6 +22,17 @@ impl State {
row.push(rand::thread_rng().gen_range(1..=6)); row.push(rand::thread_rng().gen_range(1..=6));
} }
pub fn push(&mut self, value: u16) {
if self.row_finished() {
return;
}
self.rows.last_mut().unwrap().push(value);
}
pub fn longest(&self) -> usize {
self.rows.iter().map(|row| row.len()).max().unwrap_or(0)
}
pub fn row_finished(&self) -> bool { pub fn row_finished(&self) -> bool {
match self.rows.last() { match self.rows.last() {
Some(row) => row.len() > 1 && row.last().copied() == Some(5), Some(row) => row.len() > 1 && row.last().copied() == Some(5),
@ -38,11 +52,28 @@ fn main() {
#[component] #[component]
fn App() -> Element { fn App() -> Element {
let mut rows = use_signal(State::default); let mut rows = use_signal(State::default);
let snow = false; let longest = use_memo(move || rows.read().longest());
let snow = true;
rsx! { rsx! {
document::Link { rel: "icon", href: FAVICON } document::Link { rel: "icon", href: FAVICON }
document::Link { rel: "stylesheet", href: MAIN_CSS } document::Link { rel: "stylesheet", href: MAIN_CSS }
document::Link { rel: "preconnect", href: "https://fonts.googleapis.com" }
document::Link { rel: "preconnect", href: "https://fonts.gstatic.com", crossorigin: "" }
document::Link { href: "https://fonts.googleapis.com/css2?family=Barlow+Semi+Condensed:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap", rel: "stylesheet" }
main { main {
onkeydown: move |event: Event<KeyboardData>| {
let number = match event.data.key() {
Key::Character(c) if c == "1" => 1,
Key::Character(c) if c == "2" => 2,
Key::Character(c) if c == "3" => 3,
Key::Character(c) if c == "4" => 4,
Key::Character(c) if c == "5" => 5,
Key::Character(c) if c == "6" => 6,
_ => return,
};
let Ok(mut rows) = rows.try_write() else { return };
rows.push(number);
},
table { table {
thead { thead {
for _ in 0..20 { for _ in 0..20 {
@ -60,12 +91,12 @@ fn App() -> Element {
} }
td { td {
class: "number", class: "number",
colspan: (19 - row.len()).to_string() colspan: (max(19, longest()).saturating_sub(row.len())).to_string()
} }
td { td {
class: "number", class: "number",
b { b {
{row.iter().copied().sum::<u8>().to_string()} {row.iter().copied().sum::<u16>().to_string()}
} }
} }
} }
@ -73,10 +104,22 @@ fn App() -> Element {
} }
} }
div { div {
id: "controls", class: "controls",
if rows.read().row_finished() { if rows.read().row_finished() {
button { onclick: move |_| rows.write().new_row(), "Start new row" } div {
class: "number-buttons",
for n in 1..=6 {
button { disabled: true, "{n}" }
}
}
button { onclick: move |_| rows.write().new_row(), "Start new row" }
} else { } else {
div {
class: "number-buttons",
for n in 1..=6 {
button { onclick: move |_| rows.write().push(n), "{n}" }
}
}
button { onclick: move |_| rows.write().roll(), "Roll" } button { onclick: move |_| rows.write().roll(), "Roll" }
} }
} }
@ -100,6 +143,10 @@ fn Snow() -> Element {
div { class: "inner", "" } div { class: "inner", "" }
} }
} }
div {
class: "snowflake",
img { class: "inner", src: DANIEL }
}
} }
} }
} }