Update branding
Update the Ferese symbols, appearance-specific wallpapers, and rounded wallpaper and theme previews. Bundle Figtree and add the Ferese name to the website header. Verified configuration, theme, Settings, wallpaper and installer tests, both UI renderers, the static site build, and browser layouts.
This commit is contained in:
1 parent
f81d8d50ea
commit
3533fac521
35 files changed
+1212
-309
No files matched your search
@@ -38,13 +38,26 @@ pub fn config_path() -> Option<PathBuf> {
|
||||
}
|
||||
|
||||
pub fn default_wallpaper() -> &'static str {
|
||||
static PATH: std::sync::OnceLock<String> = std::sync::OnceLock::new();
|
||||
PATH.get_or_init(|| {
|
||||
default_wallpaper_for(theme::Appearance::Dark)
|
||||
}
|
||||
|
||||
pub fn default_wallpaper_for(appearance: theme::Appearance) -> &'static str {
|
||||
static LIGHT: std::sync::OnceLock<String> = std::sync::OnceLock::new();
|
||||
static DARK: std::sync::OnceLock<String> = std::sync::OnceLock::new();
|
||||
let (slot, name) = match appearance {
|
||||
theme::Appearance::Light => (&LIGHT, "ferese-wallpaper-light.png"),
|
||||
theme::Appearance::Dark => (&DARK, "ferese-wallpaper-dark.jpg"),
|
||||
};
|
||||
slot.get_or_init(|| {
|
||||
let path = std::env::current_exe()
|
||||
.ok()
|
||||
.and_then(|path| path.parent().map(|dir| dir.join("wallpapers/ferese.png")))
|
||||
.and_then(|path| path.parent().map(|dir| dir.join("wallpapers").join(name)))
|
||||
.filter(|path| path.is_file())
|
||||
.unwrap_or_else(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../assets/wallpapers/ferese.png"));
|
||||
.unwrap_or_else(|| {
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("../../assets/wallpapers")
|
||||
.join(name)
|
||||
});
|
||||
|
||||
path.canonicalize().unwrap_or(path).to_string_lossy().into_owned()
|
||||
})
|
||||
|
||||
@@ -575,6 +575,7 @@ pub fn preset(name: &str, appearance: Appearance) -> Result<Tokens, String> {
|
||||
return Err(format!("Preset {name} does not support {appearance:?}"));
|
||||
}
|
||||
let mut tokens = default_tokens();
|
||||
tokens.background.path = Some(crate::default_wallpaper_for(appearance).into());
|
||||
tokens.colors.surface_base = preset.base.into();
|
||||
tokens.colors.surface_raised = preset.raised.into();
|
||||
tokens.colors.application_background = preset.application_background.into();
|
||||
@@ -601,6 +602,7 @@ pub fn preset(name: &str, appearance: Appearance) -> Result<Tokens, String> {
|
||||
return Ok(tokens);
|
||||
}
|
||||
let mut t = default_tokens();
|
||||
t.background.path = Some(crate::default_wallpaper_for(appearance).into());
|
||||
let (base, text, muted, accent, border) = match name {
|
||||
"monochrome" => ("#101012", "#EDEDF0", "#97979F", "#E5E5E5", "#FFFFFF18"),
|
||||
"dracula" => ("#282A36", "#F8F8F2", "#A4ADCD", "#BD93F9", "#44475A"),
|
||||
@@ -962,6 +964,62 @@ mod tests {
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wallpapers_follow_appearance_unless_explicitly_selected() {
|
||||
for (mode, appearance) in [("light", Appearance::Light), ("dark", Appearance::Dark)] {
|
||||
let default = candidate(&format!("theme {{ mode \"{mode}\"; }}")).unwrap();
|
||||
assert_eq!(
|
||||
default.theme.tokens.background.path.as_deref(),
|
||||
Some(Path::new(crate::default_wallpaper_for(appearance)))
|
||||
);
|
||||
|
||||
let shared = candidate(&format!(
|
||||
"theme {{ mode \"{mode}\"; background {{ path \"shared.png\"; }}; }}"
|
||||
))
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
shared.theme.tokens.background.path.as_deref(),
|
||||
Some(Path::new("/config/ferese/shared.png"))
|
||||
);
|
||||
|
||||
let separate = candidate(&format!("theme {{ mode \"{mode}\"; background {{ path \"shared.png\"; }}; light {{ background {{ path \"light.png\"; }}; }}; dark {{ background {{ path \"dark.jpg\"; }}; }}; }}")).unwrap();
|
||||
assert_eq!(
|
||||
separate.theme.tokens.background.path.as_deref(),
|
||||
Some(Path::new(&format!(
|
||||
"/config/ferese/{}",
|
||||
if appearance == Appearance::Light {
|
||||
"light.png"
|
||||
} else {
|
||||
"dark.jpg"
|
||||
}
|
||||
)))
|
||||
);
|
||||
}
|
||||
|
||||
let auto = candidate("theme { mode \"auto\"; schedule { timezone \"UTC\"; }; }").unwrap();
|
||||
assert_eq!(auto.theme.appearance, Appearance::Light);
|
||||
assert_eq!(
|
||||
auto.theme.tokens.background.path.as_deref(),
|
||||
Some(Path::new(crate::default_wallpaper_for(Appearance::Light)))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imported_theme_wallpaper_is_not_overwritten_by_bundled_defaults() {
|
||||
let source = "theme { mode \"light\"; family \"custom\"; custom-themes { custom { file \"custom.kdl\"; }; }; }";
|
||||
let result = resolve(
|
||||
&Document::parse(source).unwrap(),
|
||||
Path::new("/config/ferese"),
|
||||
"2026-09-30T12:00:00Z".parse().unwrap(),
|
||||
|_| Ok("light { background { path \"authored.png\"; }; }".into()),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
result.theme.tokens.background.path.as_deref(),
|
||||
Some(Path::new("/config/ferese/authored.png"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn automatic_gradients_follow_presets_and_preserve_border_alpha() {
|
||||
for preset in crate::presets::PRESETS {
|
||||
|
||||
Reference in new issue
Block a user