use actix_web::{get, App, HttpServer, Result as AwResult}; use actix_files::Files; use maud::{DOCTYPE, html, Markup}; use std::io; use chrono::Local; #[derive(Clone)] struct NavElement { name: String, href: String, class: String } #[cfg(debug_assertions)] const URL: &str = "http://localhost:5050/api"; #[cfg(debug_assertions)] const STATIC: &str = "./static"; #[cfg(not(debug_assertions))] const URL: &str = "https://kate.breadlabs.de/api"; #[cfg(not(debug_assertions))] const STATIC: &str = "../../src/static"; fn head(page_title: &str) -> Markup { html! { (DOCTYPE) head { meta charset="utf-8"; title { (page_title) } link rel="icon" href={(format!("{}/neodog_laptop_notice.png", STATIC))}; link rel="stylesheet" href=(format!("{}/static/style.css", STATIC)); script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js" {} script { "htmx.config.selfRequestsOnly = false" } } } } fn nav_bar(mut elements: Vec, current: &str) -> Markup { elements.first_mut().map(|e| e.class.push_str(" first")); elements.last_mut().map(|e| e.class.push_str(" last")); elements.iter_mut().filter(|e| e.href == current).for_each(|e| e.class.push_str(" current")); html!( nav.navBar { @for (i, element) in elements.iter().enumerate() { ( nav_element(i, element) ) } } ) } fn nav_element(id: usize, element: &NavElement) -> Markup { html!( a class={( element.class.to_string() )} id={(format!("navElement-{}", id))} href={( element.href )} {( element.name )} ) } fn header(current: &str) -> Markup{ html!( header { (nav_bar(vec![ NavElement{ name: "breadsite".to_string(), href: "/".to_string(), class: String::from("navElement")}, NavElement{ name: "boop".to_string(), href: "/boop".to_string(), class: String::from("navElement")}, NavElement{ name: "waf".to_string(), href: "/waf".to_string(), class: String::from("navElement")}, ], current)) div class="htmx-indicator nowPlaying loading" hx-get={(format!("{}/now-playing", URL))} hx-swap="outerHTML" hx-trigger="load" { ". . ." } } ) } // TODOO: pawer 81x31 // TODOO: pawer links fn pawer() -> Markup { html! { pawer { ul { li {"fedi: " a href="https://plasmatrap.com/@bread" {"@plasmatrap.com@bread"}} br; br; li {sub {"paws...."}} } } } } // TODOOOO: about me // TODO: idea: heart rate monitor // TODO: idea: svg -> neocat generator fn breadsite() -> Markup { html! { h1 { "Hiiii" } } } fn boop() -> Markup { html! { h1 { "Boop me" } div class="boop timestamp" { (format!("boops since {}:",Local::now().format("%d/%m/%Y %H:%M UTC%Z"))) } div class="boop counter" #boop-counter hx-get={(format!("{}/boop", URL))} hx-trigger="load" {} div class="boop stack" { img class="boop unboop" src=(format!("{}/neodog.png", STATIC)) {} button class="boop button" hx-post={(format!("{}/boop", URL))} hx-trigger="mousedown throttle:300ms" hx-swap="swap:275ms" hx-target="#boop-counter" {} } } } fn waf() -> Markup { html! { h1 { "waf :3" } } } fn layout(page_title: &str, current: &str,site: Markup) -> Markup { html! { (head(page_title)) body class={(page_title)} { (header(current)) main {(site)} (pawer()) } } } #[get("/")] async fn breadsite_index() -> AwResult { Ok(html! { (layout("breadsite", "/", breadsite())) }) } #[get("/boop")] async fn breadsite_boop() -> AwResult { Ok(html! { (layout("boop", "/boop", boop())) }) } #[get("/waf")] async fn breadsite_waf() -> AwResult { Ok(html! { (layout("waf", "/waf", waf())) }) } #[actix_web::main] async fn main() -> io::Result<()> { HttpServer::new(|| App::new() .service(breadsite_index) .service(breadsite_boop) .service(breadsite_waf) .service(Files::new("/static", "./static")) ) .bind(("localhost", 8083))? .run() .await }