fix: kiosk cursor, Esc dead-end, PWA prompt, password overlay, gamepad Enter
Some checks failed
Build Archipelago ISO / build-iso (push) Failing after 11m2s

- Kiosk: show cursor when active (removed -nocursor from Xorg),
  unclutter hides after 3s idle. X11 on VT7 for Ctrl+Alt+F1/F7 switching.
- Kiosk: keep getty@tty1 running so MOTD is accessible via Ctrl+Alt+F1
- Kiosk: disable Chromium password save overlay (--password-store=basic)
- Esc: don't navigate back from top-level pages (dashboard, login, kiosk)
  to prevent dead-end at root redirect
- PWA: suppress install prompt in kiosk mode (/kiosk path)
- Gamepad: Enter in text fields moves focus to next element (submit button)
  instead of submitting the form

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-26 21:16:07 +00:00
parent 13b832fdd3
commit e4bdc775e4
3 changed files with 29 additions and 8 deletions

View File

@@ -43,7 +43,8 @@ let deferredPrompt: { prompt: () => Promise<{ outcome: string }> } | null = null
const DISMISS_KEY = 'archipelago_pwa_install_dismissed'
onMounted(() => {
// Don't show if already dismissed this session or if already installed
// Don't show in kiosk mode, if already dismissed, or if already installed
if (window.location.pathname.startsWith('/kiosk')) return
if (sessionStorage.getItem(DISMISS_KEY) === '1') return
if (window.matchMedia('(display-mode: standalone)').matches) return
if ((window.navigator as Navigator & { standalone?: boolean }).standalone) return

View File

@@ -149,6 +149,18 @@ export function useControllerNav(containerRef?: { value: HTMLElement | null }) {
const target = e.target as HTMLElement
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
// Enter in text field: blur and move to next focusable element (e.g., submit button)
if (e.key === 'Enter' && target.tagName === 'INPUT' && (target as HTMLInputElement).type !== 'submit') {
e.preventDefault()
const root = containerRef?.value ?? document
const all = getFocusableElements(root)
const idx = all.indexOf(target as HTMLElement)
if (idx >= 0 && idx < all.length - 1) {
all[idx + 1].focus()
all[idx + 1].scrollIntoView({ block: 'nearest', behavior: 'smooth' })
}
return
}
if (e.key !== 'Escape') return
}
@@ -207,9 +219,13 @@ export function useControllerNav(containerRef?: { value: HTMLElement | null }) {
return
}
playNavSound('back')
window.history.back()
e.preventDefault()
// Don't navigate back from top-level pages — it leads to a dead end
const topLevel = ['/', '/dashboard', '/login', '/kiosk']
if (!topLevel.some(p => route.path === p || route.path.startsWith('/dashboard'))) {
playNavSound('back')
window.history.back()
e.preventDefault()
}
return
}