about summary refs log tree commit diff
path: root/src/screens/Messages/Conversation/MessageInput.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens/Messages/Conversation/MessageInput.tsx')
-rw-r--r--src/screens/Messages/Conversation/MessageInput.tsx57
1 files changed, 47 insertions, 10 deletions
diff --git a/src/screens/Messages/Conversation/MessageInput.tsx b/src/screens/Messages/Conversation/MessageInput.tsx
index 1a63b1b5b..f92773621 100644
--- a/src/screens/Messages/Conversation/MessageInput.tsx
+++ b/src/screens/Messages/Conversation/MessageInput.tsx
@@ -1,5 +1,16 @@
 import React from 'react'
-import {Pressable, TextInput, View} from 'react-native'
+import {
+  Dimensions,
+  Keyboard,
+  NativeSyntheticEvent,
+  Pressable,
+  TextInput,
+  TextInputContentSizeChangeEventData,
+  View,
+} from 'react-native'
+import {useSafeAreaInsets} from 'react-native-safe-area-context'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
 
 import {atoms as a, useTheme} from '#/alf'
 import {Text} from '#/components/Typography'
@@ -13,41 +24,67 @@ export function MessageInput({
   onFocus: () => void
   onBlur: () => void
 }) {
+  const {_} = useLingui()
   const t = useTheme()
   const [message, setMessage] = React.useState('')
+  const [maxHeight, setMaxHeight] = React.useState<number | undefined>()
+  const [isInputScrollable, setIsInputScrollable] = React.useState(false)
+
+  const {top: topInset} = useSafeAreaInsets()
 
   const inputRef = React.useRef<TextInput>(null)
 
   const onSubmit = React.useCallback(() => {
-    onSendMessage(message)
+    if (message.trim() === '') {
+      return
+    }
+    onSendMessage(message.trimEnd())
     setMessage('')
     setTimeout(() => {
       inputRef.current?.focus()
     }, 100)
   }, [message, onSendMessage])
 
+  const onInputLayout = React.useCallback(
+    (e: NativeSyntheticEvent<TextInputContentSizeChangeEventData>) => {
+      const keyboardHeight = Keyboard.metrics()?.height ?? 0
+      const windowHeight = Dimensions.get('window').height
+
+      const max = windowHeight - keyboardHeight - topInset - 100
+      const availableSpace = max - e.nativeEvent.contentSize.height
+
+      setMaxHeight(max)
+      setIsInputScrollable(availableSpace < 30)
+    },
+    [topInset],
+  )
+
   return (
     <View
       style={[
         a.flex_row,
         a.py_sm,
         a.px_sm,
-        a.rounded_full,
+        a.pl_md,
         a.mt_sm,
         t.atoms.bg_contrast_25,
+        {borderRadius: 23},
       ]}>
       <TextInput
-        accessibilityLabel="Text input field"
-        accessibilityHint="Write a message"
+        accessibilityLabel={_(msg`Message input field`)}
+        accessibilityHint={_(msg`Type your message here`)}
+        placeholder={_(msg`Write a message`)}
+        placeholderTextColor={t.palette.contrast_500}
         value={message}
+        multiline={true}
         onChangeText={setMessage}
-        placeholder="Write a message"
-        style={[a.flex_1, a.text_sm, a.px_sm, t.atoms.text]}
-        onSubmitEditing={onSubmit}
+        style={[a.flex_1, a.text_md, a.px_sm, t.atoms.text, {maxHeight}]}
+        keyboardAppearance={t.name === 'light' ? 'light' : 'dark'}
+        scrollEnabled={isInputScrollable}
+        blurOnSubmit={false}
         onFocus={onFocus}
         onBlur={onBlur}
-        placeholderTextColor={t.palette.contrast_500}
-        keyboardAppearance={t.name === 'light' ? 'light' : 'dark'}
+        onContentSizeChange={onInputLayout}
         ref={inputRef}
       />
       <Pressable