diff options
author | Eric Bailey <git@esb.lol> | 2024-09-13 16:48:28 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-13 16:48:28 -0500 |
commit | d76f9abdd718e24848a9b8f67486129aee421427 (patch) | |
tree | e5574c807eea6010746006a234e3a79dc0684552 /src/state/shell | |
parent | cac43127f0163c84a921afd806d91e1df10ea568 (diff) | |
download | voidsky-d76f9abdd718e24848a9b8f67486129aee421427.tar.zst |
"N" keyboard shortcut to open a new post modal (#5197)
* feat: Add hook on web app to open composer with 'N' keyboard shortcut * Extract, don't fire open composer if already open * Ignore interactive elements --------- Co-authored-by: João Gabriel <joaog@nocorp.io> Co-authored-by: Hailey <me@haileyok.com>
Diffstat (limited to 'src/state/shell')
-rw-r--r-- | src/state/shell/composer/index.tsx (renamed from src/state/shell/composer.tsx) | 0 | ||||
-rw-r--r-- | src/state/shell/composer/useComposerKeyboardShortcut.tsx | 49 |
2 files changed, 49 insertions, 0 deletions
diff --git a/src/state/shell/composer.tsx b/src/state/shell/composer/index.tsx index 612388ff8..612388ff8 100644 --- a/src/state/shell/composer.tsx +++ b/src/state/shell/composer/index.tsx diff --git a/src/state/shell/composer/useComposerKeyboardShortcut.tsx b/src/state/shell/composer/useComposerKeyboardShortcut.tsx new file mode 100644 index 000000000..f46062185 --- /dev/null +++ b/src/state/shell/composer/useComposerKeyboardShortcut.tsx @@ -0,0 +1,49 @@ +import React from 'react' + +import {useComposerControls} from './' + +/** + * Based on {@link https://github.com/jaywcjlove/hotkeys-js/blob/b0038773f3b902574f22af747f3bb003a850f1da/src/index.js#L51C1-L64C2} + */ +function shouldIgnore(event: KeyboardEvent) { + const target: any = event.target || event.srcElement + if (!target) return false + const {tagName} = target + if (!tagName) return false + const isInput = + tagName === 'INPUT' && + ![ + 'checkbox', + 'radio', + 'range', + 'button', + 'file', + 'reset', + 'submit', + 'color', + ].includes(target.type) + // ignore: isContentEditable === 'true', <input> and <textarea> when readOnly state is false, <select> + if ( + target.isContentEditable || + ((isInput || tagName === 'TEXTAREA' || tagName === 'SELECT') && + !target.readOnly) + ) { + return true + } + return false +} + +export function useComposerKeyboardShortcut() { + const {openComposer} = useComposerControls() + + React.useEffect(() => { + function handler(event: KeyboardEvent) { + if (shouldIgnore(event)) return + if (event.key === 'n' || event.key === 'N') { + openComposer({}) + } + } + document.addEventListener('keydown', handler) + return () => document.removeEventListener('keydown', handler) + }, [openComposer]) +} |