stream-chat-react-native-core 7.0.0-rc.8 → 7.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 (498) hide show
  1. package/README.md +1 -1
  2. package/lib/commonjs/components/Attachment/AudioAttachment.js +19 -9
  3. package/lib/commonjs/components/Attachment/AudioAttachment.js.map +1 -1
  4. package/lib/commonjs/components/Attachment/FileAttachmentGroup.js +3 -1
  5. package/lib/commonjs/components/Attachment/FileAttachmentGroup.js.map +1 -1
  6. package/lib/commonjs/components/Attachment/Gallery.js +16 -3
  7. package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
  8. package/lib/commonjs/components/Attachment/ImageReloadIndicator.js.map +1 -1
  9. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js +2 -2
  10. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  11. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerItem.js +7 -24
  12. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerItem.js.map +1 -1
  13. package/lib/commonjs/components/AutoCompleteInput/AutoCompleteInput.js +2 -4
  14. package/lib/commonjs/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
  15. package/lib/commonjs/components/Channel/Channel.js +320 -310
  16. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  17. package/lib/commonjs/components/Channel/hooks/useChannelDataState.js.map +1 -1
  18. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +2 -0
  19. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  20. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js +133 -147
  21. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js.map +1 -1
  22. package/lib/commonjs/components/Chat/Chat.js.map +1 -1
  23. package/lib/commonjs/components/KeyboardCompatibleView/KeyboardCompatibleView.js +8 -13
  24. package/lib/commonjs/components/KeyboardCompatibleView/KeyboardCompatibleView.js.map +1 -1
  25. package/lib/commonjs/components/Message/Message.js +14 -7
  26. package/lib/commonjs/components/Message/Message.js.map +1 -1
  27. package/lib/commonjs/components/Message/MessageSimple/MessageFooter.js.map +1 -1
  28. package/lib/commonjs/components/Message/MessageSimple/MessageSimple.js +70 -54
  29. package/lib/commonjs/components/Message/MessageSimple/MessageSimple.js.map +1 -1
  30. package/lib/commonjs/components/Message/MessageSimple/MessageStatus.js +14 -6
  31. package/lib/commonjs/components/Message/MessageSimple/MessageStatus.js.map +1 -1
  32. package/lib/commonjs/components/Message/MessageSimple/MessageTextContainer.js.map +1 -1
  33. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  34. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js +3 -1
  35. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  36. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  37. package/lib/commonjs/components/Message/hooks/useMessageActions.js.map +1 -1
  38. package/lib/commonjs/components/MessageInput/FileUploadPreview.js +25 -39
  39. package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
  40. package/lib/commonjs/components/MessageInput/InputButtons.js +18 -15
  41. package/lib/commonjs/components/MessageInput/InputButtons.js.map +1 -1
  42. package/lib/commonjs/components/MessageInput/MessageInput.js +96 -74
  43. package/lib/commonjs/components/MessageInput/MessageInput.js.map +1 -1
  44. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js +2 -1
  45. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js.map +1 -1
  46. package/lib/commonjs/components/MessageInput/hooks/useAudioController.js +4 -4
  47. package/lib/commonjs/components/MessageInput/hooks/useAudioController.js.map +1 -1
  48. package/lib/commonjs/components/MessageList/MessageList.js +281 -223
  49. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  50. package/lib/commonjs/components/MessageList/hooks/useMessageList.js +65 -48
  51. package/lib/commonjs/components/MessageList/hooks/useMessageList.js.map +1 -1
  52. package/lib/commonjs/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.js.map +1 -1
  53. package/lib/commonjs/components/MessageList/utils/getGroupStyles.js +1 -1
  54. package/lib/commonjs/components/MessageList/utils/getGroupStyles.js.map +1 -1
  55. package/lib/commonjs/components/MessageList/utils/getLastReceivedMessage.js.map +1 -1
  56. package/lib/commonjs/components/MessageList/utils/getReadState.js +20 -0
  57. package/lib/commonjs/components/MessageList/utils/getReadState.js.map +1 -0
  58. package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
  59. package/lib/commonjs/components/Poll/components/Button.js.map +1 -1
  60. package/lib/commonjs/components/Poll/components/PollResults/PollResultItem.js.map +1 -1
  61. package/lib/commonjs/components/Reply/Reply.js +2 -2
  62. package/lib/commonjs/components/Reply/Reply.js.map +1 -1
  63. package/lib/commonjs/components/Thread/components/ThreadFooterComponent.js +24 -6
  64. package/lib/commonjs/components/Thread/components/ThreadFooterComponent.js.map +1 -1
  65. package/lib/commonjs/components/ThreadList/ThreadListItem.js.map +1 -1
  66. package/lib/commonjs/components/UIComponents/BottomSheetModal.js +10 -6
  67. package/lib/commonjs/components/UIComponents/BottomSheetModal.js.map +1 -1
  68. package/lib/commonjs/components/index.js +15 -4
  69. package/lib/commonjs/components/index.js.map +1 -1
  70. package/lib/commonjs/contexts/attachmentPickerContext/AttachmentPickerContext.js.map +1 -1
  71. package/lib/commonjs/contexts/channelsStateContext/useChannelState.js +5 -1
  72. package/lib/commonjs/contexts/channelsStateContext/useChannelState.js.map +1 -1
  73. package/lib/commonjs/contexts/debugContext/DebugContext.js.map +1 -1
  74. package/lib/commonjs/contexts/imageGalleryContext/ImageGalleryContext.js.map +1 -1
  75. package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
  76. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +535 -523
  77. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  78. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +7 -6
  79. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  80. package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js +37 -41
  81. package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  82. package/lib/commonjs/contexts/messageInputContext/utils/utils.js +4 -4
  83. package/lib/commonjs/contexts/messageInputContext/utils/utils.js.map +1 -1
  84. package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
  85. package/lib/commonjs/contexts/pollContext/pollContext.js.map +1 -1
  86. package/lib/commonjs/contexts/suggestionsContext/SuggestionsContext.js +23 -14
  87. package/lib/commonjs/contexts/suggestionsContext/SuggestionsContext.js.map +1 -1
  88. package/lib/commonjs/contexts/themeContext/utils/theme.js +2 -1
  89. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  90. package/lib/commonjs/contexts/threadContext/ThreadContext.js.map +1 -1
  91. package/lib/commonjs/contexts/threadsContext/ThreadListItemContext.js.map +1 -1
  92. package/lib/commonjs/hooks/index.js +22 -0
  93. package/lib/commonjs/hooks/index.js.map +1 -1
  94. package/lib/commonjs/hooks/useAudioPlayer.js +60 -69
  95. package/lib/commonjs/hooks/useAudioPlayer.js.map +1 -1
  96. package/lib/commonjs/hooks/useStableCallback.js +13 -0
  97. package/lib/commonjs/hooks/useStableCallback.js.map +1 -0
  98. package/lib/commonjs/hooks/useTranslatedMessage.js.map +1 -1
  99. package/lib/commonjs/i18n/en.json +3 -0
  100. package/lib/commonjs/i18n/es.json +3 -0
  101. package/lib/commonjs/i18n/fr.json +3 -0
  102. package/lib/commonjs/i18n/he.json +3 -0
  103. package/lib/commonjs/i18n/hi.json +2 -0
  104. package/lib/commonjs/i18n/it.json +3 -0
  105. package/lib/commonjs/i18n/ja.json +1 -0
  106. package/lib/commonjs/i18n/ko.json +1 -0
  107. package/lib/commonjs/i18n/nl.json +2 -0
  108. package/lib/commonjs/i18n/pt-br.json +3 -0
  109. package/lib/commonjs/i18n/ru.json +4 -0
  110. package/lib/commonjs/i18n/tr.json +2 -0
  111. package/lib/commonjs/mock-builders/api/channelMocks.js.map +1 -1
  112. package/lib/commonjs/native.js.map +1 -1
  113. package/lib/commonjs/store/mappers/mapMessageToStorable.js.map +1 -1
  114. package/lib/commonjs/types/types.js.map +1 -1
  115. package/lib/commonjs/utils/compressImage.js +1 -1
  116. package/lib/commonjs/utils/compressImage.js.map +1 -1
  117. package/lib/commonjs/utils/removeReservedFields.js.map +1 -1
  118. package/lib/commonjs/utils/utils.js +17 -4
  119. package/lib/commonjs/utils/utils.js.map +1 -1
  120. package/lib/commonjs/version.json +1 -1
  121. package/lib/module/components/Attachment/AudioAttachment.js +19 -9
  122. package/lib/module/components/Attachment/AudioAttachment.js.map +1 -1
  123. package/lib/module/components/Attachment/FileAttachmentGroup.js +3 -1
  124. package/lib/module/components/Attachment/FileAttachmentGroup.js.map +1 -1
  125. package/lib/module/components/Attachment/Gallery.js +16 -3
  126. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  127. package/lib/module/components/Attachment/ImageReloadIndicator.js.map +1 -1
  128. package/lib/module/components/AttachmentPicker/AttachmentPicker.js +2 -2
  129. package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  130. package/lib/module/components/AttachmentPicker/components/AttachmentPickerItem.js +7 -24
  131. package/lib/module/components/AttachmentPicker/components/AttachmentPickerItem.js.map +1 -1
  132. package/lib/module/components/AutoCompleteInput/AutoCompleteInput.js +2 -4
  133. package/lib/module/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
  134. package/lib/module/components/Channel/Channel.js +320 -310
  135. package/lib/module/components/Channel/Channel.js.map +1 -1
  136. package/lib/module/components/Channel/hooks/useChannelDataState.js.map +1 -1
  137. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +2 -0
  138. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  139. package/lib/module/components/Channel/hooks/useMessageListPagination.js +133 -147
  140. package/lib/module/components/Channel/hooks/useMessageListPagination.js.map +1 -1
  141. package/lib/module/components/Chat/Chat.js.map +1 -1
  142. package/lib/module/components/KeyboardCompatibleView/KeyboardCompatibleView.js +8 -13
  143. package/lib/module/components/KeyboardCompatibleView/KeyboardCompatibleView.js.map +1 -1
  144. package/lib/module/components/Message/Message.js +14 -7
  145. package/lib/module/components/Message/Message.js.map +1 -1
  146. package/lib/module/components/Message/MessageSimple/MessageFooter.js.map +1 -1
  147. package/lib/module/components/Message/MessageSimple/MessageSimple.js +70 -54
  148. package/lib/module/components/Message/MessageSimple/MessageSimple.js.map +1 -1
  149. package/lib/module/components/Message/MessageSimple/MessageStatus.js +14 -6
  150. package/lib/module/components/Message/MessageSimple/MessageStatus.js.map +1 -1
  151. package/lib/module/components/Message/MessageSimple/MessageTextContainer.js.map +1 -1
  152. package/lib/module/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  153. package/lib/module/components/Message/hooks/useCreateMessageContext.js +3 -1
  154. package/lib/module/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  155. package/lib/module/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  156. package/lib/module/components/Message/hooks/useMessageActions.js.map +1 -1
  157. package/lib/module/components/MessageInput/FileUploadPreview.js +25 -39
  158. package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
  159. package/lib/module/components/MessageInput/InputButtons.js +18 -15
  160. package/lib/module/components/MessageInput/InputButtons.js.map +1 -1
  161. package/lib/module/components/MessageInput/MessageInput.js +96 -74
  162. package/lib/module/components/MessageInput/MessageInput.js.map +1 -1
  163. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js +2 -1
  164. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js.map +1 -1
  165. package/lib/module/components/MessageInput/hooks/useAudioController.js +4 -4
  166. package/lib/module/components/MessageInput/hooks/useAudioController.js.map +1 -1
  167. package/lib/module/components/MessageList/MessageList.js +281 -223
  168. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  169. package/lib/module/components/MessageList/hooks/useMessageList.js +65 -48
  170. package/lib/module/components/MessageList/hooks/useMessageList.js.map +1 -1
  171. package/lib/module/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.js.map +1 -1
  172. package/lib/module/components/MessageList/utils/getGroupStyles.js +1 -1
  173. package/lib/module/components/MessageList/utils/getGroupStyles.js.map +1 -1
  174. package/lib/module/components/MessageList/utils/getLastReceivedMessage.js.map +1 -1
  175. package/lib/module/components/MessageList/utils/getReadState.js +20 -0
  176. package/lib/module/components/MessageList/utils/getReadState.js.map +1 -0
  177. package/lib/module/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
  178. package/lib/module/components/Poll/components/Button.js.map +1 -1
  179. package/lib/module/components/Poll/components/PollResults/PollResultItem.js.map +1 -1
  180. package/lib/module/components/Reply/Reply.js +2 -2
  181. package/lib/module/components/Reply/Reply.js.map +1 -1
  182. package/lib/module/components/Thread/components/ThreadFooterComponent.js +24 -6
  183. package/lib/module/components/Thread/components/ThreadFooterComponent.js.map +1 -1
  184. package/lib/module/components/ThreadList/ThreadListItem.js.map +1 -1
  185. package/lib/module/components/UIComponents/BottomSheetModal.js +10 -6
  186. package/lib/module/components/UIComponents/BottomSheetModal.js.map +1 -1
  187. package/lib/module/components/index.js +15 -4
  188. package/lib/module/components/index.js.map +1 -1
  189. package/lib/module/contexts/attachmentPickerContext/AttachmentPickerContext.js.map +1 -1
  190. package/lib/module/contexts/channelsStateContext/useChannelState.js +5 -1
  191. package/lib/module/contexts/channelsStateContext/useChannelState.js.map +1 -1
  192. package/lib/module/contexts/debugContext/DebugContext.js.map +1 -1
  193. package/lib/module/contexts/imageGalleryContext/ImageGalleryContext.js.map +1 -1
  194. package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
  195. package/lib/module/contexts/messageInputContext/MessageInputContext.js +535 -523
  196. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  197. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +7 -6
  198. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  199. package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js +37 -41
  200. package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  201. package/lib/module/contexts/messageInputContext/utils/utils.js +4 -4
  202. package/lib/module/contexts/messageInputContext/utils/utils.js.map +1 -1
  203. package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
  204. package/lib/module/contexts/pollContext/pollContext.js.map +1 -1
  205. package/lib/module/contexts/suggestionsContext/SuggestionsContext.js +23 -14
  206. package/lib/module/contexts/suggestionsContext/SuggestionsContext.js.map +1 -1
  207. package/lib/module/contexts/themeContext/utils/theme.js +2 -1
  208. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  209. package/lib/module/contexts/threadContext/ThreadContext.js.map +1 -1
  210. package/lib/module/contexts/threadsContext/ThreadListItemContext.js.map +1 -1
  211. package/lib/module/hooks/index.js +22 -0
  212. package/lib/module/hooks/index.js.map +1 -1
  213. package/lib/module/hooks/useAudioPlayer.js +60 -69
  214. package/lib/module/hooks/useAudioPlayer.js.map +1 -1
  215. package/lib/module/hooks/useStableCallback.js +13 -0
  216. package/lib/module/hooks/useStableCallback.js.map +1 -0
  217. package/lib/module/hooks/useTranslatedMessage.js.map +1 -1
  218. package/lib/module/i18n/en.json +3 -0
  219. package/lib/module/i18n/es.json +3 -0
  220. package/lib/module/i18n/fr.json +3 -0
  221. package/lib/module/i18n/he.json +3 -0
  222. package/lib/module/i18n/hi.json +2 -0
  223. package/lib/module/i18n/it.json +3 -0
  224. package/lib/module/i18n/ja.json +1 -0
  225. package/lib/module/i18n/ko.json +1 -0
  226. package/lib/module/i18n/nl.json +2 -0
  227. package/lib/module/i18n/pt-br.json +3 -0
  228. package/lib/module/i18n/ru.json +4 -0
  229. package/lib/module/i18n/tr.json +2 -0
  230. package/lib/module/mock-builders/api/channelMocks.js.map +1 -1
  231. package/lib/module/native.js.map +1 -1
  232. package/lib/module/store/mappers/mapMessageToStorable.js.map +1 -1
  233. package/lib/module/types/types.js.map +1 -1
  234. package/lib/module/utils/compressImage.js +1 -1
  235. package/lib/module/utils/compressImage.js.map +1 -1
  236. package/lib/module/utils/removeReservedFields.js.map +1 -1
  237. package/lib/module/utils/utils.js +17 -4
  238. package/lib/module/utils/utils.js.map +1 -1
  239. package/lib/module/version.json +1 -1
  240. package/lib/typescript/components/Attachment/AudioAttachment.d.ts +2 -2
  241. package/lib/typescript/components/Attachment/AudioAttachment.d.ts.map +1 -1
  242. package/lib/typescript/components/Attachment/FileAttachmentGroup.d.ts.map +1 -1
  243. package/lib/typescript/components/Attachment/Gallery.d.ts +3 -3
  244. package/lib/typescript/components/Attachment/Gallery.d.ts.map +1 -1
  245. package/lib/typescript/components/Attachment/ImageReloadIndicator.d.ts +4 -3
  246. package/lib/typescript/components/Attachment/ImageReloadIndicator.d.ts.map +1 -1
  247. package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts.map +1 -1
  248. package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerItem.d.ts +2 -2
  249. package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerItem.d.ts.map +1 -1
  250. package/lib/typescript/components/AutoCompleteInput/AutoCompleteInput.d.ts +2 -3
  251. package/lib/typescript/components/AutoCompleteInput/AutoCompleteInput.d.ts.map +1 -1
  252. package/lib/typescript/components/Channel/Channel.d.ts +3 -4
  253. package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
  254. package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts +2 -3
  255. package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts.map +1 -1
  256. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +1 -1
  257. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts.map +1 -1
  258. package/lib/typescript/components/Channel/hooks/useCreateThreadContext.d.ts +6 -6
  259. package/lib/typescript/components/Channel/hooks/useCreateThreadContext.d.ts.map +1 -1
  260. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts +3 -3
  261. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts.map +1 -1
  262. package/lib/typescript/components/ChannelPreview/hooks/useChannelPreviewData.d.ts +1 -1
  263. package/lib/typescript/components/ChannelPreview/hooks/useLatestMessagePreview.d.ts +1 -1
  264. package/lib/typescript/components/Chat/Chat.d.ts +0 -9
  265. package/lib/typescript/components/Chat/Chat.d.ts.map +1 -1
  266. package/lib/typescript/components/KeyboardCompatibleView/KeyboardCompatibleView.d.ts +3 -0
  267. package/lib/typescript/components/KeyboardCompatibleView/KeyboardCompatibleView.d.ts.map +1 -1
  268. package/lib/typescript/components/Message/Message.d.ts +4 -5
  269. package/lib/typescript/components/Message/Message.d.ts.map +1 -1
  270. package/lib/typescript/components/Message/MessageSimple/MessageFooter.d.ts +2 -3
  271. package/lib/typescript/components/Message/MessageSimple/MessageFooter.d.ts.map +1 -1
  272. package/lib/typescript/components/Message/MessageSimple/MessageSimple.d.ts.map +1 -1
  273. package/lib/typescript/components/Message/MessageSimple/MessageStatus.d.ts +1 -1
  274. package/lib/typescript/components/Message/MessageSimple/MessageStatus.d.ts.map +1 -1
  275. package/lib/typescript/components/Message/MessageSimple/MessageTextContainer.d.ts.map +1 -1
  276. package/lib/typescript/components/Message/MessageSimple/utils/renderText.d.ts +2 -2
  277. package/lib/typescript/components/Message/MessageSimple/utils/renderText.d.ts.map +1 -1
  278. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts +1 -1
  279. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts.map +1 -1
  280. package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts.map +1 -1
  281. package/lib/typescript/components/Message/hooks/useMessageActions.d.ts +2 -2
  282. package/lib/typescript/components/Message/hooks/useMessageActions.d.ts.map +1 -1
  283. package/lib/typescript/components/MessageInput/FileUploadPreview.d.ts +2 -4
  284. package/lib/typescript/components/MessageInput/FileUploadPreview.d.ts.map +1 -1
  285. package/lib/typescript/components/MessageInput/InputButtons.d.ts +1 -1
  286. package/lib/typescript/components/MessageInput/InputButtons.d.ts.map +1 -1
  287. package/lib/typescript/components/MessageInput/MessageInput.d.ts +1 -1
  288. package/lib/typescript/components/MessageInput/MessageInput.d.ts.map +1 -1
  289. package/lib/typescript/components/MessageInput/hooks/useAudioController.d.ts.map +1 -1
  290. package/lib/typescript/components/MessageList/MessageList.d.ts +4 -4
  291. package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
  292. package/lib/typescript/components/MessageList/MessageSystem.d.ts +2 -2
  293. package/lib/typescript/components/MessageList/MessageSystem.d.ts.map +1 -1
  294. package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts +14 -9
  295. package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts.map +1 -1
  296. package/lib/typescript/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.d.ts +2 -2
  297. package/lib/typescript/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.d.ts.map +1 -1
  298. package/lib/typescript/components/MessageList/utils/getGroupStyles.d.ts.map +1 -1
  299. package/lib/typescript/components/MessageList/utils/getLastReceivedMessage.d.ts +2 -2
  300. package/lib/typescript/components/MessageList/utils/getLastReceivedMessage.d.ts.map +1 -1
  301. package/lib/typescript/components/MessageList/utils/getReadState.d.ts +9 -0
  302. package/lib/typescript/components/MessageList/utils/getReadState.d.ts.map +1 -0
  303. package/lib/typescript/components/MessageMenu/hooks/useFetchReactions.d.ts +2 -3
  304. package/lib/typescript/components/MessageMenu/hooks/useFetchReactions.d.ts.map +1 -1
  305. package/lib/typescript/components/Poll/components/Button.d.ts +2 -3
  306. package/lib/typescript/components/Poll/components/Button.d.ts.map +1 -1
  307. package/lib/typescript/components/Poll/components/PollResults/PollResultItem.d.ts +2 -3
  308. package/lib/typescript/components/Poll/components/PollResults/PollResultItem.d.ts.map +1 -1
  309. package/lib/typescript/components/Reply/Reply.d.ts.map +1 -1
  310. package/lib/typescript/components/Thread/components/ThreadFooterComponent.d.ts.map +1 -1
  311. package/lib/typescript/components/ThreadList/ThreadListItem.d.ts.map +1 -1
  312. package/lib/typescript/components/UIComponents/BottomSheetModal.d.ts.map +1 -1
  313. package/lib/typescript/components/index.d.ts +2 -1
  314. package/lib/typescript/components/index.d.ts.map +1 -1
  315. package/lib/typescript/contexts/attachmentPickerContext/AttachmentPickerContext.d.ts +3 -3
  316. package/lib/typescript/contexts/attachmentPickerContext/AttachmentPickerContext.d.ts.map +1 -1
  317. package/lib/typescript/contexts/channelsStateContext/useChannelState.d.ts.map +1 -1
  318. package/lib/typescript/contexts/debugContext/DebugContext.d.ts +2 -3
  319. package/lib/typescript/contexts/debugContext/DebugContext.d.ts.map +1 -1
  320. package/lib/typescript/contexts/imageGalleryContext/ImageGalleryContext.d.ts +3 -3
  321. package/lib/typescript/contexts/imageGalleryContext/ImageGalleryContext.d.ts.map +1 -1
  322. package/lib/typescript/contexts/messageContext/MessageContext.d.ts +6 -4
  323. package/lib/typescript/contexts/messageContext/MessageContext.d.ts.map +1 -1
  324. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +13 -15
  325. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts.map +1 -1
  326. package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts +1 -1
  327. package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts.map +1 -1
  328. package/lib/typescript/contexts/messageInputContext/hooks/useMessageDetailsForState.d.ts +3 -3
  329. package/lib/typescript/contexts/messageInputContext/hooks/useMessageDetailsForState.d.ts.map +1 -1
  330. package/lib/typescript/contexts/messageInputContext/utils/utils.d.ts +2 -2
  331. package/lib/typescript/contexts/messageInputContext/utils/utils.d.ts.map +1 -1
  332. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +25 -21
  333. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts.map +1 -1
  334. package/lib/typescript/contexts/pollContext/pollContext.d.ts +2 -3
  335. package/lib/typescript/contexts/pollContext/pollContext.d.ts.map +1 -1
  336. package/lib/typescript/contexts/suggestionsContext/SuggestionsContext.d.ts.map +1 -1
  337. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +1 -0
  338. package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
  339. package/lib/typescript/contexts/threadContext/ThreadContext.d.ts +4 -5
  340. package/lib/typescript/contexts/threadContext/ThreadContext.d.ts.map +1 -1
  341. package/lib/typescript/contexts/threadsContext/ThreadListItemContext.d.ts +3 -4
  342. package/lib/typescript/contexts/threadsContext/ThreadListItemContext.d.ts.map +1 -1
  343. package/lib/typescript/hooks/index.d.ts +2 -0
  344. package/lib/typescript/hooks/index.d.ts.map +1 -1
  345. package/lib/typescript/hooks/useAudioPlayer.d.ts.map +1 -1
  346. package/lib/typescript/hooks/useStableCallback.d.ts +26 -0
  347. package/lib/typescript/hooks/useStableCallback.d.ts.map +1 -0
  348. package/lib/typescript/hooks/useTranslatedMessage.d.ts +59 -58
  349. package/lib/typescript/hooks/useTranslatedMessage.d.ts.map +1 -1
  350. package/lib/typescript/i18n/en.json +3 -0
  351. package/lib/typescript/i18n/es.json +3 -0
  352. package/lib/typescript/i18n/fr.json +3 -0
  353. package/lib/typescript/i18n/he.json +3 -0
  354. package/lib/typescript/i18n/hi.json +2 -0
  355. package/lib/typescript/i18n/it.json +3 -0
  356. package/lib/typescript/i18n/ja.json +1 -0
  357. package/lib/typescript/i18n/ko.json +1 -0
  358. package/lib/typescript/i18n/nl.json +2 -0
  359. package/lib/typescript/i18n/pt-br.json +3 -0
  360. package/lib/typescript/i18n/ru.json +4 -0
  361. package/lib/typescript/i18n/tr.json +2 -0
  362. package/lib/typescript/native.d.ts +8 -11
  363. package/lib/typescript/native.d.ts.map +1 -1
  364. package/lib/typescript/store/apis/insertReaction.d.ts +2 -2
  365. package/lib/typescript/store/apis/insertReaction.d.ts.map +1 -1
  366. package/lib/typescript/store/apis/updateMessage.d.ts +2 -2
  367. package/lib/typescript/store/apis/updateMessage.d.ts.map +1 -1
  368. package/lib/typescript/store/apis/updateReaction.d.ts +2 -2
  369. package/lib/typescript/store/apis/updateReaction.d.ts.map +1 -1
  370. package/lib/typescript/store/mappers/mapMessageToStorable.d.ts +2 -2
  371. package/lib/typescript/store/mappers/mapMessageToStorable.d.ts.map +1 -1
  372. package/lib/typescript/types/types.d.ts +28 -50
  373. package/lib/typescript/types/types.d.ts.map +1 -1
  374. package/lib/typescript/utils/compressImage.d.ts +2 -2
  375. package/lib/typescript/utils/compressImage.d.ts.map +1 -1
  376. package/lib/typescript/utils/i18n/Streami18n.d.ts +3 -0
  377. package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
  378. package/lib/typescript/utils/removeReservedFields.d.ts +2 -3
  379. package/lib/typescript/utils/removeReservedFields.d.ts.map +1 -1
  380. package/lib/typescript/utils/utils.d.ts +10 -10
  381. package/lib/typescript/utils/utils.d.ts.map +1 -1
  382. package/package.json +4 -3
  383. package/src/components/Attachment/AudioAttachment.tsx +12 -6
  384. package/src/components/Attachment/FileAttachmentGroup.tsx +3 -1
  385. package/src/components/Attachment/Gallery.tsx +22 -7
  386. package/src/components/Attachment/ImageReloadIndicator.tsx +4 -5
  387. package/src/components/AttachmentPicker/AttachmentPicker.tsx +4 -10
  388. package/src/components/AttachmentPicker/components/AttachmentPickerItem.tsx +9 -37
  389. package/src/components/AutoCompleteInput/AutoCompleteInput.tsx +27 -23
  390. package/src/components/AutoCompleteInput/__tests__/AutoCompleteInput.test.js +12 -12
  391. package/src/components/Channel/Channel.tsx +423 -361
  392. package/src/components/Channel/__tests__/Channel.test.js +10 -3
  393. package/src/components/Channel/hooks/useChannelDataState.ts +2 -4
  394. package/src/components/Channel/hooks/useCreateMessagesContext.ts +2 -0
  395. package/src/components/Channel/hooks/useMessageListPagination.tsx +150 -150
  396. package/src/components/Chat/Chat.tsx +0 -9
  397. package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +8 -7
  398. package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx +5 -4
  399. package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx +5 -4
  400. package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx +3 -2
  401. package/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx +12 -5
  402. package/src/components/Message/Message.tsx +16 -15
  403. package/src/components/Message/MessageSimple/MessageFooter.tsx +2 -3
  404. package/src/components/Message/MessageSimple/MessageSimple.tsx +112 -70
  405. package/src/components/Message/MessageSimple/MessageStatus.tsx +19 -17
  406. package/src/components/Message/MessageSimple/MessageTextContainer.tsx +3 -3
  407. package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js +11 -5
  408. package/src/components/Message/MessageSimple/__tests__/MessageTextContainer.test.tsx +5 -4
  409. package/src/components/Message/MessageSimple/utils/renderText.tsx +2 -3
  410. package/src/components/Message/hooks/useCreateMessageContext.ts +3 -0
  411. package/src/components/Message/hooks/useMessageActionHandlers.ts +1 -3
  412. package/src/components/Message/hooks/useMessageActions.tsx +4 -3
  413. package/src/components/MessageInput/FileUploadPreview.tsx +41 -70
  414. package/src/components/MessageInput/ImageUploadPreview.tsx +2 -2
  415. package/src/components/MessageInput/InputButtons.tsx +14 -10
  416. package/src/components/MessageInput/MessageInput.tsx +28 -30
  417. package/src/components/MessageInput/__tests__/FileUploadPreview.test.js +1 -1
  418. package/src/components/MessageInput/__tests__/MessageInput.test.js +3 -1
  419. package/src/components/MessageInput/components/AudioRecorder/AudioRecordingButton.tsx +1 -0
  420. package/src/components/MessageInput/hooks/useAudioController.tsx +6 -5
  421. package/src/components/MessageList/MessageList.tsx +253 -137
  422. package/src/components/MessageList/MessageSystem.tsx +2 -2
  423. package/src/components/MessageList/hooks/useMessageList.ts +82 -64
  424. package/src/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.ts +2 -2
  425. package/src/components/MessageList/utils/getGroupStyles.ts +7 -5
  426. package/src/components/MessageList/utils/getLastReceivedMessage.ts +3 -3
  427. package/src/components/MessageList/utils/getReadState.ts +27 -0
  428. package/src/components/MessageMenu/__tests__/MessageUserReactions.test.tsx +2 -3
  429. package/src/components/MessageMenu/hooks/useFetchReactions.ts +2 -3
  430. package/src/components/Poll/components/Button.tsx +2 -4
  431. package/src/components/Poll/components/PollResults/PollResultItem.tsx +2 -3
  432. package/src/components/Reply/Reply.tsx +1 -2
  433. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +318 -847
  434. package/src/components/Thread/components/ThreadFooterComponent.tsx +31 -9
  435. package/src/components/ThreadList/ThreadListItem.tsx +6 -4
  436. package/src/components/UIComponents/BottomSheetModal.tsx +11 -7
  437. package/src/components/index.ts +2 -1
  438. package/src/contexts/attachmentPickerContext/AttachmentPickerContext.tsx +5 -4
  439. package/src/contexts/channelsStateContext/useChannelState.ts +5 -1
  440. package/src/contexts/debugContext/DebugContext.tsx +2 -4
  441. package/src/contexts/imageGalleryContext/ImageGalleryContext.tsx +5 -4
  442. package/src/contexts/messageContext/MessageContext.tsx +6 -4
  443. package/src/contexts/messageInputContext/MessageInputContext.tsx +295 -262
  444. package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap +10 -6
  445. package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx +6 -5
  446. package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx +3 -5
  447. package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx +14 -9
  448. package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts +7 -3
  449. package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts +37 -40
  450. package/src/contexts/messageInputContext/utils/utils.ts +6 -8
  451. package/src/contexts/messagesContext/MessagesContext.tsx +26 -20
  452. package/src/contexts/pollContext/pollContext.tsx +2 -4
  453. package/src/contexts/suggestionsContext/SuggestionsContext.tsx +33 -14
  454. package/src/contexts/themeContext/utils/theme.ts +2 -0
  455. package/src/contexts/threadContext/ThreadContext.tsx +4 -6
  456. package/src/contexts/threadsContext/ThreadListItemContext.tsx +3 -5
  457. package/src/hooks/index.ts +2 -0
  458. package/src/hooks/useAudioPlayer.ts +37 -31
  459. package/src/hooks/useStableCallback.ts +37 -0
  460. package/src/hooks/useTranslatedMessage.ts +2 -2
  461. package/src/i18n/en.json +3 -0
  462. package/src/i18n/es.json +3 -0
  463. package/src/i18n/fr.json +3 -0
  464. package/src/i18n/he.json +3 -0
  465. package/src/i18n/hi.json +2 -0
  466. package/src/i18n/it.json +3 -0
  467. package/src/i18n/ja.json +1 -0
  468. package/src/i18n/ko.json +1 -0
  469. package/src/i18n/nl.json +2 -0
  470. package/src/i18n/pt-br.json +3 -0
  471. package/src/i18n/ru.json +4 -0
  472. package/src/i18n/tr.json +2 -0
  473. package/src/mock-builders/api/channelMocks.tsx +2 -8
  474. package/src/native.ts +13 -8
  475. package/src/store/apis/insertReaction.ts +2 -2
  476. package/src/store/apis/updateMessage.ts +2 -2
  477. package/src/store/apis/updateReaction.ts +2 -2
  478. package/src/store/mappers/mapMessageToStorable.ts +2 -2
  479. package/src/types/stream-chat-common-custom-data.d.ts +22 -22
  480. package/src/types/types.ts +35 -54
  481. package/src/utils/compressImage.ts +3 -4
  482. package/src/utils/removeReservedFields.ts +3 -5
  483. package/src/utils/utils.ts +25 -16
  484. package/src/version.json +1 -1
  485. package/lib/commonjs/components/MessageList/hooks/useLastReadData.js +0 -20
  486. package/lib/commonjs/components/MessageList/hooks/useLastReadData.js.map +0 -1
  487. package/lib/commonjs/components/MessageList/utils/getReadStates.js +0 -34
  488. package/lib/commonjs/components/MessageList/utils/getReadStates.js.map +0 -1
  489. package/lib/module/components/MessageList/hooks/useLastReadData.js +0 -20
  490. package/lib/module/components/MessageList/hooks/useLastReadData.js.map +0 -1
  491. package/lib/module/components/MessageList/utils/getReadStates.js +0 -34
  492. package/lib/module/components/MessageList/utils/getReadStates.js.map +0 -1
  493. package/lib/typescript/components/MessageList/hooks/useLastReadData.d.ts +0 -12
  494. package/lib/typescript/components/MessageList/hooks/useLastReadData.d.ts.map +0 -1
  495. package/lib/typescript/components/MessageList/utils/getReadStates.d.ts +0 -5
  496. package/lib/typescript/components/MessageList/utils/getReadStates.d.ts.map +0 -1
  497. package/src/components/MessageList/hooks/useLastReadData.ts +0 -29
  498. package/src/components/MessageList/utils/getReadStates.ts +0 -55
@@ -10,13 +10,9 @@ import {
10
10
  ViewToken,
11
11
  } from 'react-native';
12
12
 
13
- import type { FormatMessageResponse } from 'stream-chat';
13
+ import type { Channel, Event, LocalMessage, MessageResponse } from 'stream-chat';
14
14
 
15
- import {
16
- isMessageWithStylesReadByAndDateSeparator,
17
- MessageType,
18
- useMessageList,
19
- } from './hooks/useMessageList';
15
+ import { useMessageList } from './hooks/useMessageList';
20
16
  import { useShouldScrollToRecentOnNewOwnMessage } from './hooks/useShouldScrollToRecentOnNewOwnMessage';
21
17
 
22
18
  import { InlineLoadingMoreIndicator } from './InlineLoadingMoreIndicator';
@@ -53,6 +49,7 @@ import {
53
49
  import { mergeThemes, ThemeProvider, useTheme } from '../../contexts/themeContext/ThemeContext';
54
50
  import { ThreadContextValue, useThreadContext } from '../../contexts/threadContext/ThreadContext';
55
51
 
52
+ import { useStableCallback } from '../../hooks';
56
53
  import { FileTypes } from '../../types/types';
57
54
 
58
55
  // This is just to make sure that the scrolling happens in a different task queue.
@@ -90,7 +87,7 @@ const styles = StyleSheet.create({
90
87
  },
91
88
  });
92
89
 
93
- const keyExtractor = (item: MessageType) => {
90
+ const keyExtractor = (item: LocalMessage) => {
94
91
  if (item.id) {
95
92
  return item.id;
96
93
  }
@@ -104,6 +101,26 @@ const flatListViewabilityConfig: ViewabilityConfig = {
104
101
  viewAreaCoveragePercentThreshold: 1,
105
102
  };
106
103
 
104
+ const hasReadLastMessage = (channel: Channel, userId: string) => {
105
+ const latestMessageIdInChannel = channel.state.latestMessages.slice(-1)[0]?.id;
106
+ const lastReadMessageIdServer = channel.state.read[userId]?.last_read_message_id;
107
+ return latestMessageIdInChannel === lastReadMessageIdServer;
108
+ };
109
+
110
+ const getPreviousLastMessage = (messages: LocalMessage[], newMessage?: MessageResponse) => {
111
+ if (!newMessage) return;
112
+ let previousLastMessage;
113
+ for (let i = messages.length - 1; i >= 0; i--) {
114
+ const msg = messages[i];
115
+ if (!msg?.id) break;
116
+ if (msg.id !== newMessage.id) {
117
+ previousLastMessage = msg;
118
+ break;
119
+ }
120
+ }
121
+ return previousLastMessage;
122
+ };
123
+
107
124
  type MessageListPropsWithContext = Pick<
108
125
  AttachmentPickerContextValue,
109
126
  'closePicker' | 'selectedPicker' | 'setSelectedPicker'
@@ -123,6 +140,7 @@ type MessageListPropsWithContext = Pick<
123
140
  | 'NetworkDownIndicator'
124
141
  | 'reloadChannel'
125
142
  | 'scrollToFirstUnreadThreshold'
143
+ | 'setChannelUnreadState'
126
144
  | 'setTargetedMessage'
127
145
  | 'StickyHeader'
128
146
  | 'targetedMessage'
@@ -167,7 +185,7 @@ type MessageListPropsWithContext = Pick<
167
185
  * additionalFlatListProps={{ bounces: true, keyboardDismissMode: true }} />
168
186
  * ```
169
187
  */
170
- additionalFlatListProps?: Partial<FlatListProps<MessageType>>;
188
+ additionalFlatListProps?: Partial<FlatListProps<LocalMessage>>;
171
189
  /**
172
190
  * UI component for footer of message list. By default message list will use `InlineLoadingMoreIndicator`
173
191
  * as FooterComponent. If you want to implement your own inline loading indicator, you can access `loadingMore`
@@ -209,7 +227,7 @@ type MessageListPropsWithContext = Pick<
209
227
  * }}
210
228
  * ```
211
229
  */
212
- setFlatListRef?: (ref: FlatListType<MessageType> | null) => void;
230
+ setFlatListRef?: (ref: FlatListType<LocalMessage> | null) => void;
213
231
  };
214
232
 
215
233
  /**
@@ -264,6 +282,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
264
282
  reloadChannel,
265
283
  ScrollToBottomButton,
266
284
  selectedPicker,
285
+ setChannelUnreadState,
267
286
  setFlatListRef,
268
287
  setMessages,
269
288
  setSelectedPicker,
@@ -299,10 +318,11 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
299
318
  * NOTE: rawMessageList changes only when messages array state changes
300
319
  * processedMessageList changes on any state change
301
320
  */
302
- const { processedMessageList, rawMessageList } = useMessageList({
303
- noGroupByUser,
304
- threadList,
305
- });
321
+ const { dateSeparatorsRef, messageGroupStylesRef, processedMessageList, rawMessageList } =
322
+ useMessageList({
323
+ noGroupByUser,
324
+ threadList,
325
+ });
306
326
  const messageListLengthBeforeUpdate = useRef(0);
307
327
  const messageListLengthAfterUpdate = processedMessageList.length;
308
328
 
@@ -310,9 +330,9 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
310
330
  * We need topMessage and channelLastRead values to set the initial scroll position.
311
331
  * So these values only get used if `initialScrollToFirstUnreadMessage` prop is true.
312
332
  */
313
- const topMessageBeforeUpdate = useRef<FormatMessageResponse>(undefined);
314
- const latestNonCurrentMessageBeforeUpdateRef = useRef<FormatMessageResponse>(undefined);
315
- const topMessageAfterUpdate: FormatMessageResponse | undefined = rawMessageList[0];
333
+ const topMessageBeforeUpdate = useRef<LocalMessage>(undefined);
334
+ const latestNonCurrentMessageBeforeUpdateRef = useRef<LocalMessage>(undefined);
335
+ const topMessageAfterUpdate: LocalMessage | undefined = rawMessageList[0];
316
336
 
317
337
  const shouldScrollToRecentOnNewOwnMessageRef = useShouldScrollToRecentOnNewOwnMessage(
318
338
  rawMessageList,
@@ -321,6 +341,14 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
321
341
 
322
342
  const [autoscrollToRecent, setAutoscrollToRecent] = useState(false);
323
343
 
344
+ const maintainVisibleContentPosition = useMemo(
345
+ () => ({
346
+ autoscrollToTopThreshold: autoscrollToRecent ? 10 : undefined,
347
+ minIndexForVisible: 1,
348
+ }),
349
+ [autoscrollToRecent],
350
+ );
351
+
324
352
  /**
325
353
  * We want to call onEndReached and onStartReached only once, per content length.
326
354
  * We keep track of calls to these functions per content length, with following trackers.
@@ -331,7 +359,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
331
359
  const onStartReachedInPromise = useRef<Promise<void> | null>(null);
332
360
  const onEndReachedInPromise = useRef<Promise<void> | null>(null);
333
361
 
334
- const flatListRef = useRef<FlatListType<MessageType> | null>(null);
362
+ const flatListRef = useRef<FlatListType<LocalMessage> | null>(null);
335
363
 
336
364
  const channelResyncScrollSet = useRef<boolean>(true);
337
365
 
@@ -351,8 +379,9 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
351
379
  */
352
380
  const messageIdLastScrolledToRef = useRef<string>(undefined);
353
381
  const [hasMoved, setHasMoved] = useState(false);
354
- const [lastReceivedId, setLastReceivedId] = useState(
355
- getLastReceivedMessage(processedMessageList)?.id,
382
+ const lastReceivedId = useMemo(
383
+ () => getLastReceivedMessage(processedMessageList)?.id,
384
+ [processedMessageList],
356
385
  );
357
386
  const [scrollToBottomButtonVisible, setScrollToBottomButtonVisible] = useState(false);
358
387
 
@@ -363,7 +392,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
363
392
  const channelRef = useRef(channel);
364
393
  channelRef.current = channel;
365
394
 
366
- const updateStickyHeaderDateIfNeeded = (viewableItems: ViewToken[]) => {
395
+ const updateStickyHeaderDateIfNeeded = useStableCallback((viewableItems: ViewToken[]) => {
367
396
  if (!viewableItems.length) {
368
397
  return;
369
398
  }
@@ -390,12 +419,12 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
390
419
  setStickyHeaderDate(lastItem.item.created_at);
391
420
  }
392
421
  }
393
- };
422
+ });
394
423
 
395
424
  /**
396
425
  * This function should show or hide the unread indicator depending on the
397
426
  */
398
- const updateStickyUnreadIndicator = (viewableItems: ViewToken[]) => {
427
+ const updateStickyUnreadIndicator = useStableCallback((viewableItems: ViewToken[]) => {
399
428
  if (!viewableItems.length) {
400
429
  setIsUnreadNotificationOpen(false);
401
430
  return;
@@ -409,26 +438,39 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
409
438
  const lastItem = viewableItems[viewableItems.length - 1];
410
439
 
411
440
  if (lastItem) {
412
- const lastItemCreatedAt = lastItem.item.created_at;
441
+ const lastItemMessage = lastItem.item;
442
+ const lastItemCreatedAt = lastItemMessage.created_at;
413
443
 
414
444
  const unreadIndicatorDate = channelUnreadState?.last_read.getTime();
415
445
  const lastItemDate = lastItemCreatedAt.getTime();
416
446
 
417
447
  if (
418
448
  !channel.state.messagePagination.hasPrev &&
419
- processedMessageList[processedMessageList.length - 1].id === lastItem.item.id
449
+ processedMessageList[processedMessageList.length - 1].id === lastItemMessage.id
450
+ ) {
451
+ setIsUnreadNotificationOpen(false);
452
+ return;
453
+ }
454
+ /**
455
+ * This is a special case where there is a single long message by the sender.
456
+ * When a message is sent, we mark it as read before it actually has a `created_at` timestamp.
457
+ * This is a workaround to prevent the unread indicator from showing when the message is sent.
458
+ */
459
+ if (
460
+ viewableItems.length === 1 &&
461
+ channel.countUnread() === 0 &&
462
+ lastItemMessage.user.id === client.userID
420
463
  ) {
421
464
  setIsUnreadNotificationOpen(false);
422
465
  return;
423
466
  }
424
-
425
467
  if (unreadIndicatorDate && lastItemDate > unreadIndicatorDate) {
426
468
  setIsUnreadNotificationOpen(true);
427
469
  } else {
428
470
  setIsUnreadNotificationOpen(false);
429
471
  }
430
472
  }
431
- };
473
+ });
432
474
 
433
475
  /**
434
476
  * FlatList doesn't accept changeable function for onViewableItemsChanged prop.
@@ -451,7 +493,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
451
493
  const onViewableItemsChanged = useRef(unstableOnViewableItemsChanged);
452
494
  onViewableItemsChanged.current = unstableOnViewableItemsChanged;
453
495
 
454
- const stableOnViwableItemsChanged = useCallback(
496
+ const stableOnViewableItemsChanged = useCallback(
455
497
  ({ viewableItems }: { viewableItems: ViewToken[] | undefined }) => {
456
498
  onViewableItemsChanged.current({ viewableItems });
457
499
  },
@@ -476,24 +518,53 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
476
518
  * Effect to mark the channel as read when the user scrolls to the bottom of the message list.
477
519
  */
478
520
  useEffect(() => {
479
- const listener: ReturnType<typeof channel.on> = channel.on('message.new', (event) => {
480
- const newMessageToCurrentChannel = event.cid === channel.cid;
481
- const mainChannelUpdated = !event.message?.parent_id || event.message?.show_in_channel;
521
+ const shouldMarkRead = () => {
522
+ return (
523
+ !channelUnreadState?.first_unread_message_id &&
524
+ !scrollToBottomButtonVisible &&
525
+ client.user?.id &&
526
+ !hasReadLastMessage(channel, client.user?.id)
527
+ );
528
+ };
482
529
 
483
- if (newMessageToCurrentChannel && mainChannelUpdated && !scrollToBottomButtonVisible) {
484
- markRead();
530
+ const handleEvent = async (event: Event) => {
531
+ const mainChannelUpdated = !event.message?.parent_id || event.message?.show_in_channel;
532
+ // When the scrollToBottomButtonVisible is true, we need to manually update the channelUnreadState.
533
+ if (scrollToBottomButtonVisible || channelUnreadState?.first_unread_message_id) {
534
+ setChannelUnreadState((prev) => {
535
+ const previousUnreadCount = prev?.unread_messages ?? 0;
536
+ const previousLastMessage = getPreviousLastMessage(channel.state.messages, event.message);
537
+ return {
538
+ ...(prev || {}),
539
+ last_read:
540
+ prev?.last_read ??
541
+ (previousUnreadCount === 0 && previousLastMessage?.created_at
542
+ ? new Date(previousLastMessage.created_at)
543
+ : new Date(0)), // not having information about the last read message means the whole channel is unread,
544
+ unread_messages: previousUnreadCount + 1,
545
+ };
546
+ });
547
+ } else if (mainChannelUpdated && shouldMarkRead()) {
548
+ await markRead();
485
549
  }
486
- });
550
+ };
551
+
552
+ const listener: ReturnType<typeof channel.on> = channel.on('message.new', handleEvent);
487
553
 
488
554
  return () => {
489
555
  listener?.unsubscribe();
490
556
  };
491
- }, [channel, markRead, scrollToBottomButtonVisible]);
557
+ }, [
558
+ channel,
559
+ channelUnreadState?.first_unread_message_id,
560
+ client.user?.id,
561
+ markRead,
562
+ scrollToBottomButtonVisible,
563
+ setChannelUnreadState,
564
+ threadList,
565
+ ]);
492
566
 
493
567
  useEffect(() => {
494
- const lastReceivedMessage = getLastReceivedMessage(processedMessageList);
495
- setLastReceivedId(lastReceivedMessage?.id);
496
-
497
568
  /**
498
569
  * Scroll down when
499
570
  * created_at timestamp of top message before update is lesser than created_at timestamp of top message after update - channel has resynced
@@ -589,7 +660,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
589
660
  // eslint-disable-next-line react-hooks/exhaustive-deps
590
661
  }, [channel, rawMessageList, threadList]);
591
662
 
592
- const goToMessage = async (messageId: string) => {
663
+ const goToMessage = useStableCallback(async (messageId: string) => {
593
664
  const indexOfParentInMessageList = processedMessageList.findIndex(
594
665
  (message) => message?.id === messageId,
595
666
  );
@@ -617,7 +688,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
617
688
  } catch (e) {
618
689
  console.warn('Error while scrolling to message', e);
619
690
  }
620
- };
691
+ });
621
692
 
622
693
  /**
623
694
  * Check if a messageId needs to be scrolled to after list loads, and scroll to it
@@ -660,72 +731,101 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
660
731
  // TODO: do not apply on RN 0.73 and above
661
732
  const shouldApplyAndroidWorkaround = inverted && Platform.OS === 'android';
662
733
 
663
- const renderItem = ({ index, item: message }: { index: number; item: MessageType }) => {
664
- if (!channel || channel.disconnected || (!channel.initialized && !channel.offlineMode)) {
665
- return null;
666
- }
734
+ const renderItem = useCallback(
735
+ ({ index, item: message }: { index: number; item: LocalMessage }) => {
736
+ if (!channel || channel.disconnected || (!channel.initialized && !channel.offlineMode)) {
737
+ return null;
738
+ }
667
739
 
668
- const createdAtTimestamp = message.created_at && new Date(message.created_at).getTime();
669
- const lastReadTimestamp = channelUnreadState?.last_read.getTime();
670
- const isNewestMessage = index === 0;
671
- const isLastReadMessage =
672
- channelUnreadState?.last_read_message_id === message.id ||
673
- (!channelUnreadState?.unread_messages && createdAtTimestamp === lastReadTimestamp);
674
-
675
- const showUnreadSeparator =
676
- isLastReadMessage &&
677
- !isNewestMessage &&
678
- // The `channelUnreadState?.first_unread_message_id` is here for sent messages unread label
679
- (!!channelUnreadState?.first_unread_message_id || !!channelUnreadState?.unread_messages);
680
-
681
- const showUnreadUnderlay = !!shouldShowUnreadUnderlay && showUnreadSeparator;
682
-
683
- const wrapMessageInTheme = client.userID === message.user?.id && !!myMessageTheme;
684
- const renderDateSeperator = isMessageWithStylesReadByAndDateSeparator(message) &&
685
- message.dateSeparator && <InlineDateSeparator date={message.dateSeparator} />;
686
- const renderMessage = (
687
- <Message
688
- goToMessage={goToMessage}
689
- groupStyles={isMessageWithStylesReadByAndDateSeparator(message) ? message.groupStyles : []}
690
- isTargetedMessage={highlightedMessageId === message.id}
691
- lastReceivedId={
692
- lastReceivedId === message.id || message.quoted_message_id ? lastReceivedId : undefined
693
- }
694
- message={message}
695
- onThreadSelect={onThreadSelect}
696
- showUnreadUnderlay={showUnreadUnderlay}
697
- style={[messageContainer]}
698
- threadList={threadList}
699
- />
700
- );
740
+ const createdAtTimestamp = message.created_at && new Date(message.created_at).getTime();
741
+ const lastReadTimestamp = channelUnreadState?.last_read.getTime();
742
+ const isNewestMessage = index === 0;
743
+ const isLastReadMessage =
744
+ channelUnreadState?.last_read_message_id === message.id ||
745
+ (!channelUnreadState?.unread_messages && createdAtTimestamp === lastReadTimestamp);
701
746
 
702
- return (
703
- <View
704
- style={[shouldApplyAndroidWorkaround ? styles.invertAndroid : undefined]}
705
- testID={`message-list-item-${index}`}
706
- >
707
- {message.type === 'system' ? (
708
- <MessageSystem
709
- message={message}
710
- style={[{ paddingHorizontal: screenPadding }, messageContainer]}
711
- />
712
- ) : wrapMessageInTheme ? (
713
- <ThemeProvider mergedStyle={modifiedTheme}>
747
+ const showUnreadSeparator =
748
+ isLastReadMessage &&
749
+ !isNewestMessage &&
750
+ // The `channelUnreadState?.first_unread_message_id` is here for sent messages unread label
751
+ (!!channelUnreadState?.first_unread_message_id || !!channelUnreadState?.unread_messages);
752
+
753
+ const showUnreadUnderlay = !!shouldShowUnreadUnderlay && showUnreadSeparator;
754
+
755
+ const wrapMessageInTheme = client.userID === message.user?.id && !!myMessageTheme;
756
+ const renderDateSeperator = dateSeparatorsRef.current[message.id] && (
757
+ <InlineDateSeparator date={dateSeparatorsRef.current[message.id]} />
758
+ );
759
+
760
+ const renderMessage = (
761
+ <Message
762
+ goToMessage={goToMessage}
763
+ groupStyles={messageGroupStylesRef.current[message.id] ?? []}
764
+ isTargetedMessage={highlightedMessageId === message.id}
765
+ lastReceivedId={
766
+ lastReceivedId === message.id || message.quoted_message_id ? lastReceivedId : undefined
767
+ }
768
+ message={message}
769
+ onThreadSelect={onThreadSelect}
770
+ showUnreadUnderlay={showUnreadUnderlay}
771
+ style={[messageContainer]}
772
+ threadList={threadList}
773
+ />
774
+ );
775
+
776
+ return (
777
+ <View
778
+ style={[shouldApplyAndroidWorkaround ? styles.invertAndroid : undefined]}
779
+ testID={`message-list-item-${index}`}
780
+ >
781
+ {message.type === 'system' ? (
782
+ <MessageSystem
783
+ message={message}
784
+ style={[{ paddingHorizontal: screenPadding }, messageContainer]}
785
+ />
786
+ ) : wrapMessageInTheme ? (
787
+ <ThemeProvider mergedStyle={modifiedTheme}>
788
+ <View testID={`message-list-item-${index}`}>
789
+ {renderDateSeperator}
790
+ {renderMessage}
791
+ </View>
792
+ </ThemeProvider>
793
+ ) : (
714
794
  <View testID={`message-list-item-${index}`}>
715
795
  {renderDateSeperator}
716
796
  {renderMessage}
717
797
  </View>
718
- </ThemeProvider>
719
- ) : (
720
- <View testID={`message-list-item-${index}`}>
721
- {renderDateSeperator}
722
- {renderMessage}
723
- </View>
724
- )}
725
- {showUnreadUnderlay && <InlineUnreadIndicator />}
726
- </View>
727
- );
728
- };
798
+ )}
799
+ {showUnreadUnderlay && <InlineUnreadIndicator />}
800
+ </View>
801
+ );
802
+ },
803
+ [
804
+ InlineDateSeparator,
805
+ InlineUnreadIndicator,
806
+ Message,
807
+ MessageSystem,
808
+ channel,
809
+ channelUnreadState?.first_unread_message_id,
810
+ channelUnreadState?.last_read,
811
+ channelUnreadState?.last_read_message_id,
812
+ channelUnreadState?.unread_messages,
813
+ client.userID,
814
+ dateSeparatorsRef,
815
+ goToMessage,
816
+ highlightedMessageId,
817
+ lastReceivedId,
818
+ messageContainer,
819
+ messageGroupStylesRef,
820
+ modifiedTheme,
821
+ myMessageTheme,
822
+ onThreadSelect,
823
+ screenPadding,
824
+ shouldApplyAndroidWorkaround,
825
+ shouldShowUnreadUnderlay,
826
+ threadList,
827
+ ],
828
+ );
729
829
 
730
830
  /**
731
831
  * We are keeping full control on message pagination, and not relying on react-native for it.
@@ -750,7 +850,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
750
850
  * 2. Ensures that we call `loadMoreRecent`, once per content length
751
851
  * 3. If the call to `loadMore` is in progress, we wait for it to finish to make sure scroll doesn't jump.
752
852
  */
753
- const maybeCallOnStartReached = async () => {
853
+ const maybeCallOnStartReached = useStableCallback(async () => {
754
854
  // If onStartReached has already been called for given data length, then ignore.
755
855
  if (
756
856
  processedMessageList?.length &&
@@ -787,14 +887,14 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
787
887
  )
788
888
  .then(callback)
789
889
  .catch(onError);
790
- };
890
+ });
791
891
 
792
892
  /**
793
893
  * 1. Makes a call to `loadMore` function, which queries more older messages.
794
894
  * 2. Ensures that we call `loadMore`, once per content length
795
895
  * 3. If the call to `loadMoreRecent` is in progress, we wait for it to finish to make sure scroll doesn't jump.
796
896
  */
797
- const maybeCallOnEndReached = async () => {
897
+ const maybeCallOnEndReached = useStableCallback(async () => {
798
898
  // If onEndReached has already been called for given messageList length, then ignore.
799
899
  if (processedMessageList?.length && onEndReachedTracker.current[processedMessageList.length]) {
800
900
  return;
@@ -823,9 +923,9 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
823
923
  onEndReachedInPromise.current = (threadList ? loadMoreThread() : loadMore())
824
924
  .then(callback)
825
925
  .catch(onError);
826
- };
926
+ });
827
927
 
828
- const onUserScrollEvent: NonNullable<ScrollViewProps['onScroll']> = (event) => {
928
+ const onUserScrollEvent: NonNullable<ScrollViewProps['onScroll']> = useStableCallback((event) => {
829
929
  const nativeEvent = event.nativeEvent;
830
930
  clearTimeout(onScrollEventTimeoutRef.current);
831
931
  const offset = nativeEvent.contentOffset.y;
@@ -846,9 +946,9 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
846
946
  if (isScrollAtEnd) {
847
947
  maybeCallOnEndReached();
848
948
  }
849
- };
949
+ });
850
950
 
851
- const handleScroll: ScrollViewProps['onScroll'] = (event) => {
951
+ const handleScroll: ScrollViewProps['onScroll'] = useStableCallback((event) => {
852
952
  const messageListHasMessages = processedMessageList.length > 0;
853
953
  const offset = event.nativeEvent.contentOffset.y;
854
954
  // Show scrollToBottom button once scroll position goes beyond 150.
@@ -870,9 +970,9 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
870
970
  if (onListScroll) {
871
971
  onListScroll(event);
872
972
  }
873
- };
973
+ });
874
974
 
875
- const goToNewMessages = async () => {
975
+ const goToNewMessages = useStableCallback(async () => {
876
976
  const isNotLatestSet = channel.state.messages !== channel.state.latestMessages;
877
977
 
878
978
  if (isNotLatestSet) {
@@ -886,11 +986,18 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
886
986
  }
887
987
 
888
988
  setScrollToBottomButtonVisible(false);
889
- };
989
+ /**
990
+ * When we are not in the bottom of the list, and we receive new messages, we need to mark the channel as read.
991
+ We would still need to show the unread label, where the first unread message appeared so we don't update the channelUnreadState.
992
+ */
993
+ await markRead({
994
+ updateChannelUnreadState: false,
995
+ });
996
+ });
890
997
 
891
998
  const scrollToIndexFailedRetryCountRef = useRef<number>(0);
892
999
  const failScrollTimeoutId = useRef<ReturnType<typeof setTimeout>>(undefined);
893
- const onScrollToIndexFailedRef = useRef<FlatListProps<MessageType>['onScrollToIndexFailed']>(
1000
+ const onScrollToIndexFailedRef = useRef<FlatListProps<LocalMessage>['onScrollToIndexFailed']>(
894
1001
  (info) => {
895
1002
  // We got a failure as we tried to scroll to an item that was outside the render length
896
1003
  if (!flatListRef.current) {
@@ -975,7 +1082,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
975
1082
  isListActive &&
976
1083
  ((threadList && thread) || (!threadList && !thread))
977
1084
  ) {
978
- setMessages(messagesWithImages as MessageType[]);
1085
+ setMessages(messagesWithImages as LocalMessage[]);
979
1086
  }
980
1087
  // eslint-disable-next-line react-hooks/exhaustive-deps
981
1088
  }, [
@@ -987,35 +1094,35 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
987
1094
  threadList,
988
1095
  ]);
989
1096
 
990
- const dismissImagePicker = () => {
1097
+ const dismissImagePicker = useStableCallback(() => {
991
1098
  if (selectedPicker) {
992
1099
  setSelectedPicker(undefined);
993
1100
  closePicker();
994
1101
  }
995
- };
1102
+ });
996
1103
 
997
- const onScrollBeginDrag: ScrollViewProps['onScrollBeginDrag'] = (event) => {
1104
+ const onScrollBeginDrag: ScrollViewProps['onScrollBeginDrag'] = useStableCallback((event) => {
998
1105
  !hasMoved && selectedPicker && setHasMoved(true);
999
1106
  onUserScrollEvent(event);
1000
- };
1107
+ });
1001
1108
 
1002
- const onScrollEndDrag: ScrollViewProps['onScrollEndDrag'] = (event) => {
1109
+ const onScrollEndDrag: ScrollViewProps['onScrollEndDrag'] = useStableCallback((event) => {
1003
1110
  hasMoved && selectedPicker && setHasMoved(false);
1004
1111
  onUserScrollEvent(event);
1005
- };
1112
+ });
1006
1113
 
1007
- const refCallback = (ref: FlatListType<MessageType>) => {
1114
+ const refCallback = useStableCallback((ref: FlatListType<LocalMessage>) => {
1008
1115
  flatListRef.current = ref;
1009
1116
 
1010
1117
  if (setFlatListRef) {
1011
1118
  setFlatListRef(ref);
1012
1119
  }
1013
- };
1120
+ });
1014
1121
 
1015
- const onUnreadNotificationClose = async () => {
1122
+ const onUnreadNotificationClose = useStableCallback(async () => {
1016
1123
  await markRead();
1017
1124
  setIsUnreadNotificationOpen(false);
1018
- };
1125
+ });
1019
1126
 
1020
1127
  const debugRef = useDebugContext();
1021
1128
 
@@ -1076,6 +1183,25 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
1076
1183
  additionalFlatListPropsExcludingStyle = rest;
1077
1184
  }
1078
1185
 
1186
+ const flatListStyle = useMemo(
1187
+ () => [
1188
+ styles.listContainer,
1189
+ listContainer,
1190
+ additionalFlatListProps?.style,
1191
+ shouldApplyAndroidWorkaround ? styles.invertAndroid : undefined,
1192
+ ],
1193
+ [additionalFlatListProps?.style, listContainer, shouldApplyAndroidWorkaround],
1194
+ );
1195
+
1196
+ const flatListContentContainerStyle = useMemo(
1197
+ () => [
1198
+ styles.contentContainer,
1199
+ additionalFlatListProps?.contentContainerStyle,
1200
+ contentContainer,
1201
+ ],
1202
+ [additionalFlatListProps?.contentContainerStyle, contentContainer],
1203
+ );
1204
+
1079
1205
  if (!FlatList) {
1080
1206
  return null;
1081
1207
  }
@@ -1100,11 +1226,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
1100
1226
  </View>
1101
1227
  ) : (
1102
1228
  <FlatList
1103
- contentContainerStyle={[
1104
- styles.contentContainer,
1105
- additionalFlatListProps?.contentContainerStyle,
1106
- contentContainer,
1107
- ]}
1229
+ contentContainerStyle={flatListContentContainerStyle}
1108
1230
  /** Disables the MessageList UI. Which means, message actions, reactions won't work. */
1109
1231
  data={processedMessageList}
1110
1232
  extraData={disabled}
@@ -1120,10 +1242,7 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
1120
1242
  minIndexForVisible = 1 means that beyond the item at index 1 we will not change the position on list updates,
1121
1243
  however it is not used when autoscrollToTopThreshold = 10.
1122
1244
  */
1123
- maintainVisibleContentPosition={{
1124
- autoscrollToTopThreshold: autoscrollToRecent ? 10 : undefined,
1125
- minIndexForVisible: 1,
1126
- }}
1245
+ maintainVisibleContentPosition={maintainVisibleContentPosition}
1127
1246
  maxToRenderPerBatch={30}
1128
1247
  onMomentumScrollEnd={onUserScrollEvent}
1129
1248
  onScroll={handleScroll}
@@ -1131,17 +1250,12 @@ const MessageListWithContext = (props: MessageListPropsWithContext) => {
1131
1250
  onScrollEndDrag={onScrollEndDrag}
1132
1251
  onScrollToIndexFailed={onScrollToIndexFailedRef.current}
1133
1252
  onTouchEnd={dismissImagePicker}
1134
- onViewableItemsChanged={stableOnViwableItemsChanged}
1253
+ onViewableItemsChanged={stableOnViewableItemsChanged}
1135
1254
  ref={refCallback}
1136
1255
  renderItem={renderItem}
1137
1256
  scrollEnabled={overlay === 'none'}
1138
1257
  showsVerticalScrollIndicator={!shouldApplyAndroidWorkaround}
1139
- style={[
1140
- styles.listContainer,
1141
- listContainer,
1142
- additionalFlatListProps?.style,
1143
- shouldApplyAndroidWorkaround ? styles.invertAndroid : undefined,
1144
- ]}
1258
+ style={flatListStyle}
1145
1259
  testID='message-flat-list'
1146
1260
  viewabilityConfig={flatListViewabilityConfig}
1147
1261
  {...additionalFlatListPropsExcludingStyle}
@@ -1191,6 +1305,7 @@ export const MessageList = (props: MessageListProps) => {
1191
1305
  NetworkDownIndicator,
1192
1306
  reloadChannel,
1193
1307
  scrollToFirstUnreadThreshold,
1308
+ setChannelUnreadState,
1194
1309
  setTargetedMessage,
1195
1310
  StickyHeader,
1196
1311
  targetedMessage,
@@ -1255,6 +1370,7 @@ export const MessageList = (props: MessageListProps) => {
1255
1370
  ScrollToBottomButton,
1256
1371
  scrollToFirstUnreadThreshold,
1257
1372
  selectedPicker,
1373
+ setChannelUnreadState,
1258
1374
  setMessages,
1259
1375
  setSelectedPicker,
1260
1376
  setTargetedMessage,