This commit is contained in:
ac615223s5 2025-03-31 10:59:32 -04:00 committed by GitHub
commit 37b343b580
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 72 additions and 86 deletions

View file

@ -12,8 +12,9 @@ REDLIB_ROBOTS_DISABLE_INDEXING=off
REDLIB_PUSHSHIFT_FRONTEND=undelete.pullpush.io REDLIB_PUSHSHIFT_FRONTEND=undelete.pullpush.io
# Default user settings # Default user settings
# Set the default theme (options: system, light, dark, black, dracula, nord, laserwave, violet, gold, rosebox, gruvboxdark, gruvboxlight) # Set the default theme (options: light, dark, black, dracula, nord, laserwave, violet, gold, rosebox, gruvboxdark, gruvboxlight)
REDLIB_DEFAULT_THEME=system REDLIB_DEFAULT_THEME_LIGHT=light
REDLIB_DEFAULT_THEME_DARK=dark
# Set the default front page (options: default, popular, all) # Set the default front page (options: default, popular, all)
REDLIB_DEFAULT_FRONT_PAGE=default REDLIB_DEFAULT_FRONT_PAGE=default
# Set the default layout (options: card, clean, compact) # Set the default layout (options: card, clean, compact)

View file

@ -370,7 +370,7 @@ REDLIB_DEFAULT_SHOW_NSFW=on redlib
``` ```
```bash ```bash
REDLIB_DEFAULT_WIDE=on REDLIB_DEFAULT_THEME=dark redlib -r REDLIB_DEFAULT_WIDE=on REDLIB_DEFAULT_THEME_DARK=dark redlib -r
``` ```
You can also configure Redlib with a configuration file named `redlib.toml`. For example: You can also configure Redlib with a configuration file named `redlib.toml`. For example:
@ -423,7 +423,8 @@ Assign a default value for each user-modifiable setting by passing environment v
| Name | Possible values | Default value | | Name | Possible values | Default value |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------- | | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `THEME` | `["system", "light", "dark", "black", "dracula", "nord", "laserwave", "violet", "gold", "rosebox", "gruvboxdark", "gruvboxlight", "tokyoNight", "icebergDark", "doomone", "libredditBlack", "libredditDark", "libredditLight"]` | `system` | | `THEME_LIGHT` | `["light", "dark", "black", "dracula", "nord", "laserwave", "violet", "gold", "rosebox", "gruvboxdark", "gruvboxlight", "tokyoNight", "icebergDark", "doomone", "libredditBlack", "libredditDark", "libredditLight"]` | `light` |
| `THEME_DARK` | `["light", "dark", "black", "dracula", "nord", "laserwave", "violet", "gold", "rosebox", "gruvboxdark", "gruvboxlight", "tokyoNight", "icebergDark", "doomone", "libredditBlack", "libredditDark", "libredditLight"]` | `dark` |
| `FRONT_PAGE` | `["default", "popular", "all"]` | `default` | | `FRONT_PAGE` | `["default", "popular", "all"]` | `default` |
| `LAYOUT` | `["card", "clean", "compact"]` | `card` | | `LAYOUT` | `["card", "clean", "compact"]` | `card` |
| `WIDE` | `["on", "off"]` | `off` | | `WIDE` | `["on", "off"]` | `off` |
@ -436,6 +437,7 @@ Assign a default value for each user-modifiable setting by passing environment v
| `HIDE_HLS_NOTIFICATION` | `["on", "off"]` | `off` | | `HIDE_HLS_NOTIFICATION` | `["on", "off"]` | `off` |
| `AUTOPLAY_VIDEOS` | `["on", "off"]` | `off` | | `AUTOPLAY_VIDEOS` | `["on", "off"]` | `off` |
| `SUBSCRIPTIONS` | `+`-delimited list of subreddits (`sub1+sub2+sub3+...`) | _(none)_ | | `SUBSCRIPTIONS` | `+`-delimited list of subreddits (`sub1+sub2+sub3+...`) | _(none)_ |
| `FILTERS` | `+`-delimited list of subreddits (`sub1+sub2+sub3+...`) | _(none)_ |
| `HIDE_AWARDS` | `["on", "off"]` | `off` | | `HIDE_AWARDS` | `["on", "off"]` | `off` |
| `DISABLE_VISIT_REDDIT_CONFIRMATION` | `["on", "off"]` | `off` | | `DISABLE_VISIT_REDDIT_CONFIRMATION` | `["on", "off"]` | `off` |
| `HIDE_SCORE` | `["on", "off"]` | `off` | | `HIDE_SCORE` | `["on", "off"]` | `off` |

View file

@ -11,7 +11,10 @@
], ],
"stack": "container", "stack": "container",
"env": { "env": {
"REDLIB_DEFAULT_THEME": { "REDLIB_DEFAULT_THEME_LIGHT": {
"required": false
},
"REDLIB_DEFAULT_THEME_DARK": {
"required": false "required": false
}, },
"REDLIB_DEFAULT_FRONT_PAGE": { "REDLIB_DEFAULT_FRONT_PAGE": {

View file

@ -24,9 +24,13 @@ pub struct Config {
#[serde(alias = "LIBREDDIT_SFW_ONLY")] #[serde(alias = "LIBREDDIT_SFW_ONLY")]
pub(crate) sfw_only: Option<String>, pub(crate) sfw_only: Option<String>,
#[serde(rename = "REDLIB_DEFAULT_THEME")] #[serde(rename = "REDLIB_DEFAULT_THEME_LIGHT")]
#[serde(alias = "LIBREDDIT_DEFAULT_THEME")] #[serde(alias = "LIBREDDIT_DEFAULT_THEME_LIGHT")]
pub(crate) default_theme: Option<String>, pub(crate) default_theme_light: Option<String>,
#[serde(rename = "REDLIB_DEFAULT_THEME_DARK")]
#[serde(alias = "LIBREDDIT_DEFAULT_THEME_DARK")]
pub(crate) default_theme_dark: Option<String>,
#[serde(rename = "REDLIB_DEFAULT_FRONT_PAGE")] #[serde(rename = "REDLIB_DEFAULT_FRONT_PAGE")]
#[serde(alias = "LIBREDDIT_DEFAULT_FRONT_PAGE")] #[serde(alias = "LIBREDDIT_DEFAULT_FRONT_PAGE")]
@ -137,7 +141,8 @@ impl Config {
}; };
Self { Self {
sfw_only: parse("REDLIB_SFW_ONLY"), sfw_only: parse("REDLIB_SFW_ONLY"),
default_theme: parse("REDLIB_DEFAULT_THEME"), default_theme_light: parse("REDLIB_DEFAULT_THEME_LIGHT"),
default_theme_dark: parse("REDLIB_DEFAULT_THEME_DARK"),
default_front_page: parse("REDLIB_DEFAULT_FRONT_PAGE"), default_front_page: parse("REDLIB_DEFAULT_FRONT_PAGE"),
default_layout: parse("REDLIB_DEFAULT_LAYOUT"), default_layout: parse("REDLIB_DEFAULT_LAYOUT"),
default_post_sort: parse("REDLIB_DEFAULT_POST_SORT"), default_post_sort: parse("REDLIB_DEFAULT_POST_SORT"),
@ -167,7 +172,8 @@ impl Config {
fn get_setting_from_config(name: &str, config: &Config) -> Option<String> { fn get_setting_from_config(name: &str, config: &Config) -> Option<String> {
match name { match name {
"REDLIB_SFW_ONLY" => config.sfw_only.clone(), "REDLIB_SFW_ONLY" => config.sfw_only.clone(),
"REDLIB_DEFAULT_THEME" => config.default_theme.clone(), "REDLIB_DEFAULT_THEME_LIGHT" => config.default_theme_light.clone(),
"REDLIB_DEFAULT_THEME_DARK" => config.default_theme_dark.clone(),
"REDLIB_DEFAULT_FRONT_PAGE" => config.default_front_page.clone(), "REDLIB_DEFAULT_FRONT_PAGE" => config.default_front_page.clone(),
"REDLIB_DEFAULT_LAYOUT" => config.default_layout.clone(), "REDLIB_DEFAULT_LAYOUT" => config.default_layout.clone(),
"REDLIB_DEFAULT_COMMENT_SORT" => config.default_comment_sort.clone(), "REDLIB_DEFAULT_COMMENT_SORT" => config.default_comment_sort.clone(),

View file

@ -138,7 +138,8 @@ impl InstanceInfo {
Table::from([ Table::from([
["Hide awards", &convert(&self.config.default_hide_awards)], ["Hide awards", &convert(&self.config.default_hide_awards)],
["Hide score", &convert(&self.config.default_hide_score)], ["Hide score", &convert(&self.config.default_hide_score)],
["Theme", &convert(&self.config.default_theme)], ["Light Theme", &convert(&self.config.default_theme_light)],
["Dark Theme", &convert(&self.config.default_theme_dark)],
["Front page", &convert(&self.config.default_front_page)], ["Front page", &convert(&self.config.default_front_page)],
["Layout", &convert(&self.config.default_layout)], ["Layout", &convert(&self.config.default_layout)],
["Wide", &convert(&self.config.default_wide)], ["Wide", &convert(&self.config.default_wide)],
@ -175,7 +176,8 @@ impl InstanceInfo {
Banner: {:?}\n Banner: {:?}\n
Hide awards: {:?}\n Hide awards: {:?}\n
Hide score: {:?}\n Hide score: {:?}\n
Default theme: {:?}\n Default light theme: {:?}\n
Default dark theme: {:?}\n
Default front page: {:?}\n Default front page: {:?}\n
Default layout: {:?}\n Default layout: {:?}\n
Default wide: {:?}\n Default wide: {:?}\n
@ -202,7 +204,8 @@ impl InstanceInfo {
self.config.banner, self.config.banner,
self.config.default_hide_awards, self.config.default_hide_awards,
self.config.default_hide_score, self.config.default_hide_score,
self.config.default_theme, self.config.default_theme_light,
self.config.default_theme_dark,
self.config.default_front_page, self.config.default_front_page,
self.config.default_layout, self.config.default_layout,
self.config.default_wide, self.config.default_wide,

View file

@ -95,8 +95,28 @@ async fn style() -> Result<Response<Body>, String> {
let mut res = include_str!("../static/style.css").to_string(); let mut res = include_str!("../static/style.css").to_string();
for file in ThemeAssets::iter() { for file in ThemeAssets::iter() {
res.push('\n'); res.push('\n');
let theme = ThemeAssets::get(file.as_ref()).unwrap(); let theme: Vec<&str> = file.as_ref().split(".css").collect();
res.push_str(std::str::from_utf8(theme.data.as_ref()).unwrap()); let theme = ".".to_owned() + theme[0];
let style = ThemeAssets::get(file.as_ref()).unwrap();
let style = std::str::from_utf8(style.data.as_ref()).unwrap();
let style_light = &style.replace(&theme, &(theme.clone() + "_light"));
let style_light = &format!(
"
@media (prefers-color-scheme: light) {{
{style_light}
}}
"
);
let style_dark = &style.replace(&theme, &(theme.clone() + "_dark"));
let style_dark = &format!(
"
@media (prefers-color-scheme: dark) {{
{style_dark}
}}
"
);
res.push_str(style_light);
res.push_str(style_dark);
} }
Ok( Ok(
Response::builder() Response::builder()

View file

@ -24,8 +24,9 @@ struct SettingsTemplate {
// CONSTANTS // CONSTANTS
const PREFS: [&str; 19] = [ const PREFS: [&str; 20] = [
"theme", "theme_light",
"theme_dark",
"front_page", "front_page",
"layout", "layout",
"wide", "wide",

View file

@ -627,7 +627,9 @@ pub struct Preferences {
#[serde(skip_serializing, skip_deserializing)] #[serde(skip_serializing, skip_deserializing)]
pub available_themes: Vec<String>, pub available_themes: Vec<String>,
#[revision(start = 1)] #[revision(start = 1)]
pub theme: String, pub theme_light: String,
#[revision(start = 1)]
pub theme_dark: String,
#[revision(start = 1)] #[revision(start = 1)]
pub front_page: String, pub front_page: String,
#[revision(start = 1)] #[revision(start = 1)]
@ -699,15 +701,15 @@ impl Preferences {
// Build preferences from cookies // Build preferences from cookies
pub fn new(req: &Request<Body>) -> Self { pub fn new(req: &Request<Body>) -> Self {
// Read available theme names from embedded css files. // Read available theme names from embedded css files.
// Always make the default "system" theme available. let mut themes = Vec::new();
let mut themes = vec!["system".to_string()];
for file in ThemeAssets::iter() { for file in ThemeAssets::iter() {
let chunks: Vec<&str> = file.as_ref().split(".css").collect(); let chunks: Vec<&str> = file.as_ref().split(".css").collect();
themes.push(chunks[0].to_owned()); themes.push(chunks[0].to_owned());
} }
Self { Self {
available_themes: themes, available_themes: themes,
theme: setting(req, "theme"), theme_light: setting(req, "theme_light"),
theme_dark: setting(req, "theme_dark"),
front_page: setting(req, "front_page"), front_page: setting(req, "front_page"),
layout: setting(req, "layout"), layout: setting(req, "layout"),
wide: setting(req, "wide"), wide: setting(req, "wide"),
@ -1526,7 +1528,8 @@ mod tests {
fn serialize_prefs() { fn serialize_prefs() {
let prefs = Preferences { let prefs = Preferences {
available_themes: vec![], available_themes: vec![],
theme: "laserwave".to_owned(), theme_light: "laserwave".to_owned(),
theme_dark: "laserwave".to_owned(),
front_page: "default".to_owned(), front_page: "default".to_owned(),
layout: "compact".to_owned(), layout: "compact".to_owned(),
wide: "on".to_owned(), wide: "on".to_owned(),

View file

@ -37,66 +37,6 @@
font-weight: 100 900; font-weight: 100 900;
} }
/* Automatic theme selection */
:root,
.dark {
/* Default & fallback theme (dark) */
--accent: #d54455;
--green: #5cff85;
--text: white;
--foreground: #222;
--background: #0f0f0f;
--outside: #1f1f1f;
--post: #161616;
--panel-border: 1px solid #333;
--highlighted: #333;
--visited: #aaa;
--shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
--popup: #b80a27;
--spoiler: #ddd;
/* Hint color theme to browser for scrollbar */
color-scheme: dark;
}
/* Browser-defined light theme */
@media (prefers-color-scheme: light) {
:root {
--accent: #bb2b3b;
--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);
--spoiler: #0f0f0f;
/* Hint color theme to browser for scrollbar */
color-scheme: light;
}
}
/* Other themes are located in the "themes" folder */
/* Tokyo Night theme setting */
.tokyoNight {
--accent: #565f89;
--green: #73daca;
--text: #a9b1d6;
--foreground: #24283b;
--background: #1a1b26;
--outside: #24283b;
--post: #1a1b26;
--panel-border: 1px solid #a9b1d6;
--highlighted: #414868;
--visited: #414868;
--shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
/* General */ /* General */
::selection { ::selection {

View file

@ -34,7 +34,8 @@
<body class=" <body class="
{% if prefs.layout != "" %}{{ prefs.layout }}{% endif %} {% if prefs.layout != "" %}{{ prefs.layout }}{% endif %}
{% if prefs.wide == "on" %} wide{% endif %} {% if prefs.wide == "on" %} wide{% endif %}
{% if prefs.theme != "system" %} {{ prefs.theme }}{% endif %} {{ prefs.theme_light }}_light
{{ prefs.theme_dark }}_dark
{% if prefs.fixed_navbar == "on" %} fixed_navbar{% endif %}"> {% if prefs.fixed_navbar == "on" %} fixed_navbar{% endif %}">
<!-- NAVIGATION BAR --> <!-- NAVIGATION BAR -->
<nav class=" <nav class="

View file

@ -18,9 +18,15 @@
<fieldset> <fieldset>
<legend>Appearance</legend> <legend>Appearance</legend>
<div class="prefs-group"> <div class="prefs-group">
<label for="theme">Theme:</label> <label for="theme_light">Light Theme:</label>
<select name="theme" id="theme"> <select name="theme_light" id="theme_light">
{% call utils::options(prefs.theme, prefs.available_themes, "system") %} {% call utils::options(prefs.theme_light, prefs.available_themes, "light") %}
</select>
</div>
<div class="prefs-group">
<label for="theme_dark">Dark Theme:</label>
<select name="theme_dark" id="theme_dark">
{% call utils::options(prefs.theme_dark, prefs.available_themes, "dark") %}
</select> </select>
</div> </div>
</fieldset> </fieldset>