use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::RwLock; use std::time::Instant; /// Thread-safe shared state accessible by the coordinator, IPC listener, and tray icon. pub struct SharedState { pub state: RwLock, /// True when recording or transcribing — the hotkey listener uses this to /// decide whether to swallow the cancel key. pub is_active: AtomicBool, pub model: String, pub accelerator: String, pub started_at: Instant, } impl SharedState { pub fn new(model: String, accelerator: String) -> Self { Self { state: RwLock::new("idle".to_string()), is_active: AtomicBool::new(false), model, accelerator, started_at: Instant::now(), } } pub fn set_state(&self, state: &str) { if let Ok(mut s) = self.state.write() { *s = state.to_string(); } self.is_active.store(state != "idle", Ordering::Release); } pub fn get_state(&self) -> String { self.state.read().map(|s| s.clone()).unwrap_or_else(|_| "unknown".to_string()) } pub fn uptime_secs(&self) -> u64 { self.started_at.elapsed().as_secs() } }