Turn the next-sync indicator into a live ticking countdown
Replaces the one-time UTC-to-local formatting with a per-second countdown (HH:MM:SS, or MM:SS under an hour) that fits the dark cockpit theme's instrument-panel feel, falling back to "due now" once the target passes instead of showing a negative duration. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,39 @@
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.querySelectorAll("time[data-utc]").forEach((el) => {
|
||||
const date = new Date(el.dataset.utc);
|
||||
if (Number.isNaN(date.getTime())) {
|
||||
return;
|
||||
function formatCountdown(remainingMs) {
|
||||
if (remainingMs <= 0) {
|
||||
return "due now";
|
||||
}
|
||||
const totalSeconds = Math.floor(remainingMs / 1000);
|
||||
const hours = Math.floor(totalSeconds / 3600);
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
const seconds = totalSeconds % 60;
|
||||
const pad = (n) => String(n).padStart(2, "0");
|
||||
if (hours > 0) {
|
||||
return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
|
||||
}
|
||||
return `${pad(minutes)}:${pad(seconds)}`;
|
||||
}
|
||||
|
||||
function startSyncCountdown(el) {
|
||||
const target = new Date(el.dataset.utc);
|
||||
if (Number.isNaN(target.getTime())) {
|
||||
return;
|
||||
}
|
||||
el.title = `${target.toLocaleString(undefined, { dateStyle: "medium", timeStyle: "short" })} · ${el.dataset.utc} UTC`;
|
||||
|
||||
let intervalId = null;
|
||||
const tick = () => {
|
||||
const remaining = target.getTime() - Date.now();
|
||||
el.textContent = formatCountdown(remaining);
|
||||
if (remaining <= 0 && intervalId !== null) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
el.textContent = date.toLocaleString(undefined, { dateStyle: "medium", timeStyle: "short" });
|
||||
el.title = `${el.dataset.utc} (UTC)`;
|
||||
});
|
||||
};
|
||||
tick();
|
||||
if (target.getTime() - Date.now() > 0) {
|
||||
intervalId = setInterval(tick, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.querySelectorAll("time.next-sync[data-utc]").forEach(startSyncCountdown);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user