diff options
Diffstat (limited to 'src-tauri/src/lib.rs')
| -rw-r--r-- | src-tauri/src/lib.rs | 66 |
1 files changed, 51 insertions, 15 deletions
diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index c298fdf..aff41cc 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -23,6 +23,17 @@ fn app_data_dir(app: &AppHandle) -> std::path::PathBuf { app.path().app_data_dir().expect("Failed to resolve app data dir") } +fn persist_timer_snapshot( + timer: &TimerState, + data: &State<'_, AppDataWrapper>, + app: &AppHandle, +) -> Result<(), String> { + let mut app_data = data.data.lock().unwrap(); + app_data.current_task_id = timer.current_task_id.clone(); + app_data.timer_snapshot = Some(timer.snapshot()); + storage::save(&app_data_dir(app), &app_data) +} + fn sync_audio_ducking(audio: &AudioState, phase: TimerPhase) { if let Some(engine) = audio.0.lock().unwrap().as_mut() { if audio::should_duck_for_phase(phase) { @@ -49,19 +60,33 @@ fn get_timer_status(timer: State<'_, TimerStateWrapper>) -> serde_json::Value { } #[tauri::command] -fn start_timer(timer: State<'_, TimerStateWrapper>) { +fn start_timer( + timer: State<'_, TimerStateWrapper>, + data: State<'_, AppDataWrapper>, + app: AppHandle, +) -> Result<(), String> { let mut ts = timer.0.lock().unwrap(); ts.running = true; + persist_timer_snapshot(&ts, &data, &app) } #[tauri::command] -fn pause_timer(timer: State<'_, TimerStateWrapper>) { +fn pause_timer( + timer: State<'_, TimerStateWrapper>, + data: State<'_, AppDataWrapper>, + app: AppHandle, +) -> Result<(), String> { let mut ts = timer.0.lock().unwrap(); ts.running = false; + persist_timer_snapshot(&ts, &data, &app) } #[tauri::command] -fn reset_timer(timer: State<'_, TimerStateWrapper>, data: State<'_, AppDataWrapper>) { +fn reset_timer( + timer: State<'_, TimerStateWrapper>, + data: State<'_, AppDataWrapper>, + app: AppHandle, +) -> Result<(), String> { let mut ts = timer.0.lock().unwrap(); let total = { let app_data = data.data.lock().unwrap(); @@ -74,6 +99,7 @@ fn reset_timer(timer: State<'_, TimerStateWrapper>, data: State<'_, AppDataWrapp ts.remaining_secs = total; ts.total_secs = total; ts.running = false; + persist_timer_snapshot(&ts, &data, &app) } #[tauri::command] @@ -82,7 +108,7 @@ fn skip_phase( data: State<'_, AppDataWrapper>, audio: State<'_, AudioState>, app: AppHandle, -) { +) -> Result<(), String> { use tauri::Emitter; let mut ts = timer.0.lock().unwrap(); let app_data = data.data.lock().unwrap(); @@ -111,6 +137,7 @@ fn skip_phase( ts.running = false; let phase = ts.phase; let session_count = ts.session_count; + persist_timer_snapshot(&ts, &data, &app)?; drop(ts); sync_audio_ducking(&audio, phase); @@ -122,6 +149,8 @@ fn skip_phase( session_count, }, ); + + Ok(()) } #[tauri::command] @@ -132,19 +161,17 @@ fn set_current_task( app: AppHandle, ) -> Result<(), String> { { - let mut app_data = data.data.lock().unwrap(); - // Validate task exists if Some + let app_data = data.data.lock().unwrap(); if let Some(ref tid) = task_id { if !app_data.tasks.iter().any(|t| &t.id == tid) { return Err(format!("Task {} not found", tid)); } } - app_data.current_task_id = task_id.clone(); - storage::save(&app_data_dir(&app), &app_data)?; } { let mut ts = timer.0.lock().unwrap(); ts.current_task_id = task_id; + persist_timer_snapshot(&ts, &data, &app)?; } Ok(()) } @@ -170,7 +197,6 @@ fn update_settings( { let mut app_data = data.data.lock().unwrap(); app_data.settings = settings.clone(); - storage::save(&app_data_dir(&app), &app_data)?; } // Restart timer at new work duration { @@ -180,6 +206,7 @@ fn update_settings( ts.remaining_secs = settings.work_duration_secs; ts.running = false; ts.session_count = 0; + persist_timer_snapshot(&ts, &data, &app)?; } sync_audio_ducking(&audio, TimerPhase::Work); Ok(()) @@ -199,6 +226,14 @@ fn add_task( data: State<'_, AppDataWrapper>, app: AppHandle, ) -> Result<Task, String> { + let name = name.trim().to_string(); + if name.is_empty() { + return Err("Task name cannot be empty".to_string()); + } + if total_sessions == 0 { + return Err("total_sessions must be at least 1".to_string()); + } + let task = Task { id: Uuid::new_v4().to_string(), name, @@ -268,6 +303,7 @@ fn delete_task( let mut ts = timer.0.lock().unwrap(); if ts.current_task_id.as_deref() == Some(&id) { ts.current_task_id = None; + persist_timer_snapshot(&ts, &data, &app)?; } } Ok(()) @@ -363,14 +399,14 @@ pub fn run() { // Load persisted data let app_data = storage::load(&data_dir); let work_secs = app_data.settings.work_duration_secs; - let current_task_id = app_data.current_task_id.clone(); + let timer_snapshot = app_data.timer_snapshot.clone(); let data_arc = Arc::new(Mutex::new(app_data)); - let timer_arc = Arc::new(Mutex::new({ - let mut ts = TimerState::new(work_secs); - ts.current_task_id = current_task_id; - ts - })); + let timer_arc = Arc::new(Mutex::new( + timer_snapshot + .map(TimerState::from_snapshot) + .unwrap_or_else(|| TimerState::new(work_secs)) + )); // Register managed state app.manage(TimerStateWrapper(Arc::clone(&timer_arc))); |
