diff --git a/TODO.md b/TODO.md index 791de19..610834d 100644 --- a/TODO.md +++ b/TODO.md @@ -140,7 +140,8 @@ Now behavior: - Now is session-local UI state and is not persisted to SQLite. - Reopening the app should start with no Now task selected. - When Now is active, the Now TODO title is emphasized and other incomplete TODO titles are dimmed. -- Setting Now resets the Pomodoro timer to `25:00` and starts focus. +- Setting Now resets the Pomodoro timer to the configured focus duration and starts focus when the timer is idle or paused. +- Setting Now while the Pomodoro timer is already running only updates Now and does not reset the remaining time. - Unsetting Now does not stop the Pomodoro timer. - Completing the Now task clears Now but does not stop the Pomodoro timer. diff --git a/src/lib/components/PomodoroSection.svelte b/src/lib/components/PomodoroSection.svelte index 7702b74..56e4306 100644 --- a/src/lib/components/PomodoroSection.svelte +++ b/src/lib/components/PomodoroSection.svelte @@ -18,7 +18,7 @@ pomodoroStatus, resetPomodoro, setPomodoroDuration, - startFocusPomodoro, + startFocusPomodoroUnlessRunning, tickPomodoro, togglePomodoro, type PomodoroState, @@ -147,7 +147,16 @@ } function startFocusTimer() { - pomodoroState = startFocusPomodoro(focusDurationSeconds); + const nextState = startFocusPomodoroUnlessRunning( + pomodoroState, + focusDurationSeconds, + ); + + if (nextState === pomodoroState) { + return; + } + + pomodoroState = nextState; syncInterval(); } diff --git a/src/lib/pomodoro/timer.test.ts b/src/lib/pomodoro/timer.test.ts index 1dac9a0..fa38fe7 100644 --- a/src/lib/pomodoro/timer.test.ts +++ b/src/lib/pomodoro/timer.test.ts @@ -9,6 +9,7 @@ import { resetPomodoro, setPomodoroDuration, startFocusPomodoro, + startFocusPomodoroUnlessRunning, tickPomodoro, togglePomodoro, } from "$lib/pomodoro/timer"; @@ -38,6 +39,30 @@ describe("pomodoro timer state", () => { }); }); + it("does not restart focus when the timer is already running", () => { + const state = { + remainingSeconds: 10 * 60, + durationSeconds: FOCUS_DURATION_SECONDS, + running: true, + }; + + expect(startFocusPomodoroUnlessRunning(state)).toBe(state); + }); + + it("starts focus from the full duration when the timer is not running", () => { + expect( + startFocusPomodoroUnlessRunning({ + remainingSeconds: 10 * 60, + durationSeconds: FOCUS_DURATION_SECONDS, + running: false, + }), + ).toEqual({ + remainingSeconds: FOCUS_DURATION_SECONDS, + durationSeconds: FOCUS_DURATION_SECONDS, + running: true, + }); + }); + it("uses custom focus durations", () => { const durationSeconds = 10 * 60; diff --git a/src/lib/pomodoro/timer.ts b/src/lib/pomodoro/timer.ts index 7b4735f..82492c5 100644 --- a/src/lib/pomodoro/timer.ts +++ b/src/lib/pomodoro/timer.ts @@ -59,6 +59,17 @@ export function startFocusPomodoro( }; } +export function startFocusPomodoroUnlessRunning( + state: PomodoroState, + durationSeconds = FOCUS_DURATION_SECONDS, +): PomodoroState { + if (state.running) { + return state; + } + + return startFocusPomodoro(durationSeconds); +} + export function setPomodoroDuration( state: PomodoroState, durationSeconds: number,