react-native-gifted-chat 2.8.1 → 2.8.2-alpha.1

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 (195) hide show
  1. package/README.md +18 -17
  2. package/package.json +41 -35
  3. package/src/Bubble/index.tsx +15 -39
  4. package/src/Bubble/types.ts +5 -5
  5. package/src/Composer.tsx +19 -26
  6. package/src/Constant.ts +0 -1
  7. package/src/GiftedAvatar.tsx +29 -36
  8. package/src/GiftedChat/index.tsx +34 -65
  9. package/src/GiftedChat/types.ts +8 -53
  10. package/src/InputToolbar.tsx +25 -8
  11. package/src/LoadEarlier.tsx +19 -17
  12. package/src/MessageAudio.tsx +19 -7
  13. package/src/MessageContainer/components/DayAnimated/index.tsx +14 -9
  14. package/src/MessageContainer/components/Item/index.tsx +7 -1
  15. package/src/MessageContainer/index.tsx +104 -64
  16. package/src/MessageContainer/styles.ts +3 -2
  17. package/src/MessageContainer/types.ts +36 -14
  18. package/src/MessageImage.tsx +18 -6
  19. package/src/MessageText.tsx +88 -128
  20. package/src/MessageVideo.tsx +19 -7
  21. package/src/QuickReplies.tsx +17 -10
  22. package/src/Send.tsx +7 -1
  23. package/src/SystemMessage.tsx +12 -2
  24. package/src/Time.tsx +9 -2
  25. package/src/TypingIndicator/index.tsx +2 -1
  26. package/src/TypingIndicator/types.ts +3 -0
  27. package/src/__tests__/Actions.test.tsx +3 -4
  28. package/src/__tests__/Avatar.test.tsx +5 -6
  29. package/src/__tests__/Bubble.test.tsx +14 -19
  30. package/src/__tests__/Composer.test.tsx +3 -4
  31. package/src/__tests__/Day.test.tsx +5 -8
  32. package/src/__tests__/DayAnimated.test.tsx +52 -0
  33. package/src/__tests__/GiftedAvatar.test.tsx +3 -8
  34. package/src/__tests__/GiftedChat.test.tsx +37 -21
  35. package/src/__tests__/InputToolbar.test.tsx +3 -4
  36. package/src/__tests__/LoadEarlier.test.tsx +3 -4
  37. package/src/__tests__/Message.test.tsx +51 -58
  38. package/src/__tests__/MessageContainer.test.tsx +39 -5
  39. package/src/__tests__/MessageImage.test.tsx +12 -15
  40. package/src/__tests__/MessageText.test.tsx +7 -4
  41. package/src/__tests__/Send.test.tsx +7 -8
  42. package/src/__tests__/SystemMessage.test.tsx +12 -15
  43. package/src/__tests__/Time.test.tsx +5 -8
  44. package/src/__tests__/__snapshots__/Bubble.test.tsx.snap +48 -50
  45. package/src/__tests__/__snapshots__/Composer.test.tsx.snap +1 -2
  46. package/src/__tests__/__snapshots__/Constant.test.tsx.snap +0 -1
  47. package/src/__tests__/__snapshots__/DayAnimated.test.tsx.snap +5 -0
  48. package/src/__tests__/__snapshots__/GiftedChat.test.tsx.snap +25 -0
  49. package/src/__tests__/__snapshots__/InputToolbar.test.tsx.snap +2 -2
  50. package/src/__tests__/__snapshots__/Message.test.tsx.snap +146 -150
  51. package/src/__tests__/__snapshots__/MessageImage.test.tsx.snap +12 -10
  52. package/src/__tests__/__snapshots__/MessageText.test.tsx.snap +12 -8
  53. package/src/__tests__/__snapshots__/Send.test.tsx.snap +2 -0
  54. package/src/reanimatedCompat.ts +27 -0
  55. package/src/types.ts +4 -0
  56. package/src/utils.ts +77 -1
  57. package/lib/Actions.d.ts +0 -14
  58. package/lib/Actions.js +0 -57
  59. package/lib/Actions.js.map +0 -1
  60. package/lib/Avatar.d.ts +0 -18
  61. package/lib/Avatar.js +0 -93
  62. package/lib/Avatar.js.map +0 -1
  63. package/lib/Bubble/index.d.ts +0 -6
  64. package/lib/Bubble/index.js +0 -257
  65. package/lib/Bubble/index.js.map +0 -1
  66. package/lib/Bubble/styles.d.ts +0 -69
  67. package/lib/Bubble/styles.js +0 -72
  68. package/lib/Bubble/styles.js.map +0 -1
  69. package/lib/Bubble/types.d.ts +0 -47
  70. package/lib/Bubble/types.js +0 -2
  71. package/lib/Bubble/types.js.map +0 -1
  72. package/lib/Color.d.ts +0 -18
  73. package/lib/Color.js +0 -18
  74. package/lib/Color.js.map +0 -1
  75. package/lib/Composer.d.ts +0 -20
  76. package/lib/Composer.js +0 -60
  77. package/lib/Composer.js.map +0 -1
  78. package/lib/Constant.d.ts +0 -10
  79. package/lib/Constant.js +0 -17
  80. package/lib/Constant.js.map +0 -1
  81. package/lib/Day/index.d.ts +0 -4
  82. package/lib/Day/index.js +0 -39
  83. package/lib/Day/index.js.map +0 -1
  84. package/lib/Day/styles.d.ts +0 -20
  85. package/lib/Day/styles.js +0 -22
  86. package/lib/Day/styles.js.map +0 -1
  87. package/lib/Day/types.d.ts +0 -9
  88. package/lib/Day/types.js +0 -2
  89. package/lib/Day/types.js.map +0 -1
  90. package/lib/GiftedAvatar.d.ts +0 -11
  91. package/lib/GiftedAvatar.js +0 -104
  92. package/lib/GiftedAvatar.js.map +0 -1
  93. package/lib/GiftedChat/index.d.ts +0 -26
  94. package/lib/GiftedChat/index.js +0 -302
  95. package/lib/GiftedChat/index.js.map +0 -1
  96. package/lib/GiftedChat/styles.d.ts +0 -6
  97. package/lib/GiftedChat/styles.js +0 -7
  98. package/lib/GiftedChat/styles.js.map +0 -1
  99. package/lib/GiftedChat/types.d.ts +0 -117
  100. package/lib/GiftedChat/types.js +0 -2
  101. package/lib/GiftedChat/types.js.map +0 -1
  102. package/lib/GiftedChatContext.d.ts +0 -9
  103. package/lib/GiftedChatContext.js +0 -9
  104. package/lib/GiftedChatContext.js.map +0 -1
  105. package/lib/InputToolbar.d.ts +0 -23
  106. package/lib/InputToolbar.js +0 -56
  107. package/lib/InputToolbar.js.map +0 -1
  108. package/lib/LoadEarlier.d.ts +0 -14
  109. package/lib/LoadEarlier.js +0 -45
  110. package/lib/LoadEarlier.js.map +0 -1
  111. package/lib/Message/index.d.ts +0 -6
  112. package/lib/Message/index.js +0 -80
  113. package/lib/Message/index.js.map +0 -1
  114. package/lib/Message/styles.d.ts +0 -21
  115. package/lib/Message/styles.js +0 -22
  116. package/lib/Message/styles.js.map +0 -1
  117. package/lib/Message/types.d.ts +0 -22
  118. package/lib/Message/types.js +0 -2
  119. package/lib/Message/types.js.map +0 -1
  120. package/lib/MessageAudio.d.ts +0 -2
  121. package/lib/MessageAudio.js +0 -14
  122. package/lib/MessageAudio.js.map +0 -1
  123. package/lib/MessageContainer/components/DayAnimated/index.d.ts +0 -5
  124. package/lib/MessageContainer/components/DayAnimated/index.js +0 -85
  125. package/lib/MessageContainer/components/DayAnimated/index.js.map +0 -1
  126. package/lib/MessageContainer/components/DayAnimated/styles.d.ts +0 -11
  127. package/lib/MessageContainer/components/DayAnimated/styles.js +0 -12
  128. package/lib/MessageContainer/components/DayAnimated/styles.js.map +0 -1
  129. package/lib/MessageContainer/components/DayAnimated/types.d.ts +0 -17
  130. package/lib/MessageContainer/components/DayAnimated/types.js +0 -2
  131. package/lib/MessageContainer/components/DayAnimated/types.js.map +0 -1
  132. package/lib/MessageContainer/components/Item/index.d.ts +0 -23
  133. package/lib/MessageContainer/components/Item/index.js +0 -88
  134. package/lib/MessageContainer/components/Item/index.js.map +0 -1
  135. package/lib/MessageContainer/components/Item/types.d.ts +0 -17
  136. package/lib/MessageContainer/components/Item/types.js +0 -2
  137. package/lib/MessageContainer/components/Item/types.js.map +0 -1
  138. package/lib/MessageContainer/index.d.ts +0 -6
  139. package/lib/MessageContainer/index.js +0 -224
  140. package/lib/MessageContainer/index.js.map +0 -1
  141. package/lib/MessageContainer/styles.d.ts +0 -34
  142. package/lib/MessageContainer/styles.js +0 -31
  143. package/lib/MessageContainer/styles.js.map +0 -1
  144. package/lib/MessageContainer/types.d.ts +0 -54
  145. package/lib/MessageContainer/types.js +0 -2
  146. package/lib/MessageContainer/types.js.map +0 -1
  147. package/lib/MessageImage.d.ts +0 -13
  148. package/lib/MessageImage.js +0 -30
  149. package/lib/MessageImage.js.map +0 -1
  150. package/lib/MessageText.d.ts +0 -15
  151. package/lib/MessageText.js +0 -108
  152. package/lib/MessageText.js.map +0 -1
  153. package/lib/MessageVideo.d.ts +0 -2
  154. package/lib/MessageVideo.js +0 -14
  155. package/lib/MessageVideo.js.map +0 -1
  156. package/lib/QuickReplies.d.ts +0 -15
  157. package/lib/QuickReplies.js +0 -101
  158. package/lib/QuickReplies.js.map +0 -1
  159. package/lib/Send.d.ts +0 -15
  160. package/lib/Send.js +0 -34
  161. package/lib/Send.js.map +0 -1
  162. package/lib/SystemMessage.d.ts +0 -10
  163. package/lib/SystemMessage.js +0 -26
  164. package/lib/SystemMessage.js.map +0 -1
  165. package/lib/Time.d.ts +0 -11
  166. package/lib/Time.js +0 -56
  167. package/lib/Time.js.map +0 -1
  168. package/lib/TypingIndicator/index.d.ts +0 -5
  169. package/lib/TypingIndicator/index.js +0 -94
  170. package/lib/TypingIndicator/index.js.map +0 -1
  171. package/lib/TypingIndicator/styles.d.ts +0 -20
  172. package/lib/TypingIndicator/styles.js +0 -22
  173. package/lib/TypingIndicator/styles.js.map +0 -1
  174. package/lib/TypingIndicator/types.d.ts +0 -3
  175. package/lib/TypingIndicator/types.js +0 -2
  176. package/lib/TypingIndicator/types.js.map +0 -1
  177. package/lib/hooks/useUpdateLayoutEffect.d.ts +0 -8
  178. package/lib/hooks/useUpdateLayoutEffect.js +0 -17
  179. package/lib/hooks/useUpdateLayoutEffect.js.map +0 -1
  180. package/lib/index.d.ts +0 -4
  181. package/lib/index.js +0 -5
  182. package/lib/index.js.map +0 -1
  183. package/lib/logging.d.ts +0 -2
  184. package/lib/logging.js +0 -5
  185. package/lib/logging.js.map +0 -1
  186. package/lib/styles.d.ts +0 -10
  187. package/lib/styles.js +0 -11
  188. package/lib/styles.js.map +0 -1
  189. package/lib/types.d.ts +0 -67
  190. package/lib/types.js +0 -2
  191. package/lib/types.js.map +0 -1
  192. package/lib/utils.d.ts +0 -3
  193. package/lib/utils.js +0 -17
  194. package/lib/utils.js.map +0 -1
  195. package/src/__tests__/__snapshots__/MessageContainer.test.tsx.snap +0 -101
@@ -14,7 +14,6 @@ import {
14
14
  import dayjs from 'dayjs'
15
15
  import localizedFormat from 'dayjs/plugin/localizedFormat'
16
16
  import {
17
- Platform,
18
17
  TextInput,
19
18
  View,
20
19
  LayoutChangeEvent,
@@ -72,23 +71,18 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
72
71
  onSend,
73
72
  locale = 'en',
74
73
  renderLoading,
75
- actionSheet = null,
74
+ actionSheet,
76
75
  textInputProps,
77
- renderChatFooter = null,
78
- renderInputToolbar = null,
76
+ renderChatFooter,
77
+ renderInputToolbar,
79
78
  bottomOffset = 0,
80
79
  focusOnInputWhenOpeningKeyboard = true,
81
- keyboardShouldPersistTaps = Platform.select({
82
- ios: 'never',
83
- android: 'always',
84
- default: 'never',
85
- }),
86
- onInputTextChanged = null,
87
- maxInputLength = null,
80
+ onInputTextChanged,
88
81
  inverted = true,
89
82
  minComposerHeight = MIN_COMPOSER_HEIGHT,
90
83
  maxComposerHeight = MAX_COMPOSER_HEIGHT,
91
84
  isKeyboardInternallyHandled = true,
85
+ disableKeyboardController = false,
92
86
  } = props
93
87
 
94
88
  const actionSheetRef = useRef<ActionSheetProviderRef>(null)
@@ -110,11 +104,18 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
110
104
  minComposerHeight!
111
105
  )
112
106
  const [text, setText] = useState<string | undefined>(() => props.text || '')
113
- const [isTypingDisabled, setIsTypingDisabled] = useState<boolean>(false)
114
107
 
115
- const keyboard = useReanimatedKeyboardAnimation()
108
+ // Always call the hook, but conditionally use its data
109
+ const keyboardControllerData = useReanimatedKeyboardAnimation()
110
+
111
+ // Create a mock keyboard object when disabled
112
+ const keyboard = useMemo(() => {
113
+ if (disableKeyboardController)
114
+ return { height: { value: 0 } }
115
+ return keyboardControllerData
116
+ }, [disableKeyboardController, keyboardControllerData])
117
+
116
118
  const trackingKeyboardMovement = useSharedValue(false)
117
- const debounceEnableTypingTimeoutId = useRef<ReturnType<typeof setTimeout>>(undefined)
118
119
  const keyboardOffsetBottom = useSharedValue(0)
119
120
 
120
121
  const contentStyleAnim = useAnimatedStyle(
@@ -164,23 +165,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
164
165
  isTextInputWasFocused.current = false
165
166
  }, [textInputRef])
166
167
 
167
- const disableTyping = useCallback(() => {
168
- clearTimeout(debounceEnableTypingTimeoutId.current)
169
- setIsTypingDisabled(true)
170
- }, [])
171
-
172
- const enableTyping = useCallback(() => {
173
- clearTimeout(debounceEnableTypingTimeoutId.current)
174
- setIsTypingDisabled(false)
175
- }, [])
176
-
177
- const debounceEnableTyping = useCallback(() => {
178
- clearTimeout(debounceEnableTypingTimeoutId.current)
179
- debounceEnableTypingTimeoutId.current = setTimeout(() => {
180
- enableTyping()
181
- }, 50)
182
- }, [enableTyping])
183
-
184
168
  const scrollToBottom = useCallback(
185
169
  (isAnimated = true) => {
186
170
  if (!messageContainerRef?.current)
@@ -209,10 +193,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
209
193
  <View style={[stylesCommon.fill, messagesContainerStyle]}>
210
194
  <MessageContainer<TMessage>
211
195
  {...messagesContainerProps}
212
- invertibleScrollViewProps={{
213
- inverted,
214
- keyboardShouldPersistTaps,
215
- }}
196
+ inverted={inverted}
216
197
  messages={messages}
217
198
  forwardRef={messageContainerRef}
218
199
  isTyping={isTyping}
@@ -226,7 +207,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
226
207
  messages,
227
208
  props,
228
209
  inverted,
229
- keyboardShouldPersistTaps,
230
210
  messageContainerRef,
231
211
  renderChatFooter,
232
212
  ])
@@ -242,13 +222,11 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
242
222
 
243
223
  setComposerHeight(minComposerHeight!)
244
224
  setText(getTextFromProp(''))
245
- enableTyping()
246
225
  }, [
247
226
  minComposerHeight,
248
227
  getTextFromProp,
249
228
  textInputRef,
250
229
  notifyInputTextReset,
251
- enableTyping,
252
230
  ])
253
231
 
254
232
  const _onSend = useCallback(
@@ -265,17 +243,14 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
265
243
  }
266
244
  })
267
245
 
268
- if (shouldResetInputToolbar === true) {
269
- disableTyping()
270
-
246
+ if (shouldResetInputToolbar === true)
271
247
  resetInputToolbar()
272
- }
273
248
 
274
249
  onSend?.(newMessages)
275
250
 
276
251
  setTimeout(() => scrollToBottom(), 10)
277
252
  },
278
- [messageIdGenerator, onSend, user, resetInputToolbar, disableTyping, scrollToBottom]
253
+ [messageIdGenerator, onSend, user, resetInputToolbar, scrollToBottom]
279
254
  )
280
255
 
281
256
  const onInputSizeChanged = useCallback(
@@ -291,17 +266,14 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
291
266
  )
292
267
 
293
268
  const _onInputTextChanged = useCallback(
294
- (_text: string) => {
295
- if (isTypingDisabled)
296
- return
297
-
298
- onInputTextChanged?.(_text)
269
+ (text: string) => {
270
+ onInputTextChanged?.(text)
299
271
 
300
272
  // Only set state if it's not being overridden by a prop.
301
273
  if (props.text === undefined)
302
- setText(_text)
274
+ setText(text)
303
275
  },
304
- [onInputTextChanged, isTypingDisabled, props.text]
276
+ [onInputTextChanged, props.text]
305
277
  )
306
278
 
307
279
  const onInitialLayoutViewLayout = useCallback(
@@ -337,7 +309,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
337
309
  textInputProps: {
338
310
  ...textInputProps,
339
311
  ref: textInputRef,
340
- maxLength: isTypingDisabled ? 0 : maxInputLength,
341
312
  },
342
313
  }
343
314
 
@@ -349,14 +320,12 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
349
320
  isInitialized,
350
321
  _onSend,
351
322
  getTextFromProp,
352
- maxInputLength,
353
323
  minComposerHeight,
354
324
  onInputSizeChanged,
355
325
  props,
356
326
  text,
357
327
  renderInputToolbar,
358
328
  composerHeight,
359
- isTypingDisabled,
360
329
  textInputRef,
361
330
  textInputProps,
362
331
  _onInputTextChanged,
@@ -380,9 +349,14 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
380
349
  setText(props.text)
381
350
  }, [props.text])
382
351
 
352
+ // Only set up keyboard animation when keyboard controller is enabled
383
353
  useAnimatedReaction(
384
- () => -keyboard.height.value,
354
+ () => disableKeyboardController ? 0 : -keyboard.height.value,
385
355
  (value, prevValue) => {
356
+ // Skip keyboard handling when disabled
357
+ if (disableKeyboardController)
358
+ return
359
+
386
360
  if (prevValue !== null && value !== prevValue) {
387
361
  const isKeyboardMovingUp = value > prevValue
388
362
  if (isKeyboardMovingUp !== trackingKeyboardMovement.value) {
@@ -400,13 +374,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
400
374
  runOnJS(handleTextInputFocusWhenKeyboardShow)()
401
375
  else
402
376
  runOnJS(handleTextInputFocusWhenKeyboardHide)()
403
-
404
- if (value === 0) {
405
- runOnJS(enableTyping)()
406
- } else {
407
- runOnJS(disableTyping)()
408
- runOnJS(debounceEnableTyping)()
409
- }
410
377
  }
411
378
  }
412
379
  },
@@ -416,10 +383,8 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
416
383
  focusOnInputWhenOpeningKeyboard,
417
384
  handleTextInputFocusWhenKeyboardHide,
418
385
  handleTextInputFocusWhenKeyboardShow,
419
- enableTyping,
420
- disableTyping,
421
- debounceEnableTyping,
422
386
  bottomOffset,
387
+ disableKeyboardController,
423
388
  ]
424
389
  )
425
390
 
@@ -433,7 +398,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
433
398
  >
434
399
  {isInitialized
435
400
  ? (
436
- <Animated.View style={[stylesCommon.fill, isKeyboardInternallyHandled && contentStyleAnim]}>
401
+ <Animated.View style={[stylesCommon.fill, (isKeyboardInternallyHandled && !disableKeyboardController) && contentStyleAnim]}>
437
402
  {renderMessages}
438
403
  {inputToolbarFragment}
439
404
  </Animated.View>
@@ -448,6 +413,10 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
448
413
  }
449
414
 
450
415
  function GiftedChatWrapper<TMessage extends IMessage = IMessage> (props: GiftedChatProps<TMessage>) {
416
+ // Don't use KeyboardProvider when keyboard controller is disabled
417
+ if (props.disableKeyboardController)
418
+ return <GiftedChat<TMessage> {...props} />
419
+
451
420
  return (
452
421
  <KeyboardProvider>
453
422
  <GiftedChat<TMessage> {...props} />
@@ -12,9 +12,7 @@ import { LightboxProps } from 'react-native-lightbox-v2'
12
12
  import { ActionsProps } from '../Actions'
13
13
  import { AvatarProps } from '../Avatar'
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'
19
17
  import { MessageImageProps } from '../MessageImage'
20
18
  import { MessageTextProps } from '../MessageText'
@@ -23,14 +21,13 @@ import {
23
21
  LeftRightStyle,
24
22
  MessageAudioProps,
25
23
  MessageVideoProps,
26
- Reply,
27
24
  User,
28
25
  } from '../types'
29
26
  import { QuickRepliesProps } from '../QuickReplies'
30
27
  import { SendProps } from '../Send'
31
28
  import { SystemMessageProps } from '../SystemMessage'
32
29
  import { TimeProps } from '../Time'
33
- import { AnimatedList, ListViewProps, MessageContainerProps } from '../MessageContainer'
30
+ import { AnimatedList, MessageContainerProps } from '../MessageContainer'
34
31
  import { BubbleProps } from '../Bubble'
35
32
 
36
33
  export interface GiftedChatProps<TMessage extends IMessage> extends Partial<MessageContainerProps<TMessage>> {
@@ -38,27 +35,13 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
38
35
  messageContainerRef?: RefObject<AnimatedList<TMessage>>
39
36
  /* text input ref */
40
37
  textInputRef?: RefObject<TextInput>
41
- /* Messages to display */
42
- messages?: TMessage[]
43
- /* Typing Indicator state */
44
- isTyping?: boolean
45
38
  /* Controls whether or not to show user.name property in the message bubble */
46
39
  renderUsernameOnMessage?: boolean
47
40
  /* Messages container style */
48
41
  messagesContainerStyle?: StyleProp<ViewStyle>
49
42
  /* Input text; default is undefined, but if specified, it will override GiftedChat's internal state */
50
43
  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
44
  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
45
  /* User sending the messages: { _id, name, avatar } */
63
46
  user?: User
64
47
  /* Locale to localize the dates */
@@ -69,19 +52,16 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
69
52
  dateFormat?: string
70
53
  /* Format to use for rendering relative times; Today - for now. See more: https://day.js.org/docs/en/plugin/calendar */
71
54
  dateFormatCalendar?: object
72
- /* Enables the "Load earlier messages" button */
73
- loadEarlier?: boolean
74
- /* Display an ActivityIndicator when loading earlier messages */
75
- isLoadingEarlier?: boolean
76
55
  /* 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
56
  isKeyboardInternallyHandled?: boolean
57
+ /* Completely disable react-native-keyboard-controller. Useful when using react-native-navigation or other conflicting keyboard libraries; default is `false` */
58
+ disableKeyboardController?: boolean
78
59
  /* Whether to render an avatar for the current user; default is false, only show avatars for other users */
79
60
  showUserAvatar?: boolean
80
61
  /* When false, avatars will only be displayed when a consecutive message is from the same user on the same day; default is false */
81
62
  showAvatarForEveryMessage?: boolean
82
63
  /* Render the message avatar at the top of consecutive messages, rather than the bottom; default is false */
83
64
  renderAvatarOnTop?: boolean
84
- inverted?: boolean
85
65
  /* Extra props to be passed to the <Image> component created by the default renderMessageImage */
86
66
  imageProps?: MessageImageProps<TMessage>
87
67
  /* Extra props to be passed to the MessageImage's Lightbox */
@@ -92,20 +72,12 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
92
72
  focusOnInputWhenOpeningKeyboard?: boolean
93
73
  /* Minimum height of the input toolbar; default is 44 */
94
74
  minInputToolbarHeight?: number
95
- /* Extra props to be passed to the messages <ListView>; some props can't be overridden, see the code in MessageContainer.render() for details */
96
- listViewProps?: ListViewProps
97
- /* Extra props to be passed to the <TextInput> */
98
- textInputProps?: object
99
- /* Determines whether the keyboard should stay visible after a tap; see <ScrollView> docs */
100
- keyboardShouldPersistTaps?: 'always' | 'never' | 'handled'
101
- /* Max message composer TextInput length */
102
- maxInputLength?: number
75
+ /* Extra props to be passed to the <TextInput>. See https://reactnative.dev/docs/textinput */
76
+ textInputProps?: Partial<React.ComponentProps<typeof TextInput>>
103
77
  /* Force send button */
104
78
  alwaysShowSend?: boolean
105
79
  /* Image style */
106
80
  imageStyle?: StyleProp<ViewStyle>
107
- /* This can be used to pass unknown data which needs to be re-rendered */
108
- extraData?: object
109
81
  /* composer min Height */
110
82
  minComposerHeight?: number
111
83
  /* composer min Height */
@@ -117,8 +89,6 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
117
89
  quickReplyContainerStyle?: StyleProp<ViewStyle>
118
90
  /* optional prop used to place customView below text, image and video views; default is false */
119
91
  isCustomViewBottom?: boolean
120
- /* infinite scroll up when reach the top of messages container, automatically call onLoadEarlier function if exist */
121
- infiniteScroll?: boolean
122
92
  timeTextStyle?: LeftRightStyle<TextStyle>
123
93
  /* Custom action sheet */
124
94
  actionSheet?(): {
@@ -135,12 +105,8 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
135
105
  messageIdGenerator?(message?: TMessage): string
136
106
  /* Callback when sending a message */
137
107
  onSend?(messages: TMessage[]): void
138
- /* Callback when loading earlier messages */
139
- onLoadEarlier?(): void
140
108
  /* Render a loading view when initializing */
141
109
  renderLoading?(): React.ReactNode
142
- /* Custom "Load earlier messages" button */
143
- renderLoadEarlier?(props: LoadEarlierProps): React.ReactNode
144
110
  /* Custom message avatar; set to null to not render any avatar for the message */
145
111
  renderAvatar?: null | ((props: AvatarProps<TMessage>) => React.ReactNode)
146
112
  /* Custom message bubble */
@@ -148,14 +114,12 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
148
114
  /* Custom system message */
149
115
  renderSystemMessage?(props: SystemMessageProps<TMessage>): React.ReactNode
150
116
  /* Callback when a message bubble is pressed; default is to do nothing */
151
- onPress?(context: unknown, message: TMessage): void
117
+ onPressMessage?(context: unknown, message: TMessage): void
152
118
  /* Callback when a message bubble is long-pressed; default is to show an ActionSheet with "Copy Text" (see example using showActionSheetWithOptions()) */
153
- onLongPress?(context: unknown, message: TMessage): void
119
+ onLongPressMessage?(context: unknown, message: TMessage): void
154
120
  /* Custom Username container */
155
121
  renderUsername?(user: User): React.ReactNode
156
122
  /* Reverses display order of messages; default is true */
157
- /* Custom message container */
158
- renderMessage?(message: MessageProps<TMessage>): React.ReactElement
159
123
  /* Custom message text */
160
124
  renderMessageText?(messageText: MessageTextProps<TMessage>): React.ReactNode
161
125
  /* Custom message image */
@@ -166,14 +130,8 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
166
130
  renderMessageAudio?(props: MessageAudioProps<TMessage>): React.ReactNode
167
131
  /* Custom view inside the bubble */
168
132
  renderCustomView?(props: BubbleProps<TMessage>): React.ReactNode
169
- /* Custom day above a message */
170
- renderDay?(props: DayProps): React.ReactNode
171
133
  /* Custom time inside a message */
172
134
  renderTime?(props: TimeProps<TMessage>): React.ReactNode
173
- /* Custom footer component on the ListView, e.g. 'User is typing...' */
174
- renderFooter?(props: MessageContainerProps<TMessage>): React.ReactNode
175
- /* Custom component to render in the ListView when messages are empty */
176
- renderChatEmpty?(): React.ReactNode
177
135
  /* Custom component to render below the MessageContainer (separate from the ListView) */
178
136
  renderChatFooter?(): React.ReactNode
179
137
  /* Custom message composer container */
@@ -191,14 +149,11 @@ export interface GiftedChatProps<TMessage extends IMessage> extends Partial<Mess
191
149
  /* Callback when the input text changes */
192
150
  onInputTextChanged?(text: string): void
193
151
  /* Custom parse patterns for react-native-parsed-text used to linking message content (like URLs and phone numbers) */
194
- parsePatterns?: (linkStyle?: TextStyle) => { type?: string, pattern?: RegExp, style?: StyleProp<TextStyle> | object, onPress?: unknown, renderText?: unknown }[]
195
- onQuickReply?(replies: Reply[]): void
152
+ matchers?: MessageTextProps<TMessage>['matchers']
196
153
  renderQuickReplies?(
197
154
  quickReplies: QuickRepliesProps<TMessage>,
198
155
  ): React.ReactNode
199
156
  renderQuickReplySend?(): React.ReactNode
200
- /* Scroll to bottom custom component */
201
- scrollToBottomComponent?(): React.ReactNode
202
157
  shouldUpdateMessage?(
203
158
  props: MessageProps<TMessage>,
204
159
  nextProps: MessageProps<TMessage>,
@@ -1,5 +1,5 @@
1
1
  import React, { useMemo } from 'react'
2
- import { StyleSheet, View, StyleProp, ViewStyle } from 'react-native'
2
+ import { StyleSheet, View, StyleProp, ViewStyle, useColorScheme } from 'react-native'
3
3
 
4
4
  import { Composer, ComposerProps } from './Composer'
5
5
  import { Send, SendProps } from './Send'
@@ -38,6 +38,8 @@ export function InputToolbar<TMessage extends IMessage = IMessage> (
38
38
  containerStyle,
39
39
  } = props
40
40
 
41
+ const colorScheme = useColorScheme()
42
+
41
43
  const actionsFragment = useMemo(() => {
42
44
  const props = {
43
45
  onPressActionButton,
@@ -69,18 +71,29 @@ export function InputToolbar<TMessage extends IMessage = IMessage> (
69
71
  )
70
72
  }, [renderComposer, props])
71
73
 
74
+ const sendFragment = useMemo(() => {
75
+ return renderSend?.(props) || <Send {...props} />
76
+ }, [renderSend, props])
77
+
78
+ const accessoryFragment = useMemo(() => {
79
+ if (!renderAccessory)
80
+ return null
81
+
82
+ return (
83
+ <View style={[styles.accessory, props.accessoryStyle]}>
84
+ {renderAccessory(props)}
85
+ </View>
86
+ )
87
+ }, [renderAccessory, props])
88
+
72
89
  return (
73
- <View style={[styles.container, containerStyle]}>
90
+ <View style={[styles.container, styles[`container_${colorScheme}`], containerStyle]}>
74
91
  <View style={[styles.primary, props.primaryStyle]}>
75
92
  {actionsFragment}
76
93
  {composerFragment}
77
- {renderSend?.(props) || <Send {...props} />}
94
+ {sendFragment}
78
95
  </View>
79
- {renderAccessory && (
80
- <View style={[styles.accessory, props.accessoryStyle]}>
81
- {renderAccessory(props)}
82
- </View>
83
- )}
96
+ {accessoryFragment}
84
97
  </View>
85
98
  )
86
99
  }
@@ -91,6 +104,10 @@ const styles = StyleSheet.create({
91
104
  borderTopColor: Color.defaultColor,
92
105
  backgroundColor: Color.white,
93
106
  },
107
+ container_dark: {
108
+ backgroundColor: '#1a1a1a',
109
+ borderTopColor: '#444',
110
+ },
94
111
  primary: {
95
112
  flexDirection: 'row',
96
113
  alignItems: 'flex-end',
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { useMemo } from 'react'
2
2
  import {
3
3
  ActivityIndicator,
4
4
  Platform,
@@ -63,6 +63,23 @@ export function LoadEarlier ({
63
63
  activityIndicatorSize = 'small',
64
64
  activityIndicatorStyle,
65
65
  }: LoadEarlierProps): React.ReactElement {
66
+ const loadingContent = useMemo(() => (
67
+ <View>
68
+ <Text style={[styles.text, textStyle, { opacity: 0 }]}>
69
+ {label}
70
+ </Text>
71
+ <ActivityIndicator
72
+ color={activityIndicatorColor!}
73
+ size={activityIndicatorSize!}
74
+ style={[styles.activityIndicator, activityIndicatorStyle]}
75
+ />
76
+ </View>
77
+ ), [label, textStyle, activityIndicatorColor, activityIndicatorSize, activityIndicatorStyle])
78
+
79
+ const labelContent = useMemo(() => (
80
+ <Text style={[styles.text, textStyle]}>{label}</Text>
81
+ ), [label, textStyle])
82
+
66
83
  return (
67
84
  <TouchableOpacity
68
85
  style={[styles.container, containerStyle]}
@@ -71,22 +88,7 @@ export function LoadEarlier ({
71
88
  accessibilityRole='button'
72
89
  >
73
90
  <View style={[stylesCommon.centerItems, styles.wrapper, wrapperStyle]}>
74
- {isLoadingEarlier
75
- ? (
76
- <View>
77
- <Text style={[styles.text, textStyle, { opacity: 0 }]}>
78
- {label}
79
- </Text>
80
- <ActivityIndicator
81
- color={activityIndicatorColor!}
82
- size={activityIndicatorSize!}
83
- style={[styles.activityIndicator, activityIndicatorStyle]}
84
- />
85
- </View>
86
- )
87
- : (
88
- <Text style={[styles.text, textStyle]}>{label}</Text>
89
- )}
91
+ {isLoadingEarlier ? loadingContent : labelContent}
90
92
  </View>
91
93
  </TouchableOpacity>
92
94
  )
@@ -1,16 +1,28 @@
1
- import React from 'react'
1
+ import React, { useMemo } from 'react'
2
2
  import Color from './Color'
3
- import { View, Text } from 'react-native'
3
+ import { View, Text, StyleSheet } from 'react-native'
4
+
5
+ const styles = StyleSheet.create({
6
+ container: {
7
+ padding: 20,
8
+ },
9
+ text: {
10
+ color: Color.alizarin,
11
+ fontWeight: '600',
12
+ },
13
+ })
4
14
 
5
15
  export function MessageAudio () {
6
- return (
7
- <View style={{ padding: 20 }}>
8
- <Text style={{ color: Color.alizarin, fontWeight: '600' }}>
16
+ const content = useMemo(() => (
17
+ <View style={styles.container}>
18
+ <Text style={styles.text}>
9
19
  {'Audio is not implemented by GiftedChat.'}
10
20
  </Text>
11
- <Text style={{ color: Color.alizarin, fontWeight: '600' }}>
21
+ <Text style={styles.text}>
12
22
  {'\nYou need to provide your own implementation by using renderMessageAudio prop.'}
13
23
  </Text>
14
24
  </View>
15
- )
25
+ ), [])
26
+
27
+ return content
16
28
  }
@@ -114,6 +114,19 @@ const DayAnimated = ({ scrolledY, daysPositions, listHeight, renderDay, messages
114
114
  isLoadingEarlierAnim.value = isLoadingEarlier
115
115
  }, [isLoadingEarlierAnim, isLoadingEarlier])
116
116
 
117
+ const dayContent = useMemo(() => {
118
+ if (!createdAt)
119
+ return null
120
+
121
+ return renderDay
122
+ ? renderDay({ ...rest, createdAt })
123
+ : <Day
124
+ {...rest}
125
+ containerStyle={[styles.dayAnimatedDayContainerStyle, rest.containerStyle]}
126
+ createdAt={createdAt}
127
+ />
128
+ }, [createdAt, renderDay, rest])
129
+
117
130
  if (!createdAt)
118
131
  return null
119
132
 
@@ -126,15 +139,7 @@ const DayAnimated = ({ scrolledY, daysPositions, listHeight, renderDay, messages
126
139
  style={contentStyle}
127
140
  pointerEvents='none'
128
141
  >
129
- {
130
- renderDay
131
- ? renderDay({ ...rest, createdAt })
132
- : <Day
133
- {...rest}
134
- containerStyle={[styles.dayAnimatedDayContainerStyle, rest.containerStyle]}
135
- createdAt={createdAt}
136
- />
137
- }
142
+ {dayContent}
138
143
  </Animated.View>
139
144
  </Animated.View>
140
145
  )
@@ -33,7 +33,13 @@ export const useRelativeScrolledPositionToBottomOfDay = (
33
33
  const absoluteScrolledPositionToBottomOfDay = useAbsoluteScrolledPositionToBottomOfDay(listHeight, scrolledY, containerHeight, dayBottomMargin, dayTopOffset)
34
34
 
35
35
  // sorted array of days positions by y
36
- const daysPositionsArray = useDerivedValue(() => Object.values(daysPositions.value).sort((a, b) => a.y - b.y))
36
+ const daysPositionsArray = useDerivedValue(() => {
37
+ return Object.values(daysPositions.value).sort((a, b) => {
38
+ 'worklet'
39
+
40
+ return a.y - b.y
41
+ })
42
+ })
37
43
 
38
44
  // find current day position by scrolled position
39
45
  const currentDayPosition = useDerivedValue(() => {