From 2100b7c91416c9f485d609bb629a606ef153cc02 Mon Sep 17 00:00:00 2001 From: okaryo Date: Sun, 31 May 2026 19:29:22 +0900 Subject: [PATCH] fix: update Now behavior and Pomodoro timer logic to prevent resets when already running --- TODO.md | 3 ++- src/lib/components/PomodoroSection.svelte | 13 ++++++++++-- src/lib/pomodoro/timer.test.ts | 25 +++++++++++++++++++++++ src/lib/pomodoro/timer.ts | 11 ++++++++++ 4 files changed, 49 insertions(+), 3 deletions(-) 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,