From 3207c8ea57eac714417494e06ce0f82864b7ff1e Mon Sep 17 00:00:00 2001
From: Vika <vika@fireburn.ru>
Date: Sun, 20 Apr 2025 08:25:57 +0300
Subject: WIP: Theme support

Kittybox can now ship with several different stylesheets, provided by
the renderer. Unknown stylesheets fall back to the default one, which is
the same Kittybox has shipped since its inception.

There's also a settings field for custom CSS, but it's not exposed
anywhere yet.

Change-Id: I2850dace5c40f9fed04b4651c551a861df5b83d3
---
 templates/src/lib.rs       |  1 +
 templates/src/templates.rs |  6 +++---
 templates/src/themes.rs    | 25 +++++++++++++++++++++++++
 3 files changed, 29 insertions(+), 3 deletions(-)
 create mode 100644 templates/src/themes.rs

(limited to 'templates/src')

diff --git a/templates/src/lib.rs b/templates/src/lib.rs
index 0f9f7c6..194a837 100644
--- a/templates/src/lib.rs
+++ b/templates/src/lib.rs
@@ -10,6 +10,7 @@ mod mf2;
 pub use mf2::{Entry, Feed, Food, VCard, POSTS_PER_PAGE};
 pub mod admin;
 pub mod assets;
+pub mod themes;
 
 #[cfg(test)]
 mod tests {
diff --git a/templates/src/templates.rs b/templates/src/templates.rs
index 5772b4d..785a4b8 100644
--- a/templates/src/templates.rs
+++ b/templates/src/templates.rs
@@ -1,16 +1,16 @@
 #![allow(clippy::needless_lifetimes)]
-use crate::{Feed, VCard};
+use crate::{themes::ThemeName, Feed, VCard};
 use http::StatusCode;
 use kittybox_util::micropub::Channel;
 
 markup::define! {
-    Template<'a>(title: &'a str, blog_name: &'a str, feeds: Vec<Channel>, user: Option<&'a kittybox_indieauth::ProfileUrl>, content: String) {
+    Template<'a>(title: &'a str, blog_name: &'a str, feeds: Vec<Channel>, theme: ThemeName, user: Option<&'a kittybox_indieauth::ProfileUrl>, content: String) {
         @markup::doctype()
         html {
             head {
                 title { @title }
                 link[rel="preconnect", href="https://fonts.gstatic.com"];
-                link[rel="stylesheet", href="/.kittybox/static/style.css"];
+                link[rel="stylesheet", href=theme.into_css_link()];
                 meta[name="viewport", content="initial-scale=1, width=device-width"];
 
                 link[rel="micropub", href="/.kittybox/micropub"];
diff --git a/templates/src/themes.rs b/templates/src/themes.rs
new file mode 100644
index 0000000..ebc0ed9
--- /dev/null
+++ b/templates/src/themes.rs
@@ -0,0 +1,25 @@
+#[derive(Debug, Default, serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, Eq)]
+#[serde(rename_all = "snake_case")]
+/// Choices of themes possible in Kittybox.
+pub enum ThemeName {
+    #[default]
+    /// Default theme shipped with Kittybox.
+    Kittybox,
+    /// "Serious business" theme, typeset like a business memo.
+    VivianWork,
+    /// Emulation of the old style websites used back in the day.
+    Retro,
+    /// Custom CSS specified by user.
+    Custom,
+}
+
+impl ThemeName {
+    pub(crate) fn into_css_link(self) -> &'static str {
+        match self {
+            ThemeName::Kittybox => "/.kittybox/static/style.css",
+            ThemeName::VivianWork => "/.kittybox/static/vivian_work.style.css",
+            ThemeName::Retro => "/.kittybox/static/retro.style.css",
+            ThemeName::Custom => "/.kittybox/custom_style.css",
+        }
+    }
+}
-- 
cgit 1.4.1