Bring back the big timer; the bar pill takes over on scroll
The big asleep/awake card returns below the frozen bar, and the bar pill becomes its twin: both tick together, but the pill stays visibility-hidden — slot reserved, so the bar never shifts — while the card is on screen, appearing only once the card scrolls out of sight (rAF-throttled scroll check against the bar's bottom edge).
This commit is contained in:
+49
-6
@@ -673,29 +673,59 @@
|
||||
let bigClockState = null; // "asleep" | "awake" | null
|
||||
let bigClockSince = 0;
|
||||
|
||||
function renderBigClock(events) {
|
||||
// The counter renders twice: the big card at the top of the page and the
|
||||
// compact pill in the frozen day bar. The pill only *shows* once the big
|
||||
// card is scrolled out of sight (see updateBarClockMode); while the card is
|
||||
// visible the pill is invisible but keeps its slot so the bar never shifts.
|
||||
function updateBarClockMode() {
|
||||
const pill = document.getElementById("bar-clock");
|
||||
const icon = document.getElementById("bar-clock-icon");
|
||||
const time = document.getElementById("bar-clock-time");
|
||||
if (!bigClockState || pill.hidden) return;
|
||||
const card = document.getElementById("big-clock");
|
||||
const bar = document.querySelector(".day-bar");
|
||||
const cardVisible =
|
||||
card.getBoundingClientRect().bottom > bar.getBoundingClientRect().bottom;
|
||||
pill.classList.toggle("standby", cardVisible);
|
||||
}
|
||||
|
||||
function renderBigClock(events) {
|
||||
const card = document.getElementById("big-clock");
|
||||
const label = document.getElementById("bc-label");
|
||||
const time = document.getElementById("bc-time");
|
||||
const since = document.getElementById("bc-since");
|
||||
const pill = document.getElementById("bar-clock");
|
||||
const icon = document.getElementById("bar-clock-icon");
|
||||
const ptime = document.getElementById("bar-clock-time");
|
||||
const { state, since: ts } = currentSleepState(events);
|
||||
bigClockState = state;
|
||||
bigClockSince = ts;
|
||||
if (!state) {
|
||||
card.hidden = true;
|
||||
pill.hidden = true;
|
||||
return;
|
||||
}
|
||||
card.hidden = false;
|
||||
pill.hidden = false;
|
||||
card.classList.toggle("asleep", state === "asleep");
|
||||
card.classList.toggle("awake", state === "awake");
|
||||
pill.classList.toggle("asleep", state === "asleep");
|
||||
pill.classList.toggle("awake", state === "awake");
|
||||
label.textContent = state === "asleep" ? "Asleep for" : "Awake for";
|
||||
const counter = formatCounter(Date.now() - ts);
|
||||
time.textContent = counter;
|
||||
ptime.textContent = counter;
|
||||
since.textContent = `since ${formatTime(ts)}`;
|
||||
icon.textContent = state === "asleep" ? "😴" : "☀️";
|
||||
pill.title = `${state === "asleep" ? "Asleep" : "Awake"} since ${formatTime(ts)}`;
|
||||
time.textContent = formatCounter(Date.now() - ts);
|
||||
updateBarClockMode();
|
||||
}
|
||||
|
||||
function tickBigClock() {
|
||||
if (!bigClockState) return;
|
||||
const time = document.getElementById("bar-clock-time");
|
||||
if (time) time.textContent = formatCounter(Date.now() - bigClockSince);
|
||||
const counter = formatCounter(Date.now() - bigClockSince);
|
||||
const time = document.getElementById("bc-time");
|
||||
const ptime = document.getElementById("bar-clock-time");
|
||||
if (time) time.textContent = counter;
|
||||
if (ptime) ptime.textContent = counter;
|
||||
}
|
||||
|
||||
function renderWindowList(listId, emptyId, windows, ongoingLabel, extraClass) {
|
||||
@@ -2309,6 +2339,19 @@
|
||||
b.addEventListener("click", () => setChartDays(Number(b.dataset.days)));
|
||||
});
|
||||
|
||||
// Swap the timer pill in/out of the frozen bar as the big card scrolls
|
||||
// past. rAF-throttled: scroll events fire far more often than we can paint.
|
||||
{
|
||||
let queued = false;
|
||||
const onScroll = () => {
|
||||
if (queued) return;
|
||||
queued = true;
|
||||
requestAnimationFrame(() => { queued = false; updateBarClockMode(); });
|
||||
};
|
||||
window.addEventListener("scroll", onScroll, { passive: true });
|
||||
window.addEventListener("resize", onScroll, { passive: true });
|
||||
}
|
||||
|
||||
dayPicker.value = ymd(new Date());
|
||||
dayPicker.addEventListener("change", render);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user