Added custom themes, import/export option with json (#159)

Reviewed-on: https://codeberg.org/ArkHost/HelixNotes/pulls/159
This commit is contained in:
blake
2026-06-23 20:19:23 +02:00
committed by ArkHost
parent 84ff75f223
commit 7b3609afbb
9 changed files with 866 additions and 10 deletions
+21
View File
@@ -0,0 +1,21 @@
{
"themes": [
{
"colors": {
"bg_active": "#373a52",
"bg_editor": "#1a1b26",
"bg_hover": "#2f3145",
"bg_primary": "#1a1b26",
"bg_secondary": "#1f2029",
"bg_tertiary": "#2a2b3d",
"border_color": "#2f3145",
"text_primary": "#c8cde4",
"text_secondary": "#6b7094"
},
"id": "custom-1782146306429",
"is_dark": true,
"name": "My theme"
}
],
"version": 1
}
+52
View File
@@ -90,6 +90,58 @@ pub fn set_accent_color(state: State<'_, AppState>, color: String) -> Result<(),
Ok(())
}
#[tauri::command]
pub fn save_custom_theme(state: State<'_, AppState>, theme: crate::types::CustomTheme) -> Result<(), String> {
let mut config = state.config.lock().map_err(|e| e.to_string())?;
if let Some(pos) = config.custom_themes.iter().position(|t| t.id == theme.id) {
config.custom_themes[pos] = theme;
} else {
config.custom_themes.push(theme);
}
save_app_config(&config)?;
Ok(())
}
#[tauri::command]
pub fn delete_custom_theme(state: State<'_, AppState>, id: String) -> Result<(), String> {
let mut config = state.config.lock().map_err(|e| e.to_string())?;
config.custom_themes.retain(|t| t.id != id);
if config.theme == id {
config.theme = "system".to_string();
}
save_app_config(&config)?;
Ok(())
}
#[tauri::command]
pub fn export_custom_theme(state: State<'_, AppState>, id: String, path: String) -> Result<(), String> {
let config = state.config.lock().map_err(|e| e.to_string())?;
let theme = config.custom_themes.iter().find(|t| t.id == id)
.ok_or_else(|| "Theme not found".to_string())?;
let export = serde_json::json!({ "version": 1, "themes": [theme] });
let data = serde_json::to_string_pretty(&export).map_err(|e| e.to_string())?;
std::fs::write(&path, data).map_err(|e| e.to_string())?;
Ok(())
}
#[tauri::command]
pub fn import_custom_themes(state: State<'_, AppState>, path: String) -> Result<Vec<crate::types::CustomTheme>, String> {
let data = std::fs::read_to_string(&path).map_err(|e| e.to_string())?;
let parsed: serde_json::Value = serde_json::from_str(&data).map_err(|e| e.to_string())?;
let themes: Vec<crate::types::CustomTheme> = serde_json::from_value(parsed["themes"].clone())
.map_err(|e| format!("Invalid theme file: {}", e))?;
let mut config = state.config.lock().map_err(|e| e.to_string())?;
for theme in &themes {
if let Some(pos) = config.custom_themes.iter().position(|t| t.id == theme.id) {
config.custom_themes[pos] = theme.clone();
} else {
config.custom_themes.push(theme.clone());
}
}
save_app_config(&config)?;
Ok(themes)
}
#[tauri::command]
pub fn set_font_size(state: State<'_, AppState>, size: u32) -> Result<(), String> {
let mut config = state.config.lock().map_err(|e| e.to_string())?;
+4
View File
@@ -116,6 +116,10 @@ pub fn run() {
commands::get_app_config,
commands::set_theme,
commands::set_accent_color,
commands::save_custom_theme,
commands::delete_custom_theme,
commands::export_custom_theme,
commands::import_custom_themes,
commands::set_font_size,
commands::set_font_family,
commands::set_line_height,
+24
View File
@@ -56,6 +56,27 @@ pub struct VaultConfig {
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CustomThemeColors {
pub bg_primary: String,
pub bg_secondary: String,
pub bg_tertiary: String,
pub bg_hover: String,
pub bg_active: String,
pub bg_editor: String,
pub text_primary: String,
pub text_secondary: String,
pub border_color: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CustomTheme {
pub id: String,
pub name: String,
pub is_dark: bool,
pub colors: CustomThemeColors,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppConfig {
pub vaults: Vec<VaultConfig>,
@@ -168,6 +189,8 @@ pub struct AppConfig {
pub sync_interval_minutes: u32,
#[serde(default)]
pub last_sync_time: Option<String>,
#[serde(default)]
pub custom_themes: Vec<CustomTheme>,
}
fn default_true() -> bool {
@@ -265,6 +288,7 @@ impl Default for AppConfig {
sync_on_change: false,
sync_interval_minutes: 0,
last_sync_time: None,
custom_themes: Vec::new(),
}
}
}