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().
This commit is contained in:
Alexander Heldt
2026-07-10 12:33:00 +00:00
parent dbcac0653e
commit 8f4034ef47
+11 -14
View File
@@ -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 {