diff --git a/ts/components/CompositionArea.tsx b/ts/components/CompositionArea.tsx index 31a4d76621..6335138b89 100644 --- a/ts/components/CompositionArea.tsx +++ b/ts/components/CompositionArea.tsx @@ -54,7 +54,7 @@ import { countStickers } from './stickers/lib'; import { useAttachFileShortcut, useEditLastMessageSent, - useKeyboardShortcuts, + useKeyboardShortcutsConditionally, } from '../hooks/useKeyboardShortcuts'; import { MediaEditor } from './MediaEditor'; import { isImageTypeSupported } from '../util/GoogleChrome'; @@ -416,9 +416,15 @@ export function CompositionArea({ setMessageToEdit, ]); + const [hasFocus, setHasFocus] = useState(false); + const attachFileShortcut = useAttachFileShortcut(launchAttachmentPicker); const editLastMessageSent = useEditLastMessageSent(maybeEditMessage); - useKeyboardShortcuts(attachFileShortcut, editLastMessageSent); + useKeyboardShortcutsConditionally( + hasFocus, + attachFileShortcut, + editLastMessageSent + ); // Focus input on first mount const previousFocusCounter = usePrevious( @@ -954,6 +960,8 @@ export function CompositionArea({ large={large} linkPreviewLoading={linkPreviewLoading} linkPreviewResult={linkPreviewResult} + onBlur={() => setHasFocus(false)} + onFocus={() => setHasFocus(true)} onCloseLinkPreview={onCloseLinkPreview} onDirtyChange={setDirty} onEditorStateChange={onEditorStateChange} diff --git a/ts/components/CompositionInput.tsx b/ts/components/CompositionInput.tsx index 3e77b2842a..c07ebf89cc 100644 --- a/ts/components/CompositionInput.tsx +++ b/ts/components/CompositionInput.tsx @@ -120,6 +120,8 @@ export type Props = Readonly<{ }): unknown; onTextTooLong(): unknown; onPickEmoji(o: EmojiPickDataType): unknown; + onBlur?: () => unknown; + onFocus?: () => unknown; onSubmit( message: string, bodyRanges: DraftBodyRanges, @@ -159,6 +161,8 @@ export function CompositionInput(props: Props): React.ReactElement { linkPreviewResult, moduleClassName, onCloseLinkPreview, + onBlur, + onFocus, onPickEmoji, onScroll, onSubmit, @@ -610,6 +614,29 @@ export function CompositionInput(props: Props): React.ReactElement { quill.focus(); }, [disabled]); + React.useEffect(() => { + const quill = quillRef.current; + + if (quill === undefined) { + return; + } + + function handleFocus() { + onFocus?.(); + } + function handleBlur() { + onBlur?.(); + } + + quill.root.addEventListener('focus', handleFocus); + quill.root.addEventListener('blur', handleBlur); + + return () => { + quill.root.removeEventListener('focus', handleFocus); + quill.root.removeEventListener('blur', handleBlur); + }; + }, [onFocus, onBlur]); + React.useEffect(() => { const emojiCompletion = emojiCompletionRef.current;