stream-chat-react-native-core 6.0.0-rc.8 → 6.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 (571) hide show
  1. package/README.md +1 -1
  2. package/lib/commonjs/components/AITypingIndicatorView/AITypingIndicatorView.js +53 -0
  3. package/lib/commonjs/components/AITypingIndicatorView/AITypingIndicatorView.js.map +1 -0
  4. package/lib/commonjs/components/AITypingIndicatorView/hooks/useAIState.js +59 -0
  5. package/lib/commonjs/components/AITypingIndicatorView/hooks/useAIState.js.map +1 -0
  6. package/lib/commonjs/components/AITypingIndicatorView/index.js +26 -0
  7. package/lib/commonjs/components/AITypingIndicatorView/index.js.map +1 -0
  8. package/lib/commonjs/components/Attachment/AudioAttachment.js +27 -22
  9. package/lib/commonjs/components/Attachment/AudioAttachment.js.map +1 -1
  10. package/lib/commonjs/components/Attachment/Gallery.js +3 -1
  11. package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
  12. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js +2 -2
  13. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  14. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerItem.js +37 -133
  15. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerItem.js.map +1 -1
  16. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerSelectionBar.js +6 -4
  17. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerSelectionBar.js.map +1 -1
  18. package/lib/commonjs/components/Channel/Channel.js +483 -1056
  19. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  20. package/lib/commonjs/components/Channel/hooks/useChannelDataState.js +174 -0
  21. package/lib/commonjs/components/Channel/hooks/useChannelDataState.js.map +1 -0
  22. package/lib/commonjs/components/Channel/hooks/useCreateChannelContext.js +0 -6
  23. package/lib/commonjs/components/Channel/hooks/useCreateChannelContext.js.map +1 -1
  24. package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js +2 -0
  25. package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
  26. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +4 -0
  27. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  28. package/lib/commonjs/components/Channel/hooks/useCreatePaginatedMessageListContext.js +3 -3
  29. package/lib/commonjs/components/Channel/hooks/useCreatePaginatedMessageListContext.js.map +1 -1
  30. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js +324 -0
  31. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js.map +1 -0
  32. package/lib/commonjs/components/ChannelList/Skeleton.js +7 -3
  33. package/lib/commonjs/components/ChannelList/Skeleton.js.map +1 -1
  34. package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js +85 -45
  35. package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
  36. package/lib/commonjs/components/ChannelPreview/ChannelPreview.js +17 -91
  37. package/lib/commonjs/components/ChannelPreview/ChannelPreview.js.map +1 -1
  38. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessenger.js +3 -24
  39. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessenger.js.map +1 -1
  40. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMutedStatus.js +2 -2
  41. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMutedStatus.js.map +1 -1
  42. package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewData.js +121 -0
  43. package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewData.js.map +1 -0
  44. package/lib/commonjs/components/ChannelPreview/hooks/useIsChannelMuted.js +35 -0
  45. package/lib/commonjs/components/ChannelPreview/hooks/useIsChannelMuted.js.map +1 -0
  46. package/lib/commonjs/components/Chat/Chat.js +5 -1
  47. package/lib/commonjs/components/Chat/Chat.js.map +1 -1
  48. package/lib/commonjs/components/Chat/hooks/useAppSettings.js +15 -9
  49. package/lib/commonjs/components/Chat/hooks/useAppSettings.js.map +1 -1
  50. package/lib/commonjs/components/Chat/hooks/useCreateChatContext.js +2 -0
  51. package/lib/commonjs/components/Chat/hooks/useCreateChatContext.js.map +1 -1
  52. package/lib/commonjs/components/Chat/hooks/useIsOnline.js +0 -4
  53. package/lib/commonjs/components/Chat/hooks/useIsOnline.js.map +1 -1
  54. package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
  55. package/lib/commonjs/components/ImageGallery/components/ImageGalleryFooter.js +46 -46
  56. package/lib/commonjs/components/ImageGallery/components/ImageGalleryFooter.js.map +1 -1
  57. package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js +3 -4
  58. package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
  59. package/lib/commonjs/components/ImageGallery/hooks/useAnimatedGalleryStyle.js +2 -2
  60. package/lib/commonjs/components/ImageGallery/hooks/useAnimatedGalleryStyle.js.map +1 -1
  61. package/lib/commonjs/components/Message/Message.js +7 -0
  62. package/lib/commonjs/components/Message/Message.js.map +1 -1
  63. package/lib/commonjs/components/Message/MessageSimple/MessageContent.js +17 -4
  64. package/lib/commonjs/components/Message/MessageSimple/MessageContent.js.map +1 -1
  65. package/lib/commonjs/components/Message/MessageSimple/MessageFooter.js +15 -6
  66. package/lib/commonjs/components/Message/MessageSimple/MessageFooter.js.map +1 -1
  67. package/lib/commonjs/components/Message/MessageSimple/StreamingMessageView.js +36 -0
  68. package/lib/commonjs/components/Message/MessageSimple/StreamingMessageView.js.map +1 -0
  69. package/lib/commonjs/components/Message/MessageSimple/utils/generateMarkdownText.js +9 -1
  70. package/lib/commonjs/components/Message/MessageSimple/utils/generateMarkdownText.js.map +1 -1
  71. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js +209 -23
  72. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  73. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js +2 -0
  74. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  75. package/lib/commonjs/components/Message/hooks/useStreamingMessage.js +43 -0
  76. package/lib/commonjs/components/Message/hooks/useStreamingMessage.js.map +1 -0
  77. package/lib/commonjs/components/MessageInput/MessageInput.js +41 -21
  78. package/lib/commonjs/components/MessageInput/MessageInput.js.map +1 -1
  79. package/lib/commonjs/components/MessageInput/StopMessageStreamingButton.js +39 -0
  80. package/lib/commonjs/components/MessageInput/StopMessageStreamingButton.js.map +1 -0
  81. package/lib/commonjs/components/MessageList/MessageList.js +74 -73
  82. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  83. package/lib/commonjs/components/MessageList/ScrollToBottomButton.js +1 -1
  84. package/lib/commonjs/components/MessageList/ScrollToBottomButton.js.map +1 -1
  85. package/lib/commonjs/components/MessageList/hooks/useMessageList.js.map +1 -1
  86. package/lib/commonjs/components/MessageList/utils/getReadStates.js.map +1 -1
  87. package/lib/commonjs/components/MessageMenu/MessageUserReactions.js +1 -1
  88. package/lib/commonjs/components/MessageMenu/MessageUserReactions.js.map +1 -1
  89. package/lib/commonjs/components/MessageMenu/MessageUserReactionsItem.js +4 -2
  90. package/lib/commonjs/components/MessageMenu/MessageUserReactionsItem.js.map +1 -1
  91. package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js +3 -2
  92. package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
  93. package/lib/commonjs/components/Poll/CreatePollContent.js +14 -9
  94. package/lib/commonjs/components/Poll/CreatePollContent.js.map +1 -1
  95. package/lib/commonjs/components/Poll/Poll.js +2 -8
  96. package/lib/commonjs/components/Poll/Poll.js.map +1 -1
  97. package/lib/commonjs/components/Poll/components/Button.js +9 -474
  98. package/lib/commonjs/components/Poll/components/Button.js.map +1 -1
  99. package/lib/commonjs/components/Poll/components/CreatePollIcon.js +2 -2
  100. package/lib/commonjs/components/Poll/components/CreatePollIcon.js.map +1 -1
  101. package/lib/commonjs/components/Poll/components/CreatePollOptions.js +9 -4
  102. package/lib/commonjs/components/Poll/components/CreatePollOptions.js.map +1 -1
  103. package/lib/commonjs/components/Poll/components/PollAnswersList.js +99 -26
  104. package/lib/commonjs/components/Poll/components/PollAnswersList.js.map +1 -1
  105. package/lib/commonjs/components/Poll/components/PollButtons.js +291 -0
  106. package/lib/commonjs/components/Poll/components/PollButtons.js.map +1 -0
  107. package/lib/commonjs/components/Poll/components/PollInputDialog.js +14 -4
  108. package/lib/commonjs/components/Poll/components/PollInputDialog.js.map +1 -1
  109. package/lib/commonjs/components/Poll/components/PollModalHeader.js +7 -1
  110. package/lib/commonjs/components/Poll/components/PollModalHeader.js.map +1 -1
  111. package/lib/commonjs/components/Poll/components/PollOption.js +88 -6
  112. package/lib/commonjs/components/Poll/components/PollOption.js.map +1 -1
  113. package/lib/commonjs/components/Poll/components/PollResults/PollOptionFullResults.js +2 -2
  114. package/lib/commonjs/components/Poll/components/PollResults/PollOptionFullResults.js.map +1 -1
  115. package/lib/commonjs/components/Poll/components/PollResults/PollResultItem.js +62 -67
  116. package/lib/commonjs/components/Poll/components/PollResults/PollResultItem.js.map +1 -1
  117. package/lib/commonjs/components/Poll/components/PollResults/PollVote.js +89 -0
  118. package/lib/commonjs/components/Poll/components/PollResults/PollVote.js.map +1 -0
  119. package/lib/commonjs/components/Poll/components/index.js +11 -0
  120. package/lib/commonjs/components/Poll/components/index.js.map +1 -1
  121. package/lib/commonjs/components/ThreadList/ThreadList.js +0 -3
  122. package/lib/commonjs/components/ThreadList/ThreadList.js.map +1 -1
  123. package/lib/commonjs/components/UIComponents/BottomSheetModal.js +11 -5
  124. package/lib/commonjs/components/UIComponents/BottomSheetModal.js.map +1 -1
  125. package/lib/commonjs/components/index.js +66 -0
  126. package/lib/commonjs/components/index.js.map +1 -1
  127. package/lib/commonjs/contexts/channelContext/ChannelContext.js.map +1 -1
  128. package/lib/commonjs/contexts/channelsStateContext/ChannelsStateContext.js +0 -35
  129. package/lib/commonjs/contexts/channelsStateContext/ChannelsStateContext.js.map +1 -1
  130. package/lib/commonjs/contexts/channelsStateContext/useChannelState.js +7 -84
  131. package/lib/commonjs/contexts/channelsStateContext/useChannelState.js.map +1 -1
  132. package/lib/commonjs/contexts/chatContext/ChatContext.js.map +1 -1
  133. package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
  134. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +4 -2
  135. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  136. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +2 -0
  137. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  138. package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
  139. package/lib/commonjs/contexts/paginatedMessageListContext/PaginatedMessageListContext.js.map +1 -1
  140. package/lib/commonjs/contexts/themeContext/utils/theme.js +15 -0
  141. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  142. package/lib/commonjs/i18n/en.json +2 -0
  143. package/lib/commonjs/i18n/es.json +2 -0
  144. package/lib/commonjs/i18n/fr.json +2 -0
  145. package/lib/commonjs/i18n/he.json +2 -0
  146. package/lib/commonjs/i18n/hi.json +2 -0
  147. package/lib/commonjs/i18n/it.json +2 -0
  148. package/lib/commonjs/i18n/ja.json +2 -0
  149. package/lib/commonjs/i18n/ko.json +2 -0
  150. package/lib/commonjs/i18n/nl.json +2 -0
  151. package/lib/commonjs/i18n/pt-br.json +2 -0
  152. package/lib/commonjs/i18n/ru.json +2 -0
  153. package/lib/commonjs/i18n/tr.json +2 -0
  154. package/lib/commonjs/mock-builders/event/notificationChannelMutesUpdated.js +14 -0
  155. package/lib/commonjs/mock-builders/event/notificationChannelMutesUpdated.js.map +1 -0
  156. package/lib/commonjs/mock-builders/event/notificationMarkRead.js +14 -0
  157. package/lib/commonjs/mock-builders/event/notificationMarkRead.js.map +1 -0
  158. package/lib/commonjs/mock-builders/event/notificationMarkUnread.js +17 -0
  159. package/lib/commonjs/mock-builders/event/notificationMarkUnread.js.map +1 -0
  160. package/lib/commonjs/mock-builders/generator/channel.js +1 -0
  161. package/lib/commonjs/mock-builders/generator/channel.js.map +1 -1
  162. package/lib/commonjs/store/SqliteClient.js +11 -2
  163. package/lib/commonjs/store/SqliteClient.js.map +1 -1
  164. package/lib/commonjs/utils/getTrimmedAttachmentTitle.js +8 -2
  165. package/lib/commonjs/utils/getTrimmedAttachmentTitle.js.map +1 -1
  166. package/lib/commonjs/utils/utils.js +3 -2
  167. package/lib/commonjs/utils/utils.js.map +1 -1
  168. package/lib/commonjs/version.json +1 -1
  169. package/lib/module/components/AITypingIndicatorView/AITypingIndicatorView.js +53 -0
  170. package/lib/module/components/AITypingIndicatorView/AITypingIndicatorView.js.map +1 -0
  171. package/lib/module/components/AITypingIndicatorView/hooks/useAIState.js +59 -0
  172. package/lib/module/components/AITypingIndicatorView/hooks/useAIState.js.map +1 -0
  173. package/lib/module/components/AITypingIndicatorView/index.js +26 -0
  174. package/lib/module/components/AITypingIndicatorView/index.js.map +1 -0
  175. package/lib/module/components/Attachment/AudioAttachment.js +27 -22
  176. package/lib/module/components/Attachment/AudioAttachment.js.map +1 -1
  177. package/lib/module/components/Attachment/Gallery.js +3 -1
  178. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  179. package/lib/module/components/AttachmentPicker/AttachmentPicker.js +2 -2
  180. package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  181. package/lib/module/components/AttachmentPicker/components/AttachmentPickerItem.js +37 -133
  182. package/lib/module/components/AttachmentPicker/components/AttachmentPickerItem.js.map +1 -1
  183. package/lib/module/components/AttachmentPicker/components/AttachmentPickerSelectionBar.js +6 -4
  184. package/lib/module/components/AttachmentPicker/components/AttachmentPickerSelectionBar.js.map +1 -1
  185. package/lib/module/components/Channel/Channel.js +483 -1056
  186. package/lib/module/components/Channel/Channel.js.map +1 -1
  187. package/lib/module/components/Channel/hooks/useChannelDataState.js +174 -0
  188. package/lib/module/components/Channel/hooks/useChannelDataState.js.map +1 -0
  189. package/lib/module/components/Channel/hooks/useCreateChannelContext.js +0 -6
  190. package/lib/module/components/Channel/hooks/useCreateChannelContext.js.map +1 -1
  191. package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js +2 -0
  192. package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
  193. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +4 -0
  194. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  195. package/lib/module/components/Channel/hooks/useCreatePaginatedMessageListContext.js +3 -3
  196. package/lib/module/components/Channel/hooks/useCreatePaginatedMessageListContext.js.map +1 -1
  197. package/lib/module/components/Channel/hooks/useMessageListPagination.js +324 -0
  198. package/lib/module/components/Channel/hooks/useMessageListPagination.js.map +1 -0
  199. package/lib/module/components/ChannelList/Skeleton.js +7 -3
  200. package/lib/module/components/ChannelList/Skeleton.js.map +1 -1
  201. package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js +85 -45
  202. package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
  203. package/lib/module/components/ChannelPreview/ChannelPreview.js +17 -91
  204. package/lib/module/components/ChannelPreview/ChannelPreview.js.map +1 -1
  205. package/lib/module/components/ChannelPreview/ChannelPreviewMessenger.js +3 -24
  206. package/lib/module/components/ChannelPreview/ChannelPreviewMessenger.js.map +1 -1
  207. package/lib/module/components/ChannelPreview/ChannelPreviewMutedStatus.js +2 -2
  208. package/lib/module/components/ChannelPreview/ChannelPreviewMutedStatus.js.map +1 -1
  209. package/lib/module/components/ChannelPreview/hooks/useChannelPreviewData.js +121 -0
  210. package/lib/module/components/ChannelPreview/hooks/useChannelPreviewData.js.map +1 -0
  211. package/lib/module/components/ChannelPreview/hooks/useIsChannelMuted.js +35 -0
  212. package/lib/module/components/ChannelPreview/hooks/useIsChannelMuted.js.map +1 -0
  213. package/lib/module/components/Chat/Chat.js +5 -1
  214. package/lib/module/components/Chat/Chat.js.map +1 -1
  215. package/lib/module/components/Chat/hooks/useAppSettings.js +15 -9
  216. package/lib/module/components/Chat/hooks/useAppSettings.js.map +1 -1
  217. package/lib/module/components/Chat/hooks/useCreateChatContext.js +2 -0
  218. package/lib/module/components/Chat/hooks/useCreateChatContext.js.map +1 -1
  219. package/lib/module/components/Chat/hooks/useIsOnline.js +0 -4
  220. package/lib/module/components/Chat/hooks/useIsOnline.js.map +1 -1
  221. package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
  222. package/lib/module/components/ImageGallery/components/ImageGalleryFooter.js +46 -46
  223. package/lib/module/components/ImageGallery/components/ImageGalleryFooter.js.map +1 -1
  224. package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js +3 -4
  225. package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
  226. package/lib/module/components/ImageGallery/hooks/useAnimatedGalleryStyle.js +2 -2
  227. package/lib/module/components/ImageGallery/hooks/useAnimatedGalleryStyle.js.map +1 -1
  228. package/lib/module/components/Message/Message.js +7 -0
  229. package/lib/module/components/Message/Message.js.map +1 -1
  230. package/lib/module/components/Message/MessageSimple/MessageContent.js +17 -4
  231. package/lib/module/components/Message/MessageSimple/MessageContent.js.map +1 -1
  232. package/lib/module/components/Message/MessageSimple/MessageFooter.js +15 -6
  233. package/lib/module/components/Message/MessageSimple/MessageFooter.js.map +1 -1
  234. package/lib/module/components/Message/MessageSimple/StreamingMessageView.js +36 -0
  235. package/lib/module/components/Message/MessageSimple/StreamingMessageView.js.map +1 -0
  236. package/lib/module/components/Message/MessageSimple/utils/generateMarkdownText.js +9 -1
  237. package/lib/module/components/Message/MessageSimple/utils/generateMarkdownText.js.map +1 -1
  238. package/lib/module/components/Message/MessageSimple/utils/renderText.js +209 -23
  239. package/lib/module/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  240. package/lib/module/components/Message/hooks/useCreateMessageContext.js +2 -0
  241. package/lib/module/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  242. package/lib/module/components/Message/hooks/useStreamingMessage.js +43 -0
  243. package/lib/module/components/Message/hooks/useStreamingMessage.js.map +1 -0
  244. package/lib/module/components/MessageInput/MessageInput.js +41 -21
  245. package/lib/module/components/MessageInput/MessageInput.js.map +1 -1
  246. package/lib/module/components/MessageInput/StopMessageStreamingButton.js +39 -0
  247. package/lib/module/components/MessageInput/StopMessageStreamingButton.js.map +1 -0
  248. package/lib/module/components/MessageList/MessageList.js +74 -73
  249. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  250. package/lib/module/components/MessageList/ScrollToBottomButton.js +1 -1
  251. package/lib/module/components/MessageList/ScrollToBottomButton.js.map +1 -1
  252. package/lib/module/components/MessageList/hooks/useMessageList.js.map +1 -1
  253. package/lib/module/components/MessageList/utils/getReadStates.js.map +1 -1
  254. package/lib/module/components/MessageMenu/MessageUserReactions.js +1 -1
  255. package/lib/module/components/MessageMenu/MessageUserReactions.js.map +1 -1
  256. package/lib/module/components/MessageMenu/MessageUserReactionsItem.js +4 -2
  257. package/lib/module/components/MessageMenu/MessageUserReactionsItem.js.map +1 -1
  258. package/lib/module/components/MessageMenu/hooks/useFetchReactions.js +3 -2
  259. package/lib/module/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
  260. package/lib/module/components/Poll/CreatePollContent.js +14 -9
  261. package/lib/module/components/Poll/CreatePollContent.js.map +1 -1
  262. package/lib/module/components/Poll/Poll.js +2 -8
  263. package/lib/module/components/Poll/Poll.js.map +1 -1
  264. package/lib/module/components/Poll/components/Button.js +9 -474
  265. package/lib/module/components/Poll/components/Button.js.map +1 -1
  266. package/lib/module/components/Poll/components/CreatePollIcon.js +2 -2
  267. package/lib/module/components/Poll/components/CreatePollIcon.js.map +1 -1
  268. package/lib/module/components/Poll/components/CreatePollOptions.js +9 -4
  269. package/lib/module/components/Poll/components/CreatePollOptions.js.map +1 -1
  270. package/lib/module/components/Poll/components/PollAnswersList.js +99 -26
  271. package/lib/module/components/Poll/components/PollAnswersList.js.map +1 -1
  272. package/lib/module/components/Poll/components/PollButtons.js +291 -0
  273. package/lib/module/components/Poll/components/PollButtons.js.map +1 -0
  274. package/lib/module/components/Poll/components/PollInputDialog.js +14 -4
  275. package/lib/module/components/Poll/components/PollInputDialog.js.map +1 -1
  276. package/lib/module/components/Poll/components/PollModalHeader.js +7 -1
  277. package/lib/module/components/Poll/components/PollModalHeader.js.map +1 -1
  278. package/lib/module/components/Poll/components/PollOption.js +88 -6
  279. package/lib/module/components/Poll/components/PollOption.js.map +1 -1
  280. package/lib/module/components/Poll/components/PollResults/PollOptionFullResults.js +2 -2
  281. package/lib/module/components/Poll/components/PollResults/PollOptionFullResults.js.map +1 -1
  282. package/lib/module/components/Poll/components/PollResults/PollResultItem.js +62 -67
  283. package/lib/module/components/Poll/components/PollResults/PollResultItem.js.map +1 -1
  284. package/lib/module/components/Poll/components/PollResults/PollVote.js +89 -0
  285. package/lib/module/components/Poll/components/PollResults/PollVote.js.map +1 -0
  286. package/lib/module/components/Poll/components/index.js +11 -0
  287. package/lib/module/components/Poll/components/index.js.map +1 -1
  288. package/lib/module/components/ThreadList/ThreadList.js +0 -3
  289. package/lib/module/components/ThreadList/ThreadList.js.map +1 -1
  290. package/lib/module/components/UIComponents/BottomSheetModal.js +11 -5
  291. package/lib/module/components/UIComponents/BottomSheetModal.js.map +1 -1
  292. package/lib/module/components/index.js +66 -0
  293. package/lib/module/components/index.js.map +1 -1
  294. package/lib/module/contexts/channelContext/ChannelContext.js.map +1 -1
  295. package/lib/module/contexts/channelsStateContext/ChannelsStateContext.js +0 -35
  296. package/lib/module/contexts/channelsStateContext/ChannelsStateContext.js.map +1 -1
  297. package/lib/module/contexts/channelsStateContext/useChannelState.js +7 -84
  298. package/lib/module/contexts/channelsStateContext/useChannelState.js.map +1 -1
  299. package/lib/module/contexts/chatContext/ChatContext.js.map +1 -1
  300. package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
  301. package/lib/module/contexts/messageInputContext/MessageInputContext.js +4 -2
  302. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  303. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +2 -0
  304. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  305. package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
  306. package/lib/module/contexts/paginatedMessageListContext/PaginatedMessageListContext.js.map +1 -1
  307. package/lib/module/contexts/themeContext/utils/theme.js +15 -0
  308. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  309. package/lib/module/i18n/en.json +2 -0
  310. package/lib/module/i18n/es.json +2 -0
  311. package/lib/module/i18n/fr.json +2 -0
  312. package/lib/module/i18n/he.json +2 -0
  313. package/lib/module/i18n/hi.json +2 -0
  314. package/lib/module/i18n/it.json +2 -0
  315. package/lib/module/i18n/ja.json +2 -0
  316. package/lib/module/i18n/ko.json +2 -0
  317. package/lib/module/i18n/nl.json +2 -0
  318. package/lib/module/i18n/pt-br.json +2 -0
  319. package/lib/module/i18n/ru.json +2 -0
  320. package/lib/module/i18n/tr.json +2 -0
  321. package/lib/module/mock-builders/event/notificationChannelMutesUpdated.js +14 -0
  322. package/lib/module/mock-builders/event/notificationChannelMutesUpdated.js.map +1 -0
  323. package/lib/module/mock-builders/event/notificationMarkRead.js +14 -0
  324. package/lib/module/mock-builders/event/notificationMarkRead.js.map +1 -0
  325. package/lib/module/mock-builders/event/notificationMarkUnread.js +17 -0
  326. package/lib/module/mock-builders/event/notificationMarkUnread.js.map +1 -0
  327. package/lib/module/mock-builders/generator/channel.js +1 -0
  328. package/lib/module/mock-builders/generator/channel.js.map +1 -1
  329. package/lib/module/store/SqliteClient.js +11 -2
  330. package/lib/module/store/SqliteClient.js.map +1 -1
  331. package/lib/module/utils/getTrimmedAttachmentTitle.js +8 -2
  332. package/lib/module/utils/getTrimmedAttachmentTitle.js.map +1 -1
  333. package/lib/module/utils/utils.js +3 -2
  334. package/lib/module/utils/utils.js.map +1 -1
  335. package/lib/module/version.json +1 -1
  336. package/lib/typescript/components/AITypingIndicatorView/AITypingIndicatorView.d.ts +11 -0
  337. package/lib/typescript/components/AITypingIndicatorView/AITypingIndicatorView.d.ts.map +1 -0
  338. package/lib/typescript/components/AITypingIndicatorView/hooks/useAIState.d.ts +18 -0
  339. package/lib/typescript/components/AITypingIndicatorView/hooks/useAIState.d.ts.map +1 -0
  340. package/lib/typescript/components/AITypingIndicatorView/index.d.ts +3 -0
  341. package/lib/typescript/components/AITypingIndicatorView/index.d.ts.map +1 -0
  342. package/lib/typescript/components/Attachment/AudioAttachment.d.ts.map +1 -1
  343. package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts.map +1 -1
  344. package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerItem.d.ts.map +1 -1
  345. package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerSelectionBar.d.ts.map +1 -1
  346. package/lib/typescript/components/Channel/Channel.d.ts +7 -6
  347. package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
  348. package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts +75 -0
  349. package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts.map +1 -0
  350. package/lib/typescript/components/Channel/hooks/useCreateChannelContext.d.ts +1 -1
  351. package/lib/typescript/components/Channel/hooks/useCreateChannelContext.d.ts.map +1 -1
  352. package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts +1 -1
  353. package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts.map +1 -1
  354. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +128 -1
  355. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts.map +1 -1
  356. package/lib/typescript/components/Channel/hooks/useCreatePaginatedMessageListContext.d.ts +1 -1
  357. package/lib/typescript/components/Channel/hooks/useCreatePaginatedMessageListContext.d.ts.map +1 -1
  358. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts +28 -0
  359. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts.map +1 -0
  360. package/lib/typescript/components/ChannelList/Skeleton.d.ts.map +1 -1
  361. package/lib/typescript/components/ChannelList/hooks/usePaginatedChannels.d.ts.map +1 -1
  362. package/lib/typescript/components/ChannelPreview/ChannelPreview.d.ts +1 -2
  363. package/lib/typescript/components/ChannelPreview/ChannelPreview.d.ts.map +1 -1
  364. package/lib/typescript/components/ChannelPreview/ChannelPreviewMessenger.d.ts +2 -0
  365. package/lib/typescript/components/ChannelPreview/ChannelPreviewMessenger.d.ts.map +1 -1
  366. package/lib/typescript/components/ChannelPreview/ChannelPreviewMutedStatus.d.ts.map +1 -1
  367. package/lib/typescript/components/ChannelPreview/hooks/useChannelPreviewData.d.ts +8 -0
  368. package/lib/typescript/components/ChannelPreview/hooks/useChannelPreviewData.d.ts.map +1 -0
  369. package/lib/typescript/components/ChannelPreview/hooks/useIsChannelMuted.d.ts +8 -0
  370. package/lib/typescript/components/ChannelPreview/hooks/useIsChannelMuted.d.ts.map +1 -0
  371. package/lib/typescript/components/Chat/Chat.d.ts +7 -1
  372. package/lib/typescript/components/Chat/Chat.d.ts.map +1 -1
  373. package/lib/typescript/components/Chat/hooks/useAppSettings.d.ts.map +1 -1
  374. package/lib/typescript/components/Chat/hooks/useCreateChatContext.d.ts +1 -1
  375. package/lib/typescript/components/Chat/hooks/useCreateChatContext.d.ts.map +1 -1
  376. package/lib/typescript/components/Chat/hooks/useIsOnline.d.ts.map +1 -1
  377. package/lib/typescript/components/ImageGallery/ImageGallery.d.ts.map +1 -1
  378. package/lib/typescript/components/Message/Message.d.ts +1 -1
  379. package/lib/typescript/components/Message/Message.d.ts.map +1 -1
  380. package/lib/typescript/components/Message/MessageSimple/MessageContent.d.ts +1 -1
  381. package/lib/typescript/components/Message/MessageSimple/MessageContent.d.ts.map +1 -1
  382. package/lib/typescript/components/Message/MessageSimple/MessageFooter.d.ts.map +1 -1
  383. package/lib/typescript/components/Message/MessageSimple/StreamingMessageView.d.ts +12 -0
  384. package/lib/typescript/components/Message/MessageSimple/StreamingMessageView.d.ts.map +1 -0
  385. package/lib/typescript/components/Message/MessageSimple/utils/generateMarkdownText.d.ts.map +1 -1
  386. package/lib/typescript/components/Message/MessageSimple/utils/renderText.d.ts +16 -1
  387. package/lib/typescript/components/Message/MessageSimple/utils/renderText.d.ts.map +1 -1
  388. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts +1 -1
  389. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts.map +1 -1
  390. package/lib/typescript/components/Message/hooks/useStreamingMessage.d.ts +17 -0
  391. package/lib/typescript/components/Message/hooks/useStreamingMessage.d.ts.map +1 -0
  392. package/lib/typescript/components/MessageInput/MessageInput.d.ts +1 -1
  393. package/lib/typescript/components/MessageInput/MessageInput.d.ts.map +1 -1
  394. package/lib/typescript/components/MessageInput/StopMessageStreamingButton.d.ts +10 -0
  395. package/lib/typescript/components/MessageInput/StopMessageStreamingButton.d.ts.map +1 -0
  396. package/lib/typescript/components/MessageList/MessageList.d.ts +1 -1
  397. package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
  398. package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts.map +1 -1
  399. package/lib/typescript/components/MessageList/utils/getReadStates.d.ts +1 -1
  400. package/lib/typescript/components/MessageList/utils/getReadStates.d.ts.map +1 -1
  401. package/lib/typescript/components/MessageMenu/MessageUserReactionsItem.d.ts.map +1 -1
  402. package/lib/typescript/components/MessageMenu/hooks/useFetchReactions.d.ts +3 -2
  403. package/lib/typescript/components/MessageMenu/hooks/useFetchReactions.d.ts.map +1 -1
  404. package/lib/typescript/components/Poll/Poll.d.ts +0 -1
  405. package/lib/typescript/components/Poll/Poll.d.ts.map +1 -1
  406. package/lib/typescript/components/Poll/components/Button.d.ts +0 -17
  407. package/lib/typescript/components/Poll/components/Button.d.ts.map +1 -1
  408. package/lib/typescript/components/Poll/components/CreatePollOptions.d.ts.map +1 -1
  409. package/lib/typescript/components/Poll/components/PollAnswersList.d.ts +2 -0
  410. package/lib/typescript/components/Poll/components/PollAnswersList.d.ts.map +1 -1
  411. package/lib/typescript/components/Poll/components/PollButtons.d.ts +10 -0
  412. package/lib/typescript/components/Poll/components/PollButtons.d.ts.map +1 -0
  413. package/lib/typescript/components/Poll/components/PollInputDialog.d.ts.map +1 -1
  414. package/lib/typescript/components/Poll/components/PollOption.d.ts +2 -0
  415. package/lib/typescript/components/Poll/components/PollOption.d.ts.map +1 -1
  416. package/lib/typescript/components/Poll/components/PollResults/PollResultItem.d.ts +11 -4
  417. package/lib/typescript/components/Poll/components/PollResults/PollResultItem.d.ts.map +1 -1
  418. package/lib/typescript/components/Poll/components/PollResults/PollVote.d.ts +6 -0
  419. package/lib/typescript/components/Poll/components/PollResults/PollVote.d.ts.map +1 -0
  420. package/lib/typescript/components/Poll/components/index.d.ts +1 -0
  421. package/lib/typescript/components/Poll/components/index.d.ts.map +1 -1
  422. package/lib/typescript/components/ThreadList/ThreadList.d.ts.map +1 -1
  423. package/lib/typescript/components/UIComponents/BottomSheetModal.d.ts.map +1 -1
  424. package/lib/typescript/components/index.d.ts +6 -0
  425. package/lib/typescript/components/index.d.ts.map +1 -1
  426. package/lib/typescript/contexts/channelContext/ChannelContext.d.ts +27 -37
  427. package/lib/typescript/contexts/channelContext/ChannelContext.d.ts.map +1 -1
  428. package/lib/typescript/contexts/channelsStateContext/ChannelsStateContext.d.ts +0 -16
  429. package/lib/typescript/contexts/channelsStateContext/ChannelsStateContext.d.ts.map +1 -1
  430. package/lib/typescript/contexts/channelsStateContext/useChannelState.d.ts +7 -13
  431. package/lib/typescript/contexts/channelsStateContext/useChannelState.d.ts.map +1 -1
  432. package/lib/typescript/contexts/chatContext/ChatContext.d.ts +2 -1
  433. package/lib/typescript/contexts/chatContext/ChatContext.d.ts.map +1 -1
  434. package/lib/typescript/contexts/messageContext/MessageContext.d.ts +4 -0
  435. package/lib/typescript/contexts/messageContext/MessageContext.d.ts.map +1 -1
  436. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +2 -1
  437. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts.map +1 -1
  438. package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts +1 -1
  439. package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts.map +1 -1
  440. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +8 -4
  441. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts.map +1 -1
  442. package/lib/typescript/contexts/paginatedMessageListContext/PaginatedMessageListContext.d.ts +17 -16
  443. package/lib/typescript/contexts/paginatedMessageListContext/PaginatedMessageListContext.d.ts.map +1 -1
  444. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +16 -1
  445. package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
  446. package/lib/typescript/i18n/en.json +2 -0
  447. package/lib/typescript/i18n/es.json +2 -0
  448. package/lib/typescript/i18n/fr.json +2 -0
  449. package/lib/typescript/i18n/he.json +2 -0
  450. package/lib/typescript/i18n/hi.json +2 -0
  451. package/lib/typescript/i18n/it.json +2 -0
  452. package/lib/typescript/i18n/ja.json +2 -0
  453. package/lib/typescript/i18n/ko.json +2 -0
  454. package/lib/typescript/i18n/nl.json +2 -0
  455. package/lib/typescript/i18n/pt-br.json +2 -0
  456. package/lib/typescript/i18n/ru.json +2 -0
  457. package/lib/typescript/i18n/tr.json +2 -0
  458. package/lib/typescript/store/SqliteClient.d.ts.map +1 -1
  459. package/lib/typescript/types/types.d.ts +3 -0
  460. package/lib/typescript/types/types.d.ts.map +1 -1
  461. package/lib/typescript/utils/getTrimmedAttachmentTitle.d.ts.map +1 -1
  462. package/lib/typescript/utils/i18n/Streami18n.d.ts +2 -0
  463. package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
  464. package/lib/typescript/utils/utils.d.ts.map +1 -1
  465. package/package.json +5 -5
  466. package/src/components/AITypingIndicatorView/AITypingIndicatorView.tsx +50 -0
  467. package/src/components/AITypingIndicatorView/hooks/useAIState.ts +68 -0
  468. package/src/components/AITypingIndicatorView/index.ts +2 -0
  469. package/src/components/Attachment/AudioAttachment.tsx +20 -19
  470. package/src/components/Attachment/Gallery.tsx +1 -1
  471. package/src/components/AttachmentPicker/AttachmentPicker.tsx +7 -2
  472. package/src/components/AttachmentPicker/components/AttachmentPickerItem.tsx +16 -32
  473. package/src/components/AttachmentPicker/components/AttachmentPickerSelectionBar.tsx +3 -5
  474. package/src/components/Channel/Channel.tsx +262 -835
  475. package/src/components/Channel/__tests__/Channel.test.js +244 -13
  476. package/src/components/Channel/__tests__/useMessageListPagination.test.js +419 -0
  477. package/src/components/Channel/hooks/useChannelDataState.ts +235 -0
  478. package/src/components/Channel/hooks/useCreateChannelContext.ts +0 -6
  479. package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts +2 -0
  480. package/src/components/Channel/hooks/useCreateMessagesContext.ts +4 -0
  481. package/src/components/Channel/hooks/useCreatePaginatedMessageListContext.ts +3 -10
  482. package/src/components/Channel/hooks/useMessageListPagination.tsx +246 -0
  483. package/src/components/ChannelList/Skeleton.tsx +9 -1
  484. package/src/components/ChannelList/hooks/usePaginatedChannels.ts +37 -30
  485. package/src/components/ChannelPreview/ChannelPreview.tsx +28 -107
  486. package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx +5 -15
  487. package/src/components/ChannelPreview/ChannelPreviewMutedStatus.tsx +2 -7
  488. package/src/components/ChannelPreview/__tests__/ChannelPreview.test.tsx +226 -10
  489. package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx +1 -1
  490. package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewMuted.test.tsx +62 -0
  491. package/src/components/ChannelPreview/hooks/useChannelPreviewData.ts +138 -0
  492. package/src/components/ChannelPreview/hooks/useIsChannelMuted.ts +29 -0
  493. package/src/components/Chat/Chat.tsx +11 -2
  494. package/src/components/Chat/hooks/__tests__/useAppSettings.test.tsx +1 -0
  495. package/src/components/Chat/hooks/useAppSettings.ts +2 -0
  496. package/src/components/Chat/hooks/useCreateChatContext.ts +2 -0
  497. package/src/components/Chat/hooks/useIsOnline.ts +0 -5
  498. package/src/components/ImageGallery/ImageGallery.tsx +1 -0
  499. package/src/components/ImageGallery/components/ImageGalleryFooter.tsx +32 -32
  500. package/src/components/ImageGallery/components/ImageGalleryHeader.tsx +5 -6
  501. package/src/components/ImageGallery/hooks/useAnimatedGalleryStyle.tsx +2 -2
  502. package/src/components/Message/Message.tsx +16 -2
  503. package/src/components/Message/MessageSimple/MessageContent.tsx +22 -2
  504. package/src/components/Message/MessageSimple/MessageFooter.tsx +16 -5
  505. package/src/components/Message/MessageSimple/StreamingMessageView.tsx +34 -0
  506. package/src/components/Message/MessageSimple/utils/generateMarkdownText.ts +15 -1
  507. package/src/components/Message/MessageSimple/utils/renderText.tsx +207 -3
  508. package/src/components/Message/hooks/useCreateMessageContext.ts +2 -0
  509. package/src/components/Message/hooks/useStreamingMessage.ts +54 -0
  510. package/src/components/MessageInput/MessageInput.tsx +38 -20
  511. package/src/components/MessageInput/StopMessageStreamingButton.tsx +34 -0
  512. package/src/components/MessageInput/__tests__/MessageInput.test.js +116 -2
  513. package/src/components/MessageList/MessageList.tsx +53 -85
  514. package/src/components/MessageList/ScrollToBottomButton.tsx +1 -1
  515. package/src/components/MessageList/__tests__/MessageList.test.js +174 -2
  516. package/src/components/MessageList/__tests__/ScrollToBottomButton.test.js +3 -3
  517. package/src/components/MessageList/__tests__/__snapshots__/ScrollToBottomButton.test.js.snap +1 -1
  518. package/src/components/MessageList/hooks/useMessageList.ts +2 -5
  519. package/src/components/MessageList/utils/getReadStates.ts +3 -2
  520. package/src/components/MessageMenu/MessageUserReactions.tsx +1 -1
  521. package/src/components/MessageMenu/MessageUserReactionsItem.tsx +4 -2
  522. package/src/components/MessageMenu/hooks/useFetchReactions.ts +6 -3
  523. package/src/components/Poll/CreatePollContent.tsx +4 -4
  524. package/src/components/Poll/Poll.tsx +1 -20
  525. package/src/components/Poll/components/Button.tsx +8 -420
  526. package/src/components/Poll/components/CreatePollIcon.tsx +1 -1
  527. package/src/components/Poll/components/CreatePollOptions.tsx +9 -4
  528. package/src/components/Poll/components/PollAnswersList.tsx +66 -3
  529. package/src/components/Poll/components/PollButtons.tsx +241 -0
  530. package/src/components/Poll/components/PollInputDialog.tsx +9 -6
  531. package/src/components/Poll/components/PollModalHeader.tsx +3 -3
  532. package/src/components/Poll/components/PollOption.tsx +74 -4
  533. package/src/components/Poll/components/PollResults/PollOptionFullResults.tsx +1 -1
  534. package/src/components/Poll/components/PollResults/PollResultItem.tsx +68 -52
  535. package/src/components/Poll/components/PollResults/PollVote.tsx +68 -0
  536. package/src/components/Poll/components/index.ts +1 -0
  537. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +37 -4
  538. package/src/components/ThreadList/ThreadList.tsx +0 -2
  539. package/src/components/UIComponents/BottomSheetModal.tsx +7 -3
  540. package/src/components/index.ts +7 -0
  541. package/src/contexts/channelContext/ChannelContext.tsx +35 -37
  542. package/src/contexts/channelsStateContext/ChannelsStateContext.tsx +1 -67
  543. package/src/contexts/channelsStateContext/useChannelState.ts +6 -108
  544. package/src/contexts/chatContext/ChatContext.tsx +2 -1
  545. package/src/contexts/messageContext/MessageContext.tsx +4 -0
  546. package/src/contexts/messageInputContext/MessageInputContext.tsx +5 -1
  547. package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts +2 -0
  548. package/src/contexts/messagesContext/MessagesContext.tsx +8 -3
  549. package/src/contexts/paginatedMessageListContext/PaginatedMessageListContext.tsx +17 -16
  550. package/src/contexts/themeContext/utils/theme.ts +30 -1
  551. package/src/i18n/en.json +2 -0
  552. package/src/i18n/es.json +2 -0
  553. package/src/i18n/fr.json +2 -0
  554. package/src/i18n/he.json +2 -0
  555. package/src/i18n/hi.json +2 -0
  556. package/src/i18n/it.json +2 -0
  557. package/src/i18n/ja.json +2 -0
  558. package/src/i18n/ko.json +2 -0
  559. package/src/i18n/nl.json +2 -0
  560. package/src/i18n/pt-br.json +2 -0
  561. package/src/i18n/ru.json +2 -0
  562. package/src/i18n/tr.json +2 -0
  563. package/src/mock-builders/event/notificationChannelMutesUpdated.js +7 -0
  564. package/src/mock-builders/event/notificationMarkRead.js +7 -0
  565. package/src/mock-builders/event/notificationMarkUnread.js +9 -0
  566. package/src/mock-builders/generator/channel.ts +1 -0
  567. package/src/store/SqliteClient.ts +5 -1
  568. package/src/types/types.ts +3 -0
  569. package/src/utils/getTrimmedAttachmentTitle.ts +10 -2
  570. package/src/utils/utils.ts +5 -2
  571. package/src/version.json +1 -1
@@ -1,4 +1,4 @@
1
- import React, { PropsWithChildren, useCallback, useEffect, useMemo, useRef, useState } from 'react';
1
+ import React, { PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { KeyboardAvoidingViewProps, StyleSheet, Text, View } from 'react-native';
3
3
 
4
4
  import debounce from 'lodash/debounce';
@@ -11,6 +11,7 @@ import {
11
11
  ChannelState,
12
12
  Channel as ChannelType,
13
13
  EventHandler,
14
+ FormatMessageResponse,
14
15
  logChatPromiseExecution,
15
16
  MessageResponse,
16
17
  Reaction,
@@ -21,6 +22,7 @@ import {
21
22
  Thread,
22
23
  } from 'stream-chat';
23
24
 
25
+ import { useChannelDataState } from './hooks/useChannelDataState';
24
26
  import { useCreateChannelContext } from './hooks/useCreateChannelContext';
25
27
 
26
28
  import { useCreateInputMessageInputContext } from './hooks/useCreateInputMessageInputContext';
@@ -34,8 +36,10 @@ import { useCreateThreadContext } from './hooks/useCreateThreadContext';
34
36
 
35
37
  import { useCreateTypingContext } from './hooks/useCreateTypingContext';
36
38
 
39
+ import { useMessageListPagination } from './hooks/useMessageListPagination';
37
40
  import { useTargetedMessage } from './hooks/useTargetedMessage';
38
41
 
42
+ import { MessageContextValue } from '../../contexts';
39
43
  import { ChannelContextValue, ChannelProvider } from '../../contexts/channelContext/ChannelContext';
40
44
  import type { UseChannelStateValue } from '../../contexts/channelsStateContext/useChannelState';
41
45
  import { useChannelState } from '../../contexts/channelsStateContext/useChannelState';
@@ -142,6 +146,7 @@ import { MessageStatus as MessageStatusDefault } from '../Message/MessageSimple/
142
146
  import { MessageTimestamp as MessageTimestampDefault } from '../Message/MessageSimple/MessageTimestamp';
143
147
  import { ReactionListBottom as ReactionListBottomDefault } from '../Message/MessageSimple/ReactionList/ReactionListBottom';
144
148
  import { ReactionListTop as ReactionListTopDefault } from '../Message/MessageSimple/ReactionList/ReactionListTop';
149
+ import { StreamingMessageView as DefaultStreamingMessageView } from '../Message/MessageSimple/StreamingMessageView';
145
150
  import { AttachButton as AttachButtonDefault } from '../MessageInput/AttachButton';
146
151
  import { CommandsButton as CommandsButtonDefault } from '../MessageInput/CommandsButton';
147
152
  import { AudioRecorder as AudioRecorderDefault } from '../MessageInput/components/AudioRecorder/AudioRecorder';
@@ -161,6 +166,7 @@ import { MoreOptionsButton as MoreOptionsButtonDefault } from '../MessageInput/M
161
166
  import { SendButton as SendButtonDefault } from '../MessageInput/SendButton';
162
167
  import { SendMessageDisallowedIndicator as SendMessageDisallowedIndicatorDefault } from '../MessageInput/SendMessageDisallowedIndicator';
163
168
  import { ShowThreadMessageInChannelButton as ShowThreadMessageInChannelButtonDefault } from '../MessageInput/ShowThreadMessageInChannelButton';
169
+ import { StopMessageStreamingButton as DefaultStopMessageStreamingButton } from '../MessageInput/StopMessageStreamingButton';
164
170
  import { UploadProgressIndicator as UploadProgressIndicatorDefault } from '../MessageInput/UploadProgressIndicator';
165
171
  import { DateHeader as DateHeaderDefault } from '../MessageList/DateHeader';
166
172
  import type { MessageType } from '../MessageList/hooks/useMessageList';
@@ -265,7 +271,7 @@ export type ChannelPropsWithContext<
265
271
  'messages' | 'loadingMore' | 'loadingMoreRecent'
266
272
  >
267
273
  > &
268
- UseChannelStateValue<StreamChatGenerics> &
274
+ Pick<UseChannelStateValue<StreamChatGenerics>, 'threadMessages' | 'setThreadMessages'> &
269
275
  Partial<
270
276
  Pick<
271
277
  MessagesContextValue<StreamChatGenerics>,
@@ -354,8 +360,10 @@ export type ChannelPropsWithContext<
354
360
  | 'VideoThumbnail'
355
361
  | 'PollContent'
356
362
  | 'hasCreatePoll'
363
+ | 'StreamingMessageView'
357
364
  >
358
365
  > &
366
+ Partial<Pick<MessageContextValue<StreamChatGenerics>, 'isMessageAIGenerated'>> &
359
367
  Partial<Pick<ThreadContextValue<StreamChatGenerics>, 'allowThreadMessagesInChannel'>> & {
360
368
  shouldSyncChannel: boolean;
361
369
  thread: ThreadType<StreamChatGenerics>;
@@ -363,10 +371,6 @@ export type ChannelPropsWithContext<
363
371
  * Additional props passed to keyboard avoiding view
364
372
  */
365
373
  additionalKeyboardAvoidingViewProps?: Partial<KeyboardAvoidingViewProps>;
366
- /**
367
- * Disables the channel UI if the channel is frozen
368
- */
369
- disableIfFrozenChannel?: boolean;
370
374
  /**
371
375
  * When true, disables the KeyboardCompatibleView wrapper
372
376
  *
@@ -434,6 +438,10 @@ export type ChannelPropsWithContext<
434
438
  * Load the channel at a specified message instead of the most recent message.
435
439
  */
436
440
  messageId?: string;
441
+ /**
442
+ * @deprecated
443
+ * The time interval for throttling while updating the message state
444
+ */
437
445
  newMessageStateUpdateThrottleInterval?: number;
438
446
  overrideOwnCapabilities?: Partial<OwnCapabilitiesContextValue>;
439
447
  stateUpdateThrottleInterval?: number;
@@ -441,7 +449,12 @@ export type ChannelPropsWithContext<
441
449
  * Tells if channel is rendering a thread list
442
450
  */
443
451
  threadList?: boolean;
444
- } & Partial<Pick<InputMessageInputContextValue, 'openPollCreationDialog' | 'CreatePollContent'>>;
452
+ } & Partial<
453
+ Pick<
454
+ InputMessageInputContextValue,
455
+ 'openPollCreationDialog' | 'CreatePollContent' | 'StopMessageStreamingButton'
456
+ >
457
+ >;
445
458
 
446
459
  const ChannelWithContext = <
447
460
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -486,7 +499,6 @@ const ChannelWithContext = <
486
499
  CreatePollContent,
487
500
  DateHeader = DateHeaderDefault,
488
501
  deletedMessagesVisibilityType = 'always',
489
- disableIfFrozenChannel = true,
490
502
  disableKeyboardCompatibleView = false,
491
503
  disableTypingIndicator,
492
504
  dismissKeyboardOnMessageTouch = true,
@@ -544,6 +556,7 @@ const ChannelWithContext = <
544
556
  InputGiphySearch = InputGiphyCommandInputDefault,
545
557
  InputReplyStateHeader = InputReplyStateHeaderDefault,
546
558
  isAttachmentEqual,
559
+ isMessageAIGenerated = () => false,
547
560
  keyboardBehavior,
548
561
  KeyboardCompatibleView = KeyboardCompatibleViewDefault,
549
562
  keyboardVerticalOffset,
@@ -556,7 +569,6 @@ const ChannelWithContext = <
556
569
  maxMessageLength: maxMessageLengthProp,
557
570
  maxNumberOfFiles = 10,
558
571
  maxTimeBetweenGroupedMessages,
559
- members,
560
572
  mentionAllAppUsersEnabled = false,
561
573
  mentionAllAppUsersQuery,
562
574
  Message = MessageDefault,
@@ -566,7 +578,15 @@ const ChannelWithContext = <
566
578
  MessageAvatar = MessageAvatarDefault,
567
579
  MessageBounce = MessageBounceDefault,
568
580
  MessageContent = MessageContentDefault,
569
- messageContentOrder = ['quoted_reply', 'gallery', 'files', 'poll', 'text', 'attachments'],
581
+ messageContentOrder = [
582
+ 'quoted_reply',
583
+ 'gallery',
584
+ 'files',
585
+ 'poll',
586
+ 'ai_text',
587
+ 'text',
588
+ 'attachments',
589
+ ],
570
590
  MessageDeleted = MessageDeletedDefault,
571
591
  MessageEditedTimestamp = MessageEditedTimestampDefault,
572
592
  MessageError = MessageErrorDefault,
@@ -579,12 +599,11 @@ const ChannelWithContext = <
579
599
  MessageReactionPicker = MessageReactionPickerDefault,
580
600
  MessageReplies = MessageRepliesDefault,
581
601
  MessageRepliesAvatars = MessageRepliesAvatarsDefault,
582
- messages,
583
602
  MessageSimple = MessageSimpleDefault,
584
603
  MessageStatus = MessageStatusDefault,
585
604
  MessageSystem = MessageSystemDefault,
586
605
  MessageText,
587
- messageTextNumberOfLines = 5,
606
+ messageTextNumberOfLines,
588
607
  MessageTimestamp = MessageTimestampDefault,
589
608
  MessageUserReactions = MessageUserReactionsDefault,
590
609
  MessageUserReactionsAvatar = MessageUserReactionsAvatarDefault,
@@ -592,6 +611,7 @@ const ChannelWithContext = <
592
611
  MoreOptionsButton = MoreOptionsButtonDefault,
593
612
  myMessageTheme,
594
613
  NetworkDownIndicator = NetworkDownIndicatorDefault,
614
+ // TODO: Think about this one
595
615
  newMessageStateUpdateThrottleInterval = defaultThrottleInterval,
596
616
  numberOfLines = 5,
597
617
  onChangeText,
@@ -604,7 +624,6 @@ const ChannelWithContext = <
604
624
  ReactionListBottom = ReactionListBottomDefault,
605
625
  reactionListPosition = 'top',
606
626
  ReactionListTop = ReactionListTopDefault,
607
- read,
608
627
  Reply = ReplyDefault,
609
628
  ScrollToBottomButton = ScrollToBottomButtonDefault,
610
629
  selectReaction,
@@ -612,35 +631,32 @@ const ChannelWithContext = <
612
631
  sendImageAsync = false,
613
632
  SendMessageDisallowedIndicator = SendMessageDisallowedIndicatorDefault,
614
633
  setInputRef,
615
- setMembers,
616
- setMessages,
617
- setRead,
618
634
  setThreadMessages,
619
- setTyping,
620
- setWatcherCount,
621
- setWatchers,
622
635
  shouldShowUnreadUnderlay = true,
623
636
  shouldSyncChannel,
624
637
  ShowThreadMessageInChannelButton = ShowThreadMessageInChannelButtonDefault,
625
638
  StartAudioRecordingButton = AudioRecordingButtonDefault,
626
639
  stateUpdateThrottleInterval = defaultThrottleInterval,
627
640
  StickyHeader = StickyHeaderDefault,
641
+ StopMessageStreamingButton: StopMessageStreamingButtonOverride,
642
+ StreamingMessageView = DefaultStreamingMessageView,
628
643
  supportedReactions = reactionData,
629
644
  t,
630
645
  thread: threadFromProps,
631
646
  threadList,
632
647
  threadMessages,
633
- typing,
634
648
  TypingIndicator = TypingIndicatorDefault,
635
649
  TypingIndicatorContainer = TypingIndicatorContainerDefault,
636
650
  UploadProgressIndicator = UploadProgressIndicatorDefault,
637
651
  UrlPreview = CardDefault,
638
652
  VideoThumbnail = VideoThumbnailDefault,
639
- watcherCount,
640
- watchers,
641
653
  } = props;
642
654
 
643
655
  const { thread: threadProps, threadInstance } = threadFromProps;
656
+ const StopMessageStreamingButton =
657
+ StopMessageStreamingButtonOverride === undefined
658
+ ? DefaultStopMessageStreamingButton
659
+ : StopMessageStreamingButtonOverride;
644
660
 
645
661
  const {
646
662
  theme: {
@@ -648,15 +664,10 @@ const ChannelWithContext = <
648
664
  colors: { black },
649
665
  },
650
666
  } = useTheme();
651
- const [deleted, setDeleted] = useState(false);
667
+ const [deleted, setDeleted] = useState<boolean>(false);
652
668
  const [editing, setEditing] = useState<MessageType<StreamChatGenerics> | undefined>(undefined);
653
669
  const [error, setError] = useState<Error | boolean>(false);
654
- const [hasMore, setHasMore] = useState(true);
655
670
  const [lastRead, setLastRead] = useState<ChannelContextValue<StreamChatGenerics>['lastRead']>();
656
- const [loading, setLoading] = useState(false);
657
- const [loadingMore, setLoadingMore] = useState(false);
658
-
659
- const [loadingMoreRecent, setLoadingMoreRecent] = useState(false);
660
671
  const [quotedMessage, setQuotedMessage] = useState<MessageType<StreamChatGenerics> | undefined>(
661
672
  undefined,
662
673
  );
@@ -666,19 +677,7 @@ const ChannelWithContext = <
666
677
 
667
678
  const syncingChannelRef = useRef(false);
668
679
 
669
- /**
670
- * Flag to track if we know for sure that there are no more recent messages to load.
671
- * This is necessary to avoid unnecessary api calls to load recent messages on pagination.
672
- */
673
- const [hasNoMoreRecentMessagesToLoad, setHasNoMoreRecentMessagesToLoad] = useState(true);
674
-
675
- const { prevTargetedMessage, setTargetedMessage, targetedMessage } = useTargetedMessage();
676
-
677
- /**
678
- * If we loaded a channel around message
679
- * We may have moved latest message to a new message set in that case mark this ref to avoid fetching
680
- */
681
- const hasOverlappingRecentMessagesRef = useRef(false);
680
+ const { setTargetedMessage, targetedMessage } = useTargetedMessage();
682
681
 
683
682
  /**
684
683
  * This ref will hold the abort controllers for
@@ -690,50 +689,142 @@ const ChannelWithContext = <
690
689
  const channelId = channel?.id || '';
691
690
  const pollCreationEnabled = !channel.disconnected && !!channel?.id && channel?.getConfig()?.polls;
692
691
 
692
+ const {
693
+ copyStateFromChannel,
694
+ initStateFromChannel,
695
+ setTyping,
696
+ state: channelState,
697
+ } = useChannelDataState<StreamChatGenerics>(channel);
698
+
699
+ const {
700
+ copyMessagesStateFromChannel,
701
+ loadChannelAroundMessage: loadChannelAroundMessageFn,
702
+ loadChannelAtFirstUnreadMessage,
703
+ loadInitialMessagesStateFromChannel,
704
+ loadLatestMessages,
705
+ loadMore,
706
+ loadMoreRecent,
707
+ state: channelMessagesState,
708
+ } = useMessageListPagination<StreamChatGenerics>({
709
+ channel,
710
+ });
711
+
712
+ /**
713
+ * Since we copy the current channel state all together, we need to find the greatest time among the below two and apply it as the throttling time for copying the channel state.
714
+ * This is done until we remove the newMessageStateUpdateThrottleInterval prop.
715
+ */
716
+ const copyChannelStateThrottlingTime =
717
+ newMessageStateUpdateThrottleInterval > stateUpdateThrottleInterval
718
+ ? newMessageStateUpdateThrottleInterval
719
+ : stateUpdateThrottleInterval;
720
+
721
+ const copyChannelState = useRef(
722
+ throttle(
723
+ () => {
724
+ if (channel) {
725
+ copyStateFromChannel(channel);
726
+ copyMessagesStateFromChannel(channel);
727
+ }
728
+ },
729
+ copyChannelStateThrottlingTime,
730
+ throttleOptions,
731
+ ),
732
+ ).current;
733
+
734
+ const handleEvent: EventHandler<StreamChatGenerics> = (event) => {
735
+ if (shouldSyncChannel) {
736
+ // Ignore user.watching.start and user.watching.stop events
737
+ const ignorableEvents = ['user.watching.start', 'user.watching.stop'];
738
+ if (ignorableEvents.includes(event.type)) return;
739
+
740
+ // If the event is typing.start or typing.stop, set the typing state
741
+ const isTypingEvent = event.type === 'typing.start' || event.type === 'typing.stop';
742
+ if (isTypingEvent) {
743
+ setTyping(channel);
744
+ } else {
745
+ if (thread?.id) {
746
+ const updatedThreadMessages =
747
+ (thread.id && channel && channel.state.threads[thread.id]) || threadMessages;
748
+ setThreadMessages(updatedThreadMessages);
749
+
750
+ if (channel && event.message?.id === thread.id && !threadInstance) {
751
+ const updatedThread = channel.state.formatMessage(event.message);
752
+ setThread(updatedThread);
753
+ }
754
+ }
755
+ }
756
+
757
+ // only update channel state if the events are not the previously subscribed useEffect's subscription events
758
+ if (channel && channel.initialized) {
759
+ copyChannelState();
760
+ }
761
+ }
762
+ };
763
+
693
764
  useEffect(() => {
765
+ let listener: ReturnType<typeof channel.on>;
694
766
  const initChannel = async () => {
695
767
  if (!channel || !shouldSyncChannel || channel.offlineMode) return;
696
- /**
697
- * Loading channel at first unread message requires channel to be initialized in the first place,
698
- * since we use read state on channel to decide what offset to load channel at.
699
- * Also there is no use case from UX perspective, why one would need loading uninitialized channel at particular message.
700
- * If the channel is not initiated, then we need to do channel.watch, which is more expensive for backend than channel.query.
701
- */
702
- if (!channel.initialized) {
703
- await loadChannel();
768
+ let errored = false;
769
+
770
+ if (!channel.initialized || !channel.state.isUpToDate) {
771
+ try {
772
+ await channel?.watch();
773
+ } catch (err) {
774
+ console.warn('Channel watch request failed with error:', err);
775
+ setError(true);
776
+ errored = true;
777
+ }
704
778
  }
705
779
 
706
- if (messageId) {
707
- loadChannelAroundMessage({ messageId });
780
+ if (!errored) {
781
+ initStateFromChannel(channel);
782
+ loadInitialMessagesStateFromChannel(channel, channel.state.messagePagination.hasPrev);
708
783
  }
709
- // The condition, where if the count of unread messages is greater than 4, then scroll to the first unread message.
710
- else if (
784
+
785
+ if (messageId) {
786
+ await loadChannelAroundMessage({ messageId, setTargetedMessage });
787
+ } else if (
711
788
  initialScrollToFirstUnreadMessage &&
712
789
  channel.countUnread() > scrollToFirstUnreadThreshold
713
790
  ) {
714
- loadChannelAtFirstUnreadMessage();
715
- }
716
- // If the messageId is undefined and the last message and the current message id do not match we load the channel at the very bottom.
717
- else if (
718
- channel.state.messages?.[channel.state.messages.length - 1]?.id !==
719
- channel.state.latestMessages?.[channel.state.latestMessages.length - 1]?.id &&
720
- !messageId
721
- ) {
722
- await loadChannel();
791
+ await loadChannelAtFirstUnreadMessage({ setTargetedMessage });
723
792
  }
793
+ listener = channel.on(handleEvent);
724
794
  };
725
795
 
726
796
  initChannel();
727
797
 
728
798
  return () => {
729
799
  copyChannelState.cancel();
730
- copyReadState.cancel();
731
- copyTypingState.cancel();
732
- loadMoreFinished.cancel();
733
800
  loadMoreThreadFinished.cancel();
801
+ listener?.unsubscribe();
734
802
  };
735
803
  // eslint-disable-next-line react-hooks/exhaustive-deps
736
- }, [channelId, messageId]);
804
+ }, [channel.cid, messageId, shouldSyncChannel]);
805
+
806
+ // subscribe to channel.deleted event
807
+ useEffect(() => {
808
+ const { unsubscribe } = client.on('channel.deleted', (event) => {
809
+ if (event.cid === channel?.cid) {
810
+ setDeleted(true);
811
+ }
812
+ });
813
+
814
+ return unsubscribe;
815
+ }, [channel?.cid, client]);
816
+
817
+ /**
818
+ * Subscription to the Notification mark_read event.
819
+ */
820
+ useEffect(() => {
821
+ const handleEvent: EventHandler<StreamChatGenerics> = (event) => {
822
+ if (channel.cid === event.cid) copyChannelState();
823
+ };
824
+
825
+ const { unsubscribe } = client.on('notification.mark_read', handleEvent);
826
+ return unsubscribe;
827
+ }, [channel.cid, client, copyChannelState]);
737
828
 
738
829
  const threadPropsExists = !!threadProps;
739
830
 
@@ -764,17 +855,6 @@ const ChannelWithContext = <
764
855
 
765
856
  useAppStateListener(undefined, handleAppBackground);
766
857
 
767
- /**
768
- * CHANNEL CONSTANTS
769
- */
770
- const isAdmin = client?.user?.role === 'admin' || channel?.state.membership.role === 'admin';
771
-
772
- const isModerator =
773
- channel?.state.membership.role === 'channel_moderator' ||
774
- channel?.state.membership.role === 'moderator';
775
-
776
- const isOwner = channel?.state.membership.role === 'owner';
777
-
778
858
  /**
779
859
  * CHANNEL METHODS
780
860
  */
@@ -796,441 +876,6 @@ const ChannelWithContext = <
796
876
  ),
797
877
  ).current;
798
878
 
799
- const copyMessagesState = useRef(
800
- throttle(
801
- () => {
802
- if (channel) {
803
- clearInterval(mergeSetsIntervalRef.current);
804
- setMessages(channel.state.messages);
805
- restartSetsMergeFuncRef.current();
806
- }
807
- },
808
- newMessageStateUpdateThrottleInterval,
809
- throttleOptions,
810
- ),
811
- ).current;
812
-
813
- const copyTypingState = useRef(
814
- throttle(
815
- () => {
816
- if (channel) {
817
- setTyping({ ...channel.state.typing });
818
- }
819
- },
820
- stateUpdateThrottleInterval,
821
- throttleOptions,
822
- ),
823
- ).current;
824
-
825
- const copyReadState = useRef(
826
- throttle(
827
- () => {
828
- if (channel) {
829
- setRead({ ...channel.state.read });
830
- }
831
- },
832
- stateUpdateThrottleInterval,
833
- throttleOptions,
834
- ),
835
- ).current;
836
-
837
- const copyChannelState = useRef(
838
- throttle(
839
- () => {
840
- setLoading(false);
841
- if (channel) {
842
- setMembers({ ...channel.state.members });
843
- setMessages([...channel.state.messages]);
844
- setRead({ ...channel.state.read });
845
- setTyping({ ...channel.state.typing });
846
- setWatcherCount(channel.state.watcher_count);
847
- setWatchers({ ...channel.state.watchers });
848
- }
849
- },
850
- stateUpdateThrottleInterval,
851
- throttleOptions,
852
- ),
853
- ).current;
854
-
855
- // subscribe to specific channel events
856
- useEffect(() => {
857
- const channelSubscriptions: Array<ReturnType<ChannelType['on']>> = [];
858
- if (channel && shouldSyncChannel) {
859
- channelSubscriptions.push(channel.on('message.new', copyMessagesState));
860
- channelSubscriptions.push(channel.on('message.read', copyReadState));
861
- channelSubscriptions.push(channel.on('typing.start', copyTypingState));
862
- channelSubscriptions.push(channel.on('typing.stop', copyTypingState));
863
- }
864
- return () => {
865
- channelSubscriptions.forEach((s) => s.unsubscribe());
866
- };
867
- // eslint-disable-next-line react-hooks/exhaustive-deps
868
- }, [channelId, shouldSyncChannel]);
869
-
870
- // subscribe to the generic all channel event
871
- useEffect(() => {
872
- const handleEvent: EventHandler<StreamChatGenerics> = (event) => {
873
- const ignorableEvents = ['user.watching.start', 'user.watching.stop'];
874
- if (ignorableEvents.includes(event.type)) return;
875
- if (shouldSyncChannel) {
876
- const isTypingEvent = event.type === 'typing.start' || event.type === 'typing.stop';
877
- if (!isTypingEvent) {
878
- if (thread?.id) {
879
- const updatedThreadMessages =
880
- (thread.id && channel && channel.state.threads[thread.id]) || threadMessages;
881
- setThreadMessages(updatedThreadMessages);
882
- }
883
-
884
- if (channel && thread?.id && event.message?.id === thread.id && !threadInstance) {
885
- const updatedThread = channel.state.formatMessage(event.message);
886
- setThread(updatedThread);
887
- }
888
- }
889
-
890
- // only update channel state if the events are not the previously subscribed useEffect's subscription events
891
- if (
892
- channel &&
893
- channel.initialized &&
894
- event.type !== 'message.new' &&
895
- event.type !== 'message.read' &&
896
- event.type !== 'typing.start' &&
897
- event.type !== 'typing.stop'
898
- ) {
899
- copyChannelState();
900
- }
901
- }
902
- };
903
- const { unsubscribe } = channel.on(handleEvent);
904
- return unsubscribe;
905
- // eslint-disable-next-line react-hooks/exhaustive-deps
906
- }, [channelId, thread?.id, shouldSyncChannel]);
907
-
908
- // subscribe to channel.deleted event
909
- useEffect(() => {
910
- const { unsubscribe } = client.on('channel.deleted', (event) => {
911
- if (event.cid === channel?.cid) {
912
- setDeleted(true);
913
- }
914
- });
915
-
916
- return unsubscribe;
917
- // eslint-disable-next-line react-hooks/exhaustive-deps
918
- }, [channelId]);
919
-
920
- useEffect(() => {
921
- const handleEvent: EventHandler<StreamChatGenerics> = (event) => {
922
- if (channel.cid === event.cid) copyChannelState();
923
- };
924
-
925
- const { unsubscribe } = client.on('notification.mark_read', handleEvent);
926
- return unsubscribe;
927
- // eslint-disable-next-line react-hooks/exhaustive-deps
928
- }, []);
929
-
930
- const channelQueryCallRef = useRef(
931
- async (
932
- queryCall: () => Promise<void>,
933
- onAfterQueryCall: (() => void) | undefined = undefined,
934
- // if we are scrolling to a message after the query, pass it here
935
- scrollToMessageId: string | (() => string | undefined) | undefined = undefined,
936
- ) => {
937
- setError(false);
938
- try {
939
- clearInterval(mergeSetsIntervalRef.current);
940
- await queryCall();
941
- setLastRead(new Date());
942
- setHasMore(true);
943
- const currentMessages = channel.state.messages;
944
- const hadCurrentLatestMessages =
945
- currentMessages.length > 0 && currentMessages === channel.state.latestMessages;
946
- if (typeof scrollToMessageId === 'function') {
947
- scrollToMessageId = scrollToMessageId();
948
- }
949
-
950
- const scrollToMessageIndex = scrollToMessageId
951
- ? currentMessages.findIndex(({ id }) => id === scrollToMessageId)
952
- : -1;
953
- if (channel && scrollToMessageIndex !== -1) {
954
- copyChannelState.cancel();
955
- // We assume that on average user sees 5 messages on screen
956
- // We dont want new renders to happen while scrolling to the targeted message
957
- // hence we limit the number of messages to be rendered after the targeted message to 5 - 1 = 4
958
- // NOTE: we have one drawback here, if there were already a split latest and current message set
959
- // the previous latest message set will be thrown away as we cannot merge it with the current message set after the target message is set
960
- const limitAfter = 4;
961
- const currentLength = currentMessages.length;
962
- const noOfMessagesAfter = currentLength - scrollToMessageIndex - 1;
963
- // number of messages are over the limit, limit the length of messages
964
- if (noOfMessagesAfter > limitAfter) {
965
- const endIndex = scrollToMessageIndex + limitAfter;
966
- channel.state.clearMessages();
967
- channel.state.messages = currentMessages.slice(0, endIndex + 1);
968
- splitLatestCurrentMessageSetRef.current();
969
- const restOfMessages = currentMessages.slice(endIndex + 1);
970
- if (hadCurrentLatestMessages) {
971
- const latestSet = channel.state.messageSets.find((set) => set.isLatest);
972
- if (latestSet) {
973
- latestSet.messages = restOfMessages;
974
- hasOverlappingRecentMessagesRef.current = true;
975
- }
976
- }
977
- }
978
- }
979
- const hasLatestMessages = channel.state.latestMessages.length > 0;
980
- channel.state.setIsUpToDate(hasLatestMessages);
981
- setHasNoMoreRecentMessagesToLoad(hasLatestMessages);
982
- copyChannelState();
983
- if (scrollToMessageIndex !== -1) {
984
- // since we need to scroll after immediately do this without throttle
985
- copyChannelState.flush();
986
- }
987
- onAfterQueryCall?.();
988
- } catch (err) {
989
- if (err instanceof Error) {
990
- setError(err);
991
- } else {
992
- setError(true);
993
- }
994
- setLoading(false);
995
- setLastRead(new Date());
996
- }
997
- },
998
- );
999
-
1000
- /**
1001
- * Loads channel at first unread message.
1002
- */
1003
- const loadChannelAtFirstUnreadMessage = () => {
1004
- if (!channel) return;
1005
- let unreadMessageIdToScrollTo: string | undefined;
1006
- // query for messages around the last read date
1007
- return channelQueryCallRef.current(
1008
- async () => {
1009
- const unreadCount = channel.countUnread();
1010
- if (unreadCount === 0) return;
1011
- const isLatestMessageSetShown = !!channel.state.messageSets.find(
1012
- (set) => set.isCurrent && set.isLatest,
1013
- );
1014
- if (isLatestMessageSetShown && unreadCount <= channel.state.messages.length) {
1015
- unreadMessageIdToScrollTo =
1016
- channel.state.messages[channel.state.messages.length - unreadCount].id;
1017
- return;
1018
- }
1019
- const lastReadDate = channel.lastRead();
1020
-
1021
- // if last read date is present we can just fetch messages around that date
1022
- // last read date not being present is an edge case if somewhere the user of SDK deletes the read state (this will usually never happen)
1023
- if (lastReadDate) {
1024
- setLoading(true);
1025
- // get totally 30 messages... max 15 before last read date and max 15 after last read date
1026
- // ref: https://github.com/GetStream/chat/pull/2588
1027
- const res = await channel.query(
1028
- {
1029
- messages: {
1030
- created_at_around: lastReadDate,
1031
- limit: 30,
1032
- },
1033
- watch: true,
1034
- },
1035
- 'new',
1036
- );
1037
- unreadMessageIdToScrollTo = res.messages.find(
1038
- (m) => lastReadDate < (m.created_at ? new Date(m.created_at) : new Date()),
1039
- )?.id;
1040
- if (unreadMessageIdToScrollTo) {
1041
- channel.state.loadMessageIntoState(unreadMessageIdToScrollTo);
1042
- }
1043
- } else {
1044
- await loadLatestMessagesRef.current();
1045
- }
1046
- },
1047
- () => {
1048
- if (unreadMessageIdToScrollTo) {
1049
- restartSetsMergeFuncRef.current();
1050
- }
1051
- },
1052
- () => unreadMessageIdToScrollTo,
1053
- );
1054
- };
1055
-
1056
- /**
1057
- * Loads channel around a specific message
1058
- *
1059
- * @param messageId If undefined, channel will be loaded at most recent message.
1060
- */
1061
- const loadChannelAroundMessage: ChannelContextValue<StreamChatGenerics>['loadChannelAroundMessage'] =
1062
- async ({ messageId: messageIdToLoadAround }) => {
1063
- if (thread) {
1064
- if (messageIdToLoadAround) {
1065
- setThreadLoadingMore(true);
1066
- try {
1067
- await channel.state.loadMessageIntoState(messageIdToLoadAround, thread.id);
1068
- setThreadLoadingMore(false);
1069
- setThreadMessages(channel.state.threads[thread.id]);
1070
- setTargetedMessage(messageIdToLoadAround);
1071
- } catch (err) {
1072
- if (err instanceof Error) {
1073
- setError(err);
1074
- } else {
1075
- setError(true);
1076
- }
1077
- setThreadLoadingMore(false);
1078
- }
1079
- }
1080
- } else {
1081
- await channelQueryCallRef.current(
1082
- async () => {
1083
- setLoading(true);
1084
- if (messageIdToLoadAround) {
1085
- setMessages([]);
1086
- await channel.state.loadMessageIntoState(messageIdToLoadAround);
1087
- const currentMessageSet = channel.state.messageSets.find((set) => set.isCurrent);
1088
- if (currentMessageSet && !currentMessageSet?.isLatest) {
1089
- // if the current message set is not the latest, we will throw away the latest messages
1090
- // in order to attempt to not throw away, will attempt to merge it by loading 25 more messages
1091
- const recentCurrentSetMsgId =
1092
- currentMessageSet.messages[currentMessageSet.messages.length - 1].id;
1093
- await channel.query(
1094
- {
1095
- messages: {
1096
- id_gte: recentCurrentSetMsgId,
1097
- limit: 25,
1098
- },
1099
- },
1100
- 'current',
1101
- );
1102
- // if the gap is more than 25, we will unfortunately have to throw away the latest messages
1103
- }
1104
- }
1105
- },
1106
- () => {
1107
- if (messageIdToLoadAround) {
1108
- clearInterval(mergeSetsIntervalRef.current); // do not merge sets as we will scroll/highlight to the message
1109
- setTargetedMessage(messageIdToLoadAround);
1110
- }
1111
- },
1112
- messageIdToLoadAround,
1113
- );
1114
- }
1115
- };
1116
-
1117
- useEffect(() => {
1118
- if (!targetedMessage && prevTargetedMessage) {
1119
- // we cleared the merge sets interval to wait for the targeted message to be set
1120
- // now restart it since its done
1121
- restartSetsMergeFuncRef.current();
1122
- }
1123
- // eslint-disable-next-line react-hooks/exhaustive-deps
1124
- }, [targetedMessage]);
1125
-
1126
- /**
1127
- * Utility method to mark that current set if latest into two.
1128
- * With an empty latest set
1129
- * This is useful when we know that we dont know the latest messages anymore
1130
- * Or if we are loading a channel around a message
1131
- */
1132
- const splitLatestCurrentMessageSetRef = useRef(() => {
1133
- const currentLatestSet = channel.state.messageSets.find((set) => set.isCurrent && set.isLatest);
1134
- if (!currentLatestSet) return;
1135
- // unmark the current latest set
1136
- currentLatestSet.isLatest = false;
1137
- // create a new set with empty latest messages
1138
- channel.state.messageSets.push({
1139
- isCurrent: false,
1140
- isLatest: true,
1141
- messages: [],
1142
- pagination: {
1143
- hasNext: true,
1144
- hasPrev: true,
1145
- },
1146
- });
1147
- });
1148
-
1149
- /**
1150
- * Utility method to merge current and latest message set.
1151
- * Returns true if merge was successful, false otherwise.
1152
- */
1153
- const mergeOverlappingMessageSetsRef = useRef((limitToMaxRenderPerBatch = false) => {
1154
- if (hasOverlappingRecentMessagesRef.current) {
1155
- const limit = 5; // 5 is the load to recent limit, a larger value seems to cause jumpiness in some devices..
1156
- // merge current and latest sets
1157
- const latestMessageSet = channel.state.messageSets.find((set) => set.isLatest);
1158
- const currentMessageSet = channel.state.messageSets.find((set) => set.isCurrent);
1159
- if (latestMessageSet && currentMessageSet && latestMessageSet !== currentMessageSet) {
1160
- if (limitToMaxRenderPerBatch && latestMessageSet.messages.length > limit) {
1161
- currentMessageSet.messages = currentMessageSet.messages.concat(
1162
- latestMessageSet.messages.slice(0, limit),
1163
- );
1164
- latestMessageSet.messages = latestMessageSet.messages.slice(limit);
1165
- } else {
1166
- channel.state.messageSets = channel.state.messageSets.filter((set) => !set.isLatest);
1167
- currentMessageSet.messages = currentMessageSet.messages.concat(latestMessageSet.messages);
1168
- currentMessageSet.isLatest = true;
1169
- hasOverlappingRecentMessagesRef.current = false;
1170
- clearInterval(mergeSetsIntervalRef.current);
1171
- }
1172
- return true;
1173
- }
1174
- }
1175
- return false;
1176
- });
1177
-
1178
- const mergeSetsIntervalRef = useRef<NodeJS.Timeout>();
1179
-
1180
- // clear the interval on unmount
1181
- useEffect(
1182
- () => () => {
1183
- clearInterval(mergeSetsIntervalRef.current);
1184
- },
1185
- [],
1186
- );
1187
-
1188
- // if we had split the latest and current message set, we try to merge them back
1189
- // temporarily commented out the interval as it was causing issues with jankiness during scrolling
1190
- const restartSetsMergeFuncRef = useRef(() => {
1191
- clearInterval(mergeSetsIntervalRef.current);
1192
- if (!hasOverlappingRecentMessagesRef.current) return;
1193
- // mergeSetsIntervalRef.current = setInterval(() => {
1194
- // const currentLength = channel.state.messages.length || 0;
1195
- // const didMerge = mergeOverlappingMessageSetsRef.current(true);
1196
- // if (didMerge && channel.state.messages.length !== currentLength) {
1197
- // setMessages(channel.state.messages);
1198
- // }
1199
- // }, 1000);
1200
- });
1201
-
1202
- /**
1203
- * Shows the latest messages from the channel state
1204
- * If recent messages are empty, fetches new
1205
- * @param clearLatest If true, clears the latest messages before loading (useful for complete refresh)
1206
- */
1207
- const loadLatestMessagesRef = useRef(async (clearLatest = false) => {
1208
- mergeOverlappingMessageSetsRef.current();
1209
- if (clearLatest) {
1210
- const latestSet = channel.state.messageSets.find((set) => set.isLatest);
1211
- if (latestSet) latestSet.messages = [];
1212
- }
1213
- if (channel.state.latestMessages.length === 0) {
1214
- await channel.query({}, 'latest');
1215
- }
1216
- await channel.state.loadMessageIntoState('latest');
1217
- });
1218
-
1219
- const loadChannel = () =>
1220
- channelQueryCallRef.current(
1221
- async () => {
1222
- if (!channel?.initialized || !channel.state.isUpToDate) {
1223
- await channel?.watch();
1224
- } else {
1225
- await channel.state.loadMessageIntoState('latest');
1226
- }
1227
- },
1228
- () => {
1229
- channel?.state.setIsUpToDate(true);
1230
- setHasNoMoreRecentMessagesToLoad(true);
1231
- },
1232
- );
1233
-
1234
879
  const reloadThread = async () => {
1235
880
  if (!channel || !thread?.id) return;
1236
881
  setThreadLoadingMore(true);
@@ -1266,105 +911,39 @@ const ChannelWithContext = <
1266
911
 
1267
912
  const resyncChannel = async () => {
1268
913
  if (!channel || syncingChannelRef.current) return;
1269
- hasOverlappingRecentMessagesRef.current = false;
1270
- clearInterval(mergeSetsIntervalRef.current);
1271
914
  syncingChannelRef.current = true;
1272
-
1273
915
  setError(false);
1274
- try {
1275
- /**
1276
- * Allow a buffer of 30 new messages, so that MessageList won't move its scroll position,
1277
- * giving smooth user experience.
1278
- */
1279
- const state = await channel.watch({
1280
- messages: {
1281
- limit: messages.length + 30,
1282
- },
1283
- });
1284
-
1285
- const oldListTopMessage = messages[0];
1286
- const oldListTopMessageId = messages[0]?.id;
1287
- const oldListBottomMessage = messages[messages.length - 1];
1288
-
1289
- const newListTopMessage = state.messages[0];
1290
- const newListBottomMessage = state.messages[state.messages.length - 1];
1291
916
 
1292
- if (
1293
- !oldListTopMessage || // previous list was empty
1294
- !oldListBottomMessage || // previous list was empty
1295
- !newListTopMessage || // new list is truncated
1296
- !newListBottomMessage // new list is truncated
1297
- ) {
1298
- /** Channel was truncated */
1299
- channel.state.clearMessages();
1300
- channel.state.setIsUpToDate(true);
1301
- channel.state.addMessagesSorted(state.messages);
1302
- channel.state.addPinnedMessages(state.pinned_messages);
917
+ const parseMessage = (message: FormatMessageResponse<StreamChatGenerics>) =>
918
+ ({
919
+ ...message,
920
+ created_at: message.created_at.toString(),
921
+ pinned_at: message.pinned_at?.toString(),
922
+ updated_at: message.updated_at?.toString(),
923
+ } as unknown as MessageResponse<StreamChatGenerics>);
1303
924
 
925
+ try {
926
+ if (!thread) {
1304
927
  copyChannelState();
1305
- return;
1306
- }
1307
928
 
1308
- const parseMessage = (message: typeof oldListTopMessage) =>
1309
- ({
1310
- ...message,
1311
- created_at: message.created_at.toString(),
1312
- pinned_at: message.pinned_at?.toString(),
1313
- updated_at: message.updated_at?.toString(),
1314
- } as unknown as MessageResponse<StreamChatGenerics>);
1315
-
1316
- const failedMessages = messages
1317
- .filter((message) => message.status === MessageStatusTypes.FAILED)
1318
- .map(parseMessage);
1319
-
1320
- const failedThreadMessages = thread
1321
- ? threadMessages
1322
- .filter((message) => message.status === MessageStatusTypes.FAILED)
1323
- .map(parseMessage)
1324
- : [];
1325
-
1326
- const oldListTopMessageCreatedAt = oldListTopMessage.created_at;
1327
- const oldListBottomMessageCreatedAt = oldListBottomMessage.created_at;
1328
- const newListTopMessageCreatedAt = newListTopMessage.created_at
1329
- ? new Date(newListTopMessage.created_at)
1330
- : new Date();
1331
- const newListBottomMessageCreatedAt = newListBottomMessage?.created_at
1332
- ? new Date(newListBottomMessage.created_at)
1333
- : new Date();
1334
-
1335
- let finalMessages = [];
1336
-
1337
- if (
1338
- oldListTopMessage &&
1339
- oldListTopMessageCreatedAt &&
1340
- oldListBottomMessageCreatedAt &&
1341
- newListTopMessageCreatedAt < oldListTopMessageCreatedAt &&
1342
- newListBottomMessageCreatedAt >= oldListBottomMessageCreatedAt
1343
- ) {
1344
- const index = state.messages.findIndex((message) => message.id === oldListTopMessageId);
1345
- finalMessages = state.messages.slice(index);
929
+ const failedMessages = channelMessagesState.messages
930
+ ?.filter((message) => message.status === MessageStatusTypes.FAILED)
931
+ .map(parseMessage);
932
+ if (failedMessages?.length) {
933
+ channel.state.addMessagesSorted(failedMessages);
934
+ }
1346
935
  } else {
1347
- finalMessages = state.messages;
1348
- }
1349
-
1350
- channel.state.setIsUpToDate(true);
1351
- channel.state.clearMessages();
1352
- channel.state.addMessagesSorted(finalMessages);
1353
- channel.state.addPinnedMessages(state.pinned_messages);
1354
- setHasNoMoreRecentMessagesToLoad(true);
1355
- setHasMore(true);
1356
- copyChannelState();
1357
-
1358
- if (failedMessages.length) {
1359
- channel.state.addMessagesSorted(failedMessages);
1360
- copyChannelState();
1361
- }
1362
-
1363
- await reloadThread();
1364
-
1365
- if (thread && failedThreadMessages.length) {
1366
- channel.state.addMessagesSorted(failedThreadMessages);
1367
- setThreadMessages([...channel.state.threads[thread.id]]);
936
+ await reloadThread();
937
+
938
+ const failedThreadMessages = thread
939
+ ? threadMessages
940
+ .filter((message) => message.status === MessageStatusTypes.FAILED)
941
+ .map(parseMessage)
942
+ : [];
943
+ if (failedThreadMessages.length) {
944
+ channel.state.addMessagesSorted(failedThreadMessages);
945
+ setThreadMessages([...channel.state.threads[thread.id]]);
946
+ }
1368
947
  }
1369
948
  } catch (err) {
1370
949
  if (err instanceof Error) {
@@ -1372,7 +951,6 @@ const ChannelWithContext = <
1372
951
  } else {
1373
952
  setError(true);
1374
953
  }
1375
- setLoading(false);
1376
954
  }
1377
955
 
1378
956
  syncingChannelRef.current = false;
@@ -1393,7 +971,7 @@ const ChannelWithContext = <
1393
971
  if (enableOfflineSupport) {
1394
972
  connectionChangedSubscription = DBSyncManager.onSyncStatusChange((statusChanged) => {
1395
973
  if (statusChanged) {
1396
- connectionChangedHandler();
974
+ copyChannelState();
1397
975
  }
1398
976
  });
1399
977
  } else {
@@ -1409,15 +987,6 @@ const ChannelWithContext = <
1409
987
  // eslint-disable-next-line react-hooks/exhaustive-deps
1410
988
  }, [enableOfflineSupport, shouldSyncChannel]);
1411
989
 
1412
- const reloadChannel = () =>
1413
- channelQueryCallRef.current(async () => {
1414
- setLoading(true);
1415
- await loadLatestMessagesRef.current(true);
1416
- setLoading(false);
1417
- channel?.state.setIsUpToDate(true);
1418
- setHasNoMoreRecentMessagesToLoad(true);
1419
- });
1420
-
1421
990
  // In case the channel is disconnected which may happen when channel is deleted,
1422
991
  // underlying js client throws an error. Following function ensures that Channel component
1423
992
  // won't result in error in such a case.
@@ -1436,22 +1005,61 @@ const ChannelWithContext = <
1436
1005
  */
1437
1006
  const clientChannelConfig = getChannelConfigSafely();
1438
1007
 
1008
+ const reloadChannel = async () => {
1009
+ try {
1010
+ await loadLatestMessages();
1011
+ } catch (err) {
1012
+ console.warn('Reloading channel failed with error:', err);
1013
+ }
1014
+ };
1015
+
1016
+ const loadChannelAroundMessage: ChannelContextValue<StreamChatGenerics>['loadChannelAroundMessage'] =
1017
+ async ({ messageId: messageIdToLoadAround }): Promise<void> => {
1018
+ if (!messageIdToLoadAround) return;
1019
+ try {
1020
+ if (thread) {
1021
+ setThreadLoadingMore(true);
1022
+ try {
1023
+ await channel.state.loadMessageIntoState(messageIdToLoadAround, thread.id);
1024
+ setThreadLoadingMore(false);
1025
+ setThreadMessages(channel.state.threads[thread.id]);
1026
+ if (setTargetedMessage) {
1027
+ setTargetedMessage(messageIdToLoadAround);
1028
+ }
1029
+ } catch (err) {
1030
+ if (err instanceof Error) {
1031
+ setError(err);
1032
+ } else {
1033
+ setError(true);
1034
+ }
1035
+ setThreadLoadingMore(false);
1036
+ }
1037
+ } else {
1038
+ await loadChannelAroundMessageFn({
1039
+ messageId: messageIdToLoadAround,
1040
+ setTargetedMessage,
1041
+ });
1042
+ }
1043
+ } catch (err) {
1044
+ console.warn('Loading channel around message failed with error:', err);
1045
+ }
1046
+ };
1047
+
1439
1048
  /**
1440
1049
  * MESSAGE METHODS
1441
1050
  */
1442
-
1443
1051
  const updateMessage: MessagesContextValue<StreamChatGenerics>['updateMessage'] = (
1444
1052
  updatedMessage,
1445
1053
  extraState = {},
1446
1054
  ) => {
1447
- if (channel) {
1448
- channel.state.addMessageSorted(updatedMessage, true);
1449
- if (thread && updatedMessage.parent_id) {
1450
- extraState.threadMessages = channel.state.threads[updatedMessage.parent_id] || [];
1451
- setThreadMessages(extraState.threadMessages);
1452
- }
1055
+ if (!channel) return;
1056
+
1057
+ channel.state.addMessageSorted(updatedMessage, true);
1058
+ copyMessagesStateFromChannel(channel);
1453
1059
 
1454
- setMessages([...channel.state.messages]);
1060
+ if (thread && updatedMessage.parent_id) {
1061
+ extraState.threadMessages = channel.state.threads[updatedMessage.parent_id] || [];
1062
+ setThreadMessages(extraState.threadMessages);
1455
1063
  }
1456
1064
  };
1457
1065
 
@@ -1462,11 +1070,12 @@ const ChannelWithContext = <
1462
1070
  if (channel) {
1463
1071
  channel.state.removeMessage(oldMessage);
1464
1072
  channel.state.addMessageSorted(newMessage, true);
1073
+ copyMessagesStateFromChannel(channel);
1074
+
1465
1075
  if (thread && newMessage.parent_id) {
1466
1076
  const threadMessages = channel.state.threads[newMessage.parent_id] || [];
1467
1077
  setThreadMessages(threadMessages);
1468
1078
  }
1469
- setMessages(channel.state.messages);
1470
1079
  }
1471
1080
  };
1472
1081
 
@@ -1516,7 +1125,9 @@ const ChannelWithContext = <
1516
1125
  * as quoted_message is a reserved field.
1517
1126
  */
1518
1127
  if (preview.quoted_message_id) {
1519
- const quotedMessage = messages.find((message) => message.id === preview.quoted_message_id);
1128
+ const quotedMessage = channelMessagesState.messages?.find(
1129
+ (message) => message.id === preview.quoted_message_id,
1130
+ );
1520
1131
 
1521
1132
  preview.quoted_message =
1522
1133
  quotedMessage as MessageResponse<StreamChatGenerics>['quoted_message'];
@@ -1685,8 +1296,6 @@ const ChannelWithContext = <
1685
1296
  attachments: message.attachments || [],
1686
1297
  });
1687
1298
 
1688
- mergeOverlappingMessageSetsRef.current();
1689
-
1690
1299
  updateMessage(messagePreview, {
1691
1300
  commands: [],
1692
1301
  messageInput: '',
@@ -1727,159 +1336,6 @@ const ChannelWithContext = <
1727
1336
  );
1728
1337
  };
1729
1338
 
1730
- // hard limit to prevent you from scrolling faster than 1 page per 2 seconds
1731
- const loadMoreFinished = useRef(
1732
- debounce(
1733
- (updatedHasMore: boolean, newMessages: ChannelState<StreamChatGenerics>['messages']) => {
1734
- setLoading(false);
1735
- setLoadingMore(false);
1736
- setError(false);
1737
- setHasMore(updatedHasMore);
1738
- setMessages(newMessages);
1739
- },
1740
- defaultDebounceInterval,
1741
- debounceOptions,
1742
- ),
1743
- ).current;
1744
-
1745
- /**
1746
- * This function loads more messages before the first message in current channel state.
1747
- */
1748
- const loadMore = useCallback<PaginatedMessageListContextValue<StreamChatGenerics>['loadMore']>(
1749
- async (limit = 20) => {
1750
- if (loadingMore || hasMore === false) {
1751
- return;
1752
- }
1753
-
1754
- const currentMessages = channel.state.messages;
1755
-
1756
- if (!currentMessages.length) {
1757
- return setLoadingMore(false);
1758
- }
1759
-
1760
- const oldestMessage = currentMessages && currentMessages[0];
1761
-
1762
- if (oldestMessage && oldestMessage.status !== MessageStatusTypes.RECEIVED) {
1763
- return setLoadingMore(false);
1764
- }
1765
-
1766
- setLoadingMore(true);
1767
-
1768
- const oldestID = oldestMessage && oldestMessage.id;
1769
-
1770
- try {
1771
- if (channel) {
1772
- const queryResponse = await channel.query({
1773
- messages: { id_lt: oldestID, limit },
1774
- });
1775
-
1776
- const updatedHasMore = queryResponse.messages.length === limit;
1777
- loadMoreFinished(updatedHasMore, channel.state.messages);
1778
- }
1779
- } catch (err) {
1780
- if (err instanceof Error) {
1781
- setError(err);
1782
- } else {
1783
- setError(true);
1784
- }
1785
- setLoadingMore(false);
1786
- throw err;
1787
- }
1788
- },
1789
- /*
1790
- * This function is passed to useCreatePaginatedMessageListContext
1791
- * Where the deps are [channelId, hasMore, loadingMoreRecent, loadingMore]
1792
- * and only those deps should be used here because of that
1793
- */
1794
- // eslint-disable-next-line react-hooks/exhaustive-deps
1795
- [channelId, hasMore, loadingMore],
1796
- );
1797
-
1798
- /**
1799
- * This function loads more messages after the most recent message in current channel state.
1800
- */
1801
- const loadMoreRecent = useCallback<
1802
- PaginatedMessageListContextValue<StreamChatGenerics>['loadMoreRecent']
1803
- >(
1804
- async (limit = 5) => {
1805
- const latestMessageSet = channel.state.messageSets.find((set) => set.isLatest);
1806
- const latestLengthBeforeMerge = latestMessageSet?.messages.length || 0;
1807
- const didMerge = mergeOverlappingMessageSetsRef.current(true);
1808
- if (didMerge) {
1809
- if (latestMessageSet && latestLengthBeforeMerge >= limit) {
1810
- setLoadingMoreRecent(true);
1811
- channel.state.setIsUpToDate(true);
1812
- setHasNoMoreRecentMessagesToLoad(true);
1813
- loadMoreRecentFinished(channel.state.messages);
1814
- restartSetsMergeFuncRef.current();
1815
- return;
1816
- }
1817
- }
1818
- if (channel.state.isUpToDate) {
1819
- setLoadingMoreRecent(false);
1820
- return;
1821
- }
1822
- const currentMessages = channel.state.messages;
1823
- const recentMessage = currentMessages[currentMessages.length - 1];
1824
-
1825
- if (recentMessage?.status !== MessageStatusTypes.RECEIVED) {
1826
- setLoadingMoreRecent(false);
1827
- return;
1828
- }
1829
- setLoadingMoreRecent(true);
1830
- try {
1831
- if (channel) {
1832
- const queryResponse = await channel.query({
1833
- messages: {
1834
- id_gte: recentMessage.id,
1835
- limit,
1836
- },
1837
- watch: true,
1838
- });
1839
- const gotAllRecentMessages = queryResponse.messages.length < limit;
1840
- const currentSet = channel.state.messageSets.find((set) => set.isCurrent);
1841
- if (gotAllRecentMessages && currentSet && !currentSet.isLatest) {
1842
- channel.state.messageSets = channel.state.messageSets.filter((set) => !set.isLatest);
1843
- // make current set as the latest
1844
- currentSet.isLatest = true;
1845
- }
1846
- channel.state.setIsUpToDate(gotAllRecentMessages);
1847
- setHasNoMoreRecentMessagesToLoad(gotAllRecentMessages);
1848
- loadMoreRecentFinished(channel.state.messages);
1849
- }
1850
- } catch (err) {
1851
- console.warn('Message pagination request failed with error', err);
1852
- if (err instanceof Error) {
1853
- setError(err);
1854
- } else {
1855
- setError(true);
1856
- }
1857
- setLoadingMoreRecent(false);
1858
- throw err;
1859
- }
1860
- },
1861
- /*
1862
- * This function is passed to useCreatePaginatedMessageListContext
1863
- * Where the deps are [channelId, hasMore, loadingMoreRecent, loadingMore, hasNoMoreRecentMessagesToLoad]
1864
- * and and only those deps should be used here because of that
1865
- */
1866
- // eslint-disable-next-line react-hooks/exhaustive-deps
1867
- [channelId, hasNoMoreRecentMessagesToLoad],
1868
- );
1869
-
1870
- // hard limit to prevent you from scrolling faster than 1 page per 2 seconds
1871
- const loadMoreRecentFinished = useRef(
1872
- debounce(
1873
- (newMessages: ChannelState<StreamChatGenerics>['messages']) => {
1874
- setLoadingMoreRecent(false);
1875
- setMessages(newMessages);
1876
- setError(false);
1877
- },
1878
- defaultDebounceInterval,
1879
- debounceOptions,
1880
- ),
1881
- ).current;
1882
-
1883
1339
  const editMessage: InputMessageInputContextValue<StreamChatGenerics>['editMessage'] = (
1884
1340
  updatedMessage,
1885
1341
  ) =>
@@ -1914,7 +1370,8 @@ const ChannelWithContext = <
1914
1370
  ) => {
1915
1371
  if (channel) {
1916
1372
  channel.state.removeMessage(message);
1917
- setMessages(channel.state.messages);
1373
+ copyMessagesStateFromChannel(channel);
1374
+
1918
1375
  if (thread) {
1919
1376
  setThreadMessages(channel.state.threads[thread.id] || []);
1920
1377
  }
@@ -1953,7 +1410,7 @@ const ChannelWithContext = <
1953
1410
  user: client.user,
1954
1411
  });
1955
1412
 
1956
- setMessages(channel.state.messages);
1413
+ copyMessagesStateFromChannel(channel);
1957
1414
 
1958
1415
  const sendReactionResponse = await DBSyncManager.queueTask<StreamChatGenerics>({
1959
1416
  client,
@@ -2039,7 +1496,7 @@ const ChannelWithContext = <
2039
1496
  user: client.user,
2040
1497
  });
2041
1498
 
2042
- setMessages(channel.state.messages);
1499
+ copyMessagesStateFromChannel(channel);
2043
1500
 
2044
1501
  await DBSyncManager.queueTask<StreamChatGenerics>({
2045
1502
  client,
@@ -2134,11 +1591,6 @@ const ChannelWithContext = <
2134
1591
  }
2135
1592
  };
2136
1593
 
2137
- const disabledValue = useMemo(
2138
- () => !!channel?.data?.frozen && disableIfFrozenChannel,
2139
- [channel.data?.frozen, disableIfFrozenChannel],
2140
- );
2141
-
2142
1594
  const ownCapabilitiesContext = useCreateOwnCapabilitiesContext({
2143
1595
  channel,
2144
1596
  overrideCapabilities: overrideOwnCapabilities,
@@ -2146,7 +1598,7 @@ const ChannelWithContext = <
2146
1598
 
2147
1599
  const channelContext = useCreateChannelContext({
2148
1600
  channel,
2149
- disabled: disabledValue,
1601
+ disabled: !!channel?.data?.frozen,
2150
1602
  EmptyStateIndicator,
2151
1603
  enableMessageGroupingByUser,
2152
1604
  enforceUniqueReaction,
@@ -2156,19 +1608,16 @@ const ChannelWithContext = <
2156
1608
  !!(clientChannelConfig?.commands || [])?.some((command) => command.name === 'giphy'),
2157
1609
  hideDateSeparators,
2158
1610
  hideStickyDateHeader,
2159
- isAdmin,
2160
1611
  isChannelActive: shouldSyncChannel,
2161
- isModerator,
2162
- isOwner,
2163
1612
  lastRead,
2164
1613
  loadChannelAroundMessage,
2165
- loading,
1614
+ loading: channelMessagesState.loading,
2166
1615
  LoadingIndicator,
2167
1616
  markRead,
2168
1617
  maxTimeBetweenGroupedMessages,
2169
- members,
1618
+ members: channelState.members ?? {},
2170
1619
  NetworkDownIndicator,
2171
- read,
1620
+ read: channelState.read ?? {},
2172
1621
  reloadChannel,
2173
1622
  scrollToFirstUnreadThreshold,
2174
1623
  setLastRead,
@@ -2177,8 +1626,8 @@ const ChannelWithContext = <
2177
1626
  targetedMessage,
2178
1627
  threadList,
2179
1628
  uploadAbortControllerRef,
2180
- watcherCount,
2181
- watchers,
1629
+ watcherCount: channelState.watcherCount,
1630
+ watchers: channelState.watchers,
2182
1631
  });
2183
1632
 
2184
1633
  // This is mainly a hack to get around an issue with sendMessage not being passed correctly as a
@@ -2250,21 +1699,22 @@ const ChannelWithContext = <
2250
1699
  setQuotedMessageState,
2251
1700
  ShowThreadMessageInChannelButton,
2252
1701
  StartAudioRecordingButton,
1702
+ StopMessageStreamingButton,
2253
1703
  UploadProgressIndicator,
2254
1704
  });
2255
1705
 
2256
1706
  const messageListContext = useCreatePaginatedMessageListContext({
2257
1707
  channelId,
2258
- hasMore,
2259
- hasNoMoreRecentMessagesToLoad,
2260
- loadingMore: loadingMoreProp !== undefined ? loadingMoreProp : loadingMore,
1708
+ hasMore: channelMessagesState.hasMore,
1709
+ loadingMore: loadingMoreProp !== undefined ? loadingMoreProp : channelMessagesState.loadingMore,
2261
1710
  loadingMoreRecent:
2262
- loadingMoreRecentProp !== undefined ? loadingMoreRecentProp : loadingMoreRecent,
1711
+ loadingMoreRecentProp !== undefined
1712
+ ? loadingMoreRecentProp
1713
+ : channelMessagesState.loadingMoreRecent,
1714
+ loadLatestMessages,
2263
1715
  loadMore,
2264
1716
  loadMoreRecent,
2265
- messages,
2266
- setLoadingMore,
2267
- setLoadingMoreRecent,
1717
+ messages: channelMessagesState.messages ?? [],
2268
1718
  });
2269
1719
 
2270
1720
  const messagesContext = useCreateMessagesContext({
@@ -2312,6 +1762,7 @@ const ChannelWithContext = <
2312
1762
  InlineDateSeparator,
2313
1763
  InlineUnreadIndicator,
2314
1764
  isAttachmentEqual,
1765
+ isMessageAIGenerated,
2315
1766
  legacyImageViewerSwipeBehaviour,
2316
1767
  markdownRules,
2317
1768
  Message,
@@ -2359,6 +1810,7 @@ const ChannelWithContext = <
2359
1810
  setEditingState,
2360
1811
  setQuotedMessageState,
2361
1812
  shouldShowUnreadUnderlay,
1813
+ StreamingMessageView,
2362
1814
  supportedReactions,
2363
1815
  targetedMessage,
2364
1816
  TypingIndicator,
@@ -2389,13 +1841,13 @@ const ChannelWithContext = <
2389
1841
  });
2390
1842
 
2391
1843
  const typingContext = useCreateTypingContext({
2392
- typing,
1844
+ typing: channelState.typing ?? {},
2393
1845
  });
2394
1846
 
2395
1847
  // TODO: replace the null view with appropriate message. Currently this is waiting a design decision.
2396
1848
  if (deleted) return null;
2397
1849
 
2398
- if (!channel || (error && messages.length === 0)) {
1850
+ if (!channel || (error && channelMessagesState.messages?.length === 0)) {
2399
1851
  return <LoadingErrorIndicator error={error} listType='message' retry={reloadChannel} />;
2400
1852
  }
2401
1853
 
@@ -2455,7 +1907,8 @@ export const Channel = <
2455
1907
  >(
2456
1908
  props: PropsWithChildren<ChannelProps<StreamChatGenerics>>,
2457
1909
  ) => {
2458
- const { client, enableOfflineSupport } = useChatContext<StreamChatGenerics>();
1910
+ const { client, enableOfflineSupport, isMessageAIGenerated } =
1911
+ useChatContext<StreamChatGenerics>();
2459
1912
  const { t } = useTranslationContext();
2460
1913
 
2461
1914
  const threadFromProps = props?.thread;
@@ -2471,22 +1924,7 @@ export const Channel = <
2471
1924
 
2472
1925
  const shouldSyncChannel = threadMessage?.id ? !!props.threadList : true;
2473
1926
 
2474
- const {
2475
- members,
2476
- messages,
2477
- read,
2478
- setMembers,
2479
- setMessages,
2480
- setRead,
2481
- setThreadMessages,
2482
- setTyping,
2483
- setWatcherCount,
2484
- setWatchers,
2485
- threadMessages,
2486
- typing,
2487
- watcherCount,
2488
- watchers,
2489
- } = useChannelState<StreamChatGenerics>(
1927
+ const { setThreadMessages, threadMessages } = useChannelState<StreamChatGenerics>(
2490
1928
  props.channel,
2491
1929
  props.threadList ? threadMessage?.id : undefined,
2492
1930
  );
@@ -2501,21 +1939,10 @@ export const Channel = <
2501
1939
  {...props}
2502
1940
  shouldSyncChannel={shouldSyncChannel}
2503
1941
  {...{
2504
- members,
2505
- messages: props.messages || messages,
2506
- read,
2507
- setMembers,
2508
- setMessages,
2509
- setRead,
1942
+ isMessageAIGenerated,
2510
1943
  setThreadMessages,
2511
- setTyping,
2512
- setWatcherCount,
2513
- setWatchers,
2514
1944
  thread,
2515
1945
  threadMessages,
2516
- typing,
2517
- watcherCount,
2518
- watchers,
2519
1946
  }}
2520
1947
  />
2521
1948
  );