From 7637620ac5b07baa35096acc447a2056ec6cdca5 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Wed, 29 Apr 2026 17:25:35 +0300 Subject: [PATCH] gamepad: add lock unlock on dom --- src/App/GamepadModal/GamepadModal.tsx | 2 ++ src/services/GamepadContext/GamepadContext.ts | 2 ++ .../GamepadContext/GamepadProvider.tsx | 20 ++++++++++++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/App/GamepadModal/GamepadModal.tsx b/src/App/GamepadModal/GamepadModal.tsx index 1ef0f2290..30bee9e5a 100644 --- a/src/App/GamepadModal/GamepadModal.tsx +++ b/src/App/GamepadModal/GamepadModal.tsx @@ -55,6 +55,7 @@ const GamepadModal = ({ onClose }: Props) => { const labels = LABELS[gamepad?.controllerType ?? 'generic']; useEffect(() => { + gamepad?.lock('gamepad-'); const onKeyDown = ({ key }: KeyboardEvent) => { key === 'Escape' && onClose(); }; @@ -64,6 +65,7 @@ const GamepadModal = ({ onClose }: Props) => { return () => { document.removeEventListener('keydown', onKeyDown); gamepad?.off('buttonB', 'gamepad-modal'); + gamepad?.unlock(); }; }, [gamepad]); diff --git a/src/services/GamepadContext/GamepadContext.ts b/src/services/GamepadContext/GamepadContext.ts index 90bf5f915..cf147581a 100644 --- a/src/services/GamepadContext/GamepadContext.ts +++ b/src/services/GamepadContext/GamepadContext.ts @@ -7,6 +7,8 @@ export type ControllerType = 'playstation' | 'xbox' | 'generic'; const GamepadContext = createContext<{ on: (event: string, id: string, callback: (data?: string) => void) => void; off: (event: string, id: string) => void; + lock: (prefix: string) => void; + unlock: () => void; controllerType: ControllerType; } | null>(null); diff --git a/src/services/GamepadContext/GamepadProvider.tsx b/src/services/GamepadContext/GamepadProvider.tsx index 369770a88..01b48788e 100644 --- a/src/services/GamepadContext/GamepadProvider.tsx +++ b/src/services/GamepadContext/GamepadProvider.tsx @@ -34,6 +34,7 @@ const GamepadProvider = ({ enabled, onGuide, children }: GamepadProviderProps) = const axisTimer = useRef(0); const axisTimerRight = useRef(0); const eventHandlers = useRef(new Map()); + const lockPrefix = useRef(null); const [controllerType, setControllerType] = useState('generic'); const on = useCallback((event: string, id: string, callback: (data?: string) => void) => { @@ -55,12 +56,29 @@ const GamepadProvider = ({ enabled, onGuide, children }: GamepadProviderProps) = } }, []); + const lock = useCallback((prefix: string) => { + lockPrefix.current = prefix; + }, []); + + const unlock = useCallback(() => { + lockPrefix.current = null; + }, []); + const emit = (event: string, data?: string) => { if (eventHandlers.current.has(event)) { const handlersMap = eventHandlers.current.get(event)!; if (!handlersMap || handlersMap.size === 0) return; + if (lockPrefix.current) { + const matching = Array.from(handlersMap.entries()) + .filter(([id]) => id.startsWith(lockPrefix.current!)); + if (matching.length > 0) { + matching[matching.length - 1][1](data); + } + return; + } + const latestHandler = Array.from(handlersMap.values()).slice(-1)[0]; if (latestHandler) { latestHandler(data); @@ -244,7 +262,7 @@ const GamepadProvider = ({ enabled, onGuide, children }: GamepadProviderProps) = }, [enabled]); return ( - + {children} );