From 8f4034ef472200fcba0d070c5cabf9be22fa460f Mon Sep 17 00:00:00 2001 From: Alexander Heldt Date: Fri, 10 Jul 2026 12:33:00 +0000 Subject: [PATCH] Fix "Currently" row disagreeing with the big clock about sleep state The "Currently" row derived its state from isCurrentlyAsleep() (ascending stable sort, then fold) while the big clock used currentSleepState() (max-by-`at` with a strict >). When two sleep boundary events shared the same `at`, the two broke the tie differently, so the row could show "Asleep" during a wake window while the clock said "Awake". Make both read from the single currentSleepState() source, and give it a deterministic tie-breaker: for equal `at`, the later updatedAt (most recently logged boundary) wins. Remove the now-unused isCurrentlyAsleep(). --- src/app.js | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/app.js b/src/app.js index d14c712..7d8ca9c 100644 --- a/src/app.js +++ b/src/app.js @@ -394,23 +394,20 @@ return total; } - function isCurrentlyAsleep(events) { - const sorted = [...events].sort((a, b) => a.at - b.at); - let asleep = false; - for (const e of sorted) { - if (e.type === "sleep-start") asleep = true; - else if (e.type === "sleep-end") asleep = false; - } - return asleep; - } - - // Current state derived from the *latest* sleep event. Used by the live - // counter at the top of the page. + // Current state derived from the *latest* sleep event. The single source of + // truth for both the big clock and the "Currently" row. For two boundary + // events sharing the same `at` (common once "now" events are minute-floored), + // the one logged later (higher updatedAt) wins, so the tie resolves the same + // way everywhere it's read. function currentSleepState(events) { let latest = null; for (const e of events) { if (e.type !== "sleep-start" && e.type !== "sleep-end") continue; - if (!latest || e.at > latest.at) latest = e; + if (!latest || + e.at > latest.at || + (e.at === latest.at && (e.updatedAt || 0) > (latest.updatedAt || 0))) { + latest = e; + } } if (!latest) return { state: null, since: 0 }; return { @@ -603,7 +600,7 @@ const row = document.getElementById("currently-row"); const currently = document.getElementById("currently"); - if (isCurrentlyAsleep(events)) { + if (currentSleepState(events).state === "asleep") { row.hidden = false; currently.textContent = "😴 Asleep"; } else {