react-native-gifted-chat 3.3.0 → 3.3.3

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 (326) hide show
  1. package/CHANGELOG.md +435 -0
  2. package/README.md +68 -12
  3. package/lib/Actions.d.ts +16 -0
  4. package/lib/Actions.d.ts.map +1 -0
  5. package/lib/Actions.js +65 -0
  6. package/lib/Actions.js.map +1 -0
  7. package/lib/Avatar.d.ts +19 -0
  8. package/lib/Avatar.d.ts.map +1 -0
  9. package/lib/Avatar.js +93 -0
  10. package/lib/Avatar.js.map +1 -0
  11. package/lib/Bubble/index.d.ts +6 -0
  12. package/lib/Bubble/index.d.ts.map +1 -0
  13. package/lib/Bubble/index.js +269 -0
  14. package/lib/Bubble/index.js.map +1 -0
  15. package/lib/Bubble/styles.d.ts +57 -0
  16. package/lib/Bubble/styles.d.ts.map +1 -0
  17. package/lib/Bubble/styles.js +59 -0
  18. package/lib/Bubble/styles.js.map +1 -0
  19. package/lib/Bubble/types.d.ts +59 -0
  20. package/lib/Bubble/types.d.ts.map +1 -0
  21. package/lib/Bubble/types.js +2 -0
  22. package/lib/Bubble/types.js.map +1 -0
  23. package/lib/Color.d.ts +18 -0
  24. package/lib/Color.d.ts.map +1 -0
  25. package/lib/Color.js +18 -0
  26. package/lib/Color.js.map +1 -0
  27. package/lib/Composer.d.ts +9 -0
  28. package/lib/Composer.d.ts.map +1 -0
  29. package/lib/Composer.js +56 -0
  30. package/lib/Composer.js.map +1 -0
  31. package/lib/Constant.d.ts +8 -0
  32. package/lib/Constant.d.ts.map +1 -0
  33. package/lib/Constant.js +8 -0
  34. package/lib/Constant.js.map +1 -0
  35. package/lib/Day/index.d.ts +5 -0
  36. package/lib/Day/index.d.ts.map +1 -0
  37. package/lib/Day/index.js +40 -0
  38. package/lib/Day/index.js.map +1 -0
  39. package/lib/Day/styles.d.ts +21 -0
  40. package/lib/Day/styles.d.ts.map +1 -0
  41. package/lib/Day/styles.js +22 -0
  42. package/lib/Day/styles.js.map +1 -0
  43. package/lib/Day/types.d.ts +11 -0
  44. package/lib/Day/types.d.ts.map +1 -0
  45. package/lib/Day/types.js +2 -0
  46. package/lib/Day/types.js.map +1 -0
  47. package/lib/GiftedAvatar.d.ts +12 -0
  48. package/lib/GiftedAvatar.d.ts.map +1 -0
  49. package/lib/GiftedAvatar.js +101 -0
  50. package/lib/GiftedAvatar.js.map +1 -0
  51. package/lib/GiftedChat/index.d.ts +10 -0
  52. package/lib/GiftedChat/index.d.ts.map +1 -0
  53. package/lib/GiftedChat/index.js +241 -0
  54. package/lib/GiftedChat/index.js.map +1 -0
  55. package/lib/GiftedChat/styles.d.ts +13 -0
  56. package/lib/GiftedChat/styles.d.ts.map +1 -0
  57. package/lib/GiftedChat/styles.js +13 -0
  58. package/lib/GiftedChat/styles.js.map +1 -0
  59. package/lib/GiftedChat/types.d.ts +90 -0
  60. package/lib/GiftedChat/types.d.ts.map +1 -0
  61. package/lib/GiftedChat/types.js +2 -0
  62. package/lib/GiftedChat/types.js.map +1 -0
  63. package/lib/GiftedChatContext.d.ts +11 -0
  64. package/lib/GiftedChatContext.d.ts.map +1 -0
  65. package/lib/GiftedChatContext.js +10 -0
  66. package/lib/GiftedChatContext.js.map +1 -0
  67. package/lib/InputToolbar.d.ts +36 -0
  68. package/lib/InputToolbar.d.ts.map +1 -0
  69. package/lib/InputToolbar.js +108 -0
  70. package/lib/InputToolbar.js.map +1 -0
  71. package/lib/LoadEarlierMessages.d.ts +17 -0
  72. package/lib/LoadEarlierMessages.d.ts.map +1 -0
  73. package/lib/LoadEarlierMessages.js +45 -0
  74. package/lib/LoadEarlierMessages.js.map +1 -0
  75. package/lib/Message/index.d.ts +6 -0
  76. package/lib/Message/index.d.ts.map +1 -0
  77. package/lib/Message/index.js +180 -0
  78. package/lib/Message/index.js.map +1 -0
  79. package/lib/Message/styles.d.ts +18 -0
  80. package/lib/Message/styles.d.ts.map +1 -0
  81. package/lib/Message/styles.js +18 -0
  82. package/lib/Message/styles.js.map +1 -0
  83. package/lib/Message/types.d.ts +25 -0
  84. package/lib/Message/types.d.ts.map +1 -0
  85. package/lib/Message/types.js +2 -0
  86. package/lib/Message/types.js.map +1 -0
  87. package/lib/MessageAudio.d.ts +3 -0
  88. package/lib/MessageAudio.d.ts.map +1 -0
  89. package/lib/MessageAudio.js +25 -0
  90. package/lib/MessageAudio.js.map +1 -0
  91. package/lib/MessageImage.d.ts +12 -0
  92. package/lib/MessageImage.d.ts.map +1 -0
  93. package/lib/MessageImage.js +164 -0
  94. package/lib/MessageImage.js.map +1 -0
  95. package/lib/MessageReply.d.ts +15 -0
  96. package/lib/MessageReply.d.ts.map +1 -0
  97. package/lib/MessageReply.js +103 -0
  98. package/lib/MessageReply.js.map +1 -0
  99. package/lib/MessageText.d.ts +24 -0
  100. package/lib/MessageText.d.ts.map +1 -0
  101. package/lib/MessageText.js +41 -0
  102. package/lib/MessageText.js.map +1 -0
  103. package/lib/MessageVideo.d.ts +3 -0
  104. package/lib/MessageVideo.d.ts.map +1 -0
  105. package/lib/MessageVideo.js +25 -0
  106. package/lib/MessageVideo.js.map +1 -0
  107. package/lib/MessagesContainer/components/DayAnimated/index.d.ts +5 -0
  108. package/lib/MessagesContainer/components/DayAnimated/index.d.ts.map +1 -0
  109. package/lib/MessagesContainer/components/DayAnimated/index.js +92 -0
  110. package/lib/MessagesContainer/components/DayAnimated/index.js.map +1 -0
  111. package/lib/MessagesContainer/components/DayAnimated/styles.d.ts +12 -0
  112. package/lib/MessagesContainer/components/DayAnimated/styles.d.ts.map +1 -0
  113. package/lib/MessagesContainer/components/DayAnimated/styles.js +12 -0
  114. package/lib/MessagesContainer/components/DayAnimated/styles.js.map +1 -0
  115. package/lib/MessagesContainer/components/DayAnimated/types.d.ts +18 -0
  116. package/lib/MessagesContainer/components/DayAnimated/types.d.ts.map +1 -0
  117. package/lib/MessagesContainer/components/DayAnimated/types.js +2 -0
  118. package/lib/MessagesContainer/components/DayAnimated/types.js.map +1 -0
  119. package/lib/MessagesContainer/components/Item/index.d.ts +23 -0
  120. package/lib/MessagesContainer/components/Item/index.d.ts.map +1 -0
  121. package/lib/MessagesContainer/components/Item/index.js +120 -0
  122. package/lib/MessagesContainer/components/Item/index.js.map +1 -0
  123. package/lib/MessagesContainer/components/Item/types.d.ts +19 -0
  124. package/lib/MessagesContainer/components/Item/types.d.ts.map +1 -0
  125. package/lib/MessagesContainer/components/Item/types.js +2 -0
  126. package/lib/MessagesContainer/components/Item/types.js.map +1 -0
  127. package/lib/MessagesContainer/index.d.ts +6 -0
  128. package/lib/MessagesContainer/index.d.ts.map +1 -0
  129. package/lib/MessagesContainer/index.js +258 -0
  130. package/lib/MessagesContainer/index.js.map +1 -0
  131. package/lib/MessagesContainer/styles.d.ts +55 -0
  132. package/lib/MessagesContainer/styles.d.ts.map +1 -0
  133. package/lib/MessagesContainer/styles.js +42 -0
  134. package/lib/MessagesContainer/styles.js.map +1 -0
  135. package/lib/MessagesContainer/types.d.ts +88 -0
  136. package/lib/MessagesContainer/types.d.ts.map +1 -0
  137. package/lib/MessagesContainer/types.js +10 -0
  138. package/lib/MessagesContainer/types.js.map +1 -0
  139. package/lib/Models.d.ts +58 -0
  140. package/lib/Models.d.ts.map +1 -0
  141. package/lib/Models.js +2 -0
  142. package/lib/Models.js.map +1 -0
  143. package/lib/QuickReplies.d.ts +16 -0
  144. package/lib/QuickReplies.d.ts.map +1 -0
  145. package/lib/QuickReplies.js +108 -0
  146. package/lib/QuickReplies.js.map +1 -0
  147. package/lib/Reply/index.d.ts +2 -0
  148. package/lib/Reply/index.d.ts.map +1 -0
  149. package/lib/Reply/index.js +2 -0
  150. package/lib/Reply/index.js.map +1 -0
  151. package/lib/Reply/types.d.ts +72 -0
  152. package/lib/Reply/types.d.ts.map +1 -0
  153. package/lib/Reply/types.js +2 -0
  154. package/lib/Reply/types.js.map +1 -0
  155. package/lib/ReplyPreview.d.ts +14 -0
  156. package/lib/ReplyPreview.d.ts.map +1 -0
  157. package/lib/ReplyPreview.js +95 -0
  158. package/lib/ReplyPreview.js.map +1 -0
  159. package/lib/Send.d.ts +19 -0
  160. package/lib/Send.d.ts.map +1 -0
  161. package/lib/Send.js +57 -0
  162. package/lib/Send.js.map +1 -0
  163. package/lib/SystemMessage.d.ts +14 -0
  164. package/lib/SystemMessage.d.ts.map +1 -0
  165. package/lib/SystemMessage.js +42 -0
  166. package/lib/SystemMessage.js.map +1 -0
  167. package/lib/Time.d.ts +12 -0
  168. package/lib/Time.d.ts.map +1 -0
  169. package/lib/Time.js +39 -0
  170. package/lib/Time.js.map +1 -0
  171. package/lib/TypingIndicator/index.d.ts +5 -0
  172. package/lib/TypingIndicator/index.d.ts.map +1 -0
  173. package/lib/TypingIndicator/index.js +94 -0
  174. package/lib/TypingIndicator/index.js.map +1 -0
  175. package/lib/TypingIndicator/styles.d.ts +21 -0
  176. package/lib/TypingIndicator/styles.d.ts.map +1 -0
  177. package/lib/TypingIndicator/styles.js +22 -0
  178. package/lib/TypingIndicator/styles.js.map +1 -0
  179. package/lib/TypingIndicator/types.d.ts +6 -0
  180. package/lib/TypingIndicator/types.d.ts.map +1 -0
  181. package/lib/TypingIndicator/types.js +2 -0
  182. package/lib/TypingIndicator/types.js.map +1 -0
  183. package/lib/components/MessageReply.d.ts +29 -0
  184. package/lib/components/MessageReply.d.ts.map +1 -0
  185. package/lib/components/MessageReply.js +87 -0
  186. package/lib/components/MessageReply.js.map +1 -0
  187. package/lib/components/ReplyPreview.d.ts +17 -0
  188. package/lib/components/ReplyPreview.d.ts.map +1 -0
  189. package/lib/components/ReplyPreview.js +148 -0
  190. package/lib/components/ReplyPreview.js.map +1 -0
  191. package/lib/components/TouchableOpacity.d.ts +9 -0
  192. package/lib/components/TouchableOpacity.d.ts.map +1 -0
  193. package/lib/components/TouchableOpacity.js +37 -0
  194. package/lib/components/TouchableOpacity.js.map +1 -0
  195. package/lib/hooks/useColorScheme.d.ts +8 -0
  196. package/lib/hooks/useColorScheme.d.ts.map +1 -0
  197. package/lib/hooks/useColorScheme.js +17 -0
  198. package/lib/hooks/useColorScheme.js.map +1 -0
  199. package/lib/hooks/useUpdateLayoutEffect.d.ts +9 -0
  200. package/lib/hooks/useUpdateLayoutEffect.d.ts.map +1 -0
  201. package/lib/hooks/useUpdateLayoutEffect.js +17 -0
  202. package/lib/hooks/useUpdateLayoutEffect.js.map +1 -0
  203. package/lib/index.d.ts +31 -0
  204. package/lib/index.d.ts.map +1 -0
  205. package/lib/index.js +31 -0
  206. package/lib/index.js.map +1 -0
  207. package/lib/linkParser.d.ts +39 -0
  208. package/lib/linkParser.d.ts.map +1 -0
  209. package/lib/linkParser.js +154 -0
  210. package/lib/linkParser.js.map +1 -0
  211. package/lib/logging.d.ts +3 -0
  212. package/lib/logging.d.ts.map +1 -0
  213. package/lib/logging.js +5 -0
  214. package/lib/logging.js.map +1 -0
  215. package/lib/styles.d.ts +14 -0
  216. package/lib/styles.d.ts.map +1 -0
  217. package/lib/styles.js +23 -0
  218. package/lib/styles.js.map +1 -0
  219. package/lib/types.d.ts +19 -0
  220. package/lib/types.d.ts.map +1 -0
  221. package/lib/types.js +2 -0
  222. package/lib/types.js.map +1 -0
  223. package/lib/utils.d.ts +8 -0
  224. package/lib/utils.d.ts.map +1 -0
  225. package/lib/utils.js +105 -0
  226. package/lib/utils.js.map +1 -0
  227. package/package.json +12 -11
  228. package/src/Actions.tsx +0 -110
  229. package/src/Avatar.tsx +0 -169
  230. package/src/Bubble/index.tsx +0 -407
  231. package/src/Bubble/styles.ts +0 -66
  232. package/src/Bubble/types.ts +0 -104
  233. package/src/Color.ts +0 -17
  234. package/src/Composer.tsx +0 -100
  235. package/src/Constant.ts +0 -8
  236. package/src/Day/index.tsx +0 -63
  237. package/src/Day/styles.ts +0 -22
  238. package/src/Day/types.ts +0 -15
  239. package/src/GiftedAvatar.tsx +0 -187
  240. package/src/GiftedChat/index.tsx +0 -420
  241. package/src/GiftedChat/styles.ts +0 -10
  242. package/src/GiftedChat/types.ts +0 -156
  243. package/src/GiftedChatContext.ts +0 -25
  244. package/src/InputToolbar.tsx +0 -177
  245. package/src/LoadEarlierMessages.tsx +0 -94
  246. package/src/Message/index.tsx +0 -273
  247. package/src/Message/styles.ts +0 -18
  248. package/src/Message/types.ts +0 -26
  249. package/src/MessageAudio.tsx +0 -29
  250. package/src/MessageImage.tsx +0 -251
  251. package/src/MessageReply.tsx +0 -160
  252. package/src/MessageText.tsx +0 -111
  253. package/src/MessageVideo.tsx +0 -29
  254. package/src/MessagesContainer/components/DayAnimated/index.tsx +0 -151
  255. package/src/MessagesContainer/components/DayAnimated/styles.ts +0 -12
  256. package/src/MessagesContainer/components/DayAnimated/types.ts +0 -12
  257. package/src/MessagesContainer/components/Item/index.tsx +0 -197
  258. package/src/MessagesContainer/components/Item/types.ts +0 -13
  259. package/src/MessagesContainer/index.tsx +0 -434
  260. package/src/MessagesContainer/styles.ts +0 -42
  261. package/src/MessagesContainer/types.ts +0 -102
  262. package/src/Models.ts +0 -66
  263. package/src/QuickReplies.tsx +0 -181
  264. package/src/Reply/index.ts +0 -1
  265. package/src/Reply/types.ts +0 -80
  266. package/src/ReplyPreview.tsx +0 -132
  267. package/src/Send.tsx +0 -115
  268. package/src/SystemMessage.tsx +0 -79
  269. package/src/Time.tsx +0 -64
  270. package/src/TypingIndicator/index.tsx +0 -155
  271. package/src/TypingIndicator/styles.ts +0 -22
  272. package/src/TypingIndicator/types.ts +0 -6
  273. package/src/__tests__/Actions.test.tsx +0 -9
  274. package/src/__tests__/Avatar.test.tsx +0 -17
  275. package/src/__tests__/Bubble.test.tsx +0 -17
  276. package/src/__tests__/Color.test.tsx +0 -5
  277. package/src/__tests__/Composer.test.tsx +0 -10
  278. package/src/__tests__/Constant.test.tsx +0 -5
  279. package/src/__tests__/Day.test.tsx +0 -20
  280. package/src/__tests__/DayAnimated.test.tsx +0 -46
  281. package/src/__tests__/GiftedAvatar.test.tsx +0 -10
  282. package/src/__tests__/GiftedChat.test.tsx +0 -60
  283. package/src/__tests__/InputToolbar.test.tsx +0 -10
  284. package/src/__tests__/LoadEarlier.test.tsx +0 -10
  285. package/src/__tests__/Message.test.tsx +0 -67
  286. package/src/__tests__/MessageImage.test.tsx +0 -24
  287. package/src/__tests__/MessageReply.test.tsx +0 -54
  288. package/src/__tests__/MessageText.test.tsx +0 -15
  289. package/src/__tests__/MessagesContainer.test.tsx +0 -38
  290. package/src/__tests__/ReplyPreview.test.tsx +0 -41
  291. package/src/__tests__/Send.test.tsx +0 -21
  292. package/src/__tests__/SystemMessage.test.tsx +0 -24
  293. package/src/__tests__/Time.test.tsx +0 -26
  294. package/src/__tests__/__snapshots__/Actions.test.tsx.snap +0 -40
  295. package/src/__tests__/__snapshots__/Avatar.test.tsx.snap +0 -17
  296. package/src/__tests__/__snapshots__/Bubble.test.tsx.snap +0 -121
  297. package/src/__tests__/__snapshots__/Color.test.tsx.snap +0 -21
  298. package/src/__tests__/__snapshots__/Composer.test.tsx.snap +0 -51
  299. package/src/__tests__/__snapshots__/Constant.test.tsx.snap +0 -13
  300. package/src/__tests__/__snapshots__/Day.test.tsx.snap +0 -99
  301. package/src/__tests__/__snapshots__/DayAnimated.test.tsx.snap +0 -5
  302. package/src/__tests__/__snapshots__/GiftedAvatar.test.tsx.snap +0 -24
  303. package/src/__tests__/__snapshots__/GiftedChat.test.tsx.snap +0 -169
  304. package/src/__tests__/__snapshots__/InputToolbar.test.tsx.snap +0 -145
  305. package/src/__tests__/__snapshots__/LoadEarlier.test.tsx.snap +0 -33
  306. package/src/__tests__/__snapshots__/Message.test.tsx.snap +0 -510
  307. package/src/__tests__/__snapshots__/MessageImage.test.tsx.snap +0 -293
  308. package/src/__tests__/__snapshots__/MessageReply.test.tsx.snap +0 -181
  309. package/src/__tests__/__snapshots__/MessageText.test.tsx.snap +0 -29
  310. package/src/__tests__/__snapshots__/ReplyPreview.test.tsx.snap +0 -403
  311. package/src/__tests__/__snapshots__/Send.test.tsx.snap +0 -214
  312. package/src/__tests__/__snapshots__/SystemMessage.test.tsx.snap +0 -77
  313. package/src/__tests__/__snapshots__/Time.test.tsx.snap +0 -22
  314. package/src/__tests__/data.ts +0 -8
  315. package/src/__tests__/utils.test.ts +0 -31
  316. package/src/components/MessageReply.tsx +0 -156
  317. package/src/components/ReplyPreview.tsx +0 -230
  318. package/src/components/TouchableOpacity.tsx +0 -67
  319. package/src/hooks/useColorScheme.ts +0 -18
  320. package/src/hooks/useUpdateLayoutEffect.ts +0 -21
  321. package/src/index.ts +0 -29
  322. package/src/linkParser.tsx +0 -255
  323. package/src/logging.ts +0 -8
  324. package/src/styles.ts +0 -25
  325. package/src/types.ts +0 -25
  326. package/src/utils.ts +0 -134
@@ -1,434 +0,0 @@
1
- import React, { useCallback, useEffect, useMemo, useState } from 'react'
2
- import {
3
- View,
4
- LayoutChangeEvent,
5
- ListRenderItemInfo,
6
- CellRendererProps,
7
- } from 'react-native'
8
- import { Pressable, Text } from 'react-native-gesture-handler'
9
- import Animated, { runOnJS, ScrollEvent, useAnimatedScrollHandler, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated'
10
- import { LoadEarlierMessages } from '../LoadEarlierMessages'
11
- import { warning } from '../logging'
12
- import { IMessage } from '../Models'
13
- import stylesCommon from '../styles'
14
- import { TypingIndicator } from '../TypingIndicator'
15
- import { isSameDay, useCallbackThrottled } from '../utils'
16
- import { DayAnimated } from './components/DayAnimated'
17
-
18
- import { Item } from './components/Item'
19
- import { ItemProps } from './components/Item/types'
20
- import styles from './styles'
21
- import { MessagesContainerProps, DaysPositions, AnimatedFlatList } from './types'
22
-
23
- export * from './types'
24
-
25
- export const MessagesContainer = <TMessage extends IMessage>(props: MessagesContainerProps<TMessage>) => {
26
- const {
27
- messages = [],
28
- user,
29
- isTyping = false,
30
- renderChatEmpty: renderChatEmptyProp,
31
- isInverted = true,
32
- listProps,
33
- isScrollToBottomEnabled = false,
34
- scrollToBottomOffset = 200,
35
- isAlignedTop = false,
36
- scrollToBottomStyle,
37
- scrollToBottomContentStyle,
38
- loadEarlierMessagesProps,
39
- renderTypingIndicator: renderTypingIndicatorProp,
40
- renderFooter: renderFooterProp,
41
- renderLoadEarlier: renderLoadEarlierProp,
42
- forwardRef,
43
- scrollToBottomComponent: scrollToBottomComponentProp,
44
- renderDay: renderDayProp,
45
- isDayAnimationEnabled = true,
46
- } = props
47
-
48
- const listPropsOnScrollProp = listProps?.onScroll
49
-
50
- const scrollToBottomOpacity = useSharedValue(0)
51
- const isScrollingDown = useSharedValue(false)
52
- const lastScrolledY = useSharedValue(0)
53
- const [isScrollToBottomVisible, setIsScrollToBottomVisible] = useState(false)
54
- const scrollToBottomStyleAnim = useAnimatedStyle(() => ({
55
- opacity: scrollToBottomOpacity.value,
56
- }), [scrollToBottomOpacity])
57
-
58
- const daysPositions = useSharedValue<DaysPositions>({})
59
- const listHeight = useSharedValue(0)
60
- const scrolledY = useSharedValue(0)
61
-
62
- const renderTypingIndicator = useCallback(() => {
63
- if (renderTypingIndicatorProp)
64
- return renderTypingIndicatorProp()
65
-
66
- return <TypingIndicator isTyping={isTyping} style={props.typingIndicatorStyle} />
67
- }, [isTyping, renderTypingIndicatorProp, props.typingIndicatorStyle])
68
-
69
- const ListFooterComponent = useMemo(() => {
70
- if (renderFooterProp)
71
- return renderFooterProp(props)
72
-
73
- return renderTypingIndicator()
74
- }, [renderFooterProp, renderTypingIndicator, props])
75
-
76
- const renderLoadEarlier = useCallback(() => {
77
- if (loadEarlierMessagesProps?.isAvailable) {
78
- if (renderLoadEarlierProp)
79
- return renderLoadEarlierProp(loadEarlierMessagesProps)
80
-
81
- return <LoadEarlierMessages {...loadEarlierMessagesProps} />
82
- }
83
-
84
- return null
85
- }, [loadEarlierMessagesProps, renderLoadEarlierProp])
86
-
87
- const changeScrollToBottomVisibility: (isVisible: boolean) => void = useCallbackThrottled((isVisible: boolean) => {
88
- if (isScrollingDown.value && isVisible)
89
- return
90
-
91
- if (isVisible)
92
- setIsScrollToBottomVisible(true)
93
-
94
- scrollToBottomOpacity.value = withTiming(isVisible ? 1 : 0, { duration: 250 }, isFinished => {
95
- if (isFinished && !isVisible)
96
- runOnJS(setIsScrollToBottomVisible)(false)
97
- })
98
- }, [scrollToBottomOpacity, isScrollingDown], 50)
99
-
100
- const scrollTo = useCallback((options: { animated?: boolean, offset: number }) => {
101
- if (options)
102
- forwardRef?.current?.scrollToOffset(options)
103
- }, [forwardRef])
104
-
105
- const doScrollToBottom = useCallback((animated: boolean = true) => {
106
- isScrollingDown.value = true
107
- changeScrollToBottomVisibility(false)
108
-
109
- if (isInverted)
110
- scrollTo({ offset: 0, animated })
111
- else if (forwardRef?.current)
112
- forwardRef.current.scrollToEnd({ animated })
113
- }, [forwardRef, isInverted, scrollTo, isScrollingDown, changeScrollToBottomVisibility])
114
-
115
- const handleOnScroll = useCallback((event: ScrollEvent) => {
116
- listPropsOnScrollProp?.(event)
117
-
118
- const {
119
- contentOffset: { y: contentOffsetY },
120
- contentSize: { height: contentSizeHeight },
121
- layoutMeasurement: { height: layoutMeasurementHeight },
122
- } = event
123
-
124
- isScrollingDown.value =
125
- (isInverted && lastScrolledY.value > contentOffsetY) ||
126
- (!isInverted && lastScrolledY.value < contentOffsetY)
127
-
128
- lastScrolledY.value = contentOffsetY
129
-
130
- if (isInverted)
131
- if (contentOffsetY > scrollToBottomOffset!)
132
- changeScrollToBottomVisibility(true)
133
- else
134
- changeScrollToBottomVisibility(false)
135
- else if (
136
- contentOffsetY < scrollToBottomOffset! &&
137
- contentSizeHeight - layoutMeasurementHeight > scrollToBottomOffset!
138
- )
139
- changeScrollToBottomVisibility(false)
140
- else
141
- changeScrollToBottomVisibility(false)
142
- }, [isInverted, scrollToBottomOffset, changeScrollToBottomVisibility, isScrollingDown, lastScrolledY, listPropsOnScrollProp])
143
-
144
- const restProps = useMemo(() => {
145
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
146
- const { messages: _, ...rest } = props
147
- return rest
148
- }, [props])
149
-
150
- const renderItem = useCallback(({ item, index }: ListRenderItemInfo<unknown>): React.ReactElement | null => {
151
- const messageItem = item as TMessage
152
-
153
- if (!messageItem._id && messageItem._id !== 0)
154
- warning('GiftedChat: `_id` is missing for message', JSON.stringify(item))
155
-
156
- if (!messageItem.user) {
157
- if (!messageItem.system)
158
- warning(
159
- 'GiftedChat: `user` is missing for message',
160
- JSON.stringify(messageItem)
161
- )
162
-
163
- messageItem.user = { _id: 0 }
164
- }
165
-
166
- if (messages) {
167
- const previousMessage =
168
- (isInverted ? messages[index + 1] : messages[index - 1]) || {}
169
- const nextMessage =
170
- (isInverted ? messages[index - 1] : messages[index + 1]) || {}
171
-
172
- const messageProps: ItemProps<TMessage> = {
173
- position: user?._id != null && messageItem.user?._id === user._id ? 'right' : 'left',
174
- ...restProps,
175
- currentMessage: messageItem,
176
- previousMessage,
177
- nextMessage,
178
- scrolledY,
179
- daysPositions,
180
- listHeight,
181
- isDayAnimationEnabled,
182
- }
183
-
184
- return (
185
- <Item<TMessage> {...messageProps} />
186
- )
187
- }
188
-
189
- return null
190
- }, [messages, restProps, isInverted, scrolledY, daysPositions, listHeight, isDayAnimationEnabled, user])
191
-
192
- const emptyContent = useMemo(() => {
193
- if (!renderChatEmptyProp)
194
- return null
195
-
196
- return renderChatEmptyProp()
197
- }, [renderChatEmptyProp])
198
-
199
- const renderChatEmpty = useCallback(() => {
200
- if (renderChatEmptyProp)
201
- return isInverted
202
- ? (
203
- emptyContent
204
- )
205
- : (
206
- <View style={[stylesCommon.fill, styles.emptyChatContainer]}>
207
- {emptyContent}
208
- </View>
209
- )
210
-
211
- return <View style={stylesCommon.fill} />
212
- }, [isInverted, renderChatEmptyProp, emptyContent])
213
-
214
- const ListHeaderComponent = useMemo(() => {
215
- const content = renderLoadEarlier()
216
-
217
- if (!content)
218
- return null
219
-
220
- return (
221
- <View style={stylesCommon.fill}>{content}</View>
222
- )
223
- }, [renderLoadEarlier])
224
-
225
- const renderScrollBottomComponent = useCallback(() => {
226
- if (scrollToBottomComponentProp)
227
- return scrollToBottomComponentProp()
228
-
229
- return <Text>{'V'}</Text>
230
- }, [scrollToBottomComponentProp])
231
-
232
- const handleScrollToBottomPress = useCallback(() => {
233
- doScrollToBottom()
234
- }, [doScrollToBottom])
235
-
236
- const scrollToBottomContent = useMemo(() => {
237
- return (
238
- <Animated.View
239
- style={[
240
- stylesCommon.centerItems,
241
- styles.scrollToBottomContent,
242
- scrollToBottomContentStyle,
243
- scrollToBottomStyleAnim,
244
- ]}
245
- >
246
- {renderScrollBottomComponent()}
247
- </Animated.View>
248
- )
249
- }, [scrollToBottomStyleAnim, scrollToBottomContentStyle, renderScrollBottomComponent])
250
-
251
- const ScrollToBottomWrapper = useCallback(() => {
252
- if (!isScrollToBottomEnabled)
253
- return null
254
-
255
- if (!isScrollToBottomVisible)
256
- return null
257
-
258
- return (
259
- <Pressable
260
- style={[styles.scrollToBottom, scrollToBottomStyle]}
261
- onPress={handleScrollToBottomPress}
262
- >
263
- {scrollToBottomContent}
264
- </Pressable>
265
- )
266
- }, [isScrollToBottomEnabled, isScrollToBottomVisible, handleScrollToBottomPress, scrollToBottomContent, scrollToBottomStyle])
267
-
268
- const onLayoutList = useCallback((event: LayoutChangeEvent) => {
269
- listHeight.value = event.nativeEvent.layout.height
270
-
271
- if (
272
- !isInverted &&
273
- messages?.length &&
274
- isScrollToBottomEnabled
275
- )
276
- setTimeout(() => {
277
- doScrollToBottom(false)
278
- }, 500)
279
-
280
- // listProps.onLayout may be a SharedValue in Reanimated types, but we only accept functions
281
- const onLayoutProp = listProps?.onLayout as ((event: LayoutChangeEvent) => void) | undefined
282
- onLayoutProp?.(event)
283
- }, [isInverted, messages, doScrollToBottom, listHeight, listProps, isScrollToBottomEnabled])
284
-
285
- const onEndReached = useCallback(() => {
286
- if (
287
- loadEarlierMessagesProps &&
288
- loadEarlierMessagesProps.isAvailable &&
289
- loadEarlierMessagesProps.isInfiniteScrollEnabled &&
290
- !loadEarlierMessagesProps.isLoading
291
- )
292
- loadEarlierMessagesProps.onPress()
293
- }, [loadEarlierMessagesProps])
294
-
295
- const keyExtractor = useCallback((item: unknown) => (item as TMessage)._id.toString(), [])
296
-
297
- const renderCell = useCallback((props: CellRendererProps<unknown>) => {
298
- const { item, onLayout: onLayoutProp, children } = props
299
- const id = (item as IMessage)._id.toString()
300
-
301
- const handleOnLayout = (event: LayoutChangeEvent) => {
302
- onLayoutProp?.(event)
303
-
304
- // Only track positions when day animation is enabled
305
- if (!isDayAnimationEnabled)
306
- return
307
-
308
- const { y, height } = event.nativeEvent.layout
309
-
310
- const newValue = {
311
- y,
312
- height,
313
- createdAt: new Date((item as IMessage).createdAt).getTime(),
314
- }
315
-
316
- daysPositions.modify(value => {
317
- 'worklet'
318
-
319
- const isSameDay = (date1: number, date2: number) => {
320
- const d1 = new Date(date1)
321
- const d2 = new Date(date2)
322
-
323
- return (
324
- d1.getDate() === d2.getDate() &&
325
- d1.getMonth() === d2.getMonth() &&
326
- d1.getFullYear() === d2.getFullYear()
327
- )
328
- }
329
-
330
- for (const [key, item] of Object.entries(value))
331
- if (isSameDay(newValue.createdAt, item.createdAt) && (isInverted ? item.y <= newValue.y : item.y >= newValue.y)) {
332
- delete value[key]
333
- break
334
- }
335
-
336
- // @ts-expect-error: https://docs.swmansion.com/react-native-reanimated/docs/core/useSharedValue#remarks
337
- value[id] = newValue
338
- return value
339
- })
340
- }
341
-
342
- return (
343
- <View
344
- {...props}
345
- onLayout={handleOnLayout}
346
- >
347
- {children}
348
- </View>
349
- )
350
- }, [daysPositions, isInverted, isDayAnimationEnabled])
351
-
352
- const scrollHandler = useAnimatedScrollHandler({
353
- onScroll: event => {
354
- scrolledY.value = event.contentOffset.y
355
-
356
- runOnJS(handleOnScroll)(event)
357
- },
358
- }, [handleOnScroll])
359
-
360
- // removes unrendered days positions when messages are added/removed
361
- useEffect(() => {
362
- // Skip cleanup when day animation is disabled
363
- if (!isDayAnimationEnabled)
364
- return
365
-
366
- Object.keys(daysPositions.value).forEach(key => {
367
- const messageIndex = messages.findIndex(m => m._id.toString() === key)
368
- let shouldRemove = messageIndex === -1
369
-
370
- if (!shouldRemove) {
371
- const prevMessage = messages[messageIndex + (isInverted ? 1 : -1)]
372
- const message = messages[messageIndex]
373
- shouldRemove = !!prevMessage && isSameDay(message, prevMessage)
374
- }
375
-
376
- if (shouldRemove)
377
- daysPositions.modify(value => {
378
- 'worklet'
379
-
380
- delete value[key]
381
- return value
382
- })
383
- })
384
- }, [messages, daysPositions, isInverted, isDayAnimationEnabled])
385
-
386
- return (
387
- <View
388
- style={[
389
- styles.contentContainerStyle,
390
- isAlignedTop ? styles.containerAlignTop : stylesCommon.fill,
391
- ]}
392
- >
393
- <AnimatedFlatList
394
- ref={forwardRef}
395
- keyExtractor={keyExtractor}
396
- data={messages}
397
- renderItem={renderItem}
398
- inverted={isInverted}
399
- automaticallyAdjustContentInsets={false}
400
- style={stylesCommon.fill}
401
- contentContainerStyle={styles.messagesContainer}
402
- ListEmptyComponent={renderChatEmpty}
403
- ListFooterComponent={
404
- isInverted ? ListHeaderComponent : <>{ListFooterComponent}</>
405
- }
406
- ListHeaderComponent={
407
- isInverted ? <>{ListFooterComponent}</> : ListHeaderComponent
408
- }
409
- scrollEventThrottle={1}
410
- onEndReached={onEndReached}
411
- onEndReachedThreshold={0.1}
412
- keyboardDismissMode='interactive'
413
- keyboardShouldPersistTaps='handled'
414
- {...listProps}
415
- onScroll={scrollHandler}
416
- onLayout={onLayoutList}
417
- CellRendererComponent={renderCell}
418
- />
419
- <ScrollToBottomWrapper />
420
- {isDayAnimationEnabled && (
421
- <DayAnimated
422
- scrolledY={scrolledY}
423
- daysPositions={daysPositions}
424
- listHeight={listHeight}
425
- renderDay={renderDayProp}
426
- messages={messages}
427
- isLoading={loadEarlierMessagesProps?.isLoading ?? false}
428
- dateFormat={props.dateFormat}
429
- dateFormatCalendar={props.dateFormatCalendar}
430
- />
431
- )}
432
- </View>
433
- )
434
- }
@@ -1,42 +0,0 @@
1
- import { Platform, StyleSheet } from 'react-native'
2
- import { Color } from '../Color'
3
-
4
- export default StyleSheet.create({
5
- containerAlignTop: {
6
- flexDirection: 'row',
7
- alignItems: 'flex-start',
8
- },
9
- contentContainerStyle: {
10
- flexGrow: 1,
11
- justifyContent: 'flex-start',
12
- },
13
- messagesContainer: {
14
- paddingBottom: 10,
15
- },
16
- emptyChatContainer: {
17
- transform: [{ scaleY: -1 }],
18
- },
19
- scrollToBottom: {
20
- position: 'absolute',
21
- right: 10,
22
- bottom: 30,
23
- zIndex: 999,
24
- },
25
- scrollToBottomContent: {
26
- height: 40,
27
- width: 40,
28
- borderRadius: 20,
29
- backgroundColor: Color.white,
30
- ...Platform.select({
31
- ios: {
32
- shadowColor: Color.black,
33
- shadowOpacity: 0.5,
34
- shadowOffset: { width: 0, height: 0 },
35
- shadowRadius: 1,
36
- },
37
- android: {
38
- elevation: 5,
39
- },
40
- }),
41
- },
42
- })
@@ -1,102 +0,0 @@
1
- import { RefObject } from 'react'
2
- import {
3
- FlatListProps,
4
- StyleProp,
5
- ViewStyle,
6
- } from 'react-native'
7
- import { FlatList } from 'react-native-gesture-handler'
8
- import Animated, { ScrollEvent } from 'react-native-reanimated'
9
-
10
- import { DayProps } from '../Day'
11
- import { LoadEarlierMessagesProps } from '../LoadEarlierMessages'
12
- import { MessageProps } from '../Message'
13
- import { User, IMessage, Reply } from '../Models'
14
- import { ReplyProps } from '../Reply'
15
- import { TypingIndicatorProps } from '../TypingIndicator/types'
16
-
17
- /** Animated FlatList created from react-native-gesture-handler's FlatList */
18
- const RNGHAnimatedFlatList = Animated.createAnimatedComponent(FlatList)
19
-
20
- /**
21
- * Typed AnimatedFlatList component that preserves generic type parameter.
22
- * Uses react-native-gesture-handler's FlatList which respects keyboardShouldPersistTaps.
23
- */
24
- export const AnimatedFlatList = RNGHAnimatedFlatList as <TMessage>(
25
- props: FlatListProps<TMessage> & {
26
- ref?: RefObject<FlatList<TMessage>>
27
- }
28
- ) => React.ReactElement
29
-
30
- export type AnimatedListProps<TMessage extends IMessage = IMessage> = Partial<
31
- Omit<FlatListProps<TMessage>, 'onScroll'> & {
32
- onScroll?: (event: ScrollEvent) => void
33
- }
34
- >
35
-
36
- export type AnimatedList<TMessage> = FlatList<TMessage>
37
-
38
- export interface MessagesContainerProps<TMessage extends IMessage = IMessage>
39
- extends Omit<TypingIndicatorProps, 'style'> {
40
- /** Ref for the FlatList message container */
41
- forwardRef?: RefObject<AnimatedList<TMessage>>
42
- /** Messages to display */
43
- messages?: TMessage[]
44
- /** Format to use for rendering dates; default is 'll' */
45
- dateFormat?: string
46
- /** Format to use for rendering relative times */
47
- dateFormatCalendar?: object
48
- /** User sending the messages: { _id, name, avatar } */
49
- user?: User
50
- /** Additional props for FlatList */
51
- listProps?: AnimatedListProps<TMessage>
52
- /** Reverses display order of messages; default is true */
53
- isInverted?: boolean
54
- /** Controls whether or not the message bubbles appear at the top of the chat */
55
- isAlignedTop?: boolean
56
- /** Enables the isScrollToBottomEnabled Component */
57
- isScrollToBottomEnabled?: boolean
58
- /** Scroll to bottom wrapper style */
59
- scrollToBottomStyle?: StyleProp<ViewStyle>
60
- /** Scroll to bottom content style */
61
- scrollToBottomContentStyle?: StyleProp<ViewStyle>
62
- /** Distance from bottom before showing scroll to bottom button */
63
- scrollToBottomOffset?: number
64
- /** Custom component to render when messages are empty */
65
- renderChatEmpty?: () => React.ReactNode
66
- /** Custom footer component on the ListView, e.g. 'User is typing...' */
67
- renderFooter?: (props: MessagesContainerProps<TMessage>) => React.ReactNode
68
- /** Custom message container */
69
- renderMessage?: (props: MessageProps<TMessage>) => React.ReactElement
70
- /** Custom day above a message */
71
- renderDay?: (props: DayProps) => React.ReactNode
72
- /** Custom "Load earlier messages" button */
73
- renderLoadEarlier?: (props: LoadEarlierMessagesProps) => React.ReactNode
74
- /** Custom typing indicator */
75
- renderTypingIndicator?: () => React.ReactNode
76
- /** Scroll to bottom custom component */
77
- scrollToBottomComponent?: () => React.ReactNode
78
- /** Callback when quick reply is sent */
79
- onQuickReply?: (replies: Reply[]) => void
80
- /** Props to pass to the LoadEarlierMessages component. The LoadEarlierMessages button is only visible when isAvailable is true. Includes isAvailable (controls button visibility), isInfiniteScrollEnabled (infinite scroll up when reach the top of messages container, automatically call onPress function if it exists - not yet supported for web), onPress (callback when button is pressed), isLoading (display loading indicator), label (override default "Load earlier messages" text), and styling props (containerStyle, wrapperStyle, textStyle, activityIndicatorStyle, activityIndicatorColor, activityIndicatorSize). */
81
- loadEarlierMessagesProps?: LoadEarlierMessagesProps
82
- /** Style for TypingIndicator component */
83
- typingIndicatorStyle?: StyleProp<ViewStyle>
84
- /** Enable animated day label that appears on scroll; default is true */
85
- isDayAnimationEnabled?: boolean
86
- /** Reply functionality configuration */
87
- reply?: ReplyProps<TMessage>
88
- }
89
-
90
- export interface State {
91
- showScrollBottom: boolean
92
- hasScrolled: boolean
93
- }
94
-
95
- interface ViewLayout {
96
- x: number
97
- y: number
98
- width: number
99
- height: number
100
- }
101
-
102
- export type DaysPositions = { [key: string]: ViewLayout & { createdAt: number } }
package/src/Models.ts DELETED
@@ -1,66 +0,0 @@
1
- import { StyleProp, ViewStyle } from 'react-native'
2
-
3
- export type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
4
-
5
- export interface LeftRightStyle<T> {
6
- left?: StyleProp<T>
7
- right?: StyleProp<T>
8
- }
9
-
10
- type renderFunction = (x: unknown) => React.ReactNode
11
-
12
- export interface User {
13
- _id: string | number
14
- name?: string
15
- avatar?: string | number | renderFunction
16
- }
17
-
18
- export interface Reply {
19
- title: string
20
- value: string
21
- messageId?: number | string
22
- }
23
-
24
- export interface QuickReplies {
25
- type: 'radio' | 'checkbox'
26
- values: Reply[]
27
- keepIt?: boolean
28
- }
29
-
30
- export interface ReplyMessage extends Pick<IMessage, '_id' | 'text' | 'user' | 'audio' | 'image'> {}
31
-
32
- export interface IMessage {
33
- _id: string | number
34
- text: string
35
- createdAt: Date | number
36
- user: User
37
- image?: string
38
- video?: string
39
- audio?: string
40
- system?: boolean
41
- sent?: boolean
42
- received?: boolean
43
- pending?: boolean
44
- quickReplies?: QuickReplies
45
- replyMessage?: ReplyMessage
46
- location?: {
47
- latitude: number
48
- longitude: number
49
- }
50
- }
51
-
52
- export type IChatMessage = IMessage
53
-
54
- export interface MessageVideoProps<TMessage extends IMessage> {
55
- currentMessage: TMessage
56
- containerStyle?: StyleProp<ViewStyle>
57
- videoStyle?: StyleProp<ViewStyle>
58
- videoProps?: object
59
- }
60
-
61
- export interface MessageAudioProps<TMessage extends IMessage> {
62
- currentMessage: TMessage
63
- containerStyle?: StyleProp<ViewStyle>
64
- audioStyle?: StyleProp<ViewStyle>
65
- audioProps?: object
66
- }