From f033a28eb2ca63dbb2adc9f80d043a06ce5fb8a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Espino=20Garc=C3=ADa?= Date: Mon, 31 Oct 2022 18:02:44 +0100 Subject: [PATCH] Make so Autocomplete opens when we use the at quick action (#6613) * Make so Autocomplete opens when we use the at quick action * Open keyboard when the quick action is pressed --- .../draft_handler/draft_handler.tsx | 4 ++-- .../post_draft/draft_input/index.tsx | 14 ++++++++--- .../post_draft/post_input/post_input.tsx | 22 ++++++++++-------- .../input_quick_action/index.tsx | 23 ++++++++++--------- .../quick_actions/quick_actions.tsx | 10 ++++---- .../post_draft/send_handler/send_handler.tsx | 4 ++-- 6 files changed, 45 insertions(+), 32 deletions(-) diff --git a/app/components/post_draft/draft_handler/draft_handler.tsx b/app/components/post_draft/draft_handler/draft_handler.tsx index f8505bc953..342ae21320 100644 --- a/app/components/post_draft/draft_handler/draft_handler.tsx +++ b/app/components/post_draft/draft_handler/draft_handler.tsx @@ -20,9 +20,9 @@ type Props = { maxFileSize: number; maxFileCount: number; canUploadFiles: boolean; - updateCursorPosition: (cursorPosition: number) => void; + updateCursorPosition: React.Dispatch>; updatePostInputTop: (top: number) => void; - updateValue: (value: string) => void; + updateValue: React.Dispatch>; value: string; setIsFocused: (isFocused: boolean) => void; } diff --git a/app/components/post_draft/draft_input/index.tsx b/app/components/post_draft/draft_input/index.tsx index 536a99430d..a5f827de8f 100644 --- a/app/components/post_draft/draft_input/index.tsx +++ b/app/components/post_draft/draft_input/index.tsx @@ -1,7 +1,8 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useCallback} from 'react'; +import {PasteInputRef} from '@mattermost/react-native-paste-input'; +import React, {useCallback, useRef} from 'react'; import {LayoutChangeEvent, Platform, ScrollView, View} from 'react-native'; import {Edge, SafeAreaView} from 'react-native-safe-area-context'; @@ -21,7 +22,7 @@ type Props = { currentUserId: string; // Cursor Position Handler - updateCursorPosition: (pos: number) => void; + updateCursorPosition: React.Dispatch>; cursorPosition: number; // Send Handler @@ -33,7 +34,7 @@ type Props = { files: FileInfo[]; value: string; uploadFileError: React.ReactNode; - updateValue: (value: string) => void; + updateValue: React.Dispatch>; addFiles: (files: FileInfo[]) => void; updatePostInputTop: (top: number) => void; setIsFocused: (isFocused: boolean) => void; @@ -103,6 +104,11 @@ export default function DraftInput({ updatePostInputTop(e.nativeEvent.layout.height); }, []); + const inputRef = useRef(); + const focus = useCallback(() => { + inputRef.current?.focus(); + }, []); + // Render const postInputTestID = `${testID}.post.input`; const quickActionsTestID = `${testID}.quick_actions`; @@ -144,6 +150,7 @@ export default function DraftInput({ value={value} addFiles={addFiles} sendMessage={sendMessage} + inputRef={inputRef} setIsFocused={setIsFocused} /> void; + updateValue: React.Dispatch>; addFiles: (files: ExtractedFileInfo[]) => void; cursorPosition: number; - updateCursorPosition: (pos: number) => void; + updateCursorPosition: React.Dispatch>; sendMessage: () => void; + inputRef: React.MutableRefObject; setIsFocused: (isFocused: boolean) => void; } @@ -109,6 +110,7 @@ export default function PostInput({ cursorPosition, updateCursorPosition, sendMessage, + inputRef, setIsFocused, }: Props) { const intl = useIntl(); @@ -119,7 +121,7 @@ export default function PostInput({ const managedConfig = useManagedConfig(); const lastTypingEventSent = useRef(0); - const input = useRef(); + const lastNativeValue = useRef(''); const previousAppState = useRef(AppState.currentState); @@ -133,7 +135,7 @@ export default function PostInput({ }, [maxHeight, style.input]); const blur = () => { - input.current?.blur(); + inputRef.current?.blur(); }; const handleAndroidKeyboard = () => { @@ -238,12 +240,12 @@ export default function PostInput({ sendMessage(); break; case 'shift-enter': - updateValue(value.substring(0, cursorPosition) + '\n' + value.substring(cursorPosition)); - updateCursorPosition(cursorPosition + 1); + updateValue((v) => v.substring(0, cursorPosition) + '\n' + v.substring(cursorPosition)); + updateCursorPosition((pos) => pos + 1); break; } } - }, [sendMessage, updateValue, value, cursorPosition, isTablet]); + }, [sendMessage, updateValue, cursorPosition, isTablet]); const onAppStateChange = useCallback((appState: AppStateStatus) => { if (appState !== 'active' && previousAppState.current === 'active') { @@ -279,7 +281,7 @@ export default function PostInput({ const draft = value ? `${value} ${text} ` : `${text} `; updateValue(draft); updateCursorPosition(draft.length); - input.current?.focus(); + inputRef.current?.focus(); } }); return () => listener.remove(); @@ -288,7 +290,7 @@ export default function PostInput({ useEffect(() => { if (value !== lastNativeValue.current) { // May change when we implement Fabric - input.current?.setNativeProps({ + inputRef.current?.setNativeProps({ text: value, }); lastNativeValue.current = value; @@ -306,7 +308,7 @@ export default function PostInput({ void; - value: string; + updateValue: React.Dispatch>; + focus: () => void; } const getStyleSheet = makeStyleSheetFromTheme((theme) => { @@ -34,18 +34,19 @@ export default function InputQuickAction({ testID, disabled, inputType, - onTextChange, - value, + updateValue, + focus, }: Props) { const theme = useTheme(); const onPress = useCallback(() => { - let newValue = '/'; - if (inputType === 'at') { - newValue = `${value}@`; - } - - onTextChange(newValue); - }, [value, inputType]); + updateValue((v) => { + if (inputType === 'at') { + return `${v}@`; + } + return '/'; + }); + focus(); + }, [inputType]); const actionTestID = disabled ? `${testID}.disabled` : diff --git a/app/components/post_draft/quick_actions/quick_actions.tsx b/app/components/post_draft/quick_actions/quick_actions.tsx index 03696f5293..4d63402d3c 100644 --- a/app/components/post_draft/quick_actions/quick_actions.tsx +++ b/app/components/post_draft/quick_actions/quick_actions.tsx @@ -19,6 +19,7 @@ type Props = { value: string; updateValue: (value: string) => void; addFiles: (file: FileInfo[]) => void; + focus: () => void; } const style = StyleSheet.create({ @@ -47,6 +48,7 @@ export default function QuickActions({ maxFileCount, updateValue, addFiles, + focus, }: Props) { const atDisabled = value[value.length - 1] === '@'; const slashDisabled = value.length > 0; @@ -74,15 +76,15 @@ export default function QuickActions({ testID={atInputActionTestID} disabled={atDisabled} inputType='at' - onTextChange={updateValue} - value={value} + updateValue={updateValue} + focus={focus} /> void; - updateValue: (message: string) => void; - updateCursorPosition: (cursorPosition: number) => void; + updateValue: React.Dispatch>; + updateCursorPosition: React.Dispatch>; updatePostInputTop: (top: number) => void; addFiles: (file: FileInfo[]) => void; uploadFileError: React.ReactNode;