import { FocusContext, useFocusable, } from "@noriginmedia/norigin-spatial-navigation"; import { Outlet, createFileRoute, useMatch, useMatchRoute, useRouter, useRouterState, } from "@tanstack/react-router"; import { ViewTransitionOptions } from "@tanstack/router-core"; import classNames from "classnames"; import { ArrowBigLeft, FingerprintPattern, HardDrive, Info, Joystick, MonitorCog, Puzzle, RefreshCcw, } from "lucide-react"; import { JSX, useMemo } from "react"; import { twMerge } from "tailwind-merge"; import z from "zod"; import { SettingsSchema } from "../../../shared/constants"; import { GamePadButtonCode, useShortcutContext, useShortcuts } from "@/mainview/scripts/shortcuts"; import Shortcuts, { FloatingShortcuts } from "@/mainview/components/Shortcuts"; import { HandleGoBack } from "@/mainview/scripts/utils"; import { AutoFocus } from "@/mainview/components/AutoFocus"; import { oneShot } from "@/mainview/scripts/audio/audio"; import SelectMenu from "@/mainview/components/SelectMenu"; export const Route = createFileRoute("/settings")({ component: SettingsUI, validateSearch: z.object({ focus: z.keyof(SettingsSchema).optional() }), staticData: { enterSound: 'openSettings' } }); function MenuItem (data: { route: string; matchRoutes?: string[]; return?: boolean; viewTransition?: boolean | ViewTransitionOptions; icon: JSX.Element; focusSelect?: boolean; className?: string; linkClassName?: string; active?: boolean; label: string; }) { const router = useRouter(); const routerState = useRouterState(); const matchRoute = useMatchRoute(); const acitve = useMemo(() => data.matchRoutes ? data.matchRoutes.some(r => !!matchRoute({ to: r })) : !!router.matchRoute({ to: data.route }), [routerState, matchRoute, data.matchRoutes, data.route]); const handleNonFocusSelect = (e?: Event) => { if (data.return) { HandleGoBack(router, e); } else if (!acitve) { router.navigate({ to: data.route, viewTransition: { types: ['slide-up'] }, replace: true }); } oneShot('click'); }; const { ref, focusSelf } = useFocusable({ focusKey: `menu-item-${data.route}`, forceFocus: !!acitve, onFocus: () => { if (data.focusSelect && !acitve) { router.navigate({ to: data.route, viewTransition: { types: ['slide-up'] }, replace: true }); } (ref.current as HTMLElement).scrollIntoView({ inline: 'center' }); }, onEnterPress: data.focusSelect !== true ? handleNonFocusSelect : undefined, }); return (