EU-Utility-V3/src-tauri/src/settings.rs

159 lines
4.4 KiB
Rust

use std::path::PathBuf;
use std::sync::Mutex;
use serde_json::Value;
use tauri::AppHandle;
use tracing::{error, info};
pub struct SettingsManager {
app_handle: AppHandle,
settings: Mutex<Value>,
config_path: PathBuf,
}
impl SettingsManager {
pub fn new(app_handle: AppHandle) -> Self {
let config_path = app_handle
.path_resolver()
.app_config_dir()
.expect("Failed to get config dir")
.join("settings.json");
let settings = Self::load_settings(&config_path);
Self {
app_handle,
settings: Mutex::new(settings),
config_path,
}
}
fn load_settings(path: &PathBuf) -> Value {
if !path.exists() {
info!("Settings file not found, using defaults");
return Self::default_settings();
}
match std::fs::read_to_string(path) {
Ok(content) => {
match serde_json::from_str(&content) {
Ok(settings) => settings,
Err(e) => {
error!("Failed to parse settings: {}", e);
Self::default_settings()
}
}
}
Err(e) => {
error!("Failed to read settings: {}", e);
Self::default_settings()
}
}
}
fn default_settings() -> Value {
serde_json::json!({
"general": {
"start_on_boot": false,
"minimize_to_tray": true,
"theme": "dark"
},
"overlay": {
"opacity": 0.9,
"click_through": true,
"snap_to_edges": true,
"auto_hide_delay": 3000
},
"hotkeys": {
"overlay_toggle": "Ctrl+Shift+U",
"overlay_hide": "Ctrl+Shift+H",
"search_universal": "Ctrl+Shift+F",
"search_nexus": "Ctrl+Shift+N",
"calculator": "Ctrl+Shift+C",
"tracker_loot": "Ctrl+Shift+L"
},
"plugins": {
"auto_activate": [],
"disabled": []
},
"log_reader": {
"log_path": "",
"auto_detect": true
},
"nexus": {
"cache_enabled": true,
"cache_ttl": 3600
}
})
}
pub fn get(&self, key: &str) -> Result<Value, String> {
let settings = self.settings.lock().unwrap();
let keys: Vec<&str> = key.split('.').collect();
let mut current = &*settings;
for k in keys {
current = current
.get(k)
.ok_or_else(|| format!("Key not found: {}", key))?;
}
Ok(current.clone())
}
pub fn set(
&self,
key: &str,
value: Value
) -> Result<(), String> {
let mut settings = self.settings.lock().unwrap();
let keys: Vec<&str> = key.split('.').collect();
let mut current = settings.as_object_mut()
.ok_or("Settings is not an object")?;
for (i, k) in keys.iter().enumerate() {
if i == keys.len() - 1 {
current.insert(k.to_string(), value);
} else {
current = current
.entry(k.to_string())
.or_insert_with(|| serde_json::json!({}))
.as_object_mut()
.ok_or("Invalid settings structure")?;
}
}
drop(settings);
self.save()?;
Ok(())
}
pub fn get_all(&self
) -> Result<Value, String> {
let settings = self.settings.lock().unwrap();
Ok(settings.clone())
}
fn save(&self
) -> Result<(), String> {
let settings = self.settings.lock().unwrap();
// Ensure directory exists
if let Some(parent) = self.config_path.parent() {
std::fs::create_dir_all(parent)
.map_err(|e| e.to_string())?;
}
let json = serde_json::to_string_pretty(&*settings)
.map_err(|e| e.to_string())?;
std::fs::write(&self.config_path, json)
.map_err(|e| e.to_string())?;
info!("Settings saved to {:?}", self.config_path);
Ok(())
}
}