mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
fix keybindingses
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -11,7 +11,7 @@
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
||||||
<title>Multi Roomba Rover</title>
|
<title>Multi Roomba Rover</title>
|
||||||
<script type="module" crossorigin src="/assets/index-CMnGNe44.js"></script>
|
<script type="module" crossorigin src="/assets/index-DETl6izG.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-DzeZhrlZ.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-DzeZhrlZ.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useMemo, useState, useEffect, useCallback } from 'react';
|
|||||||
import { useControlSystem } from '../controls/index.js';
|
import { useControlSystem } from '../controls/index.js';
|
||||||
import { DEFAULT_KEYMAP } from '../controls/constants.js';
|
import { DEFAULT_KEYMAP } from '../controls/constants.js';
|
||||||
import { canonicalizeKeyInput, formatKeyLabel } from '../controls/keymapUtils.js';
|
import { canonicalizeKeyInput, formatKeyLabel } from '../controls/keymapUtils.js';
|
||||||
|
import { setKeyboardCaptureLocked } from '../controls/inputs/keyboardCaptureLock.js';
|
||||||
import { useSettingsNamespace } from '../settings/index.js';
|
import { useSettingsNamespace } from '../settings/index.js';
|
||||||
import { INPUT_SETTINGS_DEFAULTS } from '../settings/namespaces.js';
|
import { INPUT_SETTINGS_DEFAULTS } from '../settings/namespaces.js';
|
||||||
|
|
||||||
@@ -80,25 +81,35 @@ function mapTiltIntervalToSpeed(interval) {
|
|||||||
function useKeyCapture(onCapture) {
|
function useKeyCapture(onCapture) {
|
||||||
const [active, setActive] = useState(null);
|
const [active, setActive] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
const startCapture = useCallback((actionId) => {
|
||||||
if (!active) return undefined;
|
setKeyboardCaptureLocked(true);
|
||||||
function handle(event) {
|
setActive(actionId);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const cancel = useCallback(() => {
|
||||||
|
setKeyboardCaptureLocked(false);
|
||||||
|
setActive(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const captureFromEvent = useCallback(
|
||||||
|
(actionId, event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
if (event.key === 'Escape') {
|
if (event.key === 'Escape') {
|
||||||
setActive(null);
|
cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const canonical = canonicalizeKeyInput(event.key ?? '');
|
const canonical = canonicalizeKeyInput(event.key ?? '');
|
||||||
if (canonical) {
|
if (!canonical) return;
|
||||||
onCapture(active, canonical, event);
|
onCapture(actionId, canonical, event);
|
||||||
setActive(null);
|
cancel();
|
||||||
}
|
},
|
||||||
}
|
[cancel, onCapture],
|
||||||
window.addEventListener('keydown', handle, { capture: true });
|
);
|
||||||
return () => window.removeEventListener('keydown', handle, { capture: true });
|
|
||||||
}, [active, onCapture]);
|
|
||||||
|
|
||||||
return { active, startCapture: setActive, cancel: () => setActive(null) };
|
useEffect(() => () => setKeyboardCaptureLocked(false), []);
|
||||||
|
|
||||||
|
return { active, startCapture, cancel, captureFromEvent };
|
||||||
}
|
}
|
||||||
|
|
||||||
function SpeedField({ label, description, value, onChange, min = 0, max = 500, step = 5 }) {
|
function SpeedField({ label, description, value, onChange, min = 0, max = 500, step = 5 }) {
|
||||||
@@ -155,7 +166,7 @@ export default function KeymapSettings() {
|
|||||||
return INPUT_SETTINGS_DEFAULTS.keyboard.tiltSpeed;
|
return INPUT_SETTINGS_DEFAULTS.keyboard.tiltSpeed;
|
||||||
}, [keyboardSettings.tiltIntervalMs, keyboardSettings.tiltSpeed]);
|
}, [keyboardSettings.tiltIntervalMs, keyboardSettings.tiltSpeed]);
|
||||||
const grouped = useMemo(() => groupActions(KEY_ACTIONS), []);
|
const grouped = useMemo(() => groupActions(KEY_ACTIONS), []);
|
||||||
const { active, startCapture, cancel } = useKeyCapture((actionId, value) => {
|
const { active, startCapture, cancel, captureFromEvent } = useKeyCapture((actionId, value) => {
|
||||||
updateKeyBinding(actionId, value);
|
updateKeyBinding(actionId, value);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -265,6 +276,8 @@ export default function KeymapSettings() {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => startCapture(action.id)}
|
onClick={() => startCapture(action.id)}
|
||||||
|
onKeyDown={isActive ? (event) => captureFromEvent(action.id, event) : undefined}
|
||||||
|
autoFocus={isActive}
|
||||||
className={`${isActive ? 'px-0.5 py-0.5 bg-emerald-500 text-emerald-950 hover:bg-emerald-400' : 'button-dark'} text-[0.7rem] font-medium transition-colors`}
|
className={`${isActive ? 'px-0.5 py-0.5 bg-emerald-500 text-emerald-950 hover:bg-emerald-400' : 'button-dark'} text-[0.7rem] font-medium transition-colors`}
|
||||||
>
|
>
|
||||||
{isActive ? 'Press a key…' : 'Change'}
|
{isActive ? 'Press a key…' : 'Change'}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { useControlSystem } from '../ControlContext.jsx';
|
|||||||
import { useChat } from '../../context/ChatContext.jsx';
|
import { useChat } from '../../context/ChatContext.jsx';
|
||||||
import { useSession } from '../../context/SessionContext.jsx';
|
import { useSession } from '../../context/SessionContext.jsx';
|
||||||
import { normalizeKeymapEntries, tokensForEvent } from '../keymapUtils.js';
|
import { normalizeKeymapEntries, tokensForEvent } from '../keymapUtils.js';
|
||||||
|
import { isKeyboardCaptureLocked } from './keyboardCaptureLock.js';
|
||||||
import { isTextInputElement } from './inputFocusUtils.js';
|
import { isTextInputElement } from './inputFocusUtils.js';
|
||||||
import { useSettingsNamespace } from '../../settings/index.js';
|
import { useSettingsNamespace } from '../../settings/index.js';
|
||||||
import { INPUT_SETTINGS_DEFAULTS } from '../../settings/namespaces.js';
|
import { INPUT_SETTINGS_DEFAULTS } from '../../settings/namespaces.js';
|
||||||
@@ -344,6 +345,7 @@ export default function KeyboardInputManager() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function handleKeyDown(event) {
|
function handleKeyDown(event) {
|
||||||
|
if (isKeyboardCaptureLocked()) return;
|
||||||
if (shouldIgnoreEvent(event)) return;
|
if (shouldIgnoreEvent(event)) return;
|
||||||
const tokens = tokensForEvent(event);
|
const tokens = tokensForEvent(event);
|
||||||
if (tokens.length === 0) return;
|
if (tokens.length === 0) return;
|
||||||
@@ -389,6 +391,7 @@ export default function KeyboardInputManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleKeyUp(event) {
|
function handleKeyUp(event) {
|
||||||
|
if (isKeyboardCaptureLocked()) return;
|
||||||
const tokens = tokensForEvent(event);
|
const tokens = tokensForEvent(event);
|
||||||
tokens.forEach((token) => activeTokensRef.current.delete(token));
|
tokens.forEach((token) => activeTokensRef.current.delete(token));
|
||||||
if (hornActiveRef.current && !bindingActive(keymap.hornHonk, activeTokensRef.current)) {
|
if (hornActiveRef.current && !bindingActive(keymap.hornHonk, activeTokensRef.current)) {
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
let keyboardCaptureLocked = false;
|
||||||
|
|
||||||
|
export function setKeyboardCaptureLocked(value) {
|
||||||
|
keyboardCaptureLocked = Boolean(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isKeyboardCaptureLocked() {
|
||||||
|
return keyboardCaptureLocked;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user