From 60c7b6b23fcbbe77f36d12040195e4a04e40a606 Mon Sep 17 00:00:00 2001 From: mikupls <93015331+mikupls@users.noreply.github.com> Date: Sat, 21 May 2022 03:41:31 +0200 Subject: [PATCH] Embed css themes to simplify adding and testing new themes (#489) --- Cargo.lock | 126 ++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/main.rs | 21 +++++- src/utils.rs | 15 +++++ static/style.css | 119 +--------------------------------- static/themes/black.css | 14 ++++ static/themes/dracula.css | 14 ++++ static/themes/gold.css | 14 ++++ static/themes/laserwave.css | 14 ++++ static/themes/light.css | 14 ++++ static/themes/nord.css | 14 ++++ static/themes/rosebox.css | 13 ++++ static/themes/violet.css | 14 ++++ templates/settings.html | 2 +- 14 files changed, 274 insertions(+), 121 deletions(-) create mode 100644 static/themes/black.css create mode 100644 static/themes/dracula.css create mode 100644 static/themes/gold.css create mode 100644 static/themes/laserwave.css create mode 100644 static/themes/light.css create mode 100644 static/themes/nord.css create mode 100644 static/themes/rosebox.css create mode 100644 static/themes/violet.css diff --git a/Cargo.lock b/Cargo.lock index 58439fa..dea7b0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,6 +100,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.9.1" @@ -207,6 +216,15 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "cpufeatures" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + [[package]] name = "darling" version = "0.13.4" @@ -242,6 +260,15 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "fastrand" version = "1.7.0" @@ -371,6 +398,16 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "h2" version = "0.3.13" @@ -561,6 +598,7 @@ dependencies = [ "hyper-rustls", "regex", "route-recognizer", + "rust-embed", "serde", "serde_json", "time", @@ -668,6 +706,12 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "openssl-probe" version = "0.1.5" @@ -792,6 +836,40 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" +[[package]] +name = "rust-embed" +version = "6.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a17e5ac65b318f397182ae94e532da0ba56b88dd1200b774715d36c4943b1c3" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94e763e24ba2bf0c72bc6be883f967f794a019fafd1b86ba1daff9c91a7edd30" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756feca3afcbb1487a1d01f4ecd94cf8ec98ea074c55a69e7136d29fb6166029" +dependencies = [ + "sha2", + "walkdir", +] + [[package]] name = "rustls" version = "0.20.5" @@ -831,6 +909,15 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.19" @@ -911,6 +998,19 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -1124,6 +1224,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + [[package]] name = "unicase" version = "2.6.0" @@ -1184,6 +1290,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + [[package]] name = "want" version = "0.3.0" @@ -1290,6 +1407,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index b55c1d1..0745fb4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,4 @@ serde_json = "1.0.81" tokio = { version = "1.18.2", features = ["full"] } time = "0.3.9" url = "2.2.2" +rust-embed="6.4.0" diff --git a/src/main.rs b/src/main.rs index 7efa558..dc78a0b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ use hyper::{header::HeaderValue, Body, Request, Response}; mod client; use client::proxy; use server::RequestExt; -use utils::{error, redirect}; +use utils::{error, redirect, ThemeAssets}; mod server; @@ -85,6 +85,23 @@ async fn resource(body: &str, content_type: &str, cache: bool) -> Result Result, String> { + let mut res = include_str!("../static/style.css").to_string(); + for file in ThemeAssets::iter() { + res.push_str("\n"); + let theme = ThemeAssets::get(file.as_ref()).unwrap(); + res.push_str(std::str::from_utf8(theme.data.as_ref()).unwrap()); + } + Ok( + Response::builder() + .status(200) + .header("content-type", "text/css") + .header("Cache-Control", "public, max-age=1209600, s-maxage=86400") + .body(res.to_string().into()) + .unwrap_or_default(), + ) +} + #[tokio::main] async fn main() { let matches = Command::new("Libreddit") @@ -152,7 +169,7 @@ async fn main() { } // Read static files - app.at("/style.css").get(|_| resource(include_str!("../static/style.css"), "text/css", false).boxed()); + app.at("/style.css").get(|_| style().boxed()); app .at("/manifest.json") .get(|_| resource(include_str!("../static/manifest.json"), "application/json", false).boxed()); diff --git a/src/utils.rs b/src/utils.rs index 56a7de7..419e384 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -11,6 +11,7 @@ use std::collections::{HashMap, HashSet}; use std::str::FromStr; use time::{Duration, OffsetDateTime, macros::format_description}; use url::Url; +use rust_embed::RustEmbed; // Post flair with content, background color and foreground color pub struct Flair { @@ -445,6 +446,7 @@ pub struct Params { #[derive(Default)] pub struct Preferences { + pub available_themes: Vec, pub theme: String, pub front_page: String, pub layout: String, @@ -459,10 +461,23 @@ pub struct Preferences { pub filters: Vec, } +#[derive(RustEmbed)] +#[folder = "static/themes/"] +#[include = "*.css"] +pub struct ThemeAssets; + impl Preferences { // Build preferences from cookies pub fn new(req: Request) -> Self { + // Read available theme names from embedded css files. + // Always make the default "system" theme available. + let mut themes = vec!["system".to_string()]; + for file in ThemeAssets::iter() { + let chunks: Vec<&str> = file.as_ref().split(".css").collect(); + themes.push(chunks[0].to_owned()) + } Self { + available_themes: themes, theme: setting(&req, "theme"), front_page: setting(&req, "front_page"), layout: setting(&req, "layout"), diff --git a/static/style.css b/static/style.css index dc2a6de..664caee 100644 --- a/static/style.css +++ b/static/style.css @@ -45,124 +45,7 @@ } } -/* Light theme setting */ -.light { - --accent: #009a9a; - --green: #00a229; - --text: black; - --foreground: #f5f5f5; - --background: #ddd; - --outside: #ececec; - --post: #eee; - --panel-border: 1px solid #ccc; - --highlighted: white; - --visited: #555; - --shadow: 0 1px 3px rgba(0, 0, 0, 0.1); -} - -/* Black theme setting */ -.black { - --accent: #009a9a; - --green: #00a229; - --text: white; - --foreground: #0f0f0f; - --background: black; - --outside: black; - --post: black; - --panel-border: 2px solid #0f0f0f; - --highlighted: #0f0f0f; - --visited: #aaa; - --shadow: 0 1px 3px rgba(0, 0, 0, 0.1); -} - -/* Dracula theme setting */ -.dracula { - --accent: #bd93f9; - --green: #50fa7b; - --text: #f8f8f2; - --foreground: #3d4051; - --background: #282a36; - --outside: #393c4d; - --post: #333544; - --panel-border: 2px solid #44475a; - --highlighted: #4e5267; - --visited: #969692; - --shadow: 0 1px 3px rgba(0, 0, 0, 0.1); -} - -/* Nord theme setting */ -.nord { - --accent: #8fbcbb; - --green: #a3be8c; - --text: #eceff4; - --foreground: #3b4252; - --background: #2e3440; - --outside: #434c5e; - --post: #434c5e; - --panel-border: 2px solid #4c566a; - --highlighted: #3b4252; - --visited: #a3a5aa; - --shadow: 0 1px 3px rgba(0, 0, 0, 0.1); -} - -/* Laserwave theme setting */ -.laserwave { - --accent: #eb64b9; - --green: #74dfc4; - --text: #e0dfe1; - --foreground: #302a36; - --background: #27212e; - --outside: #3e3647; - --post: #3e3647; - --panel-border: 2px solid #2f2738; - --highlighted: #302a36; - --visited: #91889b; - --shadow: 0 1px 3px rgba(0, 0, 0, 0.1); -} - -/* Violet theme setting */ -.violet { - --accent: #7c71dd; - --green: #5cff85; - --text: white; - --foreground: #1F2347; - --background: #12152b; - --outside: #181c3a; - --post: #181c3a; - --panel-border: 1px solid #1F2347; - --highlighted: #1F2347; - --visited: #aaa; - --shadow: 0 2px 5px rgba(0, 0, 0, 0.5); -} - -/* Gold theme setting */ -.gold { - --accent: #f2aa4c; - --green: #5cff85; - --text: white; - --foreground: #234; - --background: #101820; - --outside: #1b2936; - --post: #1b2936; - --panel-border: 0px solid black; - --highlighted: #234; - --visited: #aaa; - --shadow: 0 2px 5px rgba(0, 0, 0, 0.5); -} - -/* Rosebox theme setting */ -.rosebox { - --accent: #a57562; - --green: #a3be8c; - --text: white; - --foreground: #222; - --background: #262626; - --outside: #222; - --post: #222; - --panel-border: 1px solid #222; - --highlighted: #262626; - --shadow: 0 1px 3px rgba(0, 0, 0, 0.5); -} +/* Other themes are located in the "themes" folder */ /* General */ diff --git a/static/themes/black.css b/static/themes/black.css new file mode 100644 index 0000000..5906b5b --- /dev/null +++ b/static/themes/black.css @@ -0,0 +1,14 @@ +/* Black theme setting */ +.black { + --accent: #009a9a; + --green: #00a229; + --text: white; + --foreground: #0f0f0f; + --background: black; + --outside: black; + --post: black; + --panel-border: 2px solid #0f0f0f; + --highlighted: #0f0f0f; + --visited: #aaa; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} \ No newline at end of file diff --git a/static/themes/dracula.css b/static/themes/dracula.css new file mode 100644 index 0000000..0e36e2b --- /dev/null +++ b/static/themes/dracula.css @@ -0,0 +1,14 @@ +/* Dracula theme setting */ +.dracula { + --accent: #bd93f9; + --green: #50fa7b; + --text: #f8f8f2; + --foreground: #3d4051; + --background: #282a36; + --outside: #393c4d; + --post: #333544; + --panel-border: 2px solid #44475a; + --highlighted: #4e5267; + --visited: #969692; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} \ No newline at end of file diff --git a/static/themes/gold.css b/static/themes/gold.css new file mode 100644 index 0000000..4ff7d6e --- /dev/null +++ b/static/themes/gold.css @@ -0,0 +1,14 @@ +/* Gold theme setting */ +.gold { + --accent: #f2aa4c; + --green: #5cff85; + --text: white; + --foreground: #234; + --background: #101820; + --outside: #1b2936; + --post: #1b2936; + --panel-border: 0px solid black; + --highlighted: #234; + --visited: #aaa; + --shadow: 0 2px 5px rgba(0, 0, 0, 0.5); +} \ No newline at end of file diff --git a/static/themes/laserwave.css b/static/themes/laserwave.css new file mode 100644 index 0000000..dde21f3 --- /dev/null +++ b/static/themes/laserwave.css @@ -0,0 +1,14 @@ +/* Laserwave theme setting */ +.laserwave { + --accent: #eb64b9; + --green: #74dfc4; + --text: #e0dfe1; + --foreground: #302a36; + --background: #27212e; + --outside: #3e3647; + --post: #3e3647; + --panel-border: 2px solid #2f2738; + --highlighted: #302a36; + --visited: #91889b; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} \ No newline at end of file diff --git a/static/themes/light.css b/static/themes/light.css new file mode 100644 index 0000000..1fe0387 --- /dev/null +++ b/static/themes/light.css @@ -0,0 +1,14 @@ +/* Light theme setting */ +.light { + --accent: #009a9a; + --green: #00a229; + --text: black; + --foreground: #f5f5f5; + --background: #ddd; + --outside: #ececec; + --post: #eee; + --panel-border: 1px solid #ccc; + --highlighted: white; + --visited: #555; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} \ No newline at end of file diff --git a/static/themes/nord.css b/static/themes/nord.css new file mode 100644 index 0000000..d75fd11 --- /dev/null +++ b/static/themes/nord.css @@ -0,0 +1,14 @@ +/* Nord theme setting */ +.nord { + --accent: #8fbcbb; + --green: #a3be8c; + --text: #eceff4; + --foreground: #3b4252; + --background: #2e3440; + --outside: #434c5e; + --post: #434c5e; + --panel-border: 2px solid #4c566a; + --highlighted: #3b4252; + --visited: #a3a5aa; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} diff --git a/static/themes/rosebox.css b/static/themes/rosebox.css new file mode 100644 index 0000000..903931d --- /dev/null +++ b/static/themes/rosebox.css @@ -0,0 +1,13 @@ +/* Rosebox theme setting */ +.rosebox { + --accent: #a57562; + --green: #a3be8c; + --text: white; + --foreground: #222; + --background: #262626; + --outside: #222; + --post: #222; + --panel-border: 1px solid #222; + --highlighted: #262626; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.5); +} \ No newline at end of file diff --git a/static/themes/violet.css b/static/themes/violet.css new file mode 100644 index 0000000..0d836ee --- /dev/null +++ b/static/themes/violet.css @@ -0,0 +1,14 @@ +/* Violet theme setting */ +.violet { + --accent: #7c71dd; + --green: #5cff85; + --text: white; + --foreground: #1F2347; + --background: #12152b; + --outside: #181c3a; + --post: #181c3a; + --panel-border: 1px solid #1F2347; + --highlighted: #1F2347; + --visited: #aaa; + --shadow: 0 2px 5px rgba(0, 0, 0, 0.5); +} \ No newline at end of file diff --git a/templates/settings.html b/templates/settings.html index 3669d88..60ee109 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -15,7 +15,7 @@
Interface