From 5971da3fc9bd4916dc490f75791f2a52aee55b07 Mon Sep 17 00:00:00 2001 From: Zakhar Timoshenko Date: Fri, 9 Oct 2026 21:54:07 +0300 Subject: [PATCH] feat: implement remote settings navigation and focus management - Added `useSettingsNavigation.ts` for handling remote control navigation within settings. - Introduced `arrowDirection` and `directionalFocusIndex` functions in `remote.mjs` to manage directional input and focus transitions. - Created a new markdown file `verification-settings-remote.md` documenting the changes and testing outcomes. - Developed comprehensive tests for arrow key functionality and focus behavior in `remote.test.mjs`. - Ensured compatibility with standard keys and legacy key codes, maintaining expected navigation behavior across different screen resolutions. --- README.md | 3 +- .../settings-remote-navigation-1280x720.jpg | Bin 0 -> 50091 bytes .../settings-remote-navigation-879x593.jpg | Bin 0 -> 35025 bytes artifacts/verification-settings-remote.md | 16 +++ src/SettingsPanel.tsx | 11 +- src/lib/remote.mjs | 22 ++++ src/styles.css | 4 + src/useSettingsNavigation.ts | 103 ++++++++++++++++++ test/remote.test.mjs | 28 +++++ 9 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 artifacts/settings-remote-navigation-1280x720.jpg create mode 100644 artifacts/settings-remote-navigation-879x593.jpg create mode 100644 artifacts/verification-settings-remote.md create mode 100644 src/lib/remote.mjs create mode 100644 src/useSettingsNavigation.ts create mode 100644 test/remote.test.mjs diff --git a/README.md b/README.md index 04872c8..86d1203 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,8 @@ npm start - Цикл 25 секунд / 8 секунд, настраиваемый. До ближайшего рейса ≤2 минут главный экран удерживается; можно отключить в настройках. Отмены и объезды исключают рекламную сцену из цикла. - Опциональная рекламная сцена с текстом и длительностью; по умолчанию выключена, помечена как предпросмотр. Загрузка медиа и кампании в MVP не входят. - Настройки остановки, маршрута, числа строк, интервалов и деморежима сохраняются на устройстве. Новая остановка загружает свои данные и свой кеш. -- Полный экран, пауза, ручная смена сцен. Клавиши: `S` — настройки; `F` — полный экран; `→` — следующий экран; `пробел` — пауза. `Esc` закрывает настройки. +- Полный экран, пауза, ручная смена сцен. Клавиши: `S` — настройки; `F` — полный экран; `→` — следующий экран; `пробел` — пауза. В настройках `Esc` завершает изменение поля, затем закрывает меню без сохранения. +- Настройки доступны с пульта: стрелки переводят фокус между полями и автоматически прокручивают меню. `OK / Enter` активирует кнопку, переключатель или выбор цвета; для списка и числа включает изменение значения стрелками. Повторный `OK / Enter` возвращает к навигации. Отключённые поля пропускаются. Выбранный элемент подсвечен, подсказка остаётся сверху. `Home / End` переходят в начало/конец, `PageUp / PageDown` прокручивают страницу меню. `Tab` возвращает обычное клавиатурное управление; мышь и касание работают как прежде. - Кнопки управления и курсор скрываются после 5 секунд без взаимодействия. Движение мыши, касание или клавиатура возвращают кнопки; открытые настройки и работа с клавиатурным фокусом не скрываются. Высота панели сохраняется, а освободившуюся ширину занимает подпись «Обновлено» справа. - Изменившиеся цифры часов, времени отправления, ожидания и номеров маршрутов прокручиваются вертикально. Названия рейсов при смене страниц плавно сдвигаются тем же движением. Неизменившиеся позиции чисел остаются на месте; увеличение идёт вверх, уменьшение — вниз. При `prefers-reduced-motion` движение выключено. - Для чёрного фона доступны лайм, янтарь, голубой, мята, лаванда и белый; для белого — синий, зелёный, кармин, фиолетовый, бирюзовый и графит. Акцент и логотип меняются вместе. Контраст каждой палитры с её фоном не меньше 7:1. Тема и выбранные цвета сохраняются отдельно. diff --git a/artifacts/settings-remote-navigation-1280x720.jpg b/artifacts/settings-remote-navigation-1280x720.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e2de6204d117750b2226595a049e4eb9646dc713 GIT binary patch literal 50091 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 literal 0 HcmV?d00001 diff --git a/artifacts/settings-remote-navigation-879x593.jpg b/artifacts/settings-remote-navigation-879x593.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0ded820c7ca5b9aff10d0d8e617d470d30b68698 GIT binary patch literal 35025 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[]); const [stopsError, setStopsError] = useState(false); const dialog = useRef(null); - useEffect(() => { dialog.current?.showModal(); }, []); + const navigation = useSettingsNavigation(dialog, onClose); + useEffect(() => { + dialog.current?.showModal(); + dialog.current?.querySelector('.settings-heading button')?.focus({ preventScroll: true }); + }, []); useEffect(() => { const controller = new AbortController(); fetch('/api/stops', { signal: controller.signal }).then(response => { if (!response.ok) throw new Error(); return response.json(); }) @@ -18,9 +23,11 @@ export function SettingsPanel({ settings, config, data, onSave, onClose, onFulls return () => controller.abort(); }, []); const update = (key: K, value: Settings[K]) => setDraft(previous => ({ ...previous, [key]: value })); - return

+ return
{ event.preventDefault(); onSave(draft); }}>
RIDEBUS BOARD

Настройки табло

+

{navigation.editing ? 'Измените значение стрелками · OK / Enter — готово · Esc — назад' : 'Пульт: стрелки — переход · OK / Enter — выбрать · Esc — закрыть'}

Остановка

{config.cityName} · данные RideBus API
diff --git a/src/lib/remote.mjs b/src/lib/remote.mjs new file mode 100644 index 0000000..a098a5c --- /dev/null +++ b/src/lib/remote.mjs @@ -0,0 +1,22 @@ +export function arrowDirection(key, code) { + const directions = { ArrowUp: 'up', ArrowDown: 'down', ArrowLeft: 'left', ArrowRight: 'right' }; + return directions[key] || directions[{ 37: 'ArrowLeft', 38: 'ArrowUp', 39: 'ArrowRight', 40: 'ArrowDown' }[code]] || null; +} + +// Rectangles are control labels, so a full-width switch and a two-column palette +// behave like visible rows rather than tiny radio/checkbox input coordinates. +export function directionalFocusIndex(rects, current, direction) { + if (!rects.length) return -1; + if (current < 0) return direction === 'up' ? rects.length - 1 : 0; + const origin = rects[current], vertical = direction === 'up' || direction === 'down'; + const backwards = direction === 'up' || direction === 'left'; + const primary = rect => vertical ? (rect.top + rect.bottom) / 2 : (rect.left + rect.right) / 2; + const cross = rect => vertical ? (rect.left + rect.right) / 2 : (rect.top + rect.bottom) / 2; + const low = rect => vertical ? rect.left : rect.top, high = rect => vertical ? rect.right : rect.bottom; + return rects.map((rect, index) => { + const distance = (primary(rect) - primary(origin)) * (backwards ? -1 : 1); + const overlap = Math.min(high(rect), high(origin)) - Math.max(low(rect), low(origin)) > 0; + return { index, distance, overlap, score: distance + Math.abs(cross(rect) - cross(origin)) * .3 }; + }).filter(item => item.index !== current && item.distance > 1 && (vertical || item.overlap)) + .sort((a, b) => Number(b.overlap) - Number(a.overlap) || a.score - b.score || a.index - b.index)[0]?.index ?? -1; +} diff --git a/src/styles.css b/src/styles.css index 877cec6..4cd1a0b 100644 --- a/src/styles.css +++ b/src/styles.css @@ -294,6 +294,10 @@ h1 { font-size: clamp(30px, 3.8vw, 76px); letter-spacing: -.05em; line-height: 1 .settings-dialog { width: min(600px, calc(100vw - 28px)); max-height: calc(100dvh - 32px); padding: 0; color: var(--foreground); background: var(--surface); border: 1px solid var(--outline); border-radius: 20px; overflow: auto; box-shadow: 0 25px 90px #0006; } .settings-dialog::backdrop { background: #0009; backdrop-filter: blur(8px); } +.settings-dialog { scroll-padding: 56px 14px 14px; } +.settings-navigation-hint { position: sticky; top: 0; z-index: 2; margin: 0; padding: 10px 28px; color: var(--secondary); font-size: 12px; line-height: 1.4; background: var(--surface); border-bottom: 1px solid var(--line); } +.settings-dialog[data-remote-navigation='true'] [data-tv-focus] { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 8px; } +.settings-dialog[data-remote-editing='true'] :focus { outline: 3px solid var(--accent); outline-offset: 3px; background: color-mix(in srgb, var(--accent) 12%, var(--input)); } .settings-heading { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 25px 28px; border-bottom: 1px solid var(--line); } .settings-heading h2 { margin: 8px 0 0; font-size: 27px; font-weight: 600; letter-spacing: -.04em; } .settings-heading .eyebrow { font-size: 11px; } diff --git a/src/useSettingsNavigation.ts b/src/useSettingsNavigation.ts new file mode 100644 index 0000000..de1d4b1 --- /dev/null +++ b/src/useSettingsNavigation.ts @@ -0,0 +1,103 @@ +import { useLayoutEffect, useState } from 'react'; +import type { FocusEvent, KeyboardEvent, RefObject } from 'react'; +import { arrowDirection, directionalFocusIndex } from './lib/remote.mjs'; + +const field = (element: HTMLElement) => element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement + || element instanceof HTMLInputElement && !['checkbox', 'radio', 'button', 'submit'].includes(element.type); +const focusArea = (element: HTMLElement) => element.closest('label') || element; +function controls(root: HTMLElement) { + return Array.from(root.querySelectorAll('button, input:not([type="hidden"]), select, textarea, a[href]')) + .filter(element => !element.matches(':disabled') && element.getClientRects().length > 0); +} +function reveal(root: HTMLElement, element: HTMLElement) { + root.querySelector('[data-tv-focus]')?.removeAttribute('data-tv-focus'); + focusArea(element).setAttribute('data-tv-focus', ''); + const bounds = root.getBoundingClientRect(), area = focusArea(element).getBoundingClientRect(); + const hint = root.querySelector('.settings-navigation-hint')?.getBoundingClientRect().height || 0; + const top = bounds.top + hint + 14, bottom = bounds.bottom - 14; + if (area.top < top) root.scrollTop += area.top - top; + else if (area.bottom > bottom) root.scrollTop += area.bottom - bottom; +} + +export function useSettingsNavigation(dialog: RefObject, onClose: () => void) { + const [remote, setRemote] = useState(false); + const [editing, setEditing] = useState(null); + useLayoutEffect(() => { + if (dialog.current && document.activeElement instanceof HTMLElement && dialog.current.contains(document.activeElement)) reveal(dialog.current, document.activeElement); + }, [remote, editing, dialog]); + const focus = (element: HTMLElement) => { + element.focus({ preventScroll: true }); + if (dialog.current) reveal(dialog.current, element); + }; + function onKeyDownCapture(event: KeyboardEvent) { + if (event.altKey || event.ctrlKey || event.metaKey || event.nativeEvent.isComposing) return; + const root = event.currentTarget, active = document.activeElement; + if (!(active instanceof HTMLElement)) return; + const key = event.key; + if (key === 'Tab') { setRemote(false); setEditing(null); return; } + if (['Escape', 'BrowserBack', 'GoBack'].includes(key)) { + event.preventDefault(); event.stopPropagation(); + if (editing) setEditing(null); else onClose(); + return; + } + const direction = arrowDirection(key, event.keyCode); + if (direction) { + if (editing === active) { + const step = direction === 'up' || direction === 'left' ? -1 : 1; + if (active instanceof HTMLSelectElement) { + event.preventDefault(); event.stopPropagation(); + const options = Array.from(active.options).filter(option => !option.disabled); + const index = options.findIndex(option => option.index === active.selectedIndex); + const next = options[Math.max(0, Math.min(options.length - 1, index + step))]; + if (next && next.index !== active.selectedIndex) { + active.selectedIndex = next.index; + active.dispatchEvent(new Event('change', { bubbles: true })); + } + } else if (active instanceof HTMLInputElement && active.type === 'number') { + event.preventDefault(); event.stopPropagation(); + active.stepUp(direction === 'up' || direction === 'right' ? 1 : -1); + active.dispatchEvent(new Event('input', { bubbles: true })); + } + return; + } + if (!remote && (field(active) || active instanceof HTMLInputElement)) return; + event.preventDefault(); event.stopPropagation(); setRemote(true); + const items = controls(root), index = items.indexOf(active); + const next = directionalFocusIndex(items.map(item => focusArea(item).getBoundingClientRect()), index, direction); + if (next >= 0) focus(items[next]); + return; + } + if (['Home', 'End', 'PageDown', 'PageUp'].includes(key) && !editing && (remote || !field(active))) { + event.preventDefault(); event.stopPropagation(); setRemote(true); + const items = controls(root); + if (key === 'Home') { if (items[0]) focus(items[0]); } + else if (key === 'End') { if (items.length) focus(items[items.length - 1]); } + else { + const before = root.scrollTop; + root.scrollTop += root.clientHeight * .75 * (key === 'PageDown' ? 1 : -1); + if (root.scrollTop === before) return; + const bounds = root.getBoundingClientRect(), targetY = bounds.top + root.clientHeight / 2; + const visible = items.filter(item => { const area = focusArea(item).getBoundingClientRect(); return area.top >= bounds.top + 54 && area.bottom <= bounds.bottom - 14; }); + const target = visible.reduce((best, item) => !best || Math.abs(item.getBoundingClientRect().top - targetY) < Math.abs(best.getBoundingClientRect().top - targetY) ? item : best, null); + if (target) focus(target); + } + return; + } + if ((key === 'Enter' || key === 'Select' || event.keyCode === 13 || event.keyCode === 23) && (remote || key === 'Select' || event.keyCode === 23)) { + event.preventDefault(); event.stopPropagation(); + if (event.repeat) return; + setRemote(true); + if (editing) setEditing(null); + else if (field(active)) setEditing(active); + else active.click(); + } + } + function onFocusCapture(event: FocusEvent) { + if (event.target instanceof HTMLElement) { + if (editing && event.target !== editing) setEditing(null); + reveal(event.currentTarget, event.target); + } + } + return { remote, editing: Boolean(editing), onKeyDownCapture, onFocusCapture, + onPointerDownCapture: () => { setRemote(false); setEditing(null); } }; +} diff --git a/test/remote.test.mjs b/test/remote.test.mjs new file mode 100644 index 0000000..81b79fb --- /dev/null +++ b/test/remote.test.mjs @@ -0,0 +1,28 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { arrowDirection, directionalFocusIndex } from '../src/lib/remote.mjs'; +const rect = (left, top, width = 100, height = 40) => ({ left, top, right: left + width, bottom: top + height }); + +test('remote arrows support standard keys and legacy key codes', () => { + assert.equal(arrowDirection('ArrowDown'), 'down'); + assert.equal(arrowDirection('Unidentified', 38), 'up'); + assert.equal(arrowDirection('Enter', 13), null); +}); +test('vertical focus follows rows and keeps the palette column', () => { + const boxes = [rect(0, 0, 240), rect(0, 70), rect(140, 70), rect(0, 130), rect(140, 130), rect(0, 200, 240)]; + assert.equal(directionalFocusIndex(boxes, 0, 'down'), 1); + assert.equal(directionalFocusIndex(boxes, 1, 'down'), 3); + assert.equal(directionalFocusIndex(boxes, 2, 'down'), 4); + assert.equal(directionalFocusIndex(boxes, 4, 'down'), 5); + assert.equal(directionalFocusIndex(boxes, 4, 'up'), 2); +}); +test('horizontal arrows stay in the same row and boundaries do not wrap', () => { + const boxes = [rect(0, 0), rect(140, 0), rect(0, 90), rect(140, 90)]; + assert.equal(directionalFocusIndex(boxes, 0, 'right'), 1); + assert.equal(directionalFocusIndex(boxes, 1, 'right'), -1); + assert.equal(directionalFocusIndex(boxes, 0, 'left'), -1); + assert.equal(directionalFocusIndex(boxes, 0, 'up'), -1); + assert.equal(directionalFocusIndex(boxes, 3, 'down'), -1); + assert.equal(directionalFocusIndex(boxes, -1, 'down'), 0); + assert.equal(directionalFocusIndex([], -1, 'down'), -1); +});