-
Notifications
You must be signed in to change notification settings - Fork 61
Expand file tree
/
Copy pathuseKeyboardShortcuts.ts
More file actions
83 lines (75 loc) · 2.52 KB
/
useKeyboardShortcuts.ts
File metadata and controls
83 lines (75 loc) · 2.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import { useEffect, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useConversationStore, useSettingsStore, useUIStore } from '@/stores';
import {
SHORTCUT_ACTIONS,
getShortcutBinding,
matchesShortcutEvent,
type ShortcutAction,
} from '@/lib/shortcuts';
import { executeShortcutAction } from '@/lib/shortcutActions';
export function useKeyboardShortcuts() {
const { t: _t } = useTranslation();
const setActivePage = useUIStore((s) => s.setActivePage);
const settings = useSettingsStore((s) => s.settings);
const handleKeyDown = useCallback(
async (e: KeyboardEvent) => {
for (const action of SHORTCUT_ACTIONS) {
const binding = getShortcutBinding(settings, action);
if (!binding) continue;
if (!matchesShortcutEvent(e, binding)) continue;
console.info('[shortcut-local-hit]', {
action,
binding,
key: e.key,
metaKey: e.metaKey,
ctrlKey: e.ctrlKey,
shiftKey: e.shiftKey,
altKey: e.altKey,
});
e.preventDefault();
await executeShortcutAction(action as ShortcutAction);
return;
}
const isMod = e.metaKey || e.ctrlKey;
if (!isMod) return;
switch (e.key.toLowerCase()) {
case 'f':
e.preventDefault();
setActivePage('chat');
setTimeout(() => {
const searchInput = document.querySelector<HTMLInputElement>('.chat-sidebar-search input');
searchInput?.focus();
}, 50);
return;
case 'w':
e.preventDefault();
useConversationStore.getState().setActiveConversation(null);
return;
default:
return;
}
},
[setActivePage, settings],
);
const exitSettings = useUIStore((s) => s.exitSettings);
const activePage = useUIStore((s) => s.activePage);
const handleKeyDownEsc = useCallback((e: KeyboardEvent) => {
if (e.key === 'Escape') {
if (activePage === 'settings') {
exitSettings();
return;
}
// Close voice overlay or modals via custom event
window.dispatchEvent(new CustomEvent('aqbot:escape'));
}
}, [activePage, exitSettings]);
useEffect(() => {
window.addEventListener('keydown', handleKeyDown);
window.addEventListener('keydown', handleKeyDownEsc);
return () => {
window.removeEventListener('keydown', handleKeyDown);
window.removeEventListener('keydown', handleKeyDownEsc);
};
}, [handleKeyDown, handleKeyDownEsc]);
}