mirror of
https://github.com/visortelle/haskell-spotlight.git
synced 2024-10-26 03:00:08 +03:00
119 lines
3.8 KiB
TypeScript
119 lines
3.8 KiB
TypeScript
import { KeyboardEventHandler, useEffect, useState } from 'react';
|
|
import * as s from './Popup.module.css';
|
|
import styles from './Popup.module.css';
|
|
import { applyStyles } from '../styles';
|
|
import * as k from './keybindings';
|
|
|
|
export default () => {
|
|
const [keyBinding, setKeyBinding] = useState<k.KeyBinding | undefined>();
|
|
const [tmpKeyBinding, setTmpKeyBinding] = useState<k.KeyBinding>({
|
|
code: undefined,
|
|
modifiers: {
|
|
altKey: false,
|
|
ctrlKey: false,
|
|
metaKey: false,
|
|
shiftKey: false
|
|
}
|
|
});
|
|
const [state, setState] = useState<'awaitingForNewKeyBinding' | 'awaitingForUserInput' | 'keyBindingUpdated'>('awaitingForNewKeyBinding');
|
|
|
|
useEffect(() => {
|
|
applyStyles(document.body);
|
|
styles.use();
|
|
|
|
(async () => {
|
|
const kb = await k.readKeyBinding('toggleSpotlight');
|
|
setKeyBinding(kb);
|
|
})()
|
|
}, []);
|
|
|
|
const handleKeyUp: React.KeyboardEventHandler = (event): void => {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
const isValidKb = k.validateKeyBinding(tmpKeyBinding);
|
|
if (!isValidKb) {
|
|
return;
|
|
}
|
|
|
|
setKeyBinding(tmpKeyBinding);
|
|
k.writeKeyBinding('toggleSpotlight', tmpKeyBinding).then(() => {
|
|
setState('keyBindingUpdated');
|
|
});
|
|
}
|
|
|
|
const handleKeyDown: React.KeyboardEventHandler = (event): void => {
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
|
|
if (state !== 'awaitingForUserInput') {
|
|
return;
|
|
}
|
|
|
|
const kb = k.eventToKeyBinding(event);
|
|
setTmpKeyBinding(kb);
|
|
}
|
|
|
|
const kb = state === 'awaitingForUserInput' ? tmpKeyBinding : keyBinding;
|
|
return (
|
|
<div
|
|
className={s.popup}
|
|
onKeyUp={handleKeyUp}
|
|
onKeyDown={handleKeyDown}
|
|
>
|
|
<div className={s.header}><a href="https://github.com/haskell-spotlight/haskell-spotlight">Haskell Spotlight ⭐</a></div>
|
|
<div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between', flex: '1 1' }}>
|
|
<div style={{ fontSize: '14px', textAlign: 'center', padding: '0 18px' }}>
|
|
{state === 'awaitingForNewKeyBinding' && <span>Click on the area bellow to change hotkey.</span>}
|
|
{state === 'awaitingForUserInput' && <span>Press key combination.</span>}
|
|
{state === 'keyBindingUpdated' && <span><br /><strong style={{ fontSize: '24px', color: '#5e5086' }}>Refresh the page to apply new hotkey.</strong></span>}
|
|
</div>
|
|
|
|
{kb && (
|
|
<div
|
|
className={`${s.kbdKeys} ${state === 'awaitingForUserInput' ? s.kbdKeysAwaiting : ''}`}
|
|
onClick={() => {
|
|
if (state === 'awaitingForNewKeyBinding' || state === 'keyBindingUpdated') {
|
|
setState('awaitingForUserInput')
|
|
} else if (state === 'awaitingForUserInput') {
|
|
setState('awaitingForNewKeyBinding');
|
|
}
|
|
}}
|
|
tabIndex={0}
|
|
>
|
|
<KbdKey name={kb.code} isActive={kb.code !== undefined} />
|
|
<div>
|
|
<KbdKey name="Alt" isActive={kb.modifiers.altKey} />
|
|
<KbdKey name="Ctrl" isActive={kb.modifiers.ctrlKey} />
|
|
<KbdKey name="Meta" isActive={kb.modifiers.metaKey} />
|
|
<KbdKey name="Shift" isActive={kb.modifiers.shiftKey} />
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<div
|
|
className={s.resetKeyBindingsButton}
|
|
onClick={async () => {
|
|
await k.setDefaultKeyBindings();
|
|
const kb = await k.readKeyBinding('toggleSpotlight');
|
|
setKeyBinding(kb);
|
|
setState('keyBindingUpdated');
|
|
}}
|
|
>
|
|
Reset settings
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const KbdKey = (props: { name: string, isActive: boolean }) => {
|
|
return (
|
|
<div className={s.kbd}>
|
|
<code className={`${s.kbdKey} ${props.isActive ? s.kbdKeyActive : ''}`}>
|
|
{props.name}
|
|
</code>
|
|
</div>
|
|
);
|
|
}
|