Feat: simple html frontend

This commit is contained in:
Dorian Zedler 2023-03-11 22:45:14 +01:00
parent 65401700c0
commit e496324049
Signed by: dozedler
GPG key ID: 989DE36109AFA354
9 changed files with 253 additions and 5 deletions

View file

@ -1,27 +1,45 @@
use axum::{extract::Query, routing::get, Router};
use cairo::{Context, Format, ImageSurface};
use serde::Deserialize;
use serde::{de, Deserialize};
use crate::{polygon, SharedState};
use crate::{color::Color, polygon, SharedState};
fn default_as_false() -> bool {
false
}
fn deserialize_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
D: de::Deserializer<'de>,
{
let s: &str = de::Deserialize::deserialize(deserializer)?;
match s {
"true" | "on" => Ok(true),
"false" | "off" => Ok(false),
_ => Err(de::Error::unknown_variant(
s,
&["true", "on", "false", "off"],
)),
}
}
#[derive(Deserialize)]
struct ImageProperties {
#[serde(default = "default_as_false")]
#[serde(deserialize_with = "deserialize_bool")]
dark_mode: bool,
background_color: Option<Color>,
}
async fn handler(Query(properties): Query<ImageProperties>) -> impl axum::response::IntoResponse {
let surface = ImageSurface::create(Format::ARgb32, 400, 400).unwrap();
let context = Context::new(&surface).unwrap();
if properties.dark_mode {
context.set_source_rgb(0.0, 0.0, 0.0);
if let Some(c) = properties.background_color {
context.set_source_rgb(c.r as f64 / 255.0, c.g as f64 / 255.0, c.b as f64 / 255.0);
} else {
context.set_source_rgb(1.0, 1.0, 1.0);
context.set_source_rgba(0.0, 0.0, 0.0, 0.0);
}
context.paint().unwrap();

View file

@ -1,2 +1,3 @@
pub mod favicon;
pub mod logo;
pub mod static_files;

View file

@ -0,0 +1,56 @@
use axum::{
body::{boxed, Full},
http::{header, StatusCode, Uri},
response::{IntoResponse, Response},
Router,
};
use rust_embed::{EmbeddedFile, RustEmbed};
use crate::SharedState;
#[derive(RustEmbed)]
#[folder = "static"]
struct StaticFiles;
async fn static_files(uri: Uri) -> impl IntoResponse {
let path = uri.path().trim_start_matches('/');
match StaticFiles::get(path) {
Some(file) => response(file, path),
None => {
if uri.path() == "/" {
index()
} else {
not_found()
}
}
}
}
fn index() -> Response {
match StaticFiles::get("index.html") {
Some(file) => response(file, "index.html"),
None => not_found(),
}
}
fn response(file: EmbeddedFile, path: &str) -> Response {
let body = boxed(Full::from(file.data));
let mime = mime_guess::from_path(path).first_or_octet_stream();
Response::builder()
.header(header::CONTENT_TYPE, mime.as_ref())
.body(body)
.unwrap()
}
fn not_found() -> Response {
Response::builder()
.status(StatusCode::NOT_FOUND)
.body(boxed(Full::from("404")))
.unwrap()
}
pub fn routes() -> Router<SharedState> {
Router::new().fallback(static_files)
}