use serde::{Deserialize, Serialize}; use std::sync::Mutex; use tauri::{AppHandle, Manager}; use uuid::Uuid; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct StudySession { pub id: String, pub title: String, pub duration_sec: u32, pub actual_sec: u32, pub reference_url: Option, pub notes: String, pub created_at: i64, } #[derive(Default)] pub struct StudyState { pub sessions: Mutex>, } #[tauri::command] pub fn study_start(app: AppHandle, title: String, duration_sec: u32, reference_url: Option) -> Result { let session = StudySession { id: Uuid::new_v4().to_string(), title, duration_sec, actual_sec: 0, reference_url, notes: String::new(), created_at: chrono::Utc::now().timestamp(), }; let state = app.state::(); let mut sessions = state.sessions.lock().map_err(|_| "study lock poisoned")?; sessions.push(session.clone()); crate::persistence::save_json(&app, "study_sessions.json", &*sessions)?; Ok(session) } #[tauri::command] pub fn study_complete(app: AppHandle, id: String, actual_sec: u32, notes: String) -> Result { let state = app.state::(); let mut sessions = state.sessions.lock().map_err(|_| "study lock poisoned")?; let session = sessions.iter_mut().find(|s| s.id == id).ok_or("session not found")?; session.actual_sec = actual_sec; session.notes = notes; let result = session.clone(); crate::persistence::save_json(&app, "study_sessions.json", &*sessions)?; Ok(result) } #[tauri::command] pub fn study_list(app: AppHandle) -> Result, String> { let state = app.state::(); let mut sessions = state.sessions.lock().map_err(|_| "study lock poisoned")?; if sessions.is_empty() { let loaded: Vec = crate::persistence::load_json(&app, "study_sessions.json")?; if !loaded.is_empty() { *sessions = loaded; } } Ok(sessions.clone()) }