Disable the sleep boundary that repeats the last one
While asleep, tapping "Sleep start" again can only produce a zero-length
sleep window, and likewise "Sleep end" while awake — so renderActionHints
now disables that button outright instead of merely dimming it, with a
title explaining why ("Already asleep" / "Already awake"). Every other
action stays clickable, and a genuinely missed boundary is still fixable
from the event log, which accepts any time. With no sleep history yet,
either boundary remains a valid first event.
Also adds nodejs to the dev shell for `node --check` on src/*.js.
This commit is contained in:
@@ -59,7 +59,9 @@
|
||||
};
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
packages = [ pkgs.go pkgs.python3 ];
|
||||
# nodejs is here for `node --check` on src/*.js — the frontend has no
|
||||
# build step, so this is a syntax-check tool, not a dependency.
|
||||
packages = [ pkgs.go pkgs.python3 pkgs.nodejs ];
|
||||
shellHook = ''
|
||||
echo "puppy-tracker dev shell"
|
||||
echo " cd server && go run . -static ../src -data /tmp/puppy-events.json"
|
||||
|
||||
+17
-4
@@ -1989,17 +1989,30 @@
|
||||
}
|
||||
|
||||
// Dim the quick actions that don't fit the current sleep state — a nudge
|
||||
// toward the likely next tap, never a block: everything stays clickable so
|
||||
// corrections (a missed sleep-end, a mid-nap pee) are always possible.
|
||||
// toward the likely next tap. The one boundary that would just repeat the
|
||||
// latest sleep event (a second "sleep start" while already asleep, or a
|
||||
// second "sleep end" while already awake) is disabled outright, since it
|
||||
// can only produce a zero-length window. Everything else stays clickable so
|
||||
// corrections (a mid-nap pee) are never blocked, and a genuinely missed
|
||||
// boundary is still fixable from the event log, which accepts any time.
|
||||
function renderActionHints(events) {
|
||||
const { state } = currentSleepState(events);
|
||||
document.querySelectorAll("button.action").forEach(btn => {
|
||||
const type = btn.dataset.type;
|
||||
const unlikely =
|
||||
const repeat =
|
||||
state === "asleep" ? type === "sleep-start"
|
||||
: state === "awake" ? type === "sleep-end"
|
||||
: false; // no sleep history yet — either boundary is a fine first event
|
||||
const unlikely = !repeat && (
|
||||
state === "asleep" ? type !== "sleep-end"
|
||||
: state === "awake" ? type === "sleep-end"
|
||||
: false; // no sleep history yet — no hints to give
|
||||
: false // no sleep history yet — no hints to give
|
||||
);
|
||||
btn.classList.toggle("unlikely", unlikely);
|
||||
btn.disabled = repeat;
|
||||
btn.title = repeat
|
||||
? (type === "sleep-start" ? "Already asleep" : "Already awake")
|
||||
: "";
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
[
|
||||
{ "date": "2026-08-18", "text": "The sleep button that would just repeat the last one is now disabled: while asleep you can only tap ⏰ Sleep end, and while awake only 😴 Sleep start — no more accidental double taps creating zero-length sleep windows. If you did miss a boundary, you can still add it at the right time from the event log" },
|
||||
{ "date": "2026-08-02", "text": "Added free-text notes: tap 📝 Note to jot down things that happened on a day — vaccinations, vet visits, milestones — with a date, optional photo, and any text. All your notes are collected in a new Notes section that stays visible whatever day you're viewing, so you can see at a glance when things like a tick vaccination were done" },
|
||||
{ "date": "2026-08-02", "text": "The Daily counts chart now has Pees / Poos / Meals checkboxes so you can focus on just the metrics you care about — untick the rest to see, say, only poos; your choice is remembered" },
|
||||
{ "date": "2026-08-01", "text": "Logging a pee or poo now sets off 💧/💩 fireworks that shoot up from the bottom of the screen — a little celebration you can switch off in Settings (and it honours a reduced-motion preference)" },
|
||||
|
||||
@@ -272,6 +272,17 @@ button.action.note { background: var(--note); }
|
||||
but fully tappable, so corrections are never blocked. */
|
||||
button.action.unlikely { opacity: 0.4; }
|
||||
|
||||
/* The boundary that would repeat the latest sleep event is disabled outright
|
||||
(see renderActionHints) — greyed out rather than merely dimmed, so it reads
|
||||
as unavailable instead of just discouraged. */
|
||||
button.action:disabled {
|
||||
opacity: 0.35;
|
||||
filter: grayscale(1);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
button.action:disabled:active { transform: none; }
|
||||
button.action:disabled:hover { filter: grayscale(1); }
|
||||
|
||||
button.ghost {
|
||||
background: transparent;
|
||||
color: var(--text);
|
||||
|
||||
Reference in New Issue
Block a user