feat(react/settings): react to external changes

This commit is contained in:
Elian Doran 2025-08-18 20:41:33 +03:00
parent b97a5ef888
commit 3837466cb3
No known key found for this signature in database
2 changed files with 49 additions and 7 deletions

View File

@ -4,10 +4,11 @@ interface FormTextBoxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "
id?: string;
currentValue?: string;
onChange?(newValue: string, validity: ValidityState): void;
onBlur?(newValue: string): void;
inputRef?: RefObject<HTMLInputElement>;
}
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}
/>
);

View File

@ -11,7 +11,7 @@ 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<KeyboardShortcut[]>([]);
@ -21,6 +21,36 @@ export default function ShortcutSettings() {
server.get<KeyboardShortcut[]>("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 (
<FormTextBox
currentValue={originalShortcut} onChange={(newShortcut) => {
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);
}