- Comments on visible recipes; author and admin may delete; per-user hourly rate limit (COMMENT_RATE_LIMIT_PER_HOUR) - Cooking mode with large text, tick-off checklists, serving scaling and Screen Wake Lock to keep the display on - Serving calculator auto-submits on change - Privacy tests cover comment and cooking-mode URLs Co-Authored-By: Claude Opus 5.5 <[email protected]>
42 lines
1.4 KiB
JavaScript
42 lines
1.4 KiB
JavaScript
// Small progressive enhancements. Everything works without JavaScript.
|
|
document.addEventListener("click", async (event) => {
|
|
const button = event.target.closest("[data-copy]");
|
|
if (!button) return;
|
|
const input = document.querySelector(button.dataset.copy);
|
|
if (!input) return;
|
|
input.select();
|
|
try {
|
|
await navigator.clipboard.writeText(input.value);
|
|
button.textContent = "Kopiert ✓";
|
|
} catch {
|
|
button.textContent = "Bitte manuell kopieren";
|
|
}
|
|
});
|
|
|
|
// Serving calculator: recalculate as soon as the number changes.
|
|
document.addEventListener("change", (event) => {
|
|
const input = event.target.closest(".servings input[name=portionen]");
|
|
if (input && input.value) input.form.requestSubmit();
|
|
});
|
|
|
|
// Cooking mode: keep the screen on while the page is visible (Screen Wake Lock API).
|
|
(() => {
|
|
const page = document.querySelector("[data-wakelock]");
|
|
if (!page || !("wakeLock" in navigator)) return;
|
|
const status = page.querySelector(".wakelock-status");
|
|
let lock = null;
|
|
const acquire = async () => {
|
|
try {
|
|
lock = await navigator.wakeLock.request("screen");
|
|
if (status) status.hidden = false;
|
|
lock.addEventListener("release", () => { if (status) status.hidden = true; });
|
|
} catch {
|
|
// Not allowed right now (e.g. battery saver); the page still works.
|
|
}
|
|
};
|
|
document.addEventListener("visibilitychange", () => {
|
|
if (document.visibilityState === "visible") acquire();
|
|
});
|
|
acquire();
|
|
})();
|