diff --git a/apps/client/src/widgets/react/FormTextBox.tsx b/apps/client/src/widgets/react/FormTextBox.tsx index de9e67dce..f80bbf444 100644 --- a/apps/client/src/widgets/react/FormTextBox.tsx +++ b/apps/client/src/widgets/react/FormTextBox.tsx @@ -4,10 +4,11 @@ interface FormTextBoxProps extends Omit, " id?: string; currentValue?: string; onChange?(newValue: string, validity: ValidityState): void; + onBlur?(newValue: string): void; inputRef?: RefObject; } -export default function FormTextBox({ inputRef, className, type, currentValue, onChange, ...rest}: FormTextBoxProps) { +export default function FormTextBox({ inputRef, className, type, currentValue, onChange, onBlur,...rest}: FormTextBoxProps) { if (type === "number" && currentValue) { const { min, max } = rest; const currentValueNum = parseInt(currentValue, 10); @@ -24,10 +25,14 @@ export default function FormTextBox({ inputRef, className, type, currentValue, o className={`form-control ${className ?? ""}`} type={type ?? "text"} value={currentValue} - onInput={e => { + onInput={onChange && (e => { const target = e.currentTarget; onChange?.(target.value, target.validity); - }} + })} + onBlur={onBlur && (e => { + const target = e.currentTarget; + onBlur(target.value); + })} {...rest} /> ); diff --git a/apps/client/src/widgets/type_widgets/options/shortcuts.tsx b/apps/client/src/widgets/type_widgets/options/shortcuts.tsx index a4227056c..f6d22d960 100644 --- a/apps/client/src/widgets/type_widgets/options/shortcuts.tsx +++ b/apps/client/src/widgets/type_widgets/options/shortcuts.tsx @@ -11,16 +11,46 @@ import { useCallback, useEffect, useState } from "preact/hooks"; import server from "../../../services/server"; import options from "../../../services/options"; import dialog from "../../../services/dialog"; -import { useTriliumOptions } from "../../react/hooks"; +import useTriliumEvent from "../../react/hooks"; export default function ShortcutSettings() { - const [ keyboardShortcuts, setKeyboardShortcuts ] = useState([]); + const [ keyboardShortcuts, setKeyboardShortcuts ] = useState([]); const [ filter, setFilter ] = useState(); useEffect(() => { server.get("keyboard-actions").then(setKeyboardShortcuts); }, []) + useTriliumEvent("entitiesReloaded", ({ loadResults }) => { + const optionNames = loadResults.getOptionNames(); + if (!optionNames || !optionNames.length) { + return; + } + + let updatedShortcuts: KeyboardShortcut[] = null; + + for (const optionName of optionNames) { + if (!(optionName.startsWith("keyboardShortcuts"))) { + continue; + } + + const newValue = options.get(optionName); + const actionName = getActionNameFromOptionName(optionName); + const correspondingShortcut = keyboardShortcuts.find(s => "actionName" in s && s.actionName === actionName); + if (correspondingShortcut && "effectiveShortcuts" in correspondingShortcut) { + correspondingShortcut.effectiveShortcuts = JSON.parse(newValue); + + if (!updatedShortcuts) { + updatedShortcuts = Array.from(keyboardShortcuts); + } + } + } + + if (updatedShortcuts) { + setKeyboardShortcuts(updatedShortcuts); + } + }); + const resetShortcuts = useCallback(async () => { if (!(await dialog.confirm(t("shortcuts.confirm_reset")))) { return; @@ -128,7 +158,8 @@ function ShortcutEditor({ keyboardShortcut: action }: { keyboardShortcut: Action return ( { + currentValue={originalShortcut} + onBlur={(newShortcut) => { const { actionName } = action; const optionName = getOptionName(actionName); const newShortcuts = newShortcut @@ -142,6 +173,12 @@ function ShortcutEditor({ keyboardShortcut: action }: { keyboardShortcut: Action ) } +const PREFIX = "keyboardShortcuts"; + function getOptionName(actionName: string) { - return `keyboardShortcuts${actionName.substr(0, 1).toUpperCase()}${actionName.substr(1)}` as OptionNames; + return `${PREFIX}${actionName.substr(0, 1).toUpperCase()}${actionName.substr(1)}` as OptionNames; +} + +function getActionNameFromOptionName(optionName: string) { + return optionName.at(PREFIX.length)?.toLowerCase() + optionName.substring(PREFIX.length + 1); } \ No newline at end of file