about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2025-04-20 09:16:35 +0300
committerVika <vika@fireburn.ru>2025-04-20 10:01:04 +0300
commitb02882d1d586dbc481a4c002e6e9a5892daabc9f (patch)
tree194b30281834c536493b23a09344f3ef3e98ac11
parent3207c8ea57eac714417494e06ce0f82864b7ff1e (diff)
downloadkittybox-b02882d1d586dbc481a4c002e6e9a5892daabc9f.tar.zst
Expose custom CSS as a route feature/themes
The admin dashboard (that's not done yet) should include methods for
setting this field. For now, it could very well be set through editing
the database manually. #ManualUntilItHurts

Change-Id: Ibef6fca5f1d19f237e660bf3a13b4d72c8c08a0a
-rw-r--r--src/database/settings.rs17
-rw-r--r--src/frontend/mod.rs23
-rw-r--r--src/lib.rs4
3 files changed, 44 insertions, 0 deletions
diff --git a/src/database/settings.rs b/src/database/settings.rs
index 77e5821..46346cc 100644
--- a/src/database/settings.rs
+++ b/src/database/settings.rs
@@ -80,3 +80,20 @@ impl Setting for Theme {
         Self(data)
     }
 }
+
+#[derive(Debug, Default, serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq)]
+/// Custom stylesheet for Kittybox, activated by setting the theme to [`ThemeName::Custom`].
+pub struct CustomCss(String);
+impl private::Sealed for CustomCss {}
+impl Setting for CustomCss {
+    type Data = String;
+    const ID: &'static str = "custom_css";
+
+    fn into_inner(self) -> String {
+        self.0
+    }
+
+    fn new(data: Self::Data) -> Self {
+        Self(data)
+    }
+}
diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs
index a05c91d..3a23ad9 100644
--- a/src/frontend/mod.rs
+++ b/src/frontend/mod.rs
@@ -241,6 +241,29 @@ async fn get_post_from_database<S: Storage>(
 }
 
 #[tracing::instrument(skip(db))]
+pub async fn custom_css<D: Storage>(Host(host): Host, State(db): State<D>) -> impl IntoResponse {
+    // This is stupid, but there is no other way.
+    let hcard_url: url::Url = format!("https://{}/", host).parse().unwrap();
+    match db
+        .get_setting::<crate::database::settings::CustomCss>(&hcard_url)
+        .await
+    {
+        Ok(css) => {
+            let css = css.into_inner();
+            if css.is_empty() {
+                StatusCode::NOT_FOUND.into_response()
+            } else {
+                (StatusCode::OK, [("Content-Type", "text/css")], css).into_response()
+            }
+        }
+        Err(err) => {
+            tracing::warn!("Failed to get custom CSS: {}", err);
+            StatusCode::INTERNAL_SERVER_ERROR.into_response()
+        }
+    }
+}
+
+#[tracing::instrument(skip(db))]
 pub async fn homepage<D: Storage>(
     Host(host): Host,
     Query(query): Query<QueryParams>,
diff --git a/src/lib.rs b/src/lib.rs
index 0df5e5d..c32137b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -273,6 +273,10 @@ where
             "/.kittybox/static/{*path}",
             axum::routing::get(crate::frontend::statics),
         )
+        .route(
+            "/.kittybox/custom_style.css",
+            get(crate::frontend::custom_css::<S>),
+        )
         .route("/.kittybox/coffee", get(teapot_route))
         .nest(
             "/.kittybox/micropub/client",