From fe12098ed087b504648cbdf311f576f3b2732dc9 Mon Sep 17 00:00:00 2001 From: Martin Berka Date: Mon, 19 Oct 2026 21:09:39 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20nep=C5=99ep=C3=ADn=C3=A1n=C3=AD=20dn?= =?UTF-8?q?=C5=AF/t=C3=BDdn=C5=AF=20p=C5=99i=20otev=C5=99en=C3=A9=20minih?= =?UTF-8?q?=C5=99e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/App.tsx | 2 ++ client/src/pages/OrderGroupsPage.tsx | 6 +++--- client/src/pages/StatsPage.tsx | 2 ++ client/src/utils/arrowNavigation.ts | 11 +++++++++++ server/changelogs/2026-10-19.json | 3 ++- 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 client/src/utils/arrowNavigation.ts diff --git a/client/src/App.tsx b/client/src/App.tsx index aabef14..34f8748 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -30,6 +30,7 @@ import PendingPayments from './components/PendingPayments'; import { useEasterEgg } from './context/eggs'; import { ClientData, Food, MealSlot, PendingQr, PizzaOrder, DepartureTime, PizzaDayState, Restaurant, RestaurantDayMenu, RestaurantDayMenuMap, LunchChoice, LocationLunchChoicesMap, UserLunchChoice, PizzaVariant, getData, getEasterEggImage, addPizza, removePizza, updatePizzaDayNote, createPizzaDay, deletePizzaDay, lockPizzaDay, unlockPizzaDay, finishOrder, finishDelivery, addChoice, jdemeObed, removeChoices, removeChoice, updateNote, changeDepartureTime, setBuyer, generateQr } from '../../types'; import { getLunchChoiceName } from './enums'; +import { isArrowNavigationBlocked } from './utils/arrowNavigation'; // import FallingLeaves, { LEAF_PRESETS, LEAF_COLOR_THEMES } from './FallingLeaves'; // import './FallingLeaves.scss'; @@ -244,6 +245,7 @@ function App() { // Navigace mezi dny pomocí klávesových šípek const handleKeyDown = useCallback((e: any) => { + if (isArrowNavigationBlocked(e)) return; if (e.keyCode === 37 && dayIndex != null && dayIndex > 0) { handleDayChange(dayIndex - 1); } else if (e.keyCode === 39 && dayIndex != null && dayIndex < 4) { diff --git a/client/src/pages/OrderGroupsPage.tsx b/client/src/pages/OrderGroupsPage.tsx index 0f42456..2e2a96e 100644 --- a/client/src/pages/OrderGroupsPage.tsx +++ b/client/src/pages/OrderGroupsPage.tsx @@ -30,6 +30,7 @@ import BoltSimulationModal from '../components/modals/BoltSimulationModal'; import GenerateMockOrdersModal from '../components/modals/GenerateMockOrdersModal'; import PendingPayments from '../components/PendingPayments'; import OrderProgress, { PROVIDER_LABEL } from '../components/OrderProgress'; +import { isArrowNavigationBlocked } from '../utils/arrowNavigation'; const SLOT = MealSlot.EXTRA; const TIME_REGEX = /^([01]\d|2[0-3]):[0-5]\d$/; @@ -224,9 +225,8 @@ export default function OrderGroupsPage() { // Navigace mezi dny pomocí klávesových šipek (←/→), obdobně jako na hlavní stránce const handleKeyDown = useCallback((e: KeyboardEvent) => { - // Ignorujeme, pokud uživatel právě píše do formulářového pole - const tag = (e.target as HTMLElement)?.tagName; - if (tag === 'INPUT' || tag === 'SELECT' || tag === 'TEXTAREA') return; + // Ignorujeme, pokud uživatel právě píše do formulářového pole nebo je otevřený dialog (např. minihra) + if (isArrowNavigationBlocked(e)) return; const currentIso = data?.isoDate; if (!currentIso) return; if (e.keyCode === 37) { diff --git a/client/src/pages/StatsPage.tsx b/client/src/pages/StatsPage.tsx index 6049257..26ade79 100644 --- a/client/src/pages/StatsPage.tsx +++ b/client/src/pages/StatsPage.tsx @@ -12,6 +12,7 @@ import { Legend, Line, LineChart, Tooltip, XAxis, YAxis } from "recharts"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { getLunchChoiceName } from "../enums"; import './StatsPage.scss'; +import { isArrowNavigationBlocked } from '../utils/arrowNavigation'; const CHART_WIDTH = 1400; const CHART_HEIGHT = 700; @@ -131,6 +132,7 @@ export default function StatsPage() { }, [dateRange]); const handleKeyDown = useCallback((e: any) => { + if (isArrowNavigationBlocked(e)) return; if (e.keyCode === 37) { handlePreviousWeek(); } else if (e.keyCode === 39 && !isCurrentOrFutureWeek) { diff --git a/client/src/utils/arrowNavigation.ts b/client/src/utils/arrowNavigation.ts new file mode 100644 index 0000000..e74e66b --- /dev/null +++ b/client/src/utils/arrowNavigation.ts @@ -0,0 +1,11 @@ +/** + * Zda se má stisk klávesy ignorovat pro navigaci šipkami mezi dny/týdny na pozadí stránky. + * Navigace se nemá provádět, pokud uživatel píše do formulářového pole, nebo pokud je otevřený + * modální dialog (typicky minihra jako Tetris či Had, která šipky používá k ovládání) – + * jinak by se stránka na pozadí neustále přepínala a zbytečně přenačítala data ze serveru. + */ +export function isArrowNavigationBlocked(e: KeyboardEvent): boolean { + const target = e.target as HTMLElement | null; + if (target?.closest?.('input, textarea, select, [contenteditable="true"]')) return true; + return document.body.classList.contains('modal-open') || document.querySelector('.modal.show') != null; +} diff --git a/server/changelogs/2026-10-19.json b/server/changelogs/2026-10-19.json index 2c3783d..633bd79 100644 --- a/server/changelogs/2026-10-19.json +++ b/server/changelogs/2026-10-19.json @@ -1,3 +1,4 @@ [ - "Nové nastavení: po založení skupinové objednávky nebo připojení k ní se vaše dnešní volba automaticky přepne na \"Budu objednávat\"" + "Nové nastavení: po založení skupinové objednávky nebo připojení k ní se vaše dnešní volba automaticky přepne na \"Budu objednávat\"", + "Ovládání miniher šipkami už na pozadí nepřepíná dny ani týdny" ]