//! User preferences stored as a small JSON file in the Tauri app config dir. //! //! Used for settings that need to be read before the database is available //! (e.g. the launch-time update check). Heavier user state lives in SQLite. use std::path::PathBuf; use serde::{Deserialize, Serialize}; use tauri::{AppHandle, Manager}; use tracing::instrument; use super::ApiError; const PREFERENCES_FILE: &str = "preferences.json"; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Preferences { pub update_check_on_launch: bool, } impl Default for Preferences { fn default() -> Self { Self { update_check_on_launch: true } } } fn preferences_path(app: &AppHandle) -> Result { let dir = app.path().app_config_dir() .map_err(|e| ApiError::internal(format!("Resolve app config dir: {e}")))?; std::fs::create_dir_all(&dir) .map_err(|e| ApiError::internal(format!("Create app config dir: {e}")))?; Ok(dir.join(PREFERENCES_FILE)) } pub fn load(app: &AppHandle) -> Preferences { let Ok(path) = preferences_path(app) else { return Preferences::default(); }; let Ok(bytes) = std::fs::read(&path) else { return Preferences::default(); }; serde_json::from_slice(&bytes).unwrap_or_default() } fn save(app: &AppHandle, prefs: &Preferences) -> Result<(), ApiError> { let path = preferences_path(app)?; let json = serde_json::to_vec_pretty(prefs) .map_err(|e| ApiError::internal(format!("Serialize preferences: {e}")))?; std::fs::write(&path, json) .map_err(|e| ApiError::internal(format!("Write preferences: {e}")))?; Ok(()) } #[tauri::command] #[instrument(skip_all)] pub fn get_preferences(app: AppHandle) -> Result { Ok(load(&app)) } #[tauri::command] #[instrument(skip_all)] pub fn set_update_check_on_launch(app: AppHandle, enabled: bool) -> Result<(), ApiError> { let mut prefs = load(&app); prefs.update_check_on_launch = enabled; save(&app, &prefs) }