diff --git a/client/src/App.jsx b/client/src/App.jsx index 10231e3..be0b03f 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -10,6 +10,7 @@ import { } from "./api.js"; const queueStatuses = ["new", "making", "ready"]; +const orderIdleTimeoutMs = 90_000; const initialBuilder = (settings) => ({ size: settings.sizeOptions[0]?.name ?? "Regular", @@ -44,6 +45,31 @@ export default function App() { loadBootstrap(); }, []); + useEffect(() => { + if (view !== "order" || !orderMode) { + return; + } + + let timeoutId = window.setTimeout(() => { + setOrderMode(null); + }, orderIdleTimeoutMs); + + function resetIdleTimer() { + window.clearTimeout(timeoutId); + timeoutId = window.setTimeout(() => { + setOrderMode(null); + }, orderIdleTimeoutMs); + } + + const events = ["pointerdown", "keydown", "touchstart"]; + events.forEach((eventName) => window.addEventListener(eventName, resetIdleTimer, { passive: true })); + + return () => { + window.clearTimeout(timeoutId); + events.forEach((eventName) => window.removeEventListener(eventName, resetIdleTimer)); + }; + }, [view, orderMode]); + useEffect(() => { if (!settings) { return; @@ -147,6 +173,17 @@ export default function App() { {view === "order" && (
+ {orderMode && ( +
+ +

+ This screen returns to the start menu after 90 seconds of inactivity. +

+
+ )} + {!orderMode && (
diff --git a/client/src/styles.css b/client/src/styles.css index 928702f..3e6b7ab 100644 --- a/client/src/styles.css +++ b/client/src/styles.css @@ -90,6 +90,19 @@ button { gap: 1rem; } +.order-toolbar { + grid-column: 1 / -1; + display: flex; + justify-content: space-between; + align-items: center; + gap: 1rem; + padding: 0 0.25rem; +} + +.order-toolbar-note { + margin: 0; +} + .queue-screen, .menu-screen { display: grid; @@ -354,6 +367,11 @@ select { grid-template-columns: 1fr; } + .order-toolbar { + align-items: flex-start; + flex-direction: column; + } + .tabs { width: 100%; }