Make the day-bar sleep pill a one-tap toggle
Once the big timer scrolls away, the pill in the day bar is the only thing still showing the sleep state — but acting on it meant scrolling back up to the quick actions. Tapping the pill now logs the boundary that ends the state it displays: sleep-end while asleep, sleep-start while awake. It routes through quickLog(), so the snackbar and its undo behave exactly as they do from the buttons, and the state is read from currentSleepState() rather than the cached bigClockState so a tap can't act on a stale render. The pill becomes a real <button>, which brings keyboard operation along for free. In standby it is visibility:hidden, so while the big card is on screen it is neither clickable nor tab-reachable, and the toggle is live exactly when the pill is visible. The .day-bar button padding and :disabled rules are scoped to :not(.bar-clock) so they don't start outranking the pill's own sizing, and the default accent button background is reset since the asleep/awake classes paint it.
This commit is contained in:
+13
-1
@@ -781,7 +781,9 @@
|
|||||||
ptime.textContent = counter;
|
ptime.textContent = counter;
|
||||||
since.textContent = `since ${formatTime(ts)}`;
|
since.textContent = `since ${formatTime(ts)}`;
|
||||||
icon.textContent = state === "asleep" ? "😴" : "☀️";
|
icon.textContent = state === "asleep" ? "😴" : "☀️";
|
||||||
pill.title = `${state === "asleep" ? "Asleep" : "Awake"} since ${formatTime(ts)}`;
|
const flip = state === "asleep" ? "Sleep end" : "Sleep start";
|
||||||
|
pill.title = `${state === "asleep" ? "Asleep" : "Awake"} since ${formatTime(ts)} — tap to log ${flip.toLowerCase()}`;
|
||||||
|
pill.setAttribute("aria-label", `${state === "asleep" ? "Asleep" : "Awake"} since ${formatTime(ts)}. Log ${flip.toLowerCase()}.`);
|
||||||
updateBarClockMode();
|
updateBarClockMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3674,6 +3676,16 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The timer pill doubles as a one-tap sleep toggle: tapping it logs the
|
||||||
|
// boundary that ends the state it shows, exactly like the matching quick
|
||||||
|
// action. Only reachable once the big card has scrolled away — in standby
|
||||||
|
// the pill is visibility:hidden, so clicks can never land on it.
|
||||||
|
document.getElementById("bar-clock").addEventListener("click", () => {
|
||||||
|
const { state } = currentSleepState(live());
|
||||||
|
if (!state) return; // no sleep history yet; the pill is hidden anyway
|
||||||
|
quickLog(state === "asleep" ? "sleep-end" : "sleep-start");
|
||||||
|
});
|
||||||
|
|
||||||
document.querySelectorAll(".chart-days-picker button").forEach(b => {
|
document.querySelectorAll(".chart-days-picker button").forEach(b => {
|
||||||
b.addEventListener("click", () => setChartDays(Number(b.dataset.days)));
|
b.addEventListener("click", () => setChartDays(Number(b.dataset.days)));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
[
|
[
|
||||||
|
{ "date": "2026-08-21", "text": "The sleep timer pill in the day bar — the one that appears once you've scrolled past the big timer — is now tappable: tap it while the puppy is asleep to log the wake-up, or while awake to log a sleep start, without scrolling back up to the buttons" },
|
||||||
{ "date": "2026-08-20", "text": "Added reminders: turn them on in Settings and your phone gets a notification when it's time to sleep (\"Awake for 45 min\") or when there's been no pee, poo or meal for a while. Each one has its own interval, they arrive even with the app closed, and they stay quiet while the puppy is logged as asleep so you're not nagged all night. On iPhone, add Puppy Tracker to your Home Screen first — iOS only allows notifications for installed apps" },
|
{ "date": "2026-08-20", "text": "Added reminders: turn them on in Settings and your phone gets a notification when it's time to sleep (\"Awake for 45 min\") or when there's been no pee, poo or meal for a while. Each one has its own interval, they arrive even with the app closed, and they stay quiet while the puppy is logged as asleep so you're not nagged all night. On iPhone, add Puppy Tracker to your Home Screen first — iOS only allows notifications for installed apps" },
|
||||||
{ "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-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": "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" },
|
||||||
|
|||||||
+5
-3
@@ -81,11 +81,13 @@
|
|||||||
<section class="day-bar">
|
<section class="day-bar">
|
||||||
<!-- Compact twin of the big timer below: invisible (but keeping its
|
<!-- Compact twin of the big timer below: invisible (but keeping its
|
||||||
slot) while the big card is on screen, shown once it scrolls
|
slot) while the big card is on screen, shown once it scrolls
|
||||||
away. Hidden entirely until a sleep event exists. -->
|
away. Hidden entirely until a sleep event exists. Tapping it logs
|
||||||
<div id="bar-clock" class="bar-clock" hidden>
|
the boundary that flips the current state (asleep → sleep end,
|
||||||
|
awake → sleep start). -->
|
||||||
|
<button type="button" id="bar-clock" class="bar-clock" hidden>
|
||||||
<span id="bar-clock-icon" aria-hidden="true"></span>
|
<span id="bar-clock-icon" aria-hidden="true"></span>
|
||||||
<span id="bar-clock-time"></span>
|
<span id="bar-clock-time"></span>
|
||||||
</div>
|
</button>
|
||||||
<button type="button" id="day-prev" class="ghost" aria-label="Previous day">←</button>
|
<button type="button" id="day-prev" class="ghost" aria-label="Previous day">←</button>
|
||||||
<!-- A browser won't let us shorten the text a native date input shows,
|
<!-- A browser won't let us shorten the text a native date input shows,
|
||||||
so the face button carries a compact year-less date and the real
|
so the face button carries a compact year-less date and the real
|
||||||
|
|||||||
+7
-3
@@ -177,22 +177,26 @@ body::before {
|
|||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.day-bar button {
|
.day-bar button:not(.bar-clock) {
|
||||||
padding: 8px 10px;
|
padding: 8px 10px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
/* Keep the single row intact on narrow phones. */
|
/* Keep the single row intact on narrow phones. */
|
||||||
@media (max-width: 370px) {
|
@media (max-width: 370px) {
|
||||||
.day-bar { gap: 4px; }
|
.day-bar { gap: 4px; }
|
||||||
.day-bar button { padding: 8px 7px; }
|
.day-bar button:not(.bar-clock) { padding: 8px 7px; }
|
||||||
.bar-clock { font-size: 0.9rem; padding: 6px 8px; gap: 5px; }
|
.bar-clock { font-size: 0.9rem; padding: 6px 8px; gap: 5px; }
|
||||||
}
|
}
|
||||||
.day-bar button:disabled {
|
.day-bar button:not(.bar-clock):disabled {
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
.bar-clock {
|
.bar-clock {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
/* It is a button (tapping it flips the sleep state), so undo the default
|
||||||
|
accent look — the asleep/awake classes below paint it. */
|
||||||
|
background: var(--surface);
|
||||||
|
color: var(--text);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
margin-right: auto; /* pin left; the flexible gap sits between it and the day controls */
|
margin-right: auto; /* pin left; the flexible gap sits between it and the day controls */
|
||||||
|
|||||||
Reference in New Issue
Block a user