Skip to content

Commit 5372b25

Browse files
fix(frontend): 直前のパターンを記録するように
1 parent a540713 commit 5372b25

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

packages/frontend/src/scripts/hotkey.ts

+30-4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ const MODIFIER_KEYS = ['ctrl', 'alt', 'shift'];
4444
const IGNORE_ELEMENTS = ['input', 'textarea'];
4545
//#endregion
4646

47+
//#region store
48+
let latestHotkey: Pattern & { callback: CallbackFunction } | null = null;
49+
//#endregion
50+
4751
//#region impl
4852
export const makeHotkey = (keymap: Keymap) => {
4953
const actions = parseKeymap(keymap);
@@ -53,11 +57,12 @@ export const makeHotkey = (keymap: Keymap) => {
5357
if (IGNORE_ELEMENTS.includes(document.activeElement.tagName.toLowerCase())) return;
5458
if ((document.activeElement as HTMLElement).isContentEditable) return;
5559
}
56-
for (const { patterns, callback, options } of actions) {
57-
if (matchPatterns(ev, patterns, options)) {
60+
for (const action of actions) {
61+
if (matchPatterns(ev, action)) {
5862
ev.preventDefault();
5963
ev.stopPropagation();
60-
callback(ev);
64+
action.callback(ev);
65+
storePattern(ev, action.callback);
6166
}
6267
}
6368
};
@@ -102,10 +107,21 @@ const parseOptions = (rawCallback: Keymap[keyof Keymap]) => {
102107
return { ...defaultOptions } as const satisfies Action['options'];
103108
};
104109

105-
const matchPatterns = (ev: KeyboardEvent, patterns: Action['patterns'], options: Action['options']) => {
110+
const matchPatterns = (ev: KeyboardEvent, action: Action) => {
111+
const { patterns, options, callback } = action;
106112
if (ev.repeat && !options.allowRepeat) return false;
107113
const key = ev.key.toLowerCase();
108114
return patterns.some(({ which, ctrl, shift, alt }) => {
115+
if (
116+
latestHotkey != null &&
117+
latestHotkey.which.includes(key) &&
118+
latestHotkey.ctrl === ctrl &&
119+
latestHotkey.alt === alt &&
120+
latestHotkey.shift === shift &&
121+
latestHotkey.callback === callback
122+
) {
123+
return false;
124+
}
109125
if (!which.includes(key)) return false;
110126
if (ctrl !== (ev.ctrlKey || ev.metaKey)) return false;
111127
if (alt !== ev.altKey) return false;
@@ -114,6 +130,16 @@ const matchPatterns = (ev: KeyboardEvent, patterns: Action['patterns'], options:
114130
});
115131
};
116132

133+
const storePattern = (ev: KeyboardEvent, callback: CallbackFunction) => {
134+
latestHotkey = {
135+
which: [ev.key.toLowerCase()],
136+
ctrl: ev.ctrlKey || ev.metaKey,
137+
alt: ev.altKey,
138+
shift: ev.shiftKey,
139+
callback,
140+
};
141+
};
142+
117143
const parseKeyCode = (input?: string | null) => {
118144
if (input == null) return [];
119145
const raw = getValueByKey(KEY_ALIASES, input);

0 commit comments

Comments
 (0)