diff --git a/src/Toolbar.tsx b/src/Toolbar.tsx index 0d18a45bb..992fb1753 100644 --- a/src/Toolbar.tsx +++ b/src/Toolbar.tsx @@ -10,6 +10,7 @@ import { useInteractionMap } from 'hooks/useInteractionMap' import { ActionButtonDropdown } from 'components/ActionButtonDropdown' import { useHotkeys } from 'react-hotkeys-hook' import Tooltip from 'components/Tooltip' +import { KEYBINDING_CATEGORIES } from 'lib/constants' export function Toolbar({ className = '', @@ -40,7 +41,8 @@ export function Toolbar({ guard: () => !shouldDisableModelingActions && state.matches('idle'), }, ], - [shouldDisableModelingActions, commandBarSend, state] + [shouldDisableModelingActions, commandBarSend, state], + KEYBINDING_CATEGORIES.MODELING ) const iconClassName = 'group-disabled:text-chalkboard-50 group-enabled:group-hover:!text-primary dark:group-enabled:group-hover:!text-inherit group-pressed:!text-chalkboard-10 group-ui-open:!text-chalkboard-10 dark:group-ui-open:!text-chalkboard-10' diff --git a/src/components/CommandBar/CommandBar.tsx b/src/components/CommandBar/CommandBar.tsx index ccb81dc17..97ddec7a4 100644 --- a/src/components/CommandBar/CommandBar.tsx +++ b/src/components/CommandBar/CommandBar.tsx @@ -5,9 +5,8 @@ import CommandBarArgument from './CommandBarArgument' import CommandComboBox from '../CommandComboBox' import CommandBarReview from './CommandBarReview' import { useLocation } from 'react-router-dom' -import { InteractionMapItem } from 'machines/interactionMapMachine' import { useInteractionMap } from 'hooks/useInteractionMap' -import useHotkeyWrapper from 'lib/hotkeyWrapper' +import { KEYBINDING_CATEGORIES } from 'lib/constants' export const CommandBar = () => { const { pathname } = useLocation() @@ -49,7 +48,7 @@ export const CommandBar = () => { }, ], [commandBarState, commandBarSend], - 'Command Bar' + KEYBINDING_CATEGORIES.COMMAND_BAR ) function stepBack() { diff --git a/src/components/InteractionMapMachineProvider.tsx b/src/components/InteractionMapMachineProvider.tsx index 17c304eff..a08027015 100644 --- a/src/components/InteractionMapMachineProvider.tsx +++ b/src/components/InteractionMapMachineProvider.tsx @@ -1,6 +1,12 @@ import { useMachine } from '@xstate/react' import { INTERACTION_MAP_SEPARATOR } from 'lib/constants' -import { isModifierKey, mapKey, sortKeys } from 'lib/keyboard' +import { + isModifierKey, + mapKey, + mouseButtonToName, + resolveInteractionEvent, + sortKeys, +} from 'lib/keyboard' import { MouseButtonName, interactionMapMachine, @@ -91,33 +97,18 @@ export function InteractionMapMachineProvider({ }, services: { 'Resolve hotkey by prefix': (context, event) => { - // First determine if we have a mouse or keyboard event - const action = - 'key' in event.data - ? mapKey(event.data.code) - : mouseButtonToName(event.data.button) - - console.log('action', action) + const resolvedInteraction = resolveInteractionEvent(event.data) // if the key is already a modifier key, skip everything else and reject - if (isModifierKey(action)) { + if (resolvedInteraction.isModifier) { // We return an empty string so that we don't clear the currentSequence return Promise.reject('') } - const modifiers = [ - event.data.ctrlKey && 'ctrl', - event.data.shiftKey && 'shift', - event.data.altKey && 'alt', - event.data.metaKey && 'meta', - ].filter((item) => item !== false) as string[] - const step = [action, ...modifiers] - .sort(sortKeys) - .join(INTERACTION_MAP_SEPARATOR) - // Find all the sequences that start with the current sequence const searchString = - (context.currentSequence ? context.currentSequence + ' ' : '') + step + (context.currentSequence ? context.currentSequence + ' ' : '') + + resolvedInteraction.asString const matches = context.interactionMap.filter((item) => item.sequence.startsWith(searchString) @@ -141,7 +132,7 @@ export function InteractionMapMachineProvider({ // We have a prefix match. // Reject the promise and return the step // so we can add it to currentSequence - return Promise.reject(step) + return Promise.reject(resolvedInteraction.asString) } // Resolve to just one exact match @@ -211,16 +202,3 @@ export function InteractionMapMachineProvider({ ) } - -function mouseButtonToName(button: MouseEvent['button']): MouseButtonName { - switch (button) { - case 0: - return 'LeftButton' - case 1: - return 'MiddleButton' - case 2: - return 'RightButton' - default: - return 'LeftButton' - } -} diff --git a/src/components/Settings/AllKeybindingsFields.tsx b/src/components/Settings/AllKeybindingsFields.tsx index 927a65098..444236ca1 100644 --- a/src/components/Settings/AllKeybindingsFields.tsx +++ b/src/components/Settings/AllKeybindingsFields.tsx @@ -1,4 +1,14 @@ +import { ActionIcon } from 'components/ActionIcon' import { useInteractionMapContext } from 'hooks/useInteractionMapContext' +import { + isModifierKey, + mapKey, + mouseButtonToName, + resolveInteractionEvent, +} from 'lib/keyboard' +import { InteractionMapItem } from 'machines/interactionMapMachine' +import { useEffect, useState } from 'react' +import { g } from 'vitest/dist/suite-IbNSsUWN' export function AllKeybindingsFields() { const { state } = useInteractionMapContext() @@ -6,24 +16,81 @@ export function AllKeybindingsFields() {