diff --git a/src-tauri/src/commands/config.rs b/src-tauri/src/commands/config.rs new file mode 100644 index 0000000..961b2da --- /dev/null +++ b/src-tauri/src/commands/config.rs @@ -0,0 +1,64 @@ +use serde::{Deserialize, Serialize}; +use std::fs; +use std::sync::Mutex; +use tauri::{AppHandle, Manager, State}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Config { + pub audio_device_name: Option, +} + +impl Default for Config { + fn default() -> Self { + Self { + audio_device_name: None, + } + } +} + +pub struct ConfigState(pub Mutex); + +fn config_file_path(app: &AppHandle) -> Result { + let dir = app + .path() + .app_data_dir() + .map_err(|e| format!("Failed to resolve app data dir: {e}"))?; + fs::create_dir_all(&dir).map_err(|e| format!("Failed to create app data dir: {e}"))?; + Ok(dir.join("config.json")) +} + +#[tauri::command] +pub fn update_config(state: State, config: Config) -> Result<(), String> { + *state.0.lock().unwrap() = config; + Ok(()) +} + +#[tauri::command] +pub fn save_config(app: AppHandle, state: State) -> Result<(), String> { + let path = config_file_path(&app)?; + let config = state.0.lock().unwrap(); + + let json = serde_json::to_string_pretty(&*config) + .map_err(|e| format!("Failed to serialize config: {e}"))?; + + fs::write(&path, json).map_err(|e| format!("Failed to write config: {e}"))?; + + Ok(()) +} + +#[tauri::command] +pub fn get_config(app: AppHandle, state: State) -> Result { + let path = config_file_path(&app)?; + + let config = if path.exists() { + let json = fs::read_to_string(&path).map_err(|e| format!("Failed to read config: {e}"))?; + serde_json::from_str(&json).map_err(|e| format!("Failed to parse config: {e}"))? + } else { + Config::default() + }; + + *state.0.lock().unwrap() = config.clone(); + + Ok(config) +} diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs index f8c30cc..62c6f59 100644 --- a/src-tauri/src/commands/mod.rs +++ b/src-tauri/src/commands/mod.rs @@ -1,3 +1,4 @@ pub mod accounts; pub mod audio; +pub mod config; pub mod server_list; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 72949f3..5309958 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,3 +1,7 @@ +use std::sync::Mutex; + +use crate::commands::config::ConfigState; + pub mod commands; pub mod types; @@ -5,12 +9,16 @@ pub mod types; pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_opener::init()) + .manage(ConfigState(Mutex::new(commands::config::Config::default()))) .invoke_handler(tauri::generate_handler![ commands::server_list::save_server_list, commands::server_list::get_server_list, commands::accounts::save_accounts, commands::accounts::get_accounts, commands::audio::list_input_devices, + commands::config::update_config, + commands::config::save_config, + commands::config::get_config, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src/lib/config.ts b/src/lib/config.ts new file mode 100644 index 0000000..a7194e8 --- /dev/null +++ b/src/lib/config.ts @@ -0,0 +1,17 @@ +import { invoke } from "@tauri-apps/api/core"; + +export type Config = { + audioDeviceName: string | null; +}; + +export async function updateConfig(config: Config): Promise { + await invoke("update_config", { config }); +} + +export async function saveConfig(): Promise { + await invoke("save_config"); +} + +export async function getConfig(): Promise { + return await invoke("get_config"); +}