calathea/src/server/mod.rs

60 lines
1.8 KiB
Rust

mod comments;
mod plants;
use axum::{
extract::State,
http::{header::VARY, HeaderMap, HeaderValue},
response::Html,
routing::get,
Router,
};
use tera::Context;
use tower_http::set_header::SetResponseHeaderLayer;
use crate::db::Plant;
const HX_REQUEST_HEADER: &str = "HX-Request";
const HX_HISTORY_RESTORE_HEADER: &str = "HX-History-Restore-Request";
pub fn render_partial(headers: &HeaderMap) -> bool {
let is_htmx_req = headers.get(HX_REQUEST_HEADER).is_some();
let is_hist_restore_req = headers
.get(HX_HISTORY_RESTORE_HEADER)
.map(|val| val == HeaderValue::from_static("true"))
.unwrap_or(false);
is_htmx_req && !is_hist_restore_req
}
pub fn app(ctx: crate::Context) -> axum::Router {
let mut router = Router::new()
.route("/", get(get_index))
.with_state(ctx.clone())
.nest("/plants", plants::app(ctx.clone()))
.nest("/comments", comments::app(ctx.clone()));
for (name, content) in crate::STATIC_FILES {
router = router.route(&format!("/static/{}", name), get(content))
}
// Routes return either partial or full pages depending on whether the request is done using
// HTMX or just as a plain HTTP request. Adding the Vary header ensures caches don't mix
// partial and full responses.
// https://htmx.org/docs/#caching
router.layer(SetResponseHeaderLayer::appending(
VARY,
HeaderValue::from_static(HX_REQUEST_HEADER),
))
}
async fn get_index(State(ctx): State<crate::Context>) -> Html<String> {
let plants = tokio::task::spawn_blocking(move || Plant::all(&ctx.pool))
.await
.unwrap()
.unwrap();
let mut context = Context::new();
context.insert("plants", &plants);
Html(ctx.tera.render("index.html", &context).unwrap())
}