react-native-gifted-chat 2.8.2-alpha.0 → 2.8.2-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/README.md +51 -31
  2. package/package.json +28 -30
  3. package/src/Actions.tsx +1 -1
  4. package/src/Avatar.tsx +1 -1
  5. package/src/Bubble/index.tsx +24 -20
  6. package/src/Bubble/types.ts +7 -6
  7. package/src/Composer.tsx +19 -26
  8. package/src/Constant.ts +0 -1
  9. package/src/Day/index.tsx +3 -3
  10. package/src/GiftedAvatar.tsx +31 -38
  11. package/src/GiftedChat/index.tsx +59 -106
  12. package/src/GiftedChat/styles.ts +3 -0
  13. package/src/GiftedChat/types.ts +17 -67
  14. package/src/InputToolbar.tsx +27 -10
  15. package/src/LoadEarlier.tsx +22 -20
  16. package/src/Message/index.tsx +4 -18
  17. package/src/Message/types.ts +2 -2
  18. package/src/MessageAudio.tsx +19 -7
  19. package/src/MessageContainer/components/DayAnimated/index.tsx +16 -11
  20. package/src/MessageContainer/components/Item/index.tsx +10 -4
  21. package/src/MessageContainer/components/Item/types.ts +1 -1
  22. package/src/MessageContainer/index.tsx +57 -38
  23. package/src/MessageContainer/types.ts +32 -7
  24. package/src/MessageImage.tsx +132 -18
  25. package/src/MessageText.tsx +24 -64
  26. package/src/MessageVideo.tsx +19 -7
  27. package/src/QuickReplies.tsx +19 -12
  28. package/src/Send.tsx +10 -5
  29. package/src/SystemMessage.tsx +10 -3
  30. package/src/Time.tsx +10 -3
  31. package/src/TypingIndicator/index.tsx +4 -3
  32. package/src/TypingIndicator/types.ts +3 -0
  33. package/src/__tests__/Actions.test.tsx +3 -4
  34. package/src/__tests__/Avatar.test.tsx +5 -6
  35. package/src/__tests__/Bubble.test.tsx +14 -19
  36. package/src/__tests__/Composer.test.tsx +3 -4
  37. package/src/__tests__/Day.test.tsx +5 -8
  38. package/src/__tests__/DayAnimated.test.tsx +12 -14
  39. package/src/__tests__/GiftedAvatar.test.tsx +3 -8
  40. package/src/__tests__/GiftedChat.test.tsx +34 -43
  41. package/src/__tests__/InputToolbar.test.tsx +3 -4
  42. package/src/__tests__/LoadEarlier.test.tsx +3 -4
  43. package/src/__tests__/Message.test.tsx +51 -58
  44. package/src/__tests__/MessageContainer.test.tsx +39 -5
  45. package/src/__tests__/MessageImage.test.tsx +12 -15
  46. package/src/__tests__/MessageText.test.tsx +7 -4
  47. package/src/__tests__/Send.test.tsx +7 -8
  48. package/src/__tests__/SystemMessage.test.tsx +12 -15
  49. package/src/__tests__/Time.test.tsx +5 -8
  50. package/src/__tests__/__snapshots__/Actions.test.tsx.snap +39 -7
  51. package/src/__tests__/__snapshots__/Bubble.test.tsx.snap +48 -50
  52. package/src/__tests__/__snapshots__/Composer.test.tsx.snap +1 -2
  53. package/src/__tests__/__snapshots__/Constant.test.tsx.snap +0 -1
  54. package/src/__tests__/__snapshots__/GiftedChat.test.tsx.snap +20 -22
  55. package/src/__tests__/__snapshots__/InputToolbar.test.tsx.snap +2 -2
  56. package/src/__tests__/__snapshots__/LoadEarlier.test.tsx.snap +37 -6
  57. package/src/__tests__/__snapshots__/Message.test.tsx.snap +146 -150
  58. package/src/__tests__/__snapshots__/MessageImage.test.tsx.snap +32 -11
  59. package/src/__tests__/__snapshots__/MessageText.test.tsx.snap +12 -8
  60. package/src/__tests__/__snapshots__/Send.test.tsx.snap +72 -10
  61. package/src/components/TouchableOpacity.tsx +45 -0
  62. package/src/reanimatedCompat.ts +27 -0
  63. package/src/types.ts +4 -2
  64. package/src/utils.ts +2 -2
  65. package/lib/Actions.d.ts +0 -14
  66. package/lib/Actions.js +0 -57
  67. package/lib/Actions.js.map +0 -1
  68. package/lib/Avatar.d.ts +0 -18
  69. package/lib/Avatar.js +0 -93
  70. package/lib/Avatar.js.map +0 -1
  71. package/lib/Bubble/index.d.ts +0 -6
  72. package/lib/Bubble/index.js +0 -242
  73. package/lib/Bubble/index.js.map +0 -1
  74. package/lib/Bubble/styles.d.ts +0 -69
  75. package/lib/Bubble/styles.js +0 -72
  76. package/lib/Bubble/styles.js.map +0 -1
  77. package/lib/Bubble/types.d.ts +0 -47
  78. package/lib/Bubble/types.js +0 -2
  79. package/lib/Bubble/types.js.map +0 -1
  80. package/lib/Color.d.ts +0 -18
  81. package/lib/Color.js +0 -18
  82. package/lib/Color.js.map +0 -1
  83. package/lib/Composer.d.ts +0 -20
  84. package/lib/Composer.js +0 -60
  85. package/lib/Composer.js.map +0 -1
  86. package/lib/Constant.d.ts +0 -10
  87. package/lib/Constant.js +0 -17
  88. package/lib/Constant.js.map +0 -1
  89. package/lib/Day/index.d.ts +0 -4
  90. package/lib/Day/index.js +0 -39
  91. package/lib/Day/index.js.map +0 -1
  92. package/lib/Day/styles.d.ts +0 -20
  93. package/lib/Day/styles.js +0 -22
  94. package/lib/Day/styles.js.map +0 -1
  95. package/lib/Day/types.d.ts +0 -9
  96. package/lib/Day/types.js +0 -2
  97. package/lib/Day/types.js.map +0 -1
  98. package/lib/GiftedAvatar.d.ts +0 -11
  99. package/lib/GiftedAvatar.js +0 -104
  100. package/lib/GiftedAvatar.js.map +0 -1
  101. package/lib/GiftedChat/index.d.ts +0 -26
  102. package/lib/GiftedChat/index.js +0 -317
  103. package/lib/GiftedChat/index.js.map +0 -1
  104. package/lib/GiftedChat/styles.d.ts +0 -6
  105. package/lib/GiftedChat/styles.js +0 -7
  106. package/lib/GiftedChat/styles.js.map +0 -1
  107. package/lib/GiftedChat/types.d.ts +0 -112
  108. package/lib/GiftedChat/types.js +0 -2
  109. package/lib/GiftedChat/types.js.map +0 -1
  110. package/lib/GiftedChatContext.d.ts +0 -9
  111. package/lib/GiftedChatContext.js +0 -9
  112. package/lib/GiftedChatContext.js.map +0 -1
  113. package/lib/InputToolbar.d.ts +0 -23
  114. package/lib/InputToolbar.js +0 -56
  115. package/lib/InputToolbar.js.map +0 -1
  116. package/lib/LoadEarlier.d.ts +0 -14
  117. package/lib/LoadEarlier.js +0 -45
  118. package/lib/LoadEarlier.js.map +0 -1
  119. package/lib/Message/index.d.ts +0 -6
  120. package/lib/Message/index.js +0 -80
  121. package/lib/Message/index.js.map +0 -1
  122. package/lib/Message/styles.d.ts +0 -21
  123. package/lib/Message/styles.js +0 -22
  124. package/lib/Message/styles.js.map +0 -1
  125. package/lib/Message/types.d.ts +0 -22
  126. package/lib/Message/types.js +0 -2
  127. package/lib/Message/types.js.map +0 -1
  128. package/lib/MessageAudio.d.ts +0 -2
  129. package/lib/MessageAudio.js +0 -14
  130. package/lib/MessageAudio.js.map +0 -1
  131. package/lib/MessageContainer/components/DayAnimated/index.d.ts +0 -5
  132. package/lib/MessageContainer/components/DayAnimated/index.js +0 -85
  133. package/lib/MessageContainer/components/DayAnimated/index.js.map +0 -1
  134. package/lib/MessageContainer/components/DayAnimated/styles.d.ts +0 -11
  135. package/lib/MessageContainer/components/DayAnimated/styles.js +0 -12
  136. package/lib/MessageContainer/components/DayAnimated/styles.js.map +0 -1
  137. package/lib/MessageContainer/components/DayAnimated/types.d.ts +0 -17
  138. package/lib/MessageContainer/components/DayAnimated/types.js +0 -2
  139. package/lib/MessageContainer/components/DayAnimated/types.js.map +0 -1
  140. package/lib/MessageContainer/components/Item/index.d.ts +0 -23
  141. package/lib/MessageContainer/components/Item/index.js +0 -88
  142. package/lib/MessageContainer/components/Item/index.js.map +0 -1
  143. package/lib/MessageContainer/components/Item/types.d.ts +0 -17
  144. package/lib/MessageContainer/components/Item/types.js +0 -2
  145. package/lib/MessageContainer/components/Item/types.js.map +0 -1
  146. package/lib/MessageContainer/index.d.ts +0 -6
  147. package/lib/MessageContainer/index.js +0 -235
  148. package/lib/MessageContainer/index.js.map +0 -1
  149. package/lib/MessageContainer/styles.d.ts +0 -35
  150. package/lib/MessageContainer/styles.js +0 -32
  151. package/lib/MessageContainer/styles.js.map +0 -1
  152. package/lib/MessageContainer/types.d.ts +0 -51
  153. package/lib/MessageContainer/types.js +0 -2
  154. package/lib/MessageContainer/types.js.map +0 -1
  155. package/lib/MessageImage.d.ts +0 -13
  156. package/lib/MessageImage.js +0 -30
  157. package/lib/MessageImage.js.map +0 -1
  158. package/lib/MessageText.d.ts +0 -19
  159. package/lib/MessageText.js +0 -69
  160. package/lib/MessageText.js.map +0 -1
  161. package/lib/MessageVideo.d.ts +0 -2
  162. package/lib/MessageVideo.js +0 -14
  163. package/lib/MessageVideo.js.map +0 -1
  164. package/lib/QuickReplies.d.ts +0 -15
  165. package/lib/QuickReplies.js +0 -101
  166. package/lib/QuickReplies.js.map +0 -1
  167. package/lib/Send.d.ts +0 -15
  168. package/lib/Send.js +0 -34
  169. package/lib/Send.js.map +0 -1
  170. package/lib/SystemMessage.d.ts +0 -11
  171. package/lib/SystemMessage.js +0 -27
  172. package/lib/SystemMessage.js.map +0 -1
  173. package/lib/Time.d.ts +0 -11
  174. package/lib/Time.js +0 -56
  175. package/lib/Time.js.map +0 -1
  176. package/lib/TypingIndicator/index.d.ts +0 -5
  177. package/lib/TypingIndicator/index.js +0 -94
  178. package/lib/TypingIndicator/index.js.map +0 -1
  179. package/lib/TypingIndicator/styles.d.ts +0 -20
  180. package/lib/TypingIndicator/styles.js +0 -22
  181. package/lib/TypingIndicator/styles.js.map +0 -1
  182. package/lib/TypingIndicator/types.d.ts +0 -3
  183. package/lib/TypingIndicator/types.js +0 -2
  184. package/lib/TypingIndicator/types.js.map +0 -1
  185. package/lib/hooks/useUpdateLayoutEffect.d.ts +0 -8
  186. package/lib/hooks/useUpdateLayoutEffect.js +0 -17
  187. package/lib/hooks/useUpdateLayoutEffect.js.map +0 -1
  188. package/lib/index.d.ts +0 -4
  189. package/lib/index.js +0 -5
  190. package/lib/index.js.map +0 -1
  191. package/lib/logging.d.ts +0 -2
  192. package/lib/logging.js +0 -5
  193. package/lib/logging.js.map +0 -1
  194. package/lib/styles.d.ts +0 -10
  195. package/lib/styles.js +0 -11
  196. package/lib/styles.js.map +0 -1
  197. package/lib/types.d.ts +0 -67
  198. package/lib/types.js +0 -2
  199. package/lib/types.js.map +0 -1
  200. package/lib/utils.d.ts +0 -5
  201. package/lib/utils.js +0 -83
  202. package/lib/utils.js.map +0 -1
  203. package/src/__tests__/__snapshots__/MessageContainer.test.tsx.snap +0 -108
@@ -1,8 +1,7 @@
1
- import React, { useCallback, useEffect, useState } from 'react'
1
+ import React, { useCallback, useMemo } from 'react'
2
2
  import {
3
3
  Image,
4
4
  Text,
5
- TouchableOpacity,
6
5
  View,
7
6
  StyleSheet,
8
7
  StyleProp,
@@ -10,8 +9,9 @@ import {
10
9
  TextStyle,
11
10
  } from 'react-native'
12
11
  import Color from './Color'
13
- import { User } from './types'
12
+ import { TouchableOpacity } from './components/TouchableOpacity'
14
13
  import stylesCommon from './styles'
14
+ import { User } from './types'
15
15
 
16
16
  const {
17
17
  carrot,
@@ -51,9 +51,6 @@ export interface GiftedAvatarProps {
51
51
  export function GiftedAvatar (
52
52
  props: GiftedAvatarProps
53
53
  ) {
54
- const [avatarName, setAvatarName] = useState<string | undefined>(undefined)
55
- const [backgroundColor, setBackgroundColor] = useState<string | undefined>(undefined)
56
-
57
54
  const {
58
55
  user,
59
56
  avatarStyle,
@@ -61,23 +58,23 @@ export function GiftedAvatar (
61
58
  onPress,
62
59
  } = props
63
60
 
64
- const setAvatarColor = useCallback(() => {
65
- if (backgroundColor)
66
- return
67
-
61
+ const avatarName = useMemo(() => {
68
62
  const userName = user?.name || ''
69
63
  const name = userName.toUpperCase().split(' ')
70
64
 
71
65
  if (name.length === 1)
72
- setAvatarName(`${name[0].charAt(0)}`)
66
+ return `${name[0].charAt(0)}`
73
67
  else if (name.length > 1)
74
- setAvatarName(`${name[0].charAt(0)}${name[1].charAt(0)}`)
68
+ return `${name[0].charAt(0)}${name[1].charAt(0)}`
75
69
  else
76
- setAvatarName('')
70
+ return ''
71
+ }, [user?.name])
77
72
 
73
+ const backgroundColor = useMemo(() => {
78
74
  let sumChars = 0
79
- for (let i = 0; i < userName.length; i += 1)
80
- sumChars += userName.charCodeAt(i)
75
+ if (user?.name)
76
+ for (let i = 0; i < user.name.length; i += 1)
77
+ sumChars += user.name.charCodeAt(i)
81
78
 
82
79
  // inspired by https://github.com/wbinnssmith/react-user-avatar
83
80
  // colors from https://flatuicolors.com/
@@ -91,8 +88,8 @@ export function GiftedAvatar (
91
88
  midnightBlue,
92
89
  ]
93
90
 
94
- setBackgroundColor(colors[sumChars % colors.length])
95
- }, [user?.name, backgroundColor])
91
+ return colors[sumChars % colors.length]
92
+ }, [user?.name])
96
93
 
97
94
  const renderAvatar = useCallback(() => {
98
95
  switch (typeof user?.avatar) {
@@ -125,17 +122,16 @@ export function GiftedAvatar (
125
122
  )
126
123
  }, [textStyle, avatarName])
127
124
 
128
- const handleOnPress = () => {
125
+ const handleOnPress = useCallback(() => {
129
126
  const {
130
127
  onPress,
131
128
  ...rest
132
129
  } = props
133
130
 
134
- if (onPress)
135
- onPress(rest)
136
- }
131
+ onPress?.(rest)
132
+ }, [props])
137
133
 
138
- const handleOnLongPress = () => {
134
+ const handleOnLongPress = useCallback(() => {
139
135
  const {
140
136
  onLongPress,
141
137
  ...rest
@@ -143,25 +139,22 @@ export function GiftedAvatar (
143
139
 
144
140
  if (onLongPress)
145
141
  onLongPress(rest)
146
- }
142
+ }, [props])
147
143
 
148
- useEffect(() => {
149
- setAvatarColor()
150
- }, [setAvatarColor])
144
+ const placeholderView = useMemo(() => (
145
+ <View
146
+ style={[
147
+ stylesCommon.centerItems,
148
+ styles.avatarStyle,
149
+ styles.avatarTransparent,
150
+ avatarStyle,
151
+ ]}
152
+ accessibilityRole='image'
153
+ />
154
+ ), [avatarStyle])
151
155
 
152
156
  if (!user || (!user.name && !user.avatar))
153
- // render placeholder
154
- return (
155
- <View
156
- style={[
157
- stylesCommon.centerItems,
158
- styles.avatarStyle,
159
- styles.avatarTransparent,
160
- avatarStyle,
161
- ]}
162
- accessibilityRole='image'
163
- />
164
- )
157
+ return placeholderView
165
158
 
166
159
  if (user.avatar)
167
160
  return (
@@ -7,18 +7,26 @@ import React, {
7
7
  useCallback,
8
8
  RefObject,
9
9
  } from 'react'
10
+ import {
11
+ TextInput,
12
+ View,
13
+ LayoutChangeEvent,
14
+ } from 'react-native'
10
15
  import {
11
16
  ActionSheetProvider,
12
17
  ActionSheetProviderRef,
13
18
  } from '@expo/react-native-action-sheet'
14
19
  import dayjs from 'dayjs'
15
20
  import localizedFormat from 'dayjs/plugin/localizedFormat'
16
- import {
17
- Platform,
18
- TextInput,
19
- View,
20
- LayoutChangeEvent,
21
- } from 'react-native'
21
+ import { GestureHandlerRootView } from 'react-native-gesture-handler'
22
+ import { KeyboardProvider, useReanimatedKeyboardAnimation } from 'react-native-keyboard-controller'
23
+ import Animated, {
24
+ useAnimatedStyle,
25
+ useAnimatedReaction,
26
+ useSharedValue,
27
+ withTiming,
28
+ runOnJS,
29
+ } from 'react-native-reanimated'
22
30
  import { Actions } from '../Actions'
23
31
  import { Avatar } from '../Avatar'
24
32
  import Bubble from '../Bubble'
@@ -33,25 +41,17 @@ import Message from '../Message'
33
41
  import MessageContainer, { AnimatedList } from '../MessageContainer'
34
42
  import { MessageImage } from '../MessageImage'
35
43
  import { MessageText } from '../MessageText'
36
- import {
37
- IMessage,
38
- } from '../types'
39
44
  import { Send } from '../Send'
45
+ import stylesCommon from '../styles'
40
46
  import { SystemMessage } from '../SystemMessage'
41
47
  import { Time } from '../Time'
42
- import * as utils from '../utils'
43
- import Animated, {
44
- useAnimatedStyle,
45
- useAnimatedReaction,
46
- useSharedValue,
47
- withTiming,
48
- runOnJS,
49
- } from 'react-native-reanimated'
50
- import { KeyboardProvider, useReanimatedKeyboardAnimation } from 'react-native-keyboard-controller'
51
- import { GiftedChatProps } from './types'
48
+ import {
49
+ IMessage,
50
+ } from '../types'
52
51
 
53
- import stylesCommon from '../styles'
52
+ import * as utils from '../utils'
54
53
  import styles from './styles'
54
+ import { GiftedChatProps } from './types'
55
55
 
56
56
  dayjs.extend(localizedFormat)
57
57
 
@@ -72,24 +72,17 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
72
72
  onSend,
73
73
  locale = 'en',
74
74
  renderLoading,
75
- actionSheet = null,
75
+ actionSheet,
76
76
  textInputProps,
77
- renderChatFooter = null,
78
- renderInputToolbar = null,
79
- bottomOffset = 0,
77
+ renderChatFooter,
78
+ renderInputToolbar,
79
+ keyboardBottomOffset = 0,
80
80
  focusOnInputWhenOpeningKeyboard = true,
81
- keyboardShouldPersistTaps = Platform.select({
82
- ios: 'never',
83
- android: 'always',
84
- default: 'never',
85
- }),
86
- onInputTextChanged = null,
87
- maxInputLength = null,
81
+ onInputTextChanged,
88
82
  inverted = true,
89
83
  minComposerHeight = MIN_COMPOSER_HEIGHT,
90
84
  maxComposerHeight = MAX_COMPOSER_HEIGHT,
91
85
  isKeyboardInternallyHandled = true,
92
- disableKeyboardController = false,
93
86
  } = props
94
87
 
95
88
  const actionSheetRef = useRef<ActionSheetProviderRef>(null)
@@ -111,29 +104,28 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
111
104
  minComposerHeight!
112
105
  )
113
106
  const [text, setText] = useState<string | undefined>(() => props.text || '')
114
- const [isTypingDisabled, setIsTypingDisabled] = useState<boolean>(false)
115
107
 
116
108
  // Always call the hook, but conditionally use its data
117
109
  const keyboardControllerData = useReanimatedKeyboardAnimation()
118
110
 
119
- // Create a mock keyboard object when disabled
111
+ // Create a mock keyboard object when keyboard is not internally handled
120
112
  const keyboard = useMemo(() => {
121
- if (disableKeyboardController)
113
+ if (!isKeyboardInternallyHandled)
122
114
  return { height: { value: 0 } }
115
+
123
116
  return keyboardControllerData
124
- }, [disableKeyboardController, keyboardControllerData])
117
+ }, [isKeyboardInternallyHandled, keyboardControllerData])
125
118
 
126
119
  const trackingKeyboardMovement = useSharedValue(false)
127
- const debounceEnableTypingTimeoutId = useRef<ReturnType<typeof setTimeout>>(undefined)
128
- const keyboardOffsetBottom = useSharedValue(0)
120
+ const keyboardBottomOffsetAnim = useSharedValue(0)
129
121
 
130
122
  const contentStyleAnim = useAnimatedStyle(
131
123
  () => ({
132
124
  transform: [
133
- { translateY: keyboard.height.value - keyboardOffsetBottom.value },
125
+ { translateY: keyboard.height.value + keyboardBottomOffsetAnim.value },
134
126
  ],
135
127
  }),
136
- [keyboard, keyboardOffsetBottom]
128
+ [keyboard, keyboardBottomOffsetAnim]
137
129
  )
138
130
 
139
131
  const getTextFromProp = useCallback(
@@ -174,23 +166,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
174
166
  isTextInputWasFocused.current = false
175
167
  }, [textInputRef])
176
168
 
177
- const disableTyping = useCallback(() => {
178
- clearTimeout(debounceEnableTypingTimeoutId.current)
179
- setIsTypingDisabled(true)
180
- }, [])
181
-
182
- const enableTyping = useCallback(() => {
183
- clearTimeout(debounceEnableTypingTimeoutId.current)
184
- setIsTypingDisabled(false)
185
- }, [])
186
-
187
- const debounceEnableTyping = useCallback(() => {
188
- clearTimeout(debounceEnableTypingTimeoutId.current)
189
- debounceEnableTypingTimeoutId.current = setTimeout(() => {
190
- enableTyping()
191
- }, 50)
192
- }, [enableTyping])
193
-
194
169
  const scrollToBottom = useCallback(
195
170
  (isAnimated = true) => {
196
171
  if (!messageContainerRef?.current)
@@ -219,10 +194,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
219
194
  <View style={[stylesCommon.fill, messagesContainerStyle]}>
220
195
  <MessageContainer<TMessage>
221
196
  {...messagesContainerProps}
222
- invertibleScrollViewProps={{
223
- inverted,
224
- keyboardShouldPersistTaps,
225
- }}
197
+ inverted={inverted}
226
198
  messages={messages}
227
199
  forwardRef={messageContainerRef}
228
200
  isTyping={isTyping}
@@ -236,7 +208,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
236
208
  messages,
237
209
  props,
238
210
  inverted,
239
- keyboardShouldPersistTaps,
240
211
  messageContainerRef,
241
212
  renderChatFooter,
242
213
  ])
@@ -252,13 +223,11 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
252
223
 
253
224
  setComposerHeight(minComposerHeight!)
254
225
  setText(getTextFromProp(''))
255
- enableTyping()
256
226
  }, [
257
227
  minComposerHeight,
258
228
  getTextFromProp,
259
229
  textInputRef,
260
230
  notifyInputTextReset,
261
- enableTyping,
262
231
  ])
263
232
 
264
233
  const _onSend = useCallback(
@@ -275,17 +244,14 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
275
244
  }
276
245
  })
277
246
 
278
- if (shouldResetInputToolbar === true) {
279
- disableTyping()
280
-
247
+ if (shouldResetInputToolbar === true)
281
248
  resetInputToolbar()
282
- }
283
249
 
284
250
  onSend?.(newMessages)
285
251
 
286
252
  setTimeout(() => scrollToBottom(), 10)
287
253
  },
288
- [messageIdGenerator, onSend, user, resetInputToolbar, disableTyping, scrollToBottom]
254
+ [messageIdGenerator, onSend, user, resetInputToolbar, scrollToBottom]
289
255
  )
290
256
 
291
257
  const onInputSizeChanged = useCallback(
@@ -301,21 +267,19 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
301
267
  )
302
268
 
303
269
  const _onInputTextChanged = useCallback(
304
- (_text: string) => {
305
- if (isTypingDisabled)
306
- return
307
-
308
- onInputTextChanged?.(_text)
270
+ (text: string) => {
271
+ onInputTextChanged?.(text)
309
272
 
310
273
  // Only set state if it's not being overridden by a prop.
311
274
  if (props.text === undefined)
312
- setText(_text)
275
+ setText(text)
313
276
  },
314
- [onInputTextChanged, isTypingDisabled, props.text]
277
+ [onInputTextChanged, props.text]
315
278
  )
316
279
 
317
280
  const onInitialLayoutViewLayout = useCallback(
318
281
  (e: LayoutChangeEvent) => {
282
+ console.log('onInitialLayoutViewLayout', e.nativeEvent.layout.height)
319
283
  if (isInitialized)
320
284
  return
321
285
 
@@ -347,7 +311,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
347
311
  textInputProps: {
348
312
  ...textInputProps,
349
313
  ref: textInputRef,
350
- maxLength: isTypingDisabled ? 0 : maxInputLength,
351
314
  },
352
315
  }
353
316
 
@@ -359,14 +322,12 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
359
322
  isInitialized,
360
323
  _onSend,
361
324
  getTextFromProp,
362
- maxInputLength,
363
325
  minComposerHeight,
364
326
  onInputSizeChanged,
365
327
  props,
366
328
  text,
367
329
  renderInputToolbar,
368
330
  composerHeight,
369
- isTypingDisabled,
370
331
  textInputRef,
371
332
  textInputProps,
372
333
  _onInputTextChanged,
@@ -390,23 +351,23 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
390
351
  setText(props.text)
391
352
  }, [props.text])
392
353
 
393
- // Only set up keyboard animation when keyboard controller is enabled
354
+ // Only set up keyboard animation when keyboard is internally handled
394
355
  useAnimatedReaction(
395
- () => disableKeyboardController ? 0 : -keyboard.height.value,
356
+ () => isKeyboardInternallyHandled ? keyboard.height.value : 0,
396
357
  (value, prevValue) => {
397
- // Skip keyboard handling when disabled
398
- if (disableKeyboardController)
358
+ // Skip keyboard handling when not internally handled
359
+ if (!isKeyboardInternallyHandled)
399
360
  return
400
361
 
401
362
  if (prevValue !== null && value !== prevValue) {
402
- const isKeyboardMovingUp = value > prevValue
363
+ const isKeyboardMovingUp = value < prevValue
403
364
  if (isKeyboardMovingUp !== trackingKeyboardMovement.value) {
404
365
  trackingKeyboardMovement.value = isKeyboardMovingUp
405
- keyboardOffsetBottom.value = withTiming(
406
- isKeyboardMovingUp ? bottomOffset : 0,
366
+ keyboardBottomOffsetAnim.value = withTiming(
367
+ isKeyboardMovingUp ? keyboardBottomOffset : 0,
407
368
  {
408
- // If `bottomOffset` exists, we change the duration to a smaller value to fix the delay in the keyboard animation speed
409
- duration: bottomOffset ? 150 : 400,
369
+ // If `keyboardBottomOffset` exists, we change the duration to a smaller value to fix the delay in the keyboard animation speed
370
+ duration: keyboardBottomOffset ? 150 : 400,
410
371
  }
411
372
  )
412
373
 
@@ -415,13 +376,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
415
376
  runOnJS(handleTextInputFocusWhenKeyboardShow)()
416
377
  else
417
378
  runOnJS(handleTextInputFocusWhenKeyboardHide)()
418
-
419
- if (value === 0) {
420
- runOnJS(enableTyping)()
421
- } else {
422
- runOnJS(disableTyping)()
423
- runOnJS(debounceEnableTyping)()
424
- }
425
379
  }
426
380
  }
427
381
  },
@@ -431,11 +385,8 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
431
385
  focusOnInputWhenOpeningKeyboard,
432
386
  handleTextInputFocusWhenKeyboardHide,
433
387
  handleTextInputFocusWhenKeyboardShow,
434
- enableTyping,
435
- disableTyping,
436
- debounceEnableTyping,
437
- bottomOffset,
438
- disableKeyboardController,
388
+ keyboardBottomOffset,
389
+ isKeyboardInternallyHandled,
439
390
  ]
440
391
  )
441
392
 
@@ -449,7 +400,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
449
400
  >
450
401
  {isInitialized
451
402
  ? (
452
- <Animated.View style={[stylesCommon.fill, (isKeyboardInternallyHandled && !disableKeyboardController) && contentStyleAnim]}>
403
+ <Animated.View style={[stylesCommon.fill, isKeyboardInternallyHandled && contentStyleAnim]}>
453
404
  {renderMessages}
454
405
  {inputToolbarFragment}
455
406
  </Animated.View>
@@ -464,14 +415,16 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
464
415
  }
465
416
 
466
417
  function GiftedChatWrapper<TMessage extends IMessage = IMessage> (props: GiftedChatProps<TMessage>) {
467
- // Don't use KeyboardProvider when keyboard controller is disabled
468
- if (props.disableKeyboardController)
418
+ // Don't use KeyboardProvider when keyboard is not internally handled
419
+ if (!props.isKeyboardInternallyHandled)
469
420
  return <GiftedChat<TMessage> {...props} />
470
421
 
471
422
  return (
472
- <KeyboardProvider>
473
- <GiftedChat<TMessage> {...props} />
474
- </KeyboardProvider>
423
+ <GestureHandlerRootView style={styles.fill}>
424
+ <KeyboardProvider>
425
+ <GiftedChat<TMessage> {...props} />
426
+ </KeyboardProvider>
427
+ </GestureHandlerRootView>
475
428
  )
476
429
  }
477
430
 
@@ -1,6 +1,9 @@
1
1
  import { StyleSheet } from 'react-native'
2
2
 
3
3
  export default StyleSheet.create({
4
+ fill: {
5
+ flex: 1,
6
+ },
4
7
  contentContainer: {
5
8
  overflow: 'hidden',
6
9
  },
@@ -1,64 +1,46 @@
1
1
  import React, { RefObject } from 'react'
2
- import {
3
- ActionSheetOptions,
4
- } from '@expo/react-native-action-sheet'
5
2
  import {
6
3
  TextInput,
7
4
  StyleProp,
8
5
  TextStyle,
9
6
  ViewStyle,
10
7
  } from 'react-native'
11
- import { LightboxProps } from 'react-native-lightbox-v2'
8
+ import {
9
+ ActionSheetOptions,
10
+ } from '@expo/react-native-action-sheet'
12
11
  import { ActionsProps } from '../Actions'
13
12
  import { AvatarProps } from '../Avatar'
13
+ import { BubbleProps } from '../Bubble'
14
14
  import { ComposerProps } from '../Composer'
15
- import { DayProps } from '../Day'
16
15
  import { InputToolbarProps } from '../InputToolbar'
17
- import { LoadEarlierProps } from '../LoadEarlier'
18
16
  import { MessageProps } from '../Message'
17
+ import { AnimatedList, MessageContainerProps } from '../MessageContainer'
19
18
  import { MessageImageProps } from '../MessageImage'
20
19
  import { MessageTextProps } from '../MessageText'
20
+ import { QuickRepliesProps } from '../QuickReplies'
21
+ import { SendProps } from '../Send'
22
+ import { SystemMessageProps } from '../SystemMessage'
23
+ import { TimeProps } from '../Time'
21
24
  import {
22
25
  IMessage,
23
26
  LeftRightStyle,
24
27
  MessageAudioProps,
25
28
  MessageVideoProps,
26
- Reply,
27
29
  User,
28
30
  } from '../types'
29
- import { QuickRepliesProps } from '../QuickReplies'
30
- import { SendProps } from '../Send'
31
- import { SystemMessageProps } from '../SystemMessage'
32
- import { TimeProps } from '../Time'
33
- import { AnimatedList, ListViewProps, MessageContainerProps } from '../MessageContainer'
34
- import { BubbleProps } from '../Bubble'
35
31
 
36
32
  export interface GiftedChatProps<TMessage extends IMessage> extends Partial<MessageContainerProps<TMessage>> {
37
33
  /* Message container ref */
38
34
  messageContainerRef?: RefObject<AnimatedList<TMessage>>
39
35
  /* text input ref */
40
36
  textInputRef?: RefObject<TextInput>
41
- /* Messages to display */
42
- messages?: TMessage[]
43
- /* Typing Indicator state */
44
- isTyping?: boolean
45
37
  /* Controls whether or not to show user.name property in the message bubble */
46
38
  renderUsernameOnMessage?: boolean
47
39
  /* Messages container style */
48
40
  messagesContainerStyle?: StyleProp<ViewStyle>
49
41
  /* Input text; default is undefined, but if specified, it will override GiftedChat's internal state */
50
42
  text?: string
51
- /* Controls whether or not the message bubbles appear at the top of the chat */
52
- alignTop?: boolean
53
- /* enables the isScrollToBottomEnabled Component */
54
- isScrollToBottomEnabled?: boolean
55
- /* Scroll to bottom wrapper style */
56
- scrollToBottomStyle?: StyleProp<ViewStyle>
57
43
  initialText?: string
58
- /* Placeholder when text is empty; default is 'Type a message...' */
59
- placeholder?: string
60
- /* Makes the composer not editable */
61
- disableComposer?: boolean
62
44
  /* User sending the messages: { _id, name, avatar } */
63
45
  user?: User
64
46
  /* Locale to localize the dates */
@@ -69,45 +51,28 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
69
51
  dateFormat?: string
70
52
  /* Format to use for rendering relative times; Today - for now. See more: https://day.js.org/docs/en/plugin/calendar */
71
53
  dateFormatCalendar?: object
72
- /* Enables the "Load earlier messages" button */
73
- loadEarlier?: boolean
74
- /* Display an ActivityIndicator when loading earlier messages */
75
- isLoadingEarlier?: boolean
76
54
  /* Determine whether to handle keyboard awareness inside the plugin. If you have your own keyboard handling outside the plugin set this to false; default is `true` */
77
55
  isKeyboardInternallyHandled?: boolean
78
- /* Completely disable react-native-keyboard-controller. Useful when using react-native-navigation or other conflicting keyboard libraries; default is `false` */
79
- disableKeyboardController?: boolean
80
56
  /* Whether to render an avatar for the current user; default is false, only show avatars for other users */
81
57
  showUserAvatar?: boolean
82
58
  /* When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default is false */
83
59
  showAvatarForEveryMessage?: boolean
84
60
  /* Render the message avatar at the top of consecutive messages, rather than the bottom; default is false */
85
61
  renderAvatarOnTop?: boolean
86
- inverted?: boolean
87
62
  /* Extra props to be passed to the <Image> component created by the default renderMessageImage */
88
63
  imageProps?: MessageImageProps<TMessage>
89
- /* Extra props to be passed to the MessageImage's Lightbox */
90
- lightboxProps?: LightboxProps
91
64
  /* Distance of the chat from the bottom of the screen (e.g. useful if you display a tab bar); default is 0 */
92
- bottomOffset?: number
65
+ keyboardBottomOffset?: number
93
66
  /* Focus on <TextInput> automatically when opening the keyboard; default is true */
94
67
  focusOnInputWhenOpeningKeyboard?: boolean
95
68
  /* Minimum height of the input toolbar; default is 44 */
96
69
  minInputToolbarHeight?: number
97
- /* Extra props to be passed to the messages <ListView>; some props can't be overridden, see the code in MessageContainer.render() for details */
98
- listViewProps?: ListViewProps
99
- /* Extra props to be passed to the <TextInput> */
100
- textInputProps?: object
101
- /* Determines whether the keyboard should stay visible after a tap; see <ScrollView> docs */
102
- keyboardShouldPersistTaps?: 'always' | 'never' | 'handled'
103
- /* Max message composer TextInput length */
104
- maxInputLength?: number
70
+ /* Extra props to be passed to the <TextInput>. See https://reactnative.dev/docs/textinput */
71
+ textInputProps?: Partial<React.ComponentProps<typeof TextInput>>
105
72
  /* Force send button */
106
73
  alwaysShowSend?: boolean
107
74
  /* Image style */
108
75
  imageStyle?: StyleProp<ViewStyle>
109
- /* This can be used to pass unknown data which needs to be re-rendered */
110
- extraData?: object
111
76
  /* composer min Height */
112
77
  minComposerHeight?: number
113
78
  /* composer min Height */
@@ -119,8 +84,6 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
119
84
  quickReplyContainerStyle?: StyleProp<ViewStyle>
120
85
  /* optional prop used to place customView below text, image and video views; default is false */
121
86
  isCustomViewBottom?: boolean
122
- /* infinite scroll up when reach the top of messages container, automatically call onLoadEarlier function if exist */
123
- infiniteScroll?: boolean
124
87
  timeTextStyle?: LeftRightStyle<TextStyle>
125
88
  /* Custom action sheet */
126
89
  actionSheet?(): {
@@ -137,12 +100,8 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
137
100
  messageIdGenerator?(message?: TMessage): string
138
101
  /* Callback when sending a message */
139
102
  onSend?(messages: TMessage[]): void
140
- /* Callback when loading earlier messages */
141
- onLoadEarlier?(): void
142
103
  /* Render a loading view when initializing */
143
104
  renderLoading?(): React.ReactNode
144
- /* Custom "Load earlier messages" button */
145
- renderLoadEarlier?(props: LoadEarlierProps): React.ReactNode
146
105
  /* Custom message avatar; set to null to not render any avatar for the message */
147
106
  renderAvatar?: null | ((props: AvatarProps<TMessage>) => React.ReactNode)
148
107
  /* Custom message bubble */
@@ -150,14 +109,12 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
150
109
  /* Custom system message */
151
110
  renderSystemMessage?(props: SystemMessageProps<TMessage>): React.ReactNode
152
111
  /* Callback when a message bubble is pressed; default is to do nothing */
153
- onPress?(context: unknown, message: TMessage): void
112
+ onPressMessage?(context: unknown, message: TMessage): void
154
113
  /* Callback when a message bubble is long-pressed; default is to show an ActionSheet with "Copy Text" (see example using showActionSheetWithOptions()) */
155
- onLongPress?(context: unknown, message: TMessage): void
114
+ onLongPressMessage?(context: unknown, message: TMessage): void
156
115
  /* Custom Username container */
157
116
  renderUsername?(user: User): React.ReactNode
158
117
  /* Reverses display order of messages; default is true */
159
- /* Custom message container */
160
- renderMessage?(message: MessageProps<TMessage>): React.ReactElement
161
118
  /* Custom message text */
162
119
  renderMessageText?(messageText: MessageTextProps<TMessage>): React.ReactNode
163
120
  /* Custom message image */
@@ -168,14 +125,8 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
168
125
  renderMessageAudio?(props: MessageAudioProps<TMessage>): React.ReactNode
169
126
  /* Custom view inside the bubble */
170
127
  renderCustomView?(props: BubbleProps<TMessage>): React.ReactNode
171
- /* Custom day above a message */
172
- renderDay?(props: DayProps): React.ReactNode
173
128
  /* Custom time inside a message */
174
129
  renderTime?(props: TimeProps<TMessage>): React.ReactNode
175
- /* Custom footer component on the ListView, e.g. 'User is typing...' */
176
- renderFooter?(props: MessageContainerProps<TMessage>): React.ReactNode
177
- /* Custom component to render in the ListView when messages are empty */
178
- renderChatEmpty?(): React.ReactNode
179
130
  /* Custom component to render below the MessageContainer (separate from the ListView) */
180
131
  renderChatFooter?(): React.ReactNode
181
132
  /* Custom message composer container */
@@ -192,15 +143,14 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
192
143
  onPressActionButton?(): void
193
144
  /* Callback when the input text changes */
194
145
  onInputTextChanged?(text: string): void
195
- /* Custom parse patterns for react-native-parsed-text used to linking message content (like URLs and phone numbers) */
146
+ /* Extra props to be passed to the MessageText component */
147
+ messageTextProps?: Partial<MessageTextProps<TMessage>>
148
+ /* Custom parse patterns for react-native-autolink used to linking message content (like URLs and phone numbers) */
196
149
  matchers?: MessageTextProps<TMessage>['matchers']
197
- onQuickReply?(replies: Reply[]): void
198
150
  renderQuickReplies?(
199
151
  quickReplies: QuickRepliesProps<TMessage>,
200
152
  ): React.ReactNode
201
153
  renderQuickReplySend?(): React.ReactNode
202
- /* Scroll to bottom custom component */
203
- scrollToBottomComponent?(): React.ReactNode
204
154
  shouldUpdateMessage?(
205
155
  props: MessageProps<TMessage>,
206
156
  nextProps: MessageProps<TMessage>,