From 870edda1237983f6760e0bec1a767fe703be5465 Mon Sep 17 00:00:00 2001 From: timmy Date: Wed, 19 Aug 2026 18:08:35 +0000 Subject: [PATCH] Preserve timed break when active work reopens --- frontend/today-timer.js | 3 ++- tests/test_today_break.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/frontend/today-timer.js b/frontend/today-timer.js index 0e05452..a525ffa 100644 --- a/frontend/today-timer.js +++ b/frontend/today-timer.js @@ -114,7 +114,8 @@ function createTodayTimer({ storage, getLogin, now = () => Date.now(), onChange activate(identity) { if (!key() || typeof identity !== 'string' || !identity) return false; const state = read(); - if (state.active_identity === identity && state.entries[identity]?.running) return true; + if (state.active_identity === identity && + (state.entries[identity]?.running || validBreak(state)?.identity === identity)) return true; settle(state); state.active_identity = identity; const entry = state.entries[identity] || { elapsed_ms:0, started_at:null, running:false }; diff --git a/tests/test_today_break.py b/tests/test_today_break.py index f57ae08..d08a88c 100644 --- a/tests/test_today_break.py +++ b/tests/test_today_break.py @@ -65,6 +65,34 @@ process.stdout.write(JSON.stringify(timer.snapshot())); } +def test_reactivating_the_active_item_during_reload_preserves_its_timed_break(): + script = TIMER.read_text() + r""" +const values = new Map(); +const storage = {getItem:key=>values.get(key)||null,setItem:(key,value)=>values.set(key,value)}; +let now = 100000; +const timer = createTodayTimer({storage,getLogin:()=> 'timmy',now:()=>now}); +timer.activate('issue:r:42:'); +timer.startBreak(5); +const reopened = timer.activate('issue:r:42:'); +process.stdout.write(JSON.stringify({reopened,snapshot:timer.snapshot(),pending:timer.breakSnapshot()})); +""" + + assert run_node(script) == { + "reopened": True, + "snapshot": { + "identity": "issue:r:42:", + "elapsed_ms": 0, + "running": False, + "break_deadline_at": 400_000, + }, + "pending": { + "identity": "issue:r:42:", + "deadline_at": 400_000, + "expired": False, + }, + } + + def test_break_expiry_never_restarts_time_and_resume_is_explicit_and_idempotent(): script = TIMER.read_text() + r""" const values = new Map();