Log an event that happened "now" in one tap
Logging a quick pee/poo/meal/sleep boundary took two taps: open the note dialog, then Save. Make a single tap on a quick-action log the event immediately at the current time. Non-weight quick actions now call addEvent(type, "", Date.now()) directly and show a brief snackbar with Undo (deletes the just-added event) and Add note (opens the edit dialog for it), so notes, photos and custom times are never lost. Weigh-ins still open the dialog since they need a value. addEvent now returns the created event so the snackbar can reference it.
This commit is contained in:
+55
-3
@@ -258,7 +258,7 @@
|
||||
function addEvent(type, note, at, photoId, weight) {
|
||||
const events = loadAll();
|
||||
const now = Date.now();
|
||||
events.push({
|
||||
const ev = {
|
||||
id: uuid(),
|
||||
type,
|
||||
at: Number.isFinite(at) ? at : now,
|
||||
@@ -266,10 +266,12 @@
|
||||
photoId: photoId || "",
|
||||
weight: Number.isFinite(weight) ? weight : undefined,
|
||||
updatedAt: now,
|
||||
});
|
||||
};
|
||||
events.push(ev);
|
||||
saveAll(events);
|
||||
scheduleSync();
|
||||
render();
|
||||
return ev;
|
||||
}
|
||||
|
||||
function updateEvent(id, patch) {
|
||||
@@ -1602,9 +1604,59 @@
|
||||
}
|
||||
});
|
||||
|
||||
// ---------- quick-log snackbar ----------
|
||||
// A single tap on a quick-action logs the event at the current instant, then
|
||||
// shows a brief snackbar to undo it or add detail — so the two-tap dialog flow
|
||||
// is never required for a plain pee/poo/meal/sleep boundary. Weigh-ins still
|
||||
// open the dialog since they need a value.
|
||||
const snackbar = document.getElementById("snackbar");
|
||||
const snackbarMsg = document.getElementById("snackbar-msg");
|
||||
const snackbarUndo = document.getElementById("snackbar-undo");
|
||||
const snackbarNote = document.getElementById("snackbar-note");
|
||||
let snackbarEvent = null;
|
||||
let snackbarTimer = null;
|
||||
|
||||
function hideSnackbar() {
|
||||
clearTimeout(snackbarTimer);
|
||||
snackbarTimer = null;
|
||||
snackbarEvent = null;
|
||||
snackbar.classList.remove("show");
|
||||
snackbar.hidden = true;
|
||||
}
|
||||
|
||||
function showSnackbar(msg, ev) {
|
||||
snackbarEvent = ev;
|
||||
snackbarMsg.textContent = msg;
|
||||
snackbar.hidden = false;
|
||||
void snackbar.offsetWidth; // reflow so the fade-in transition runs
|
||||
snackbar.classList.add("show");
|
||||
clearTimeout(snackbarTimer);
|
||||
snackbarTimer = setTimeout(hideSnackbar, 5000);
|
||||
}
|
||||
|
||||
function quickLog(type) {
|
||||
const ev = addEvent(type, "", Date.now());
|
||||
showSnackbar(`${EVENT_LABELS[type]} logged`, ev);
|
||||
}
|
||||
|
||||
snackbarUndo.addEventListener("click", () => {
|
||||
if (snackbarEvent) deleteEvent(snackbarEvent.id);
|
||||
hideSnackbar();
|
||||
});
|
||||
snackbarNote.addEventListener("click", () => {
|
||||
const ev = snackbarEvent;
|
||||
hideSnackbar();
|
||||
if (ev) openEditDialog(ev);
|
||||
});
|
||||
|
||||
// ---------- wiring ----------
|
||||
document.querySelectorAll("button.action").forEach(btn => {
|
||||
btn.addEventListener("click", () => openNoteDialog(btn.dataset.type));
|
||||
btn.addEventListener("click", () => {
|
||||
const type = btn.dataset.type;
|
||||
// Weigh-ins need a typed value, so they keep the full dialog.
|
||||
if (type === "weight") { openNoteDialog(type); return; }
|
||||
quickLog(type);
|
||||
});
|
||||
});
|
||||
|
||||
dayPicker.value = ymd(new Date());
|
||||
|
||||
Reference in New Issue
Block a user