feat(settings): add locale-aware font preferences

Bundle optional Inter and Outfit families, preserve the platform system default, and provide script-aware fallbacks for every supported locale.

Refs #31
This commit is contained in:
NimBold
2026-07-23 17:13:00 +03:30
parent 228db1eaa2
commit 1f1ec828f9
20 changed files with 206 additions and 10 deletions
+19
View File
@@ -214,6 +214,23 @@ pub enum Theme {
Nord,
}
#[derive(Clone, Debug, Serialize, Deserialize, TS)]
#[serde(rename_all = "lowercase")]
#[ts(export, export_to = "../../src/bindings/")]
pub enum FontFamily {
System,
Inter,
Outfit,
Serif,
Monospace,
}
impl Default for FontFamily {
fn default() -> Self {
Self::System
}
}
#[derive(Clone, Debug, Serialize, Deserialize, TS)]
#[serde(rename_all = "lowercase")]
#[ts(export, export_to = "../../src/bindings/")]
@@ -312,6 +329,8 @@ pub struct SchedulerSettings {
pub struct PersistedSettings {
pub theme: Theme,
#[serde(default)]
pub font_family: FontFamily,
#[serde(default)]
pub window_control_style: WindowControlStyle,
#[serde(default)]
pub calendar_preference: CalendarPreference,
+22 -3
View File
@@ -1,6 +1,7 @@
use crate::ipc::{
AppFontSize, CalendarPreference, ListRowDensity, MediaCookieSource, PersistedSettings,
PostQueueAction, ProxyMode, SchedulerSettings, SettingsTab, Theme, WindowControlStyle,
AppFontSize, CalendarPreference, FontFamily, ListRowDensity, MediaCookieSource,
PersistedSettings, PostQueueAction, ProxyMode, SchedulerSettings, SettingsTab, Theme,
WindowControlStyle,
};
use serde_json::{Map, Value};
use std::collections::HashMap;
@@ -192,6 +193,11 @@ fn sanitize_persisted_setting_values(state: &mut Value) {
"theme",
&["system", "light", "dark", "dracula", "nord"],
);
sanitize_allowed_string(
state,
"fontFamily",
&["system", "inter", "outfit", "serif", "monospace"],
);
sanitize_allowed_string(
state,
"windowControlStyle",
@@ -422,6 +428,7 @@ fn derived_location_path(base: &str, subfolder: &str) -> String {
fn default_settings() -> PersistedSettings {
PersistedSettings {
theme: Theme::System,
font_family: FontFamily::System,
window_control_style: WindowControlStyle::Auto,
calendar_preference: CalendarPreference::Gregorian,
language: "system".to_string(),
@@ -478,7 +485,7 @@ fn default_settings() -> PersistedSettings {
#[cfg(test)]
mod tests {
use crate::ipc::WindowControlStyle;
use crate::ipc::{FontFamily, WindowControlStyle};
use super::{
decode_stored_settings, default_settings, preserve_portable_pairing_token,
preserve_scheduler_runtime_keys,
@@ -685,6 +692,18 @@ mod tests {
assert_eq!(settings.sidebar_position, "auto");
}
#[test]
fn invalid_font_family_uses_system_font() {
let stored = json!({
"state": {"fontFamily": "comic-sans"},
"version": 5
});
let settings = decode_stored_settings(&Value::String(stored.to_string())).unwrap();
assert!(matches!(settings.font_family, FontFamily::System));
}
#[test]
fn invalid_window_control_style_uses_automatic_layout() {
let stored = json!({