From eb85449d673f56821613ca261adc17499681dda3 Mon Sep 17 00:00:00 2001 From: Bartal Laearsson Date: Mon, 24 Aug 2026 13:49:35 +0100 Subject: [PATCH] some frontend fixes --- .gitignore | 1 + Cargo.lock | 182 ++++++++++++++++++++++++++++----------- Cargo.toml | 5 +- justfile | 1 + src/main.rs | 47 ++++++++-- static/css/index.css | 18 +++- static/css/supporter.css | 5 ++ static/css/user.css | 2 +- 8 files changed, 197 insertions(+), 64 deletions(-) diff --git a/.gitignore b/.gitignore index eb5a316..d9d9c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ target +local/ diff --git a/Cargo.lock b/Cargo.lock index ae6942e..0e7591e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,6 +152,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + [[package]] name = "bumpalo" version = "3.20.3" @@ -201,6 +210,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -216,6 +231,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crypto-common" version = "0.1.7" @@ -226,6 +250,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -251,8 +284,19 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "crypto-common", + "block-buffer 0.10.4", + "crypto-common 0.1.7", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", ] [[package]] @@ -387,12 +431,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "http-range-header" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" - [[package]] name = "httparse" version = "1.10.1" @@ -405,6 +443,15 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hybrid-array" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "0.14.32" @@ -788,6 +835,41 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" +[[package]] +name = "rust-embed" +version = "8.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa66af4a4fdd5e7ebc276f115e895611a34739a9c1c01028383d612d550953c0" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcfc4d6f53af43755f7a723e4b6b8794fcce052a178dd8c6c1dadc5f5343097" +dependencies = [ + "mime_guess", + "proc-macro2", + "quote", + "rust-embed-utils", + "syn", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ffa149f6aa81b58a5b3011d01a857c4ed12c7a732d2c51947a4c7c692185f0" +dependencies = [ + "sha2", + "walkdir", +] + [[package]] name = "rustc-demangle" version = "0.1.27" @@ -806,6 +888,15 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -872,8 +963,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -1026,19 +1128,6 @@ dependencies = [ "tungstenite", ] -[[package]] -name = "tokio-util" -version = "0.7.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - [[package]] name = "tower" version = "0.4.13" @@ -1055,31 +1144,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "tower-http" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" -dependencies = [ - "bitflags 2.13.0", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "httpdate", - "mime", - "mime_guess", - "percent-encoding", - "pin-project-lite", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tower-layer" version = "0.3.3" @@ -1231,11 +1295,12 @@ dependencies = [ "chrono", "dashmap", "idna 0.5.0", + "mime_guess", + "rust-embed", "serde", "serde_json", "tokio", "tower", - "tower-http", "tracing", "tracing-subscriber", "url", @@ -1269,6 +1334,16 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -1345,6 +1420,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index af714b7..ccd117c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,6 @@ edition = "2024" [dependencies] axum = { version = "=0.6.20", features = ["ws"] } tokio = { version = "=1.35.1", features = ["full"] } -tower-http = { version = "=0.4.4", features = ["fs"] } tower = { version = "=0.4.13", features = ["util"] } serde = { version = "=1.0.197", features = ["derive"] } serde_json = "=1.0.115" @@ -17,10 +16,12 @@ tracing-subscriber = { version = "=0.3.18", features = ["env-filter"] } chrono = { version = "=0.4.35", features = ["serde"] } url = "=2.4.1" idna = "=0.5.0" +rust-embed = "=8.5.0" +mime_guess = "=2.0.5" [profile.release] opt-level = 3 lto = true codegen-units = 1 panic = "abort" -strip = true +strip = true diff --git a/justfile b/justfile index fc4c601..bc8ffb4 100644 --- a/justfile +++ b/justfile @@ -10,6 +10,7 @@ default: build: clippy fmt build-release build-release: + touch src/main.rs cargo build --release deploy: build diff --git a/src/main.rs b/src/main.rs index fcf53eb..3d7a983 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,14 +4,36 @@ mod state; use axum::{ Router, + http::{StatusCode, Uri, header}, + response::IntoResponse, routing::{get, post}, }; -use std::{net::SocketAddr, sync::Arc}; -use tower_http::services::ServeDir; +use rust_embed::RustEmbed; +use std::{borrow::Cow, net::SocketAddr, sync::Arc}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; use state::{AppState, CHAT_RESET_INTERVAL}; +#[derive(RustEmbed)] +#[folder = "static/"] +struct StaticAsset; + +async fn static_handler(uri: Uri) -> impl IntoResponse { + let path = uri.path().trim_start_matches('/'); + match StaticAsset::get(path) { + Some(content) => { + let mime = mime_guess::from_path(path).first_or_octet_stream(); + ( + StatusCode::OK, + [(header::CONTENT_TYPE, mime.as_ref())], + Cow::into_owned(content.data), + ) + .into_response() + } + None => (StatusCode::NOT_FOUND, "asset not found").into_response(), + } +} + #[tokio::main] async fn main() { tracing_subscriber::registry() @@ -34,12 +56,13 @@ async fn main() { } }); + let static_router = Router::new().route("/*path", get(static_handler)); + let app = Router::new() .route("/", get(handlers::pages::index_page)) .route("/user", get(handlers::pages::user_page)) .route("/supporter", get(handlers::pages::supporter_page)) .route("/reset-countdown", get(handlers::pages::reset_countdown)) - // New API endpoint for creating sessions without a form .route("/api/session/create", post(handlers::chat::create_session)) .route("/ws/user/:session_id", get(handlers::ws::user_ws)) .route( @@ -57,15 +80,21 @@ async fn main() { post(handlers::chat::supporter_send_message), ) .route("/sessions", get(handlers::chat::get_sessions)) - // Removed: .route("/sessions/new", post(handlers::chat::new_session)) - .nest_service("/static", ServeDir::new("static")) + .nest("/static", static_router) .with_state(state); - let listener = tokio::net::TcpListener::bind("0.0.0.0:3111").await.unwrap(); + let listener = tokio::net::TcpListener::bind("0.0.0.0:3111") + .await + .expect("failed to bind listener on 0.0.0.0:3111"); tracing::info!("Chat service running — http://0.0.0.0:3111"); - axum::Server::from_tcp(listener.into_std().unwrap()) - .unwrap() + + let std_listener = listener + .into_std() + .expect("failed to convert TcpListener to std"); + + axum::Server::from_tcp(std_listener) + .expect("failed to create axum server from TCP listener") .serve(app.into_make_service_with_connect_info::()) .await - .unwrap(); + .expect("server error"); } diff --git a/static/css/index.css b/static/css/index.css index dfed89a..a78bbe8 100644 --- a/static/css/index.css +++ b/static/css/index.css @@ -1,13 +1,25 @@ +html, body { + height: 100%; + height: 100dvh; + overflow: hidden; +} + +body { + display: flex; + flex-direction: column; +} + .page-body { flex: 1; display: flex; align-items: center; justify-content: center; - padding: calc(65px + 2.5rem) 2rem 4rem; - min-height: 100vh; - min-height: 100dvh; + padding: calc(65px + 2rem) 2rem 2rem; + min-height: 0; } + + .card { width: min(560px, 100%); background: var(--bg-panel); diff --git a/static/css/supporter.css b/static/css/supporter.css index b138658..6f8993f 100644 --- a/static/css/supporter.css +++ b/static/css/supporter.css @@ -502,3 +502,8 @@ body { #supporter-messages { padding: 0.75rem; } .theme-toggle { width: 20px; height: 20px; bottom: 1rem; right: 0.75rem; } } + +@keyframes typing-bounce { + 0%, 75%, 100% { transform: translateY(0); opacity: 0.45; } + 35% { transform: translateY(-4px); opacity: 1; } +} diff --git a/static/css/user.css b/static/css/user.css index b9f2db9..2f3fccb 100644 --- a/static/css/user.css +++ b/static/css/user.css @@ -28,7 +28,7 @@ body { font-weight: 500; letter-spacing: 0.08em; background: var(--danger-soft); - z-index: 10; + z-index: 25; white-space: nowrap; }