Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4df5b0ec08 |
+14
-26
@@ -394,20 +394,23 @@
|
||||
return total;
|
||||
}
|
||||
|
||||
// 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 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.
|
||||
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 ||
|
||||
(e.at === latest.at && (e.updatedAt || 0) > (latest.updatedAt || 0))) {
|
||||
latest = e;
|
||||
}
|
||||
if (!latest || e.at > latest.at) latest = e;
|
||||
}
|
||||
if (!latest) return { state: null, since: 0 };
|
||||
return {
|
||||
@@ -600,7 +603,7 @@
|
||||
|
||||
const row = document.getElementById("currently-row");
|
||||
const currently = document.getElementById("currently");
|
||||
if (currentSleepState(events).state === "asleep") {
|
||||
if (isCurrentlyAsleep(events)) {
|
||||
row.hidden = false;
|
||||
currently.textContent = "😴 Asleep";
|
||||
} else {
|
||||
@@ -1274,10 +1277,6 @@
|
||||
let pendingType = null;
|
||||
let notePhotoBlob = null; // pending blob for the dialog (not yet committed)
|
||||
let notePhotoURL = null; // current preview object URL
|
||||
// Whether the user has manually touched the date/time fields. While false the
|
||||
// dialog logs at the exact current millisecond rather than the minute-floored
|
||||
// input, so a just-logged event doesn't look up to ~59s old.
|
||||
let noteTimeEdited = false;
|
||||
|
||||
function clearNotePhoto() {
|
||||
notePhotoBlob = null;
|
||||
@@ -1292,7 +1291,6 @@
|
||||
function openNoteDialog(type) {
|
||||
pendingType = type;
|
||||
noteInput.value = "";
|
||||
noteTimeEdited = false;
|
||||
const now = Date.now();
|
||||
noteDate.value = toDateInput(now);
|
||||
noteTime.value = toTimeInput(now);
|
||||
@@ -1306,9 +1304,6 @@
|
||||
}
|
||||
|
||||
function noteDialogAt() {
|
||||
// Untouched time → stamp the exact current instant (sub-minute accurate).
|
||||
// Once the user picks a time, honor the input (minute precision is fine).
|
||||
if (!noteTimeEdited) return Date.now();
|
||||
const parsed = fromDateTimeInputs(noteDate.value, noteTime.value);
|
||||
return Number.isFinite(parsed) ? parsed : Date.now();
|
||||
}
|
||||
@@ -1317,13 +1312,6 @@
|
||||
const now = Date.now();
|
||||
noteDate.value = toDateInput(now);
|
||||
noteTime.value = toTimeInput(now);
|
||||
noteTimeEdited = false; // "Now" means log at the current instant again
|
||||
});
|
||||
|
||||
[noteDate, noteTime].forEach(el => {
|
||||
const markEdited = () => { noteTimeEdited = true; };
|
||||
el.addEventListener("change", markEdited);
|
||||
el.addEventListener("input", markEdited);
|
||||
});
|
||||
|
||||
notePhotoBtn.addEventListener("click", () => notePhotoInput.click());
|
||||
|
||||
Reference in New Issue
Block a user