From a7e2a94ddb19864d4a1f78a420fcf66a9e38f4e5 Mon Sep 17 00:00:00 2001 From: Solstice Date: Tue, 9 Jun 2026 00:54:12 -0700 Subject: fix: sync ambient ducking on manual phase changes --- src-tauri/src/lib.rs | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'src-tauri/src') diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index d1864eb..11bb2f9 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -23,6 +23,16 @@ fn app_data_dir(app: &AppHandle) -> std::path::PathBuf { app.path().app_data_dir().expect("Failed to resolve app data dir") } +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) { + engine.duck(); + } else { + engine.unduck(); + } + } +} + // ── Timer commands ────────────────────────────────────────────────────────── #[tauri::command] @@ -70,6 +80,7 @@ fn reset_timer(timer: State<'_, TimerStateWrapper>, data: State<'_, AppDataWrapp fn skip_phase( timer: State<'_, TimerStateWrapper>, data: State<'_, AppDataWrapper>, + audio: State<'_, AudioState>, app: AppHandle, ) { use tauri::Emitter; @@ -98,12 +109,17 @@ fn skip_phase( } ts.running = false; + let phase = ts.phase; + let session_count = ts.session_count; + drop(ts); + + sync_audio_ducking(&audio, phase); let _ = app.emit( "timer-phase-changed", timer::PhaseChangedPayload { - phase: ts.phase, - session_count: ts.session_count, + phase, + session_count, }, ); } @@ -145,6 +161,7 @@ fn update_settings( settings: Settings, data: State<'_, AppDataWrapper>, timer: State<'_, TimerStateWrapper>, + audio: State<'_, AudioState>, app: AppHandle, ) -> Result<(), String> { if settings.sessions_before_long_break == 0 { @@ -164,6 +181,7 @@ fn update_settings( ts.running = false; ts.session_count = 0; } + sync_audio_ducking(&audio, TimerPhase::Work); Ok(()) } @@ -266,7 +284,11 @@ struct AudioStatus { } #[tauri::command] -fn play_ambient(sound: String, audio: State<'_, AudioState>) -> Result<(), String> { +fn play_ambient( + sound: String, + audio: State<'_, AudioState>, + timer: State<'_, TimerStateWrapper>, +) -> Result<(), String> { let mut guard = audio.0.lock().unwrap(); match guard.as_mut() { None => Err("Audio not available".to_string()), @@ -276,7 +298,16 @@ fn play_ambient(sound: String, audio: State<'_, AudioState>) -> Result<(), Strin Ok(()) } else { match audio::AmbientSound::from_str(&sound) { - Some(s) => engine.play(s), + Some(s) => { + engine.play(s)?; + let phase = timer.0.lock().unwrap().phase; + if audio::should_duck_for_phase(phase) { + engine.duck(); + } else { + engine.unduck(); + } + Ok(()) + } None => Err(format!("Unknown sound: {sound}")), } } -- cgit v1.3-2-g0d8e