Good hotkey support

This commit is contained in:
Gregory Schier
2023-11-22 09:01:48 -08:00
parent 3ced7f7c18
commit b0026aff66
16 changed files with 428 additions and 345 deletions

View File

@@ -24,11 +24,7 @@ export function useCreateEnvironment() {
label: 'Name',
defaultValue: 'My Environment',
});
const variables =
environments.length === 0 && workspaces.length === 1
? [{ name: 'first_variable', value: 'some reusable value' }]
: [];
return invoke('create_environment', { name, variables, workspaceId });
return invoke('create_environment', { name, variables: [], workspaceId });
},
onSettled: () => trackEvent('environment', 'create'),
onSuccess: async (environment) => {

View File

@@ -1,4 +1,5 @@
import { useEffect, useRef } from 'react';
import { useOsInfo } from './useOsInfo';
export type HotkeyAction =
| 'request.send'
@@ -7,7 +8,7 @@ export type HotkeyAction =
| 'sidebar.toggle'
| 'sidebar.focus'
| 'urlBar.focus'
| 'environmentEditor.show';
| 'environmentEditor.toggle';
const hotkeys: Record<HotkeyAction, string[]> = {
'request.send': ['Meta+Enter', 'Meta+r'],
@@ -16,10 +17,18 @@ const hotkeys: Record<HotkeyAction, string[]> = {
'sidebar.toggle': ['Meta+b'],
'sidebar.focus': ['Meta+1'],
'urlBar.focus': ['Meta+l'],
'environmentEditor.show': ['Meta+e'],
'environmentEditor.toggle': ['Meta+e'],
};
export function useHotkey(action: HotkeyAction | null, callback: (e: KeyboardEvent) => void) {
useAnyHotkey((hkAction, e) => {
if (hkAction === action) {
callback(e);
}
});
}
export function useAnyHotkey(callback: (action: HotkeyAction, e: KeyboardEvent) => void) {
const currentKeys = useRef<Set<string>>(new Set());
const callbackRef = useRef(callback);
@@ -30,19 +39,17 @@ export function useHotkey(action: HotkeyAction | null, callback: (e: KeyboardEve
useEffect(() => {
const down = (e: KeyboardEvent) => {
currentKeys.current.add(e.key);
for (const [hkAction, hkKeys] of Object.entries(hotkeys)) {
for (const [hkAction, hkKeys] of Object.entries(hotkeys) as [HotkeyAction, string[]][]) {
for (const hkKey of hkKeys) {
const keys = hkKey.split('+');
if (
keys.length === currentKeys.current.size &&
keys.every((key) => currentKeys.current.has(key)) &&
hkAction === action
keys.every((key) => currentKeys.current.has(key))
) {
// Triggered hotkey!
console.log('TRIGGER!', action);
e.preventDefault();
e.stopPropagation();
callbackRef.current(e);
callbackRef.current(hkAction, e);
}
}
}
@@ -56,6 +63,45 @@ export function useHotkey(action: HotkeyAction | null, callback: (e: KeyboardEve
window.removeEventListener('keydown', down);
window.removeEventListener('keyup', up);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [action, callback]);
}, []);
}
export function useFormattedHotkey(action: HotkeyAction | null): string | null {
const osInfo = useOsInfo();
const trigger = action != null ? hotkeys[action]?.[0] ?? null : null;
if (trigger == null || osInfo == null) {
return null;
}
const os = osInfo.osType;
const parts = trigger.split('+');
const labelParts: string[] = [];
for (const p of parts) {
if (os === 'Darwin') {
if (p === 'Meta') {
labelParts.push('⌘');
} else if (p === 'Shift') {
labelParts.push('⇧');
} else if (p === 'Control') {
labelParts.push('⌃');
} else if (p === 'Enter') {
labelParts.push('↩');
} else {
labelParts.push(p.toUpperCase());
}
} else {
if (p === 'Meta') {
labelParts.push('Ctrl');
} else {
labelParts.push(p);
}
}
}
if (os === 'Darwin') {
return labelParts.join('');
} else {
return labelParts.join('+');
}
}