From ce9d3895206bb74f6ebf8f750fc580f8820c19c1 Mon Sep 17 00:00:00 2001 From: dominictb Date: Mon, 27 May 2024 09:42:19 +0700 Subject: [PATCH] fix: keep the Android keyboard visible when pasting in Composer component env: Android Chrome Signed-off-by: dominictb --- src/components/Composer/index.tsx | 2 +- src/hooks/useHtmlPaste/index.ts | 11 +++++++---- src/hooks/useHtmlPaste/types.ts | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/Composer/index.tsx b/src/components/Composer/index.tsx index f7bf277050a2..a7635db58472 100755 --- a/src/components/Composer/index.tsx +++ b/src/components/Composer/index.tsx @@ -250,7 +250,7 @@ function Composer( // eslint-disable-next-line react-hooks/exhaustive-deps }, [isComposerFullSize]); - useHtmlPaste(textInput, handlePaste, true); + useHtmlPaste(textInput, handlePaste, true, false); useEffect(() => { if (typeof ref === 'function') { diff --git a/src/hooks/useHtmlPaste/index.ts b/src/hooks/useHtmlPaste/index.ts index 925a3db518ae..b6ee5ab122fc 100644 --- a/src/hooks/useHtmlPaste/index.ts +++ b/src/hooks/useHtmlPaste/index.ts @@ -18,8 +18,7 @@ const insertAtCaret = (target: HTMLElement, text: string) => { // Move caret to the end of the newly inserted text node. range.setStart(node, node.length); range.setEnd(node, node.length); - selection.removeAllRanges(); - selection.addRange(range); + selection.setBaseAndExtent(range.startContainer, range.startOffset, range.endContainer, range.endOffset); // Dispatch paste event to simulate real browser behavior target.dispatchEvent(new Event('paste', {bubbles: true})); @@ -30,7 +29,7 @@ const insertAtCaret = (target: HTMLElement, text: string) => { } }; -const useHtmlPaste: UseHtmlPaste = (textInputRef, preHtmlPasteCallback, removeListenerOnScreenBlur = false) => { +const useHtmlPaste: UseHtmlPaste = (textInputRef, preHtmlPasteCallback, removeListenerOnScreenBlur = false, shouldRefocusAfterPaste = true) => { const navigation = useNavigation(); /** @@ -47,7 +46,11 @@ const useHtmlPaste: UseHtmlPaste = (textInputRef, preHtmlPasteCallback, removeLi } // Pointer will go out of sight when a large paragraph is pasted on the web. Refocusing the input keeps the cursor in view. - textInputRef.current?.blur(); + // If shouldRefocusAfterPaste = false, we want to call `focus()` only as it won't change the focus state of the input since it is already focused + if (shouldRefocusAfterPaste) { + textInputRef.current?.blur(); + } + textInputRef.current?.focus(); // eslint-disable-next-line no-empty } catch (e) {} diff --git a/src/hooks/useHtmlPaste/types.ts b/src/hooks/useHtmlPaste/types.ts index 305ebe5fbd0f..f2dd41eb2488 100644 --- a/src/hooks/useHtmlPaste/types.ts +++ b/src/hooks/useHtmlPaste/types.ts @@ -5,6 +5,7 @@ type UseHtmlPaste = ( textInputRef: MutableRefObject<(HTMLTextAreaElement & TextInput) | TextInput | null>, preHtmlPasteCallback?: (event: ClipboardEvent) => boolean, removeListenerOnScreenBlur?: boolean, + shouldRefocusAfterPaste?: boolean, ) => void; export default UseHtmlPaste;