| d23464c0 Andy McCall ↶ |
1 |
|
| 2 |
|
| 3 |
use axum::extract::Path; |
| 4 |
use axum::http::{header, StatusCode}; |
| 5 |
use axum::response::{IntoResponse, Response}; |
| 6 |
|
| 7 |
const CSS: &str = include_str!("../../../../templates/style.css"); |
| 8 |
const FAVICON: &str = include_str!("../../../../assets/icons/oxygenhub.svg"); |
| 9 |
|
| 8e820b4a Andy McCall ↶ |
10 |
|
| 11 |
|
| 12 |
|
| 13 |
|
| 14 |
pub fn assets_version() -> &'static str { |
| 15 |
static V: std::sync::OnceLock<String> = std::sync::OnceLock::new(); |
| 16 |
V.get_or_init(|| { |
| 17 |
let mut h = blake3::Hasher::new(); |
| 18 |
h.update(CSS.as_bytes()); |
| 19 |
for a in ASSETS.iter().filter(|a| a.path == "github.css" || a.path == "hub.js") { |
| 20 |
h.update(a.bytes); |
| 21 |
} |
| 22 |
h.finalize().to_hex()[..12].to_string() |
| 23 |
}) |
| 24 |
} |
| 25 |
|
| d23464c0 Andy McCall ↶ |
26 |
struct Asset { |
| 27 |
path: &'static str, |
| 28 |
mime: &'static str, |
| 29 |
bytes: &'static [u8], |
| 30 |
} |
| 31 |
|
| 32 |
const ASSETS: &[Asset] = &[ |
| 33 |
Asset { path: "fonts/Barlow-300.woff2", mime: "font/woff2", bytes: include_bytes!("../../../../assets/fonts/Barlow-300.woff2") }, |
| 34 |
Asset { path: "fonts/Barlow-400.woff2", mime: "font/woff2", bytes: include_bytes!("../../../../assets/fonts/Barlow-400.woff2") }, |
| 35 |
Asset { path: "fonts/Barlow-500.woff2", mime: "font/woff2", bytes: include_bytes!("../../../../assets/fonts/Barlow-500.woff2") }, |
| 36 |
Asset { path: "fonts/Barlow-600.woff2", mime: "font/woff2", bytes: include_bytes!("../../../../assets/fonts/Barlow-600.woff2") }, |
| 37 |
Asset { |
| 38 |
path: "fonts/PressStart2P-400.woff2", |
| 39 |
mime: "font/woff2", |
| 40 |
bytes: include_bytes!("../../../../assets/fonts/PressStart2P-400.woff2"), |
| 41 |
}, |
| 749d9a5f Andy McCall ↶ |
42 |
Asset { path: "github.css", mime: "text/css; charset=utf-8", bytes: include_bytes!("../../../../assets/github.css") }, |
| d23464c0 Andy McCall ↶ |
43 |
Asset { path: "hub.js", mime: "text/javascript; charset=utf-8", bytes: include_bytes!("../../../../assets/hub.js") }, |
| 14530604 Andy McCall ↶ |
44 |
Asset { |
| 45 |
path: "vendor/editor.js", |
| 46 |
mime: "text/javascript; charset=utf-8", |
| 47 |
bytes: include_bytes!("../../../../assets/vendor/editor.js"), |
| 48 |
}, |
| 49 |
Asset { |
| 50 |
path: "vendor/easymde.min.js", |
| 51 |
mime: "text/javascript; charset=utf-8", |
| 52 |
bytes: include_bytes!("../../../../assets/vendor/easymde.min.js"), |
| 53 |
}, |
| 84751769 Andy McCall ↶ |
54 |
|
| 55 |
|
| 56 |
|
| 14530604 Andy McCall ↶ |
57 |
Asset { |
| 84751769 Andy McCall ↶ |
58 |
path: "vendor/mermaid.min.js", |
| 59 |
mime: "text/javascript; charset=utf-8", |
| 60 |
bytes: include_bytes!("../../../../assets/vendor/mermaid.min.js"), |
| 61 |
}, |
| 62 |
Asset { |
| 14530604 Andy McCall ↶ |
63 |
path: "vendor/easymde.min.css", |
| 64 |
mime: "text/css; charset=utf-8", |
| 65 |
bytes: include_bytes!("../../../../assets/vendor/easymde.min.css"), |
| 66 |
}, |
| d23464c0 Andy McCall ↶ |
67 |
]; |
| 68 |
|
| 69 |
const CACHE: &str = "public, max-age=86400"; |
| 70 |
|
| 71 |
pub async fn style() -> Response { |
| 72 |
([(header::CONTENT_TYPE, "text/css; charset=utf-8"), (header::CACHE_CONTROL, CACHE)], CSS).into_response() |
| 73 |
} |
| 74 |
|
| 75 |
pub async fn favicon() -> Response { |
| 76 |
([(header::CONTENT_TYPE, "image/svg+xml"), (header::CACHE_CONTROL, CACHE)], FAVICON).into_response() |
| 77 |
} |
| 78 |
|
| 79 |
pub async fn asset(Path(path): Path<String>) -> Response { |
| 80 |
match ASSETS.iter().find(|a| a.path == path) { |
| 81 |
Some(a) => { |
| 82 |
([(header::CONTENT_TYPE, a.mime), (header::CACHE_CONTROL, "public, max-age=31536000, immutable")], a.bytes).into_response() |
| 83 |
} |
| 84 |
None => StatusCode::NOT_FOUND.into_response(), |
| 85 |
} |
| 86 |
} |