Skip to content

Commit

Permalink
Error on duplicate shortcut
Browse files Browse the repository at this point in the history
  • Loading branch information
somebody1234 committed Feb 26, 2024
1 parent ff06dfe commit e09330d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,15 @@ import * as object from '#/utilities/object'
export default function KeyboardShortcutsSettingsTab() {
const inputBindings = inputBindingsManager.useInputBindings()
const { setModal } = modalProvider.useSetModal()
const [, doRefresh] = refreshHooks.useRefresh()
const [refresh, doRefresh] = refreshHooks.useRefresh()
const scrollContainerRef = React.useRef<HTMLDivElement>(null)
const bodyRef = React.useRef<HTMLTableSectionElement>(null)
const allShortcuts = React.useMemo(() => {
// This is REQUIRED, in order to avoid disabling the `react-hooks/exhaustive-deps` lint.
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
refresh
return new Set(Object.values(inputBindings.metadata).flatMap(value => value.bindings))
}, [inputBindings.metadata, refresh])

// This is required to prevent the table body from overlapping the table header, because
// the table header is transparent.
Expand Down Expand Up @@ -139,6 +145,7 @@ export default function KeyboardShortcutsSettingsTab() {
setModal(
<CaptureKeyboardShortcutModal
description={`'${info.name}'`}
existingShortcuts={allShortcuts}
onSubmit={shortcut => {
inputBindings.add(action, shortcut)
doRefresh()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function eventToPartialShortcut(event: KeyboardEvent | React.KeyboardEvent) {
? 'Space'
: event.key === DELETE_KEY
? 'OsDelete'
: event.key
: inputBindings.normalizedKeyboardSegmentLookup[event.key.toLowerCase()] ?? event.key
return { key, modifiers }
}

Expand All @@ -42,16 +42,19 @@ function eventToPartialShortcut(event: KeyboardEvent | React.KeyboardEvent) {
/** Props for a {@link CaptureKeyboardShortcutModal}. */
export interface CaptureKeyboardShortcutModalProps {
readonly description: string
readonly existingShortcuts: Set<string>
readonly onSubmit: (shortcut: string) => void
}

/** A modal for capturing an arbitrary keyboard shortcut. */
export default function CaptureKeyboardShortcutModal(props: CaptureKeyboardShortcutModalProps) {
const { description, onSubmit } = props
const { description, existingShortcuts, onSubmit } = props
const { unsetModal } = modalProvider.useSetModal()
const [key, setKey] = React.useState<string | null>(null)
const [modifiers, setModifiers] = React.useState<string>('')
const shortcut = key == null ? modifiers : modifiers === '' ? key : `${modifiers}+${key}`
const doesAlreadyExist = key != null && existingShortcuts.has(shortcut)
const canSubmit = key != null && !doesAlreadyExist

return (
<Modal centered className="bg-dim">
Expand Down Expand Up @@ -90,23 +93,30 @@ export default function CaptureKeyboardShortcutModal(props: CaptureKeyboardShort
}}
onSubmit={event => {
event.preventDefault()
if (key != null) {
if (canSubmit) {
unsetModal()
onSubmit(shortcut)
}
}}
>
<div className="relative">Enter the new keyboard shortcut for {description}.</div>
<div className="relative flex scale-150 items-center justify-center">
<div
className={`relative flex scale-150 items-center justify-center ${
doesAlreadyExist ? 'text-red-600' : ''
}`}
>
{shortcut === '' ? (
<span className="leading-170 text-primary/30 h-6 py-px">No shortcut entered</span>
) : (
<KeyboardShortcut shortcut={shortcut} />
)}
</div>
<span className="relative text-red-600">
{doesAlreadyExist ? 'This shortcut already exists.' : ''}
</span>
<div className="relative flex self-start gap-2">
<button
disabled={key == null}
disabled={!canSubmit}
type="submit"
className="hover:cursor-pointer inline-block text-white bg-invite rounded-full px-4 py-1 disabled:opacity-50"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ type Key = (typeof ALL_KEYS)[number]
type LowercaseKey = Lowercase<Key>
/** A segment of a keyboard shortcut. */
type KeybindSegment = Key | Modifier | Pointer
const normalizedKeyboardSegmentLookup = Object.fromEntries<string>(
export const normalizedKeyboardSegmentLookup = Object.fromEntries<string>(
[...ALL_MODIFIERS, ...ALL_POINTERS, ...ALL_KEYS].map(entry => [entry.toLowerCase(), entry])
)
normalizedKeyboardSegmentLookup[''] = '+'
Expand Down

0 comments on commit e09330d

Please sign in to comment.