feat: embed htmx

image-uploads
Jef Roosens 2024-12-28 15:25:13 +01:00
parent 35f1433e40
commit 412f4cd2c7
No known key found for this signature in database
GPG Key ID: 21FD3D77D56BAF49
6 changed files with 128 additions and 10 deletions

108
Cargo.lock generated
View File

@ -38,6 +38,21 @@ dependencies = [
"memchr",
]
[[package]]
name = "alloc-no-stdlib"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
[[package]]
name = "alloc-stdlib"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
dependencies = [
"alloc-no-stdlib",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
@ -53,6 +68,20 @@ dependencies = [
"libc",
]
[[package]]
name = "async-compression"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522"
dependencies = [
"brotli",
"flate2",
"futures-core",
"memchr",
"pin-project-lite",
"tokio",
]
[[package]]
name = "async-trait"
version = "0.1.83"
@ -167,6 +196,27 @@ dependencies = [
"generic-array",
]
[[package]]
name = "brotli"
version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
"brotli-decompressor",
]
[[package]]
name = "brotli-decompressor"
version = "4.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
]
[[package]]
name = "bstr"
version = "1.11.1"
@ -206,6 +256,7 @@ dependencies = [
"serde",
"tera",
"tokio",
"tower-http",
"tracing",
"tracing-subscriber",
]
@ -276,6 +327,15 @@ dependencies = [
"libc",
]
[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
@ -339,6 +399,16 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
[[package]]
name = "flate2"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
@ -369,6 +439,12 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "futures-sink"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
[[package]]
name = "futures-task"
version = "0.3.31"
@ -1254,6 +1330,19 @@ dependencies = [
"syn",
]
[[package]]
name = "tokio-util"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tower"
version = "0.5.2"
@ -1270,6 +1359,25 @@ dependencies = [
"tracing",
]
[[package]]
name = "tower-http"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697"
dependencies = [
"async-compression",
"bitflags",
"bytes",
"futures-core",
"http",
"http-body",
"pin-project-lite",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-layer"
version = "0.3.3"

View File

@ -11,5 +11,6 @@ r2d2_sqlite = "0.25.0"
serde = { version = "1.0.217", features = ["derive"] }
tera = "1.20.0"
tokio = { version = "1.42.0", features = ["full"] }
tower-http = { version = "0.6.2", features = ["compression-br", "compression-gzip"] }
tracing = "0.1.41"
tracing-subscriber = "0.3.19"

View File

@ -4,6 +4,7 @@ use std::sync::Arc;
use r2d2_sqlite::{rusqlite, SqliteConnectionManager};
use tera::Tera;
use tower_http::compression::CompressionLayer;
pub type DbPool = r2d2::Pool<SqliteConnectionManager>;
@ -11,6 +12,10 @@ const MIGRATIONS: [&str; 2] = [
include_str!("migrations/000_initial.sql"),
include_str!("migrations/001_plants.sql"),
];
const STATIC_FILES: [(&str, &'static str); 1] = [(
"htmx_2.0.4.min.js",
include_str!("static/htmx_2.0.4.min.js"),
)];
#[derive(Clone)]
pub struct Context {
@ -31,7 +36,7 @@ async fn main() {
pool,
tera: Arc::new(tera),
};
let app = server::app(ctx);
let app = server::app(ctx).layer(CompressionLayer::new().br(true).gzip(true));
let address = "0.0.0.0:8000";
@ -80,6 +85,7 @@ fn load_templates() -> Tera {
tera.add_raw_templates(vec![
("index.html", include_str!("templates/index.html")),
("plants_ul.html", include_str!("templates/plants_ul.html")),
("plant_li.html", include_str!("templates/plant_li.html")),
])
.unwrap();

View File

@ -30,10 +30,15 @@ impl TryFrom<&Row<'_>> for Plant {
}
pub fn app(ctx: crate::Context) -> axum::Router {
Router::new()
let mut router = Router::new()
.route("/", get(get_index))
.route("/plants", post(post_plants))
.with_state(ctx)
.route("/plants", post(post_plants));
for (name, content) in crate::STATIC_FILES {
router = router.route(&format!("/static/{}", name), get(content))
}
router.with_state(ctx)
}
async fn get_index(State(ctx): State<crate::Context>) -> Html<String> {

1
src/static/htmx_2.0.4.min.js vendored 100644

File diff suppressed because one or more lines are too long

View File

@ -1,15 +1,12 @@
<html>
<head>
<script src="https://unpkg.com/htmx.org@2.0.4" integrity="sha384-HGfztofotfshcF7+8n44JQL2oJmowVChPTg48S+jvZoztPfvwD79OC/LTtG6dMp+" crossorigin="anonymous"></script>
<script src="/static/htmx_2.0.4.min.js" integrity="sha384-HGfztofotfshcF7+8n44JQL2oJmowVChPTg48S+jvZoztPfvwD79OC/LTtG6dMp+"></script>
</head>
<body>
<h1>Calathea</h1>
<h2>Plants</h2>
<ul id="plants">
{% for plant in plants %}
<li>{{ plant.name }} ({{ plant.species }})</li>
{% endfor %}
</ul>
{% include "plants_ul.html" %}
<h3>Add new plant</h3>
<form hx-post="/plants" hx-target="#plants" hx-swap="beforeend">
<label for="name">Name:</label>
<input type="text" id="name" name="name"></br>