react-native-gifted-chat 3.0.0-alpha.0 → 3.0.0

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 (33) hide show
  1. package/CHANGELOG.md +295 -0
  2. package/README.md +71 -95
  3. package/package.json +2 -2
  4. package/src/Actions.tsx +27 -18
  5. package/src/Composer.tsx +21 -84
  6. package/src/Constant.ts +0 -9
  7. package/src/GiftedChat/index.tsx +52 -163
  8. package/src/GiftedChat/types.ts +11 -12
  9. package/src/InputToolbar.tsx +6 -11
  10. package/src/MessageImage.tsx +135 -65
  11. package/src/{MessageContainer → MessagesContainer}/components/Item/index.tsx +21 -17
  12. package/src/{MessageContainer → MessagesContainer}/components/Item/types.ts +3 -2
  13. package/src/{MessageContainer → MessagesContainer}/index.tsx +18 -14
  14. package/src/{MessageContainer → MessagesContainer}/styles.ts +12 -5
  15. package/src/{MessageContainer → MessagesContainer}/types.ts +4 -2
  16. package/src/Send.tsx +40 -22
  17. package/src/__tests__/DayAnimated.test.tsx +1 -1
  18. package/src/__tests__/GiftedChat.test.tsx +0 -28
  19. package/src/__tests__/{MessageContainer.test.tsx → MessagesContainer.test.tsx} +7 -7
  20. package/src/__tests__/__snapshots__/Actions.test.tsx.snap +31 -23
  21. package/src/__tests__/__snapshots__/Composer.test.tsx.snap +29 -30
  22. package/src/__tests__/__snapshots__/Constant.test.tsx.snap +0 -2
  23. package/src/__tests__/__snapshots__/GiftedChat.test.tsx.snap +31 -54
  24. package/src/__tests__/__snapshots__/InputToolbar.test.tsx.snap +102 -31
  25. package/src/__tests__/__snapshots__/MessageImage.test.tsx.snap +252 -1
  26. package/src/__tests__/__snapshots__/Send.test.tsx.snap +189 -49
  27. package/src/index.ts +1 -1
  28. package/src/styles.ts +5 -0
  29. package/src/types.ts +1 -1
  30. package/CHANGELOG_2.8.1_to_2.8.2-alpha.5.md +0 -374
  31. /package/src/{MessageContainer → MessagesContainer}/components/DayAnimated/index.tsx +0 -0
  32. /package/src/{MessageContainer → MessagesContainer}/components/DayAnimated/styles.ts +0 -0
  33. /package/src/{MessageContainer → MessagesContainer}/components/DayAnimated/types.ts +0 -0
package/src/Actions.tsx CHANGED
@@ -19,7 +19,7 @@ export interface ActionsProps {
19
19
  icon?: () => ReactNode
20
20
  wrapperStyle?: StyleProp<ViewStyle>
21
21
  iconTextStyle?: StyleProp<TextStyle>
22
- containerStyle?: StyleProp<ViewStyle>
22
+ buttonStyle?: StyleProp<ViewStyle>
23
23
  onPressActionButton?(): void
24
24
  }
25
25
 
@@ -30,11 +30,16 @@ export function Actions ({
30
30
  wrapperStyle,
31
31
  iconTextStyle,
32
32
  onPressActionButton,
33
- containerStyle,
33
+ buttonStyle,
34
34
  }: ActionsProps) {
35
35
  const { actionSheet } = useChatContext()
36
36
 
37
- const onActionsPress = useCallback(() => {
37
+ const handlePress = useCallback(() => {
38
+ if (onPressActionButton) {
39
+ onPressActionButton()
40
+ return
41
+ }
42
+
38
43
  if (!actions?.length)
39
44
  return
40
45
 
@@ -54,47 +59,51 @@ export function Actions ({
54
59
  item.action?.()
55
60
  }
56
61
  )
57
- }, [actionSheet, actions, actionSheetOptionTintColor])
62
+ }, [actionSheet, actions, actionSheetOptionTintColor, onPressActionButton])
58
63
 
59
64
  const renderIcon = useCallback(() => {
60
65
  if (icon)
61
66
  return icon()
62
67
 
63
68
  return (
64
- <View style={[stylesCommon.fill, stylesCommon.centerItems, styles.wrapper, wrapperStyle]}>
69
+ <View style={[stylesCommon.centerItems, styles.wrapper, wrapperStyle]}>
65
70
  <Text style={[styles.iconText, iconTextStyle]}>{'+'}</Text>
66
71
  </View>
67
72
  )
68
73
  }, [icon, iconTextStyle, wrapperStyle])
69
74
 
70
75
  return (
71
- <TouchableOpacity
72
- style={[styles.container, containerStyle]}
73
- onPress={onPressActionButton || onActionsPress}
74
- >
75
- {renderIcon()}
76
- </TouchableOpacity>
76
+ <View style={styles.container}>
77
+ <TouchableOpacity
78
+ onPress={handlePress}
79
+ style={[styles.button, buttonStyle]}
80
+ >
81
+ {renderIcon()}
82
+ </TouchableOpacity>
83
+ </View>
77
84
  )
78
85
  }
79
86
 
80
87
  const styles = StyleSheet.create({
81
88
  container: {
82
- width: 26,
83
- height: 26,
84
- marginLeft: 10,
85
- marginBottom: 10,
89
+ alignItems: 'flex-end',
90
+ },
91
+ button: {
92
+ paddingHorizontal: 8,
93
+ paddingVertical: 7,
86
94
  },
95
+
87
96
  wrapper: {
88
- borderRadius: 13,
89
97
  borderColor: Color.defaultColor,
90
98
  borderWidth: 2,
99
+ width: 26,
100
+ height: 26,
101
+ borderRadius: 13,
91
102
  },
92
103
  iconText: {
93
104
  color: Color.defaultColor,
94
105
  fontWeight: 'bold',
95
106
  fontSize: 16,
96
107
  lineHeight: 16,
97
- backgroundColor: Color.backgroundTransparent,
98
- textAlign: 'center',
99
108
  },
100
109
  })
package/src/Composer.tsx CHANGED
@@ -1,118 +1,55 @@
1
- import React, { useCallback, useRef } from 'react'
1
+ import React from 'react'
2
2
  import {
3
- Platform,
4
3
  StyleSheet,
5
4
  TextInput,
6
5
  TextInputProps,
7
- NativeSyntheticEvent,
8
- TextInputContentSizeChangeEventData,
9
6
  useColorScheme,
7
+ View,
10
8
  } from 'react-native'
11
9
  import { Color } from './Color'
12
- import { MIN_COMPOSER_HEIGHT } from './Constant'
13
- import stylesCommon from './styles'
10
+ import stylesCommon, { getColorSchemeStyle } from './styles'
14
11
 
15
12
  export interface ComposerProps {
16
13
  composerHeight?: number
17
14
  text?: string
18
15
  textInputProps?: Partial<TextInputProps>
19
- onInputSizeChanged?(layout: { width: number, height: number }): void
20
16
  }
21
17
 
22
18
  export function Composer ({
23
- composerHeight = MIN_COMPOSER_HEIGHT,
24
- onInputSizeChanged,
25
19
  text = '',
26
20
  textInputProps,
27
21
  }: ComposerProps): React.ReactElement {
28
- const dimensionsRef = useRef<{ width: number, height: number }>(null)
29
22
  const colorScheme = useColorScheme()
30
23
  const isDark = colorScheme === 'dark'
31
24
 
32
- const determineInputSizeChange = useCallback(
33
- (dimensions: { width: number, height: number }) => {
34
- // Support earlier versions of React Native on Android.
35
- if (!dimensions)
36
- return
37
-
38
- if (
39
- !dimensionsRef.current ||
40
- (dimensionsRef.current &&
41
- (dimensionsRef.current.width !== dimensions.width ||
42
- dimensionsRef.current.height !== dimensions.height))
43
- ) {
44
- dimensionsRef.current = dimensions
45
- onInputSizeChanged?.(dimensions)
46
- }
47
- },
48
- [onInputSizeChanged]
49
- )
50
-
51
- const handleContentSizeChange = useCallback(
52
- ({
53
- nativeEvent: { contentSize },
54
- }: NativeSyntheticEvent<TextInputContentSizeChangeEventData>) =>
55
- determineInputSizeChange(contentSize),
56
- [determineInputSizeChange]
57
- )
58
-
59
25
  const placeholder = textInputProps?.placeholder ?? 'Type a message...'
60
26
 
61
27
  return (
62
- <TextInput
63
- testID={placeholder}
64
- accessible
65
- accessibilityLabel={placeholder}
66
- placeholderTextColor={textInputProps?.placeholderTextColor ?? (isDark ? '#888' : Color.defaultColor)}
67
- onContentSizeChange={handleContentSizeChange}
68
- value={text}
69
- enablesReturnKeyAutomatically
70
- underlineColorAndroid='transparent'
71
- keyboardAppearance={isDark ? 'dark' : 'default'}
72
- multiline
73
- placeholder={placeholder}
74
- {...textInputProps}
75
- style={[
76
- stylesCommon.fill,
77
- styles.textInput,
78
- styles[`textInput_${colorScheme}`],
79
- textInputProps?.style,
80
- {
81
- height: composerHeight,
82
- ...Platform.select({
83
- web: {
84
- outlineWidth: 0,
85
- outlineColor: 'transparent',
86
- outlineOffset: 0,
87
- },
88
- }),
89
- },
90
- ]}
91
- />
28
+ <View style={stylesCommon.fill}>
29
+ <TextInput
30
+ testID={placeholder}
31
+ accessible
32
+ accessibilityLabel={placeholder}
33
+ placeholderTextColor={textInputProps?.placeholderTextColor ?? (isDark ? '#888' : Color.defaultColor)}
34
+ value={text}
35
+ enablesReturnKeyAutomatically
36
+ underlineColorAndroid='transparent'
37
+ keyboardAppearance={isDark ? 'dark' : 'default'}
38
+ multiline
39
+ placeholder={placeholder}
40
+ {...textInputProps}
41
+ style={getColorSchemeStyle(styles, 'textInput', colorScheme)}
42
+ />
43
+ </View>
92
44
  )
93
45
  }
94
46
 
95
47
  const styles = StyleSheet.create({
96
48
  textInput: {
97
- marginLeft: 10,
98
49
  fontSize: 16,
99
50
  lineHeight: 22,
100
- ...Platform.select({
101
- web: {
102
- paddingTop: 6,
103
- paddingLeft: 4,
104
- },
105
- }),
106
- marginTop: Platform.select({
107
- ios: 6,
108
- android: 0,
109
- web: 6,
110
- }),
111
- marginBottom: Platform.select({
112
- ios: 5,
113
- android: 3,
114
- web: 4,
115
- }),
51
+ paddingTop: 8,
52
+ paddingBottom: 10,
116
53
  },
117
54
  textInput_dark: {
118
55
  color: '#fff',
package/src/Constant.ts CHANGED
@@ -1,12 +1,3 @@
1
- import { Platform } from 'react-native'
2
-
3
- export const MIN_COMPOSER_HEIGHT = Platform.select({
4
- ios: 33,
5
- android: 41,
6
- web: 34,
7
- windows: 34,
8
- })
9
- export const MAX_COMPOSER_HEIGHT = 200
10
1
  export const DATE_FORMAT = 'D MMMM'
11
2
  export const TIME_FORMAT = 'LT'
12
3
 
@@ -19,19 +19,12 @@ import {
19
19
  import dayjs from 'dayjs'
20
20
  import localizedFormat from 'dayjs/plugin/localizedFormat'
21
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
+ import { KeyboardAvoidingView, KeyboardProvider } from 'react-native-keyboard-controller'
30
23
  import { SafeAreaProvider } from 'react-native-safe-area-context'
31
- import { MAX_COMPOSER_HEIGHT, MIN_COMPOSER_HEIGHT, TEST_ID } from '../Constant'
24
+ import { TEST_ID } from '../Constant'
32
25
  import { GiftedChatContext } from '../GiftedChatContext'
33
26
  import { InputToolbar } from '../InputToolbar'
34
- import { MessageContainer, AnimatedList } from '../MessageContainer'
27
+ import { MessagesContainer, AnimatedList } from '../MessagesContainer'
35
28
  import { IMessage } from '../Models'
36
29
  import stylesCommon from '../styles'
37
30
  import { renderComponentOrElement } from '../utils'
@@ -61,19 +54,14 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
61
54
  textInputProps,
62
55
  renderChatFooter,
63
56
  renderInputToolbar,
64
- keyboardBottomOffset = 0,
65
- shouldFocusInputOnKeyboardOpen = true,
66
57
  isInverted = true,
67
- minComposerHeight = MIN_COMPOSER_HEIGHT,
68
- maxComposerHeight = MAX_COMPOSER_HEIGHT,
69
- isKeyboardInternallyHandled = true,
70
58
  } = props
71
59
 
72
60
  const actionSheetRef = useRef<ActionSheetProviderRef>(null)
73
61
 
74
- const messageContainerRef = useMemo(
75
- () => props.messageContainerRef || createRef<AnimatedList<TMessage>>(),
76
- [props.messageContainerRef]
62
+ const messagesContainerRef = useMemo(
63
+ () => props.messagesContainerRef || createRef<AnimatedList<TMessage>>(),
64
+ [props.messagesContainerRef]
77
65
  ) as RefObject<AnimatedList<TMessage>>
78
66
 
79
67
  const textInputRef = useMemo(
@@ -81,37 +69,9 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
81
69
  [props.textInputRef]
82
70
  )
83
71
 
84
- const isTextInputWasFocused: RefObject<boolean> = useRef(false)
85
-
86
72
  const [isInitialized, setIsInitialized] = useState<boolean>(false)
87
- const [composerHeight, setComposerHeight] = useState<number>(
88
- minComposerHeight!
89
- )
90
73
  const [text, setText] = useState<string | undefined>(() => props.text || '')
91
74
 
92
- // Always call the hook, but conditionally use its data
93
- const keyboardControllerData = useReanimatedKeyboardAnimation()
94
-
95
- // Create a mock keyboard object when keyboard is not internally handled
96
- const keyboard = useMemo(() => {
97
- if (!isKeyboardInternallyHandled)
98
- return { height: { value: 0 } }
99
-
100
- return keyboardControllerData
101
- }, [isKeyboardInternallyHandled, keyboardControllerData])
102
-
103
- const trackingKeyboardMovement = useSharedValue(false)
104
- const keyboardBottomOffsetAnim = useSharedValue(0)
105
-
106
- const contentStyleAnim = useAnimatedStyle(
107
- () => ({
108
- transform: [
109
- { translateY: keyboard.height.value + keyboardBottomOffsetAnim.value },
110
- ],
111
- }),
112
- [keyboard, keyboardBottomOffsetAnim]
113
- )
114
-
115
75
  const getTextFromProp = useCallback(
116
76
  (fallback: string) => {
117
77
  if (props.text === undefined)
@@ -122,50 +82,22 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
122
82
  [props.text]
123
83
  )
124
84
 
125
- /**
126
- * Store text input focus status when keyboard hide to retrieve
127
- * it afterwards if needed.
128
- * `onKeyboardWillHide` may be called twice in sequence so we
129
- * make a guard condition (eg. showing image picker)
130
- */
131
- const handleTextInputFocusWhenKeyboardHide = useCallback(() => {
132
- if (!isTextInputWasFocused.current)
133
- isTextInputWasFocused.current =
134
- textInputRef.current?.isFocused() || false
135
- }, [textInputRef])
136
-
137
- /**
138
- * Refocus the text input only if it was focused before showing keyboard.
139
- * This is needed in some cases (eg. showing image picker).
140
- */
141
- const handleTextInputFocusWhenKeyboardShow = useCallback(() => {
142
- if (
143
- textInputRef.current &&
144
- isTextInputWasFocused.current &&
145
- !textInputRef.current.isFocused()
146
- )
147
- textInputRef.current.focus()
148
-
149
- // Reset the indicator since the keyboard is shown
150
- isTextInputWasFocused.current = false
151
- }, [textInputRef])
152
-
153
85
  const scrollToBottom = useCallback(
154
86
  (isAnimated = true) => {
155
- if (!messageContainerRef?.current)
87
+ if (!messagesContainerRef?.current)
156
88
  return
157
89
 
158
90
  if (isInverted) {
159
- messageContainerRef.current.scrollToOffset({
91
+ messagesContainerRef.current.scrollToOffset({
160
92
  offset: 0,
161
93
  animated: isAnimated,
162
94
  })
163
95
  return
164
96
  }
165
97
 
166
- messageContainerRef.current.scrollToEnd({ animated: isAnimated })
98
+ messagesContainerRef.current.scrollToEnd({ animated: isAnimated })
167
99
  },
168
- [isInverted, messageContainerRef]
100
+ [isInverted, messagesContainerRef]
169
101
  )
170
102
 
171
103
  const renderMessages = useMemo(() => {
@@ -176,11 +108,11 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
176
108
 
177
109
  return (
178
110
  <View style={[stylesCommon.fill, messagesContainerStyle]}>
179
- <MessageContainer<TMessage>
111
+ <MessagesContainer<TMessage>
180
112
  {...messagesContainerProps}
181
113
  isInverted={isInverted}
182
114
  messages={messages}
183
- forwardRef={messageContainerRef}
115
+ forwardRef={messagesContainerRef}
184
116
  isTyping={isTyping}
185
117
  />
186
118
  {renderComponentOrElement(renderChatFooter, {})}
@@ -192,7 +124,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
192
124
  messages,
193
125
  props,
194
126
  isInverted,
195
- messageContainerRef,
127
+ messagesContainerRef,
196
128
  renderChatFooter,
197
129
  ])
198
130
 
@@ -205,10 +137,8 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
205
137
 
206
138
  notifyInputTextReset()
207
139
 
208
- setComposerHeight(minComposerHeight!)
209
140
  setText(getTextFromProp(''))
210
141
  }, [
211
- minComposerHeight,
212
142
  getTextFromProp,
213
143
  textInputRef,
214
144
  notifyInputTextReset,
@@ -238,18 +168,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
238
168
  [messageIdGenerator, onSend, user, resetInputToolbar, scrollToBottom]
239
169
  )
240
170
 
241
- const onInputSizeChanged = useCallback(
242
- (size: { height: number }) => {
243
- const newComposerHeight = Math.max(
244
- minComposerHeight!,
245
- Math.min(maxComposerHeight!, size.height)
246
- )
247
-
248
- setComposerHeight(newComposerHeight)
249
- },
250
- [maxComposerHeight, minComposerHeight]
251
- )
252
-
253
171
  const _onChangeText = useCallback(
254
172
  (text: string) => {
255
173
  props.textInputProps?.onChangeText?.(text)
@@ -274,10 +192,9 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
274
192
  notifyInputTextReset()
275
193
 
276
194
  setIsInitialized(true)
277
- setComposerHeight(minComposerHeight!)
278
195
  setText(getTextFromProp(initialText))
279
196
  },
280
- [isInitialized, initialText, minComposerHeight, notifyInputTextReset, getTextFromProp]
197
+ [isInitialized, initialText, notifyInputTextReset, getTextFromProp]
281
198
  )
282
199
 
283
200
  const inputToolbarFragment = useMemo(() => {
@@ -287,9 +204,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
287
204
  const inputToolbarProps = {
288
205
  ...props,
289
206
  text: getTextFromProp(text!),
290
- composerHeight: Math.max(minComposerHeight!, composerHeight),
291
207
  onSend: _onSend,
292
- onInputSizeChanged,
293
208
  textInputProps: {
294
209
  ...textInputProps,
295
210
  onChangeText: _onChangeText,
@@ -305,12 +220,9 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
305
220
  isInitialized,
306
221
  _onSend,
307
222
  getTextFromProp,
308
- minComposerHeight,
309
- onInputSizeChanged,
310
223
  props,
311
224
  text,
312
225
  renderInputToolbar,
313
- composerHeight,
314
226
  textInputRef,
315
227
  textInputProps,
316
228
  _onChangeText,
@@ -334,78 +246,55 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
334
246
  setText(props.text)
335
247
  }, [props.text])
336
248
 
337
- // Only set up keyboard animation when keyboard is internally handled
338
- useAnimatedReaction(
339
- () => isKeyboardInternallyHandled ? keyboard.height.value : 0,
340
- (value, prevValue) => {
341
- // Skip keyboard handling when not internally handled
342
- if (!isKeyboardInternallyHandled)
343
- return
344
-
345
- if (prevValue !== null && value !== prevValue) {
346
- const isKeyboardMovingUp = value < prevValue
347
- if (isKeyboardMovingUp !== trackingKeyboardMovement.value) {
348
- trackingKeyboardMovement.value = isKeyboardMovingUp
349
- keyboardBottomOffsetAnim.value = withTiming(
350
- isKeyboardMovingUp ? keyboardBottomOffset : 0,
351
- {
352
- // If `keyboardBottomOffset` exists, we change the duration to a smaller value to fix the delay in the keyboard animation speed
353
- duration: keyboardBottomOffset ? 150 : 400,
354
- }
355
- )
356
-
357
- if (shouldFocusInputOnKeyboardOpen)
358
- if (isKeyboardMovingUp)
359
- runOnJS(handleTextInputFocusWhenKeyboardShow)()
360
- else
361
- runOnJS(handleTextInputFocusWhenKeyboardHide)()
362
- }
363
- }
364
- },
365
- [
366
- keyboard,
367
- trackingKeyboardMovement,
368
- shouldFocusInputOnKeyboardOpen,
369
- handleTextInputFocusWhenKeyboardHide,
370
- handleTextInputFocusWhenKeyboardShow,
371
- keyboardBottomOffset,
372
- isKeyboardInternallyHandled,
373
- ]
374
- )
375
-
376
249
  return (
377
250
  <GiftedChatContext.Provider value={contextValues}>
378
251
  <ActionSheetProvider ref={actionSheetRef}>
379
- <View
380
- testID={TEST_ID.WRAPPER}
381
- style={[stylesCommon.fill, styles.contentContainer]}
382
- onLayout={onInitialLayoutViewLayout}
252
+ {/* @ts-expect-error */}
253
+ <KeyboardAvoidingView
254
+ behavior='padding'
255
+ style={stylesCommon.fill}
256
+ {...props.keyboardAvoidingViewProps}
383
257
  >
384
- {isInitialized
385
- ? (
386
- <Animated.View style={[stylesCommon.fill, isKeyboardInternallyHandled && contentStyleAnim]}>
387
- {renderMessages}
388
- {inputToolbarFragment}
389
- </Animated.View>
390
- )
391
- : (
392
- renderComponentOrElement(renderLoading, {})
393
- )}
394
- </View>
258
+ <View
259
+ testID={TEST_ID.WRAPPER}
260
+ style={[stylesCommon.fill, styles.contentContainer]}
261
+ onLayout={onInitialLayoutViewLayout}
262
+ >
263
+ {isInitialized
264
+ ? (
265
+ <>
266
+ {renderMessages}
267
+ {inputToolbarFragment}
268
+ </>
269
+ )
270
+ : (
271
+ renderComponentOrElement(renderLoading, {})
272
+ )}
273
+ </View>
274
+ </KeyboardAvoidingView>
395
275
  </ActionSheetProvider>
396
276
  </GiftedChatContext.Provider>
397
277
  )
398
278
  }
399
279
 
400
280
  function GiftedChatWrapper<TMessage extends IMessage = IMessage> (props: GiftedChatProps<TMessage>) {
281
+ const {
282
+ keyboardProviderProps,
283
+ ...rest
284
+ } = props
285
+
401
286
  return (
402
- <KeyboardProvider>
403
- <GestureHandlerRootView style={styles.fill}>
404
- <SafeAreaProvider>
405
- <GiftedChat<TMessage> {...props} />
406
- </SafeAreaProvider>
407
- </GestureHandlerRootView>
408
- </KeyboardProvider>
287
+ <GestureHandlerRootView style={styles.fill}>
288
+ <SafeAreaProvider>
289
+ <KeyboardProvider
290
+ statusBarTranslucent
291
+ navigationBarTranslucent
292
+ {...keyboardProviderProps}
293
+ >
294
+ <GiftedChat<TMessage> {...rest} />
295
+ </KeyboardProvider>
296
+ </SafeAreaProvider>
297
+ </GestureHandlerRootView>
409
298
  )
410
299
  }
411
300
 
@@ -8,13 +8,14 @@ import {
8
8
  import {
9
9
  ActionSheetOptions,
10
10
  } from '@expo/react-native-action-sheet'
11
+ import { KeyboardProvider, KeyboardAvoidingViewProps } from 'react-native-keyboard-controller'
11
12
  import { ActionsProps } from '../Actions'
12
13
  import { AvatarProps } from '../Avatar'
13
14
  import { BubbleProps } from '../Bubble'
14
15
  import { ComposerProps } from '../Composer'
15
16
  import { InputToolbarProps } from '../InputToolbar'
16
- import { AnimatedList, MessageContainerProps } from '../MessageContainer'
17
17
  import { MessageImageProps } from '../MessageImage'
18
+ import { AnimatedList, MessagesContainerProps } from '../MessagesContainer'
18
19
  import { MessageTextProps } from '../MessageText'
19
20
  import {
20
21
  IMessage,
@@ -28,9 +29,9 @@ import { SendProps } from '../Send'
28
29
  import { SystemMessageProps } from '../SystemMessage'
29
30
  import { TimeProps } from '../Time'
30
31
 
31
- export interface GiftedChatProps<TMessage extends IMessage> extends Partial<MessageContainerProps<TMessage>> {
32
- /* Message container ref */
33
- messageContainerRef?: RefObject<AnimatedList<TMessage>>
32
+ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<MessagesContainerProps<TMessage>> {
33
+ /* Messages container ref */
34
+ messagesContainerRef?: RefObject<AnimatedList<TMessage>>
34
35
  /* text input ref */
35
36
  textInputRef?: RefObject<TextInput>
36
37
  /* Controls whether or not to show user.name property in the message bubble */
@@ -50,8 +51,6 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
50
51
  dateFormat?: string
51
52
  /* Format to use for rendering relative times; Today - for now. See more: https://day.js.org/docs/en/plugin/calendar */
52
53
  dateFormatCalendar?: object
53
- /* 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` */
54
- isKeyboardInternallyHandled?: boolean
55
54
  /* Whether to render an avatar for the current user; default is false, only show avatars for other users */
56
55
  isUserAvatarVisible?: boolean
57
56
  /* When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default is false */
@@ -60,10 +59,6 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
60
59
  isAvatarOnTop?: boolean
61
60
  /* Extra props to be passed to the <Image> component created by the default renderMessageImage */
62
61
  imageProps?: MessageImageProps<TMessage>
63
- /* Distance of the chat from the bottom of the screen (e.g. useful if you display a tab bar); default is 0 */
64
- keyboardBottomOffset?: number
65
- /* Focus on <TextInput> automatically when opening the keyboard; default is true */
66
- shouldFocusInputOnKeyboardOpen?: boolean
67
62
  /* Minimum height of the input toolbar; default is 44 */
68
63
  minInputToolbarHeight?: number
69
64
  /* Extra props to be passed to the <TextInput>. See https://reactnative.dev/docs/textinput */
@@ -120,13 +115,13 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
120
115
  renderMessageImage?: (props: MessageImageProps<TMessage>) => React.ReactNode
121
116
  /* Custom message video */
122
117
  renderMessageVideo?: (props: MessageVideoProps<TMessage>) => React.ReactNode
123
- /* Custom message video */
118
+ /* Custom message audio */
124
119
  renderMessageAudio?: (props: MessageAudioProps<TMessage>) => React.ReactNode
125
120
  /* Custom view inside the bubble */
126
121
  renderCustomView?: (props: BubbleProps<TMessage>) => React.ReactNode
127
122
  /* Custom time inside a message */
128
123
  renderTime?: (props: TimeProps<TMessage>) => React.ReactNode
129
- /* Custom component to render below the MessageContainer (separate from the ListView) */
124
+ /* Custom component to render below the MessagesContainer */
130
125
  renderChatFooter?: () => React.ReactNode
131
126
  /* Custom message composer container. Can be a component, element, render function, or null */
132
127
  renderInputToolbar?: React.ComponentType<InputToolbarProps<TMessage>> | React.ReactElement | ((props: InputToolbarProps<TMessage>) => React.ReactNode) | null
@@ -146,4 +141,8 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
146
141
  quickReplies: QuickRepliesProps<TMessage>,
147
142
  ) => React.ReactNode
148
143
  renderQuickReplySend?: () => React.ReactNode
144
+ keyboardProviderProps?: React.ComponentProps<typeof KeyboardProvider>
145
+ keyboardAvoidingViewProps?: KeyboardAvoidingViewProps
146
+ /** Enable animated day label that appears on scroll; default is true */
147
+ isDayAnimationEnabled?: boolean
149
148
  }