stream-chat-react-native-core 7.0.0-rc.8 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (498) hide show
  1. package/README.md +1 -1
  2. package/lib/commonjs/components/Attachment/AudioAttachment.js +19 -9
  3. package/lib/commonjs/components/Attachment/AudioAttachment.js.map +1 -1
  4. package/lib/commonjs/components/Attachment/FileAttachmentGroup.js +3 -1
  5. package/lib/commonjs/components/Attachment/FileAttachmentGroup.js.map +1 -1
  6. package/lib/commonjs/components/Attachment/Gallery.js +16 -3
  7. package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
  8. package/lib/commonjs/components/Attachment/ImageReloadIndicator.js.map +1 -1
  9. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js +2 -2
  10. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  11. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerItem.js +7 -24
  12. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerItem.js.map +1 -1
  13. package/lib/commonjs/components/AutoCompleteInput/AutoCompleteInput.js +2 -4
  14. package/lib/commonjs/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
  15. package/lib/commonjs/components/Channel/Channel.js +320 -310
  16. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  17. package/lib/commonjs/components/Channel/hooks/useChannelDataState.js.map +1 -1
  18. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +2 -0
  19. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  20. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js +133 -147
  21. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js.map +1 -1
  22. package/lib/commonjs/components/Chat/Chat.js.map +1 -1
  23. package/lib/commonjs/components/KeyboardCompatibleView/KeyboardCompatibleView.js +8 -13
  24. package/lib/commonjs/components/KeyboardCompatibleView/KeyboardCompatibleView.js.map +1 -1
  25. package/lib/commonjs/components/Message/Message.js +14 -7
  26. package/lib/commonjs/components/Message/Message.js.map +1 -1
  27. package/lib/commonjs/components/Message/MessageSimple/MessageFooter.js.map +1 -1
  28. package/lib/commonjs/components/Message/MessageSimple/MessageSimple.js +70 -54
  29. package/lib/commonjs/components/Message/MessageSimple/MessageSimple.js.map +1 -1
  30. package/lib/commonjs/components/Message/MessageSimple/MessageStatus.js +14 -6
  31. package/lib/commonjs/components/Message/MessageSimple/MessageStatus.js.map +1 -1
  32. package/lib/commonjs/components/Message/MessageSimple/MessageTextContainer.js.map +1 -1
  33. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  34. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js +3 -1
  35. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  36. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  37. package/lib/commonjs/components/Message/hooks/useMessageActions.js.map +1 -1
  38. package/lib/commonjs/components/MessageInput/FileUploadPreview.js +25 -39
  39. package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
  40. package/lib/commonjs/components/MessageInput/InputButtons.js +18 -15
  41. package/lib/commonjs/components/MessageInput/InputButtons.js.map +1 -1
  42. package/lib/commonjs/components/MessageInput/MessageInput.js +96 -74
  43. package/lib/commonjs/components/MessageInput/MessageInput.js.map +1 -1
  44. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js +2 -1
  45. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js.map +1 -1
  46. package/lib/commonjs/components/MessageInput/hooks/useAudioController.js +4 -4
  47. package/lib/commonjs/components/MessageInput/hooks/useAudioController.js.map +1 -1
  48. package/lib/commonjs/components/MessageList/MessageList.js +281 -223
  49. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  50. package/lib/commonjs/components/MessageList/hooks/useMessageList.js +65 -48
  51. package/lib/commonjs/components/MessageList/hooks/useMessageList.js.map +1 -1
  52. package/lib/commonjs/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.js.map +1 -1
  53. package/lib/commonjs/components/MessageList/utils/getGroupStyles.js +1 -1
  54. package/lib/commonjs/components/MessageList/utils/getGroupStyles.js.map +1 -1
  55. package/lib/commonjs/components/MessageList/utils/getLastReceivedMessage.js.map +1 -1
  56. package/lib/commonjs/components/MessageList/utils/getReadState.js +20 -0
  57. package/lib/commonjs/components/MessageList/utils/getReadState.js.map +1 -0
  58. package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
  59. package/lib/commonjs/components/Poll/components/Button.js.map +1 -1
  60. package/lib/commonjs/components/Poll/components/PollResults/PollResultItem.js.map +1 -1
  61. package/lib/commonjs/components/Reply/Reply.js +2 -2
  62. package/lib/commonjs/components/Reply/Reply.js.map +1 -1
  63. package/lib/commonjs/components/Thread/components/ThreadFooterComponent.js +24 -6
  64. package/lib/commonjs/components/Thread/components/ThreadFooterComponent.js.map +1 -1
  65. package/lib/commonjs/components/ThreadList/ThreadListItem.js.map +1 -1
  66. package/lib/commonjs/components/UIComponents/BottomSheetModal.js +10 -6
  67. package/lib/commonjs/components/UIComponents/BottomSheetModal.js.map +1 -1
  68. package/lib/commonjs/components/index.js +15 -4
  69. package/lib/commonjs/components/index.js.map +1 -1
  70. package/lib/commonjs/contexts/attachmentPickerContext/AttachmentPickerContext.js.map +1 -1
  71. package/lib/commonjs/contexts/channelsStateContext/useChannelState.js +5 -1
  72. package/lib/commonjs/contexts/channelsStateContext/useChannelState.js.map +1 -1
  73. package/lib/commonjs/contexts/debugContext/DebugContext.js.map +1 -1
  74. package/lib/commonjs/contexts/imageGalleryContext/ImageGalleryContext.js.map +1 -1
  75. package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
  76. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +535 -523
  77. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  78. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +7 -6
  79. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  80. package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js +37 -41
  81. package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  82. package/lib/commonjs/contexts/messageInputContext/utils/utils.js +4 -4
  83. package/lib/commonjs/contexts/messageInputContext/utils/utils.js.map +1 -1
  84. package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
  85. package/lib/commonjs/contexts/pollContext/pollContext.js.map +1 -1
  86. package/lib/commonjs/contexts/suggestionsContext/SuggestionsContext.js +23 -14
  87. package/lib/commonjs/contexts/suggestionsContext/SuggestionsContext.js.map +1 -1
  88. package/lib/commonjs/contexts/themeContext/utils/theme.js +2 -1
  89. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  90. package/lib/commonjs/contexts/threadContext/ThreadContext.js.map +1 -1
  91. package/lib/commonjs/contexts/threadsContext/ThreadListItemContext.js.map +1 -1
  92. package/lib/commonjs/hooks/index.js +22 -0
  93. package/lib/commonjs/hooks/index.js.map +1 -1
  94. package/lib/commonjs/hooks/useAudioPlayer.js +60 -69
  95. package/lib/commonjs/hooks/useAudioPlayer.js.map +1 -1
  96. package/lib/commonjs/hooks/useStableCallback.js +13 -0
  97. package/lib/commonjs/hooks/useStableCallback.js.map +1 -0
  98. package/lib/commonjs/hooks/useTranslatedMessage.js.map +1 -1
  99. package/lib/commonjs/i18n/en.json +3 -0
  100. package/lib/commonjs/i18n/es.json +3 -0
  101. package/lib/commonjs/i18n/fr.json +3 -0
  102. package/lib/commonjs/i18n/he.json +3 -0
  103. package/lib/commonjs/i18n/hi.json +2 -0
  104. package/lib/commonjs/i18n/it.json +3 -0
  105. package/lib/commonjs/i18n/ja.json +1 -0
  106. package/lib/commonjs/i18n/ko.json +1 -0
  107. package/lib/commonjs/i18n/nl.json +2 -0
  108. package/lib/commonjs/i18n/pt-br.json +3 -0
  109. package/lib/commonjs/i18n/ru.json +4 -0
  110. package/lib/commonjs/i18n/tr.json +2 -0
  111. package/lib/commonjs/mock-builders/api/channelMocks.js.map +1 -1
  112. package/lib/commonjs/native.js.map +1 -1
  113. package/lib/commonjs/store/mappers/mapMessageToStorable.js.map +1 -1
  114. package/lib/commonjs/types/types.js.map +1 -1
  115. package/lib/commonjs/utils/compressImage.js +1 -1
  116. package/lib/commonjs/utils/compressImage.js.map +1 -1
  117. package/lib/commonjs/utils/removeReservedFields.js.map +1 -1
  118. package/lib/commonjs/utils/utils.js +17 -4
  119. package/lib/commonjs/utils/utils.js.map +1 -1
  120. package/lib/commonjs/version.json +1 -1
  121. package/lib/module/components/Attachment/AudioAttachment.js +19 -9
  122. package/lib/module/components/Attachment/AudioAttachment.js.map +1 -1
  123. package/lib/module/components/Attachment/FileAttachmentGroup.js +3 -1
  124. package/lib/module/components/Attachment/FileAttachmentGroup.js.map +1 -1
  125. package/lib/module/components/Attachment/Gallery.js +16 -3
  126. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  127. package/lib/module/components/Attachment/ImageReloadIndicator.js.map +1 -1
  128. package/lib/module/components/AttachmentPicker/AttachmentPicker.js +2 -2
  129. package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  130. package/lib/module/components/AttachmentPicker/components/AttachmentPickerItem.js +7 -24
  131. package/lib/module/components/AttachmentPicker/components/AttachmentPickerItem.js.map +1 -1
  132. package/lib/module/components/AutoCompleteInput/AutoCompleteInput.js +2 -4
  133. package/lib/module/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
  134. package/lib/module/components/Channel/Channel.js +320 -310
  135. package/lib/module/components/Channel/Channel.js.map +1 -1
  136. package/lib/module/components/Channel/hooks/useChannelDataState.js.map +1 -1
  137. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +2 -0
  138. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  139. package/lib/module/components/Channel/hooks/useMessageListPagination.js +133 -147
  140. package/lib/module/components/Channel/hooks/useMessageListPagination.js.map +1 -1
  141. package/lib/module/components/Chat/Chat.js.map +1 -1
  142. package/lib/module/components/KeyboardCompatibleView/KeyboardCompatibleView.js +8 -13
  143. package/lib/module/components/KeyboardCompatibleView/KeyboardCompatibleView.js.map +1 -1
  144. package/lib/module/components/Message/Message.js +14 -7
  145. package/lib/module/components/Message/Message.js.map +1 -1
  146. package/lib/module/components/Message/MessageSimple/MessageFooter.js.map +1 -1
  147. package/lib/module/components/Message/MessageSimple/MessageSimple.js +70 -54
  148. package/lib/module/components/Message/MessageSimple/MessageSimple.js.map +1 -1
  149. package/lib/module/components/Message/MessageSimple/MessageStatus.js +14 -6
  150. package/lib/module/components/Message/MessageSimple/MessageStatus.js.map +1 -1
  151. package/lib/module/components/Message/MessageSimple/MessageTextContainer.js.map +1 -1
  152. package/lib/module/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  153. package/lib/module/components/Message/hooks/useCreateMessageContext.js +3 -1
  154. package/lib/module/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  155. package/lib/module/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  156. package/lib/module/components/Message/hooks/useMessageActions.js.map +1 -1
  157. package/lib/module/components/MessageInput/FileUploadPreview.js +25 -39
  158. package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
  159. package/lib/module/components/MessageInput/InputButtons.js +18 -15
  160. package/lib/module/components/MessageInput/InputButtons.js.map +1 -1
  161. package/lib/module/components/MessageInput/MessageInput.js +96 -74
  162. package/lib/module/components/MessageInput/MessageInput.js.map +1 -1
  163. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js +2 -1
  164. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js.map +1 -1
  165. package/lib/module/components/MessageInput/hooks/useAudioController.js +4 -4
  166. package/lib/module/components/MessageInput/hooks/useAudioController.js.map +1 -1
  167. package/lib/module/components/MessageList/MessageList.js +281 -223
  168. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  169. package/lib/module/components/MessageList/hooks/useMessageList.js +65 -48
  170. package/lib/module/components/MessageList/hooks/useMessageList.js.map +1 -1
  171. package/lib/module/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.js.map +1 -1
  172. package/lib/module/components/MessageList/utils/getGroupStyles.js +1 -1
  173. package/lib/module/components/MessageList/utils/getGroupStyles.js.map +1 -1
  174. package/lib/module/components/MessageList/utils/getLastReceivedMessage.js.map +1 -1
  175. package/lib/module/components/MessageList/utils/getReadState.js +20 -0
  176. package/lib/module/components/MessageList/utils/getReadState.js.map +1 -0
  177. package/lib/module/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
  178. package/lib/module/components/Poll/components/Button.js.map +1 -1
  179. package/lib/module/components/Poll/components/PollResults/PollResultItem.js.map +1 -1
  180. package/lib/module/components/Reply/Reply.js +2 -2
  181. package/lib/module/components/Reply/Reply.js.map +1 -1
  182. package/lib/module/components/Thread/components/ThreadFooterComponent.js +24 -6
  183. package/lib/module/components/Thread/components/ThreadFooterComponent.js.map +1 -1
  184. package/lib/module/components/ThreadList/ThreadListItem.js.map +1 -1
  185. package/lib/module/components/UIComponents/BottomSheetModal.js +10 -6
  186. package/lib/module/components/UIComponents/BottomSheetModal.js.map +1 -1
  187. package/lib/module/components/index.js +15 -4
  188. package/lib/module/components/index.js.map +1 -1
  189. package/lib/module/contexts/attachmentPickerContext/AttachmentPickerContext.js.map +1 -1
  190. package/lib/module/contexts/channelsStateContext/useChannelState.js +5 -1
  191. package/lib/module/contexts/channelsStateContext/useChannelState.js.map +1 -1
  192. package/lib/module/contexts/debugContext/DebugContext.js.map +1 -1
  193. package/lib/module/contexts/imageGalleryContext/ImageGalleryContext.js.map +1 -1
  194. package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
  195. package/lib/module/contexts/messageInputContext/MessageInputContext.js +535 -523
  196. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  197. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +7 -6
  198. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  199. package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js +37 -41
  200. package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  201. package/lib/module/contexts/messageInputContext/utils/utils.js +4 -4
  202. package/lib/module/contexts/messageInputContext/utils/utils.js.map +1 -1
  203. package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
  204. package/lib/module/contexts/pollContext/pollContext.js.map +1 -1
  205. package/lib/module/contexts/suggestionsContext/SuggestionsContext.js +23 -14
  206. package/lib/module/contexts/suggestionsContext/SuggestionsContext.js.map +1 -1
  207. package/lib/module/contexts/themeContext/utils/theme.js +2 -1
  208. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  209. package/lib/module/contexts/threadContext/ThreadContext.js.map +1 -1
  210. package/lib/module/contexts/threadsContext/ThreadListItemContext.js.map +1 -1
  211. package/lib/module/hooks/index.js +22 -0
  212. package/lib/module/hooks/index.js.map +1 -1
  213. package/lib/module/hooks/useAudioPlayer.js +60 -69
  214. package/lib/module/hooks/useAudioPlayer.js.map +1 -1
  215. package/lib/module/hooks/useStableCallback.js +13 -0
  216. package/lib/module/hooks/useStableCallback.js.map +1 -0
  217. package/lib/module/hooks/useTranslatedMessage.js.map +1 -1
  218. package/lib/module/i18n/en.json +3 -0
  219. package/lib/module/i18n/es.json +3 -0
  220. package/lib/module/i18n/fr.json +3 -0
  221. package/lib/module/i18n/he.json +3 -0
  222. package/lib/module/i18n/hi.json +2 -0
  223. package/lib/module/i18n/it.json +3 -0
  224. package/lib/module/i18n/ja.json +1 -0
  225. package/lib/module/i18n/ko.json +1 -0
  226. package/lib/module/i18n/nl.json +2 -0
  227. package/lib/module/i18n/pt-br.json +3 -0
  228. package/lib/module/i18n/ru.json +4 -0
  229. package/lib/module/i18n/tr.json +2 -0
  230. package/lib/module/mock-builders/api/channelMocks.js.map +1 -1
  231. package/lib/module/native.js.map +1 -1
  232. package/lib/module/store/mappers/mapMessageToStorable.js.map +1 -1
  233. package/lib/module/types/types.js.map +1 -1
  234. package/lib/module/utils/compressImage.js +1 -1
  235. package/lib/module/utils/compressImage.js.map +1 -1
  236. package/lib/module/utils/removeReservedFields.js.map +1 -1
  237. package/lib/module/utils/utils.js +17 -4
  238. package/lib/module/utils/utils.js.map +1 -1
  239. package/lib/module/version.json +1 -1
  240. package/lib/typescript/components/Attachment/AudioAttachment.d.ts +2 -2
  241. package/lib/typescript/components/Attachment/AudioAttachment.d.ts.map +1 -1
  242. package/lib/typescript/components/Attachment/FileAttachmentGroup.d.ts.map +1 -1
  243. package/lib/typescript/components/Attachment/Gallery.d.ts +3 -3
  244. package/lib/typescript/components/Attachment/Gallery.d.ts.map +1 -1
  245. package/lib/typescript/components/Attachment/ImageReloadIndicator.d.ts +4 -3
  246. package/lib/typescript/components/Attachment/ImageReloadIndicator.d.ts.map +1 -1
  247. package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts.map +1 -1
  248. package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerItem.d.ts +2 -2
  249. package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerItem.d.ts.map +1 -1
  250. package/lib/typescript/components/AutoCompleteInput/AutoCompleteInput.d.ts +2 -3
  251. package/lib/typescript/components/AutoCompleteInput/AutoCompleteInput.d.ts.map +1 -1
  252. package/lib/typescript/components/Channel/Channel.d.ts +3 -4
  253. package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
  254. package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts +2 -3
  255. package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts.map +1 -1
  256. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +1 -1
  257. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts.map +1 -1
  258. package/lib/typescript/components/Channel/hooks/useCreateThreadContext.d.ts +6 -6
  259. package/lib/typescript/components/Channel/hooks/useCreateThreadContext.d.ts.map +1 -1
  260. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts +3 -3
  261. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts.map +1 -1
  262. package/lib/typescript/components/ChannelPreview/hooks/useChannelPreviewData.d.ts +1 -1
  263. package/lib/typescript/components/ChannelPreview/hooks/useLatestMessagePreview.d.ts +1 -1
  264. package/lib/typescript/components/Chat/Chat.d.ts +0 -9
  265. package/lib/typescript/components/Chat/Chat.d.ts.map +1 -1
  266. package/lib/typescript/components/KeyboardCompatibleView/KeyboardCompatibleView.d.ts +3 -0
  267. package/lib/typescript/components/KeyboardCompatibleView/KeyboardCompatibleView.d.ts.map +1 -1
  268. package/lib/typescript/components/Message/Message.d.ts +4 -5
  269. package/lib/typescript/components/Message/Message.d.ts.map +1 -1
  270. package/lib/typescript/components/Message/MessageSimple/MessageFooter.d.ts +2 -3
  271. package/lib/typescript/components/Message/MessageSimple/MessageFooter.d.ts.map +1 -1
  272. package/lib/typescript/components/Message/MessageSimple/MessageSimple.d.ts.map +1 -1
  273. package/lib/typescript/components/Message/MessageSimple/MessageStatus.d.ts +1 -1
  274. package/lib/typescript/components/Message/MessageSimple/MessageStatus.d.ts.map +1 -1
  275. package/lib/typescript/components/Message/MessageSimple/MessageTextContainer.d.ts.map +1 -1
  276. package/lib/typescript/components/Message/MessageSimple/utils/renderText.d.ts +2 -2
  277. package/lib/typescript/components/Message/MessageSimple/utils/renderText.d.ts.map +1 -1
  278. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts +1 -1
  279. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts.map +1 -1
  280. package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts.map +1 -1
  281. package/lib/typescript/components/Message/hooks/useMessageActions.d.ts +2 -2
  282. package/lib/typescript/components/Message/hooks/useMessageActions.d.ts.map +1 -1
  283. package/lib/typescript/components/MessageInput/FileUploadPreview.d.ts +2 -4
  284. package/lib/typescript/components/MessageInput/FileUploadPreview.d.ts.map +1 -1
  285. package/lib/typescript/components/MessageInput/InputButtons.d.ts +1 -1
  286. package/lib/typescript/components/MessageInput/InputButtons.d.ts.map +1 -1
  287. package/lib/typescript/components/MessageInput/MessageInput.d.ts +1 -1
  288. package/lib/typescript/components/MessageInput/MessageInput.d.ts.map +1 -1
  289. package/lib/typescript/components/MessageInput/hooks/useAudioController.d.ts.map +1 -1
  290. package/lib/typescript/components/MessageList/MessageList.d.ts +4 -4
  291. package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
  292. package/lib/typescript/components/MessageList/MessageSystem.d.ts +2 -2
  293. package/lib/typescript/components/MessageList/MessageSystem.d.ts.map +1 -1
  294. package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts +14 -9
  295. package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts.map +1 -1
  296. package/lib/typescript/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.d.ts +2 -2
  297. package/lib/typescript/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.d.ts.map +1 -1
  298. package/lib/typescript/components/MessageList/utils/getGroupStyles.d.ts.map +1 -1
  299. package/lib/typescript/components/MessageList/utils/getLastReceivedMessage.d.ts +2 -2
  300. package/lib/typescript/components/MessageList/utils/getLastReceivedMessage.d.ts.map +1 -1
  301. package/lib/typescript/components/MessageList/utils/getReadState.d.ts +9 -0
  302. package/lib/typescript/components/MessageList/utils/getReadState.d.ts.map +1 -0
  303. package/lib/typescript/components/MessageMenu/hooks/useFetchReactions.d.ts +2 -3
  304. package/lib/typescript/components/MessageMenu/hooks/useFetchReactions.d.ts.map +1 -1
  305. package/lib/typescript/components/Poll/components/Button.d.ts +2 -3
  306. package/lib/typescript/components/Poll/components/Button.d.ts.map +1 -1
  307. package/lib/typescript/components/Poll/components/PollResults/PollResultItem.d.ts +2 -3
  308. package/lib/typescript/components/Poll/components/PollResults/PollResultItem.d.ts.map +1 -1
  309. package/lib/typescript/components/Reply/Reply.d.ts.map +1 -1
  310. package/lib/typescript/components/Thread/components/ThreadFooterComponent.d.ts.map +1 -1
  311. package/lib/typescript/components/ThreadList/ThreadListItem.d.ts.map +1 -1
  312. package/lib/typescript/components/UIComponents/BottomSheetModal.d.ts.map +1 -1
  313. package/lib/typescript/components/index.d.ts +2 -1
  314. package/lib/typescript/components/index.d.ts.map +1 -1
  315. package/lib/typescript/contexts/attachmentPickerContext/AttachmentPickerContext.d.ts +3 -3
  316. package/lib/typescript/contexts/attachmentPickerContext/AttachmentPickerContext.d.ts.map +1 -1
  317. package/lib/typescript/contexts/channelsStateContext/useChannelState.d.ts.map +1 -1
  318. package/lib/typescript/contexts/debugContext/DebugContext.d.ts +2 -3
  319. package/lib/typescript/contexts/debugContext/DebugContext.d.ts.map +1 -1
  320. package/lib/typescript/contexts/imageGalleryContext/ImageGalleryContext.d.ts +3 -3
  321. package/lib/typescript/contexts/imageGalleryContext/ImageGalleryContext.d.ts.map +1 -1
  322. package/lib/typescript/contexts/messageContext/MessageContext.d.ts +6 -4
  323. package/lib/typescript/contexts/messageContext/MessageContext.d.ts.map +1 -1
  324. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +13 -15
  325. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts.map +1 -1
  326. package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts +1 -1
  327. package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts.map +1 -1
  328. package/lib/typescript/contexts/messageInputContext/hooks/useMessageDetailsForState.d.ts +3 -3
  329. package/lib/typescript/contexts/messageInputContext/hooks/useMessageDetailsForState.d.ts.map +1 -1
  330. package/lib/typescript/contexts/messageInputContext/utils/utils.d.ts +2 -2
  331. package/lib/typescript/contexts/messageInputContext/utils/utils.d.ts.map +1 -1
  332. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +25 -21
  333. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts.map +1 -1
  334. package/lib/typescript/contexts/pollContext/pollContext.d.ts +2 -3
  335. package/lib/typescript/contexts/pollContext/pollContext.d.ts.map +1 -1
  336. package/lib/typescript/contexts/suggestionsContext/SuggestionsContext.d.ts.map +1 -1
  337. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +1 -0
  338. package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
  339. package/lib/typescript/contexts/threadContext/ThreadContext.d.ts +4 -5
  340. package/lib/typescript/contexts/threadContext/ThreadContext.d.ts.map +1 -1
  341. package/lib/typescript/contexts/threadsContext/ThreadListItemContext.d.ts +3 -4
  342. package/lib/typescript/contexts/threadsContext/ThreadListItemContext.d.ts.map +1 -1
  343. package/lib/typescript/hooks/index.d.ts +2 -0
  344. package/lib/typescript/hooks/index.d.ts.map +1 -1
  345. package/lib/typescript/hooks/useAudioPlayer.d.ts.map +1 -1
  346. package/lib/typescript/hooks/useStableCallback.d.ts +26 -0
  347. package/lib/typescript/hooks/useStableCallback.d.ts.map +1 -0
  348. package/lib/typescript/hooks/useTranslatedMessage.d.ts +59 -58
  349. package/lib/typescript/hooks/useTranslatedMessage.d.ts.map +1 -1
  350. package/lib/typescript/i18n/en.json +3 -0
  351. package/lib/typescript/i18n/es.json +3 -0
  352. package/lib/typescript/i18n/fr.json +3 -0
  353. package/lib/typescript/i18n/he.json +3 -0
  354. package/lib/typescript/i18n/hi.json +2 -0
  355. package/lib/typescript/i18n/it.json +3 -0
  356. package/lib/typescript/i18n/ja.json +1 -0
  357. package/lib/typescript/i18n/ko.json +1 -0
  358. package/lib/typescript/i18n/nl.json +2 -0
  359. package/lib/typescript/i18n/pt-br.json +3 -0
  360. package/lib/typescript/i18n/ru.json +4 -0
  361. package/lib/typescript/i18n/tr.json +2 -0
  362. package/lib/typescript/native.d.ts +8 -11
  363. package/lib/typescript/native.d.ts.map +1 -1
  364. package/lib/typescript/store/apis/insertReaction.d.ts +2 -2
  365. package/lib/typescript/store/apis/insertReaction.d.ts.map +1 -1
  366. package/lib/typescript/store/apis/updateMessage.d.ts +2 -2
  367. package/lib/typescript/store/apis/updateMessage.d.ts.map +1 -1
  368. package/lib/typescript/store/apis/updateReaction.d.ts +2 -2
  369. package/lib/typescript/store/apis/updateReaction.d.ts.map +1 -1
  370. package/lib/typescript/store/mappers/mapMessageToStorable.d.ts +2 -2
  371. package/lib/typescript/store/mappers/mapMessageToStorable.d.ts.map +1 -1
  372. package/lib/typescript/types/types.d.ts +28 -50
  373. package/lib/typescript/types/types.d.ts.map +1 -1
  374. package/lib/typescript/utils/compressImage.d.ts +2 -2
  375. package/lib/typescript/utils/compressImage.d.ts.map +1 -1
  376. package/lib/typescript/utils/i18n/Streami18n.d.ts +3 -0
  377. package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
  378. package/lib/typescript/utils/removeReservedFields.d.ts +2 -3
  379. package/lib/typescript/utils/removeReservedFields.d.ts.map +1 -1
  380. package/lib/typescript/utils/utils.d.ts +10 -10
  381. package/lib/typescript/utils/utils.d.ts.map +1 -1
  382. package/package.json +4 -3
  383. package/src/components/Attachment/AudioAttachment.tsx +12 -6
  384. package/src/components/Attachment/FileAttachmentGroup.tsx +3 -1
  385. package/src/components/Attachment/Gallery.tsx +22 -7
  386. package/src/components/Attachment/ImageReloadIndicator.tsx +4 -5
  387. package/src/components/AttachmentPicker/AttachmentPicker.tsx +4 -10
  388. package/src/components/AttachmentPicker/components/AttachmentPickerItem.tsx +9 -37
  389. package/src/components/AutoCompleteInput/AutoCompleteInput.tsx +27 -23
  390. package/src/components/AutoCompleteInput/__tests__/AutoCompleteInput.test.js +12 -12
  391. package/src/components/Channel/Channel.tsx +423 -361
  392. package/src/components/Channel/__tests__/Channel.test.js +10 -3
  393. package/src/components/Channel/hooks/useChannelDataState.ts +2 -4
  394. package/src/components/Channel/hooks/useCreateMessagesContext.ts +2 -0
  395. package/src/components/Channel/hooks/useMessageListPagination.tsx +150 -150
  396. package/src/components/Chat/Chat.tsx +0 -9
  397. package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +8 -7
  398. package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx +5 -4
  399. package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx +5 -4
  400. package/src/components/ImageGallery/__tests__/ImageGalleryOverlay.test.tsx +3 -2
  401. package/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx +12 -5
  402. package/src/components/Message/Message.tsx +16 -15
  403. package/src/components/Message/MessageSimple/MessageFooter.tsx +2 -3
  404. package/src/components/Message/MessageSimple/MessageSimple.tsx +112 -70
  405. package/src/components/Message/MessageSimple/MessageStatus.tsx +19 -17
  406. package/src/components/Message/MessageSimple/MessageTextContainer.tsx +3 -3
  407. package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js +11 -5
  408. package/src/components/Message/MessageSimple/__tests__/MessageTextContainer.test.tsx +5 -4
  409. package/src/components/Message/MessageSimple/utils/renderText.tsx +2 -3
  410. package/src/components/Message/hooks/useCreateMessageContext.ts +3 -0
  411. package/src/components/Message/hooks/useMessageActionHandlers.ts +1 -3
  412. package/src/components/Message/hooks/useMessageActions.tsx +4 -3
  413. package/src/components/MessageInput/FileUploadPreview.tsx +41 -70
  414. package/src/components/MessageInput/ImageUploadPreview.tsx +2 -2
  415. package/src/components/MessageInput/InputButtons.tsx +14 -10
  416. package/src/components/MessageInput/MessageInput.tsx +28 -30
  417. package/src/components/MessageInput/__tests__/FileUploadPreview.test.js +1 -1
  418. package/src/components/MessageInput/__tests__/MessageInput.test.js +3 -1
  419. package/src/components/MessageInput/components/AudioRecorder/AudioRecordingButton.tsx +1 -0
  420. package/src/components/MessageInput/hooks/useAudioController.tsx +6 -5
  421. package/src/components/MessageList/MessageList.tsx +253 -137
  422. package/src/components/MessageList/MessageSystem.tsx +2 -2
  423. package/src/components/MessageList/hooks/useMessageList.ts +82 -64
  424. package/src/components/MessageList/hooks/useShouldScrollToRecentOnNewOwnMessage.ts +2 -2
  425. package/src/components/MessageList/utils/getGroupStyles.ts +7 -5
  426. package/src/components/MessageList/utils/getLastReceivedMessage.ts +3 -3
  427. package/src/components/MessageList/utils/getReadState.ts +27 -0
  428. package/src/components/MessageMenu/__tests__/MessageUserReactions.test.tsx +2 -3
  429. package/src/components/MessageMenu/hooks/useFetchReactions.ts +2 -3
  430. package/src/components/Poll/components/Button.tsx +2 -4
  431. package/src/components/Poll/components/PollResults/PollResultItem.tsx +2 -3
  432. package/src/components/Reply/Reply.tsx +1 -2
  433. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +318 -847
  434. package/src/components/Thread/components/ThreadFooterComponent.tsx +31 -9
  435. package/src/components/ThreadList/ThreadListItem.tsx +6 -4
  436. package/src/components/UIComponents/BottomSheetModal.tsx +11 -7
  437. package/src/components/index.ts +2 -1
  438. package/src/contexts/attachmentPickerContext/AttachmentPickerContext.tsx +5 -4
  439. package/src/contexts/channelsStateContext/useChannelState.ts +5 -1
  440. package/src/contexts/debugContext/DebugContext.tsx +2 -4
  441. package/src/contexts/imageGalleryContext/ImageGalleryContext.tsx +5 -4
  442. package/src/contexts/messageContext/MessageContext.tsx +6 -4
  443. package/src/contexts/messageInputContext/MessageInputContext.tsx +295 -262
  444. package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap +10 -6
  445. package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx +6 -5
  446. package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx +3 -5
  447. package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx +14 -9
  448. package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts +7 -3
  449. package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts +37 -40
  450. package/src/contexts/messageInputContext/utils/utils.ts +6 -8
  451. package/src/contexts/messagesContext/MessagesContext.tsx +26 -20
  452. package/src/contexts/pollContext/pollContext.tsx +2 -4
  453. package/src/contexts/suggestionsContext/SuggestionsContext.tsx +33 -14
  454. package/src/contexts/themeContext/utils/theme.ts +2 -0
  455. package/src/contexts/threadContext/ThreadContext.tsx +4 -6
  456. package/src/contexts/threadsContext/ThreadListItemContext.tsx +3 -5
  457. package/src/hooks/index.ts +2 -0
  458. package/src/hooks/useAudioPlayer.ts +37 -31
  459. package/src/hooks/useStableCallback.ts +37 -0
  460. package/src/hooks/useTranslatedMessage.ts +2 -2
  461. package/src/i18n/en.json +3 -0
  462. package/src/i18n/es.json +3 -0
  463. package/src/i18n/fr.json +3 -0
  464. package/src/i18n/he.json +3 -0
  465. package/src/i18n/hi.json +2 -0
  466. package/src/i18n/it.json +3 -0
  467. package/src/i18n/ja.json +1 -0
  468. package/src/i18n/ko.json +1 -0
  469. package/src/i18n/nl.json +2 -0
  470. package/src/i18n/pt-br.json +3 -0
  471. package/src/i18n/ru.json +4 -0
  472. package/src/i18n/tr.json +2 -0
  473. package/src/mock-builders/api/channelMocks.tsx +2 -8
  474. package/src/native.ts +13 -8
  475. package/src/store/apis/insertReaction.ts +2 -2
  476. package/src/store/apis/updateMessage.ts +2 -2
  477. package/src/store/apis/updateReaction.ts +2 -2
  478. package/src/store/mappers/mapMessageToStorable.ts +2 -2
  479. package/src/types/stream-chat-common-custom-data.d.ts +22 -22
  480. package/src/types/types.ts +35 -54
  481. package/src/utils/compressImage.ts +3 -4
  482. package/src/utils/removeReservedFields.ts +3 -5
  483. package/src/utils/utils.ts +25 -16
  484. package/src/version.json +1 -1
  485. package/lib/commonjs/components/MessageList/hooks/useLastReadData.js +0 -20
  486. package/lib/commonjs/components/MessageList/hooks/useLastReadData.js.map +0 -1
  487. package/lib/commonjs/components/MessageList/utils/getReadStates.js +0 -34
  488. package/lib/commonjs/components/MessageList/utils/getReadStates.js.map +0 -1
  489. package/lib/module/components/MessageList/hooks/useLastReadData.js +0 -20
  490. package/lib/module/components/MessageList/hooks/useLastReadData.js.map +0 -1
  491. package/lib/module/components/MessageList/utils/getReadStates.js +0 -34
  492. package/lib/module/components/MessageList/utils/getReadStates.js.map +0 -1
  493. package/lib/typescript/components/MessageList/hooks/useLastReadData.d.ts +0 -12
  494. package/lib/typescript/components/MessageList/hooks/useLastReadData.d.ts.map +0 -1
  495. package/lib/typescript/components/MessageList/utils/getReadStates.d.ts +0 -5
  496. package/lib/typescript/components/MessageList/utils/getReadStates.d.ts.map +0 -1
  497. package/src/components/MessageList/hooks/useLastReadData.ts +0 -29
  498. package/src/components/MessageList/utils/getReadStates.ts +0 -55
@@ -4,15 +4,16 @@ import React, {
4
4
  useCallback,
5
5
  useContext,
6
6
  useEffect,
7
+ useMemo,
7
8
  useRef,
8
9
  useState,
9
10
  } from 'react';
10
11
  import { Alert, Keyboard, Linking, TextInput, TextInputProps } from 'react-native';
11
12
 
12
13
  import uniq from 'lodash/uniq';
13
- import { lookup } from 'mime-types';
14
14
  import {
15
15
  Attachment,
16
+ LocalMessage,
16
17
  logChatPromiseExecution,
17
18
  Message,
18
19
  SendFileAPIResponse,
@@ -52,7 +53,6 @@ import type { MessageInputProps } from '../../components/MessageInput/MessageInp
52
53
  import type { MoreOptionsButtonProps } from '../../components/MessageInput/MoreOptionsButton';
53
54
  import type { SendButtonProps } from '../../components/MessageInput/SendButton';
54
55
  import type { UploadProgressIndicatorProps } from '../../components/MessageInput/UploadProgressIndicator';
55
- import type { MessageType } from '../../components/MessageList/hooks/useMessageList';
56
56
  import type { Emoji } from '../../emoji-data';
57
57
  import {
58
58
  isDocumentPickerAvailable,
@@ -60,7 +60,7 @@ import {
60
60
  MediaTypes,
61
61
  NativeHandlers,
62
62
  } from '../../native';
63
- import { Asset, File, FileTypes, FileUpload, ImageUpload } from '../../types/types';
63
+ import { File, FileTypes, FileUpload } from '../../types/types';
64
64
  import {
65
65
  ACITriggerSettings,
66
66
  ACITriggerSettingsParams,
@@ -73,6 +73,7 @@ import {
73
73
  FileStateValue,
74
74
  generateRandomId,
75
75
  getFileNameFromPath,
76
+ getFileTypeFromMimeType,
76
77
  isBouncedMessage,
77
78
  } from '../../utils/utils';
78
79
  import { useAttachmentPickerContext } from '../attachmentPickerContext/AttachmentPickerContext';
@@ -114,6 +115,7 @@ export type LocalMessageInputContext = {
114
115
  url: string;
115
116
  };
116
117
  };
118
+ giphyEnabled: boolean;
117
119
  closeAttachmentPicker: () => void;
118
120
  /** The time at which the active cooldown will end */
119
121
  cooldownEndsAt: Date;
@@ -140,6 +142,7 @@ export type LocalMessageInputContext = {
140
142
  */
141
143
  fileUploads: FileUpload[];
142
144
  giphyActive: boolean;
145
+ hasText: boolean;
143
146
  /**
144
147
  * An array of image objects which are set for upload. It has the following structure:
145
148
  *
@@ -159,7 +162,7 @@ export type LocalMessageInputContext = {
159
162
  * ```
160
163
  *
161
164
  */
162
- imageUploads: ImageUpload[];
165
+ imageUploads: FileUpload[];
163
166
  inputBoxRef: React.MutableRefObject<TextInput | null>;
164
167
  isValidMessage: () => boolean;
165
168
  mentionedUsers: string[];
@@ -204,7 +207,7 @@ export type LocalMessageInputContext = {
204
207
  >;
205
208
  setFileUploads: React.Dispatch<React.SetStateAction<FileUpload[]>>;
206
209
  setGiphyActive: React.Dispatch<React.SetStateAction<boolean>>;
207
- setImageUploads: React.Dispatch<React.SetStateAction<ImageUpload[]>>;
210
+ setImageUploads: React.Dispatch<React.SetStateAction<FileUpload[]>>;
208
211
  /**
209
212
  * Ref callback to set reference on input box
210
213
  */
@@ -229,9 +232,9 @@ export type LocalMessageInputContext = {
229
232
  /** Function for attempting to upload a file */
230
233
  uploadFile: ({ newFile }: { newFile: FileUpload }) => Promise<void>;
231
234
  /** Function for attempting to upload an image */
232
- uploadImage: ({ newImage }: { newImage: ImageUpload }) => Promise<void>;
233
- uploadNewFile: (file: File) => Promise<void>;
234
- uploadNewImage: (image: Partial<Asset>) => Promise<void>;
235
+ uploadImage: ({ newImage }: { newImage: FileUpload }) => Promise<void>;
236
+ uploadNewFile: (file: File, fileType?: FileTypes) => Promise<void>;
237
+ uploadNewImage: (image: File) => Promise<void>;
235
238
  };
236
239
 
237
240
  export type InputMessageInputContextValue = {
@@ -357,7 +360,7 @@ export type InputMessageInputContextValue = {
357
360
  SendButton: React.ComponentType<SendButtonProps>;
358
361
  sendImageAsync: boolean;
359
362
  sendMessage: (message: Partial<StreamMessage>) => Promise<void>;
360
- setQuotedMessageState: (message: MessageType) => void;
363
+ setQuotedMessageState: (message: LocalMessage) => void;
361
364
  /**
362
365
  * Custom UI component to render checkbox with text ("Also send to channel") in Thread's input box.
363
366
  * When ticked, message will also be sent in parent channel.
@@ -428,10 +431,7 @@ export type InputMessageInputContextValue = {
428
431
  * @overrideType Function
429
432
  */
430
433
  doImageUploadRequest?: (
431
- file: {
432
- name?: string;
433
- uri?: string;
434
- },
434
+ file: File,
435
435
  channel: ChannelContextValue['channel'],
436
436
  ) => Promise<SendFileAPIResponse>;
437
437
 
@@ -439,7 +439,7 @@ export type InputMessageInputContextValue = {
439
439
  * Variable that tracks the editing state.
440
440
  * It is defined with message type if the editing state is true, else its undefined.
441
441
  */
442
- editing?: MessageType;
442
+ editing?: LocalMessage;
443
443
  /**
444
444
  * Prop to override the default emoji search index in auto complete suggestion list.
445
445
  */
@@ -485,7 +485,7 @@ export type InputMessageInputContextValue = {
485
485
  */
486
486
  onChangeText?: (newText: string) => void;
487
487
  openPollCreationDialog?: ({ sendMessage }: Pick<LocalMessageInputContext, 'sendMessage'>) => void;
488
- quotedMessage?: MessageType;
488
+ quotedMessage?: LocalMessage;
489
489
  SendMessageDisallowedIndicator?: React.ComponentType;
490
490
  /**
491
491
  * ref for input setter function
@@ -585,18 +585,19 @@ export const MessageInputProvider = ({
585
585
  text,
586
586
  } = useMessageDetailsForState(editing, initialValue);
587
587
  const { endsAt: cooldownEndsAt, start: startCooldown } = useCooldown();
588
+ const { onChangeText, emojiSearchIndex, autoCompleteTriggerSettings } = value;
588
589
 
589
590
  const threadId = thread?.id;
590
591
  useEffect(() => {
591
592
  setSendThreadMessageInChannel(false);
592
593
  }, [threadId]);
593
594
 
594
- const appendText = (newText: string) => {
595
+ const appendText = useStableCallback((newText: string) => {
595
596
  setText((prevText) => `${prevText}${newText}`);
596
- };
597
+ });
597
598
 
598
599
  /** Checks if the message is valid or not. Accordingly we can enable/disable send button */
599
- const isValidMessage = () => {
600
+ const isValidMessage = useStableCallback(() => {
600
601
  if (text && text.trim()) {
601
602
  return true;
602
603
  }
@@ -630,48 +631,51 @@ export const MessageInputProvider = ({
630
631
  }
631
632
 
632
633
  return false;
633
- };
634
+ });
634
635
 
635
- const onChange = (newText: string) => {
636
- if (sending.current) {
637
- return;
638
- }
639
- setText(newText);
636
+ const onChange = useCallback(
637
+ (newText: string) => {
638
+ if (sending.current) {
639
+ return;
640
+ }
641
+ setText(newText);
640
642
 
641
- if (newText && channel && channelCapabities.sendTypingEvents && isOnline) {
642
- logChatPromiseExecution(channel.keystroke(thread?.id), 'start typing event');
643
- }
643
+ if (newText && channel && channelCapabities.sendTypingEvents && isOnline) {
644
+ logChatPromiseExecution(channel.keystroke(thread?.id), 'start typing event');
645
+ }
644
646
 
645
- if (value.onChangeText) {
646
- value.onChangeText(newText);
647
- }
648
- };
647
+ if (onChangeText) {
648
+ onChangeText(newText);
649
+ }
650
+ },
651
+ [channel, channelCapabities.sendTypingEvents, isOnline, setText, thread?.id, onChangeText],
652
+ );
649
653
 
650
- const openCommandsPicker = () => {
654
+ const openCommandsPicker = useStableCallback(() => {
651
655
  appendText('/');
652
656
  if (inputBoxRef.current) {
653
657
  inputBoxRef.current.focus();
654
658
  }
655
- };
659
+ });
656
660
 
657
- const openMentionsPicker = () => {
661
+ const openMentionsPicker = useStableCallback(() => {
658
662
  appendText('@');
659
663
  if (inputBoxRef.current) {
660
664
  inputBoxRef.current.focus();
661
665
  }
662
- };
666
+ });
663
667
 
664
668
  /**
665
669
  * Function for capturing a photo and uploading it
666
670
  */
667
- const takeAndUploadImage = async (mediaType?: MediaTypes) => {
671
+ const takeAndUploadImage = useStableCallback(async (mediaType?: MediaTypes) => {
668
672
  setSelectedPicker(undefined);
669
673
  closePicker();
670
- const photo = await NativeHandlers.takePhoto({
674
+ const file = await NativeHandlers.takePhoto({
671
675
  compressImageQuality: value.compressImageQuality,
672
676
  mediaType,
673
677
  });
674
- if (photo.askToOpenSettings) {
678
+ if (file.askToOpenSettings) {
675
679
  Alert.alert(
676
680
  t('Allow camera access in device settings'),
677
681
  t('Device camera is used to take photos or videos.'),
@@ -681,19 +685,20 @@ export const MessageInputProvider = ({
681
685
  ],
682
686
  );
683
687
  }
684
- if (!photo.cancelled) {
685
- if (photo.type.includes('image')) {
686
- await uploadNewImage(photo);
688
+ if (!file.cancelled) {
689
+ if (file.type.includes('image')) {
690
+ // We already compressed the image in the native handler, so we can upload it directly.
691
+ await uploadNewImage(file);
687
692
  } else {
688
- await uploadNewFile({ ...photo, mimeType: photo.type, type: FileTypes.Video });
693
+ await uploadNewFile(file);
689
694
  }
690
695
  }
691
- };
696
+ });
692
697
 
693
698
  /**
694
699
  * Function for picking a photo from native image picker and uploading it
695
700
  */
696
- const pickAndUploadImageFromNativePicker = async () => {
701
+ const pickAndUploadImageFromNativePicker = useStableCallback(async () => {
697
702
  const result = await NativeHandlers.pickImage();
698
703
  if (result.askToOpenSettings) {
699
704
  Alert.alert(
@@ -720,13 +725,17 @@ export const MessageInputProvider = ({
720
725
  }
721
726
  result.assets.forEach(async (asset) => {
722
727
  if (asset.type.includes('image')) {
723
- await uploadNewImage(asset);
728
+ const compressedURI = await compressedImageURI(asset, value.compressImageQuality);
729
+ await uploadNewImage({
730
+ ...asset,
731
+ uri: compressedURI,
732
+ });
724
733
  } else {
725
- await uploadNewFile({ ...asset, mimeType: asset.type, type: FileTypes.Video });
734
+ await uploadNewFile(asset);
726
735
  }
727
736
  });
728
737
  }
729
- };
738
+ });
730
739
 
731
740
  /**
732
741
  * Function to open the attachment picker if the MediaLibary is installed.
@@ -756,11 +765,11 @@ export const MessageInputProvider = ({
756
765
  }
757
766
  }, [closeAttachmentPicker, openAttachmentPicker, selectedPicker]);
758
767
 
759
- const onSelectItem = (item: UserResponse) => {
768
+ const onSelectItem = useStableCallback((item: UserResponse) => {
760
769
  setMentionedUsers((prevMentionedUsers) => [...prevMentionedUsers, item.id]);
761
- };
770
+ });
762
771
 
763
- const pickFile = async () => {
772
+ const pickFile = useStableCallback(async () => {
764
773
  if (!isDocumentPickerAvailable()) {
765
774
  console.log(
766
775
  'The file picker is not installed. Check our Getting Started documentation to install it.',
@@ -779,17 +788,18 @@ export const MessageInputProvider = ({
779
788
 
780
789
  if (!result.cancelled && result.assets) {
781
790
  result.assets.forEach(async (asset) => {
782
- /**
783
- * TODO: The current tight coupling of images to the image
784
- * picker does not allow images picked from the file picker
785
- * to be rendered in a preview via the uploadNewImage call.
786
- * This should be updated alongside allowing image a file
787
- * uploads together.
788
- */
789
- await uploadNewFile(asset);
791
+ if (asset.type.includes('image')) {
792
+ const compressedURI = await compressedImageURI(asset, value.compressImageQuality);
793
+ await uploadNewImage({
794
+ ...asset,
795
+ uri: compressedURI,
796
+ });
797
+ } else {
798
+ await uploadNewFile(asset);
799
+ }
790
800
  });
791
801
  }
792
- };
802
+ });
793
803
 
794
804
  const removeFile = useCallback(
795
805
  (id: string) => {
@@ -811,7 +821,7 @@ export const MessageInputProvider = ({
811
821
  [imageUploads, setImageUploads, setNumberOfUploads],
812
822
  );
813
823
 
814
- const resetInput = (pendingAttachments: Attachment[] = []) => {
824
+ const resetInput = useStableCallback((pendingAttachments: Attachment[] = []) => {
815
825
  /**
816
826
  * If the MediaLibrary is available, reset the selected files and images
817
827
  */
@@ -832,28 +842,28 @@ export const MessageInputProvider = ({
832
842
  if (value.editing) {
833
843
  value.clearEditingState();
834
844
  }
835
- };
845
+ });
836
846
 
837
- const mapImageUploadToAttachment = (image: ImageUpload): Attachment => {
838
- const mime_type: string | boolean = lookup(image.file.name as string);
839
- const name = image.file.name as string;
847
+ const mapImageUploadToAttachment = useStableCallback((image: FileUpload): Attachment => {
840
848
  return {
841
- fallback: name,
849
+ fallback: image.file.name,
842
850
  image_url: image.url,
843
- mime_type: mime_type ? mime_type : undefined,
844
- original_height: image.height,
845
- original_width: image.width,
851
+ mime_type: image.file.type,
852
+ original_height: image.file.height,
853
+ original_width: image.file.width,
846
854
  originalImage: image.file,
847
855
  type: FileTypes.Image,
848
856
  };
849
- };
857
+ });
850
858
 
851
- const mapFileUploadToAttachment = (file: FileUpload): Attachment => {
859
+ const mapFileUploadToAttachment = useStableCallback((file: FileUpload): Attachment => {
852
860
  if (file.type === FileTypes.Image) {
853
861
  return {
854
862
  fallback: file.file.name,
855
863
  image_url: file.url,
856
- mime_type: file.file.mimeType,
864
+ mime_type: file.file.type,
865
+ original_height: file.file.height,
866
+ original_width: file.file.width,
857
867
  originalFile: file.file,
858
868
  type: FileTypes.Image,
859
869
  };
@@ -862,7 +872,7 @@ export const MessageInputProvider = ({
862
872
  asset_url: file.url || file.file.uri,
863
873
  duration: file.file.duration,
864
874
  file_size: file.file.size,
865
- mime_type: file.file.mimeType,
875
+ mime_type: file.file.type,
866
876
  originalFile: file.file,
867
877
  title: file.file.name,
868
878
  type: FileTypes.Audio,
@@ -872,7 +882,7 @@ export const MessageInputProvider = ({
872
882
  asset_url: file.url || file.file.uri,
873
883
  duration: file.file.duration,
874
884
  file_size: file.file.size,
875
- mime_type: file.file.mimeType,
885
+ mime_type: file.file.type,
876
886
  originalFile: file.file,
877
887
  thumb_url: file.thumb_url,
878
888
  title: file.file.name,
@@ -883,7 +893,7 @@ export const MessageInputProvider = ({
883
893
  asset_url: file.url || file.file.uri,
884
894
  duration: file.file.duration,
885
895
  file_size: file.file.size,
886
- mime_type: file.file.mimeType,
896
+ mime_type: file.file.type,
887
897
  originalFile: file.file,
888
898
  title: file.file.name,
889
899
  type: FileTypes.VoiceRecording,
@@ -893,164 +903,169 @@ export const MessageInputProvider = ({
893
903
  return {
894
904
  asset_url: file.url || file.file.uri,
895
905
  file_size: file.file.size,
896
- mime_type: file.file.mimeType,
906
+ mime_type: file.file.type,
897
907
  originalFile: file.file,
898
908
  title: file.file.name,
899
909
  type: FileTypes.File,
900
910
  };
901
911
  }
902
- };
912
+ });
903
913
 
904
914
  // TODO: Figure out why this is async, as it doesn't await any promise.
905
- const sendMessage = async ({
906
- customMessageData,
907
- }: {
908
- customMessageData?: Partial<Message>;
909
- } = {}) => {
910
- if (sending.current) {
911
- return;
912
- }
913
- const linkInfos = parseLinksFromText(text);
915
+ const sendMessage = useStableCallback(
916
+ async ({
917
+ customMessageData,
918
+ }: {
919
+ customMessageData?: Partial<Message>;
920
+ } = {}) => {
921
+ if (sending.current) {
922
+ return;
923
+ }
924
+ const linkInfos = parseLinksFromText(text);
914
925
 
915
- if (!channelCapabities.sendLinks && linkInfos.length > 0) {
916
- Alert.alert(t('Links are disabled'), t('Sending links is not allowed in this conversation'));
926
+ if (!channelCapabities.sendLinks && linkInfos.length > 0) {
927
+ Alert.alert(
928
+ t('Links are disabled'),
929
+ t('Sending links is not allowed in this conversation'),
930
+ );
917
931
 
918
- return;
919
- }
932
+ return;
933
+ }
920
934
 
921
- sending.current = true;
935
+ sending.current = true;
922
936
 
923
- startCooldown();
937
+ startCooldown();
924
938
 
925
- const prevText = giphyEnabled && giphyActive ? `/giphy ${text}` : text;
926
- setText('');
939
+ const prevText = giphyEnabled && giphyActive ? `/giphy ${text}` : text;
940
+ setText('');
927
941
 
928
- if (inputBoxRef.current) {
929
- inputBoxRef.current.clear();
930
- }
942
+ if (inputBoxRef.current) {
943
+ inputBoxRef.current.clear();
944
+ }
931
945
 
932
- const attachments = [] as Attachment[];
933
- for (const image of imageUploads) {
934
- if (enableOfflineSupport) {
935
- if (image.state === FileState.NOT_SUPPORTED) {
936
- return;
946
+ const attachments = [] as Attachment[];
947
+ for (const image of imageUploads) {
948
+ if (enableOfflineSupport) {
949
+ if (image.state === FileState.NOT_SUPPORTED) {
950
+ return;
951
+ }
952
+ attachments.push(mapImageUploadToAttachment(image));
953
+ continue;
937
954
  }
938
- attachments.push(mapImageUploadToAttachment(image));
939
- continue;
940
- }
941
955
 
942
- if ((!image || image.state === FileState.UPLOAD_FAILED) && !enableOfflineSupport) {
943
- continue;
944
- }
956
+ if ((!image || image.state === FileState.UPLOAD_FAILED) && !enableOfflineSupport) {
957
+ continue;
958
+ }
945
959
 
946
- if (image.state === FileState.UPLOADING) {
947
- // TODO: show error to user that they should wait until image is uploaded
948
- if (value.sendImageAsync) {
949
- /**
950
- * If user hit send before image uploaded, push ID into a queue to later
951
- * be matched with the successful CDN response
952
- */
953
- setAsyncIds((prevAsyncIds) => [...prevAsyncIds, image.id]);
954
- } else {
955
- sending.current = false;
956
- return setText(prevText);
960
+ if (image.state === FileState.UPLOADING) {
961
+ // TODO: show error to user that they should wait until image is uploaded
962
+ if (value.sendImageAsync) {
963
+ /**
964
+ * If user hit send before image uploaded, push ID into a queue to later
965
+ * be matched with the successful CDN response
966
+ */
967
+ setAsyncIds((prevAsyncIds) => [...prevAsyncIds, image.id]);
968
+ } else {
969
+ sending.current = false;
970
+ return setText(prevText);
971
+ }
957
972
  }
958
- }
959
973
 
960
- // To get the mime type of the image from the file name and send it as an response for an image
961
- if (image.state === FileState.UPLOADED || image.state === FileState.FINISHED) {
962
- attachments.push(mapImageUploadToAttachment(image));
974
+ // To get the mime type of the image from the file name and send it as an response for an image
975
+ if (image.state === FileState.UPLOADED || image.state === FileState.FINISHED) {
976
+ attachments.push(mapImageUploadToAttachment(image));
977
+ }
963
978
  }
964
- }
965
979
 
966
- for (const file of fileUploads) {
967
- if (enableOfflineSupport) {
968
- if (file.state === FileState.NOT_SUPPORTED) {
980
+ for (const file of fileUploads) {
981
+ if (enableOfflineSupport) {
982
+ if (file.state === FileState.NOT_SUPPORTED) {
983
+ return;
984
+ }
985
+ attachments.push(mapFileUploadToAttachment(file));
986
+ continue;
987
+ }
988
+
989
+ if (!file || file.state === FileState.UPLOAD_FAILED) {
990
+ continue;
991
+ }
992
+
993
+ if (file.state === FileState.UPLOADING) {
994
+ // TODO: show error to user that they should wait until image is uploaded
995
+ sending.current = false;
969
996
  return;
970
997
  }
971
- attachments.push(mapFileUploadToAttachment(file));
972
- continue;
973
- }
974
998
 
975
- if (!file || file.state === FileState.UPLOAD_FAILED) {
976
- continue;
999
+ if (file.state === FileState.UPLOADED || file.state === FileState.FINISHED) {
1000
+ attachments.push(mapFileUploadToAttachment(file));
1001
+ }
977
1002
  }
978
1003
 
979
- if (file.state === FileState.UPLOADING) {
980
- // TODO: show error to user that they should wait until image is uploaded
1004
+ // Disallow sending message if its empty.
1005
+ if (!prevText && attachments.length === 0 && !customMessageData?.poll_id) {
981
1006
  sending.current = false;
982
1007
  return;
983
1008
  }
984
1009
 
985
- if (file.state === FileState.UPLOADED || file.state === FileState.FINISHED) {
986
- attachments.push(mapFileUploadToAttachment(file));
987
- }
988
- }
989
-
990
- // Disallow sending message if its empty.
991
- if (!prevText && attachments.length === 0 && !customMessageData?.poll_id) {
992
- sending.current = false;
993
- return;
994
- }
995
-
996
- const message = value.editing;
997
- if (message && message.type !== 'error') {
998
- const updatedMessage = {
999
- ...message,
1000
- attachments,
1001
- mentioned_users: mentionedUsers,
1002
- quoted_message: undefined,
1003
- text: prevText,
1004
- ...customMessageData,
1005
- } as Parameters<StreamChat['updateMessage']>[0];
1006
-
1007
- // TODO: Remove this line and show an error when submit fails
1008
- value.clearEditingState();
1009
-
1010
- const updateMessagePromise = value
1011
- .editMessage(
1012
- // @ts-ignore
1013
- removeReservedFields(updatedMessage),
1014
- )
1015
- .then(value.clearEditingState);
1016
- resetInput(attachments);
1017
- logChatPromiseExecution(updateMessagePromise, 'update message');
1018
-
1019
- sending.current = false;
1020
- } else {
1021
- try {
1022
- /**
1023
- * If the message is bounced by moderation, we firstly remove the message from message list and then send a new message.
1024
- */
1025
- if (message && isBouncedMessage(message as MessageType)) {
1026
- await removeMessage(message);
1027
- }
1028
- value.sendMessage({
1010
+ const message = value.editing;
1011
+ if (message && message.type !== 'error') {
1012
+ const updatedMessage = {
1013
+ ...message,
1029
1014
  attachments,
1030
- mentioned_users: uniq(mentionedUsers),
1031
- /** Parent message id - in case of thread */
1032
- parent_id: thread?.id,
1033
- quoted_message_id: value.quotedMessage ? value.quotedMessage.id : undefined,
1034
- show_in_channel: sendThreadMessageInChannel || undefined,
1015
+ mentioned_users: mentionedUsers.map((userId) => ({ id: userId })),
1016
+ quoted_message: undefined,
1035
1017
  text: prevText,
1036
1018
  ...customMessageData,
1037
- } as unknown as StreamMessage);
1038
-
1039
- value.clearQuotedMessageState();
1040
- sending.current = false;
1019
+ } as Parameters<StreamChat['updateMessage']>[0];
1020
+
1021
+ // TODO: Remove this line and show an error when submit fails
1022
+ value.clearEditingState();
1023
+
1024
+ const updateMessagePromise = value
1025
+ .editMessage(
1026
+ // @ts-ignore
1027
+ removeReservedFields(updatedMessage),
1028
+ )
1029
+ .then(value.clearEditingState);
1030
+ logChatPromiseExecution(updateMessagePromise, 'update message');
1041
1031
  resetInput(attachments);
1042
- } catch (_error) {
1032
+
1043
1033
  sending.current = false;
1044
- if (value.quotedMessage && typeof value.quotedMessage !== 'boolean') {
1045
- value.setQuotedMessageState(value.quotedMessage);
1034
+ } else {
1035
+ try {
1036
+ /**
1037
+ * If the message is bounced by moderation, we firstly remove the message from message list and then send a new message.
1038
+ */
1039
+ if (message && isBouncedMessage(message)) {
1040
+ await removeMessage(message);
1041
+ }
1042
+ value.sendMessage({
1043
+ attachments,
1044
+ mentioned_users: uniq(mentionedUsers),
1045
+ /** Parent message id - in case of thread */
1046
+ parent_id: thread?.id,
1047
+ quoted_message_id: value.quotedMessage ? value.quotedMessage.id : undefined,
1048
+ show_in_channel: sendThreadMessageInChannel || undefined,
1049
+ text: prevText,
1050
+ ...customMessageData,
1051
+ } as unknown as StreamMessage);
1052
+
1053
+ value.clearQuotedMessageState();
1054
+ sending.current = false;
1055
+ resetInput(attachments);
1056
+ } catch (_error) {
1057
+ sending.current = false;
1058
+ if (value.quotedMessage && typeof value.quotedMessage !== 'boolean') {
1059
+ value.setQuotedMessageState(value.quotedMessage);
1060
+ }
1061
+ setText(prevText.slice(giphyEnabled && giphyActive ? 7 : 0)); // 7 because of '/giphy ' length
1062
+ console.log('Failed to send message');
1046
1063
  }
1047
- setText(prevText.slice(giphyEnabled && giphyActive ? 7 : 0)); // 7 because of '/giphy ' length
1048
- console.log('Failed to send message');
1049
1064
  }
1050
- }
1051
- };
1065
+ },
1066
+ );
1052
1067
 
1053
- const sendMessageAsync = (id: string) => {
1068
+ const sendMessageAsync = useStableCallback((id: string) => {
1054
1069
  const image = asyncUploads[id];
1055
1070
  if (!image || image.state === FileState.UPLOAD_FAILED) {
1056
1071
  return;
@@ -1086,31 +1101,31 @@ export const MessageInputProvider = ({
1086
1101
  console.log('Failed');
1087
1102
  }
1088
1103
  }
1089
- };
1104
+ });
1090
1105
 
1091
- const setInputBoxRef = (ref: TextInput | null) => {
1106
+ const setInputBoxRef = useStableCallback((ref: TextInput | null) => {
1092
1107
  inputBoxRef.current = ref;
1093
1108
  if (value.setInputRef) {
1094
1109
  value.setInputRef(ref);
1095
1110
  }
1096
- };
1111
+ });
1097
1112
 
1098
- const getTriggerSettings = () => {
1113
+ const triggerSettings = useMemo(() => {
1099
1114
  try {
1100
1115
  let triggerSettings: TriggerSettings = {};
1101
1116
  if (channel) {
1102
- if (value.autoCompleteTriggerSettings) {
1103
- triggerSettings = value.autoCompleteTriggerSettings({
1117
+ if (autoCompleteTriggerSettings) {
1118
+ triggerSettings = autoCompleteTriggerSettings({
1104
1119
  channel,
1105
1120
  client,
1106
- emojiSearchIndex: value.emojiSearchIndex,
1121
+ emojiSearchIndex,
1107
1122
  onMentionSelectItem: onSelectItem,
1108
1123
  });
1109
1124
  } else {
1110
1125
  triggerSettings = ACITriggerSettings({
1111
1126
  channel,
1112
1127
  client,
1113
- emojiSearchIndex: value.emojiSearchIndex,
1128
+ emojiSearchIndex,
1114
1129
  onMentionSelectItem: onSelectItem,
1115
1130
  });
1116
1131
  }
@@ -1120,11 +1135,11 @@ export const MessageInputProvider = ({
1120
1135
  console.warn('Error in getting trigger settings', error);
1121
1136
  throw error;
1122
1137
  }
1123
- };
1138
+ }, [channel, client, onSelectItem, autoCompleteTriggerSettings, emojiSearchIndex]);
1124
1139
 
1125
- const triggerSettings = getTriggerSettings();
1140
+ // const triggerSettings = getTriggerSettings();
1126
1141
 
1127
- const updateMessage = async () => {
1142
+ const updateMessage = useStableCallback(async () => {
1128
1143
  try {
1129
1144
  if (value.editing) {
1130
1145
  await client.updateMessage({
@@ -1139,51 +1154,54 @@ export const MessageInputProvider = ({
1139
1154
  } catch (error) {
1140
1155
  console.log(error);
1141
1156
  }
1142
- };
1157
+ });
1143
1158
 
1144
1159
  const regexCondition = /File (extension \.\w{2,4}|type \S+) is not supported/;
1145
1160
 
1146
- const getUploadSetStateAction =
1147
- <UploadType extends ImageUpload | FileUpload>(
1161
+ const getUploadSetStateAction = useStableCallback(
1162
+ <UploadType extends FileUpload>(
1148
1163
  id: string,
1149
1164
  fileState: FileStateValue,
1150
1165
  extraData: Partial<UploadType> = {},
1151
1166
  ): React.SetStateAction<UploadType[]> =>
1152
- (prevUploads: UploadType[]) =>
1153
- prevUploads.map((prevUpload) => {
1154
- if (prevUpload.id === id) {
1155
- return {
1156
- ...prevUpload,
1157
- ...extraData,
1158
- state: fileState,
1159
- };
1160
- }
1161
- return prevUpload;
1162
- });
1167
+ (prevUploads: UploadType[]) =>
1168
+ prevUploads.map((prevUpload) => {
1169
+ if (prevUpload.id === id) {
1170
+ return {
1171
+ ...prevUpload,
1172
+ ...extraData,
1173
+ state: fileState,
1174
+ };
1175
+ }
1176
+ return prevUpload;
1177
+ }),
1178
+ );
1163
1179
 
1164
- const handleFileOrImageUploadError = (error: unknown, isImageError: boolean, id: string) => {
1165
- if (isImageError) {
1166
- setNumberOfUploads((prevNumberOfUploads) => prevNumberOfUploads - 1);
1167
- if (error instanceof Error) {
1168
- if (regexCondition.test(error.message)) {
1169
- return setImageUploads(getUploadSetStateAction(id, FileState.NOT_SUPPORTED));
1170
- }
1180
+ const handleFileOrImageUploadError = useStableCallback(
1181
+ (error: unknown, isImageError: boolean, id: string) => {
1182
+ if (isImageError) {
1183
+ setNumberOfUploads((prevNumberOfUploads) => prevNumberOfUploads - 1);
1184
+ if (error instanceof Error) {
1185
+ if (regexCondition.test(error.message)) {
1186
+ return setImageUploads(getUploadSetStateAction(id, FileState.NOT_SUPPORTED));
1187
+ }
1171
1188
 
1172
- return setImageUploads(getUploadSetStateAction(id, FileState.UPLOAD_FAILED));
1173
- }
1174
- } else {
1175
- setNumberOfUploads((prevNumberOfUploads) => prevNumberOfUploads - 1);
1189
+ return setImageUploads(getUploadSetStateAction(id, FileState.UPLOAD_FAILED));
1190
+ }
1191
+ } else {
1192
+ setNumberOfUploads((prevNumberOfUploads) => prevNumberOfUploads - 1);
1176
1193
 
1177
- if (error instanceof Error) {
1178
- if (regexCondition.test(error.message)) {
1179
- return setFileUploads(getUploadSetStateAction(id, FileState.NOT_SUPPORTED));
1194
+ if (error instanceof Error) {
1195
+ if (regexCondition.test(error.message)) {
1196
+ return setFileUploads(getUploadSetStateAction(id, FileState.NOT_SUPPORTED));
1197
+ }
1198
+ return setFileUploads(getUploadSetStateAction(id, FileState.UPLOAD_FAILED));
1180
1199
  }
1181
- return setFileUploads(getUploadSetStateAction(id, FileState.UPLOAD_FAILED));
1182
1200
  }
1183
- }
1184
- };
1201
+ },
1202
+ );
1185
1203
 
1186
- const uploadFile = async ({ newFile }: { newFile: FileUpload }) => {
1204
+ const uploadFile = useStableCallback(async ({ newFile }: { newFile: FileUpload }) => {
1187
1205
  const { file, id } = newFile;
1188
1206
 
1189
1207
  // The file name can have special characters, so we escape it.
@@ -1201,11 +1219,11 @@ export const MessageInputProvider = ({
1201
1219
  client.createAbortControllerForNextRequest(),
1202
1220
  );
1203
1221
  // Compress images selected through file picker when uploading them
1204
- if (file.mimeType?.includes('image')) {
1222
+ if (file.type?.includes('image')) {
1205
1223
  const compressedUri = await compressedImageURI(file, value.compressImageQuality);
1206
- response = await channel.sendFile(compressedUri, filename, file.mimeType);
1224
+ response = await channel.sendFile(compressedUri, filename, file.type);
1207
1225
  } else {
1208
- response = await channel.sendFile(file.uri, filename, file.mimeType);
1226
+ response = await channel.sendFile(file.uri, filename, file.type);
1209
1227
  }
1210
1228
  uploadAbortControllerRef.current.delete(filename);
1211
1229
  }
@@ -1226,9 +1244,9 @@ export const MessageInputProvider = ({
1226
1244
  }
1227
1245
  handleFileOrImageUploadError(error, false, id);
1228
1246
  }
1229
- };
1247
+ });
1230
1248
 
1231
- const uploadImage = async ({ newImage }: { newImage: ImageUpload }) => {
1249
+ const uploadImage = useStableCallback(async ({ newImage }: { newImage: FileUpload }) => {
1232
1250
  const { file, id } = newImage || {};
1233
1251
 
1234
1252
  if (!file) {
@@ -1242,17 +1260,16 @@ export const MessageInputProvider = ({
1242
1260
  const filename = escapeRegExp(file.name ?? getFileNameFromPath(uri));
1243
1261
 
1244
1262
  try {
1245
- const compressedUri = await compressedImageURI(file, value.compressImageQuality);
1246
- const contentType = lookup(filename) || 'multipart/form-data';
1263
+ const contentType = file.type || 'multipart/form-data';
1247
1264
  if (value.doImageUploadRequest) {
1248
1265
  response = await value.doImageUploadRequest(file, channel);
1249
- } else if (compressedUri && channel) {
1266
+ } else if (channel) {
1250
1267
  if (value.sendImageAsync) {
1251
1268
  uploadAbortControllerRef.current.set(
1252
1269
  filename,
1253
1270
  client.createAbortControllerForNextRequest(),
1254
1271
  );
1255
- channel.sendImage(compressedUri, filename, contentType).then(
1272
+ channel.sendImage(file.uri, filename, contentType).then(
1256
1273
  (res) => {
1257
1274
  uploadAbortControllerRef.current.delete(filename);
1258
1275
  if (asyncIds.includes(id)) {
@@ -1266,7 +1283,7 @@ export const MessageInputProvider = ({
1266
1283
  return prevAsyncUploads;
1267
1284
  });
1268
1285
  } else {
1269
- const newImageUploads = getUploadSetStateAction<ImageUpload>(
1286
+ const newImageUploads = getUploadSetStateAction<FileUpload>(
1270
1287
  id,
1271
1288
  FileState.UPLOADED,
1272
1289
  {
@@ -1285,13 +1302,13 @@ export const MessageInputProvider = ({
1285
1302
  filename,
1286
1303
  client.createAbortControllerForNextRequest(),
1287
1304
  );
1288
- response = await channel.sendImage(compressedUri, filename, contentType);
1305
+ response = await channel.sendImage(file.uri, filename, contentType);
1289
1306
  uploadAbortControllerRef.current.delete(filename);
1290
1307
  }
1291
1308
  }
1292
1309
 
1293
1310
  if (Object.keys(response).length) {
1294
- const newImageUploads = getUploadSetStateAction<ImageUpload>(id, FileState.UPLOADED, {
1311
+ const newImageUploads = getUploadSetStateAction<FileUpload>(id, FileState.UPLOADED, {
1295
1312
  height: file.height,
1296
1313
  url: response.file,
1297
1314
  width: file.width,
@@ -1309,9 +1326,14 @@ export const MessageInputProvider = ({
1309
1326
  }
1310
1327
  handleFileOrImageUploadError(error, true, id);
1311
1328
  }
1312
- };
1329
+ });
1313
1330
 
1314
- const uploadNewFile = async (file: File) => {
1331
+ /**
1332
+ * The fileType is optional and is used to override the file type detection.
1333
+ * This is useful for voice recordings, where the file type is not always detected correctly.
1334
+ * This will change if we unify the file uploads to attachments.
1335
+ */
1336
+ const uploadNewFile = useStableCallback(async (file: File, fileType?: FileTypes) => {
1315
1337
  try {
1316
1338
  const id: string = generateRandomId();
1317
1339
  const fileConfig = getFileUploadConfig();
@@ -1333,16 +1355,16 @@ export const MessageInputProvider = ({
1333
1355
  }
1334
1356
 
1335
1357
  const fileState = isAllowed ? FileState.UPLOADING : FileState.NOT_SUPPORTED;
1336
-
1337
- // If file type is explicitly provided while upload we use it, else we derive the file type.
1338
- const fileType = file.type || file.mimeType?.split('/')[0];
1358
+ const derivedFileType = fileType ?? getFileTypeFromMimeType(file.type);
1339
1359
 
1340
1360
  const newFile: FileUpload = {
1341
1361
  duration: file.duration || 0,
1342
1362
  file,
1343
- id: file.id || id,
1363
+ id,
1364
+ mime_type: file.type,
1344
1365
  state: fileState,
1345
- type: fileType,
1366
+ thumb_url: file.thumb_url,
1367
+ type: derivedFileType,
1346
1368
  url: file.uri,
1347
1369
  };
1348
1370
 
@@ -1357,9 +1379,9 @@ export const MessageInputProvider = ({
1357
1379
  } catch (error) {
1358
1380
  console.log('Error uploading file', error);
1359
1381
  }
1360
- };
1382
+ });
1361
1383
 
1362
- const uploadNewImage = async (image: Partial<Asset>) => {
1384
+ const uploadNewImage = useStableCallback(async (image: File) => {
1363
1385
  try {
1364
1386
  const id = generateRandomId();
1365
1387
  const imageUploadConfig = getImageUploadConfig();
@@ -1385,11 +1407,13 @@ export const MessageInputProvider = ({
1385
1407
 
1386
1408
  const imageState = isAllowed ? FileState.UPLOADING : FileState.NOT_SUPPORTED;
1387
1409
 
1388
- const newImage: ImageUpload = {
1410
+ const newImage: FileUpload = {
1389
1411
  file: image,
1390
1412
  height: image.height,
1391
1413
  id,
1414
+ mime_type: image.type,
1392
1415
  state: imageState,
1416
+ type: FileTypes.Image,
1393
1417
  url: image.uri,
1394
1418
  width: image.width,
1395
1419
  };
@@ -1405,15 +1429,15 @@ export const MessageInputProvider = ({
1405
1429
  } catch (error) {
1406
1430
  console.log('Error uploading image', error);
1407
1431
  }
1408
- };
1432
+ });
1409
1433
 
1410
- const openPollCreationDialog = () => {
1434
+ const openPollCreationDialog = useStableCallback(() => {
1411
1435
  if (openPollCreationDialogFromContext) {
1412
1436
  openPollCreationDialogFromContext({ sendMessage });
1413
1437
  return;
1414
1438
  }
1415
1439
  defaultOpenPollCreationDialog();
1416
- };
1440
+ });
1417
1441
 
1418
1442
  const messageInputContext = useCreateMessageInputContext({
1419
1443
  appendText,
@@ -1423,6 +1447,7 @@ export const MessageInputProvider = ({
1423
1447
  cooldownEndsAt,
1424
1448
  fileUploads,
1425
1449
  giphyActive,
1450
+ giphyEnabled,
1426
1451
  imageUploads,
1427
1452
  inputBoxRef,
1428
1453
  isValidMessage,
@@ -1467,6 +1492,7 @@ export const MessageInputProvider = ({
1467
1492
  uploadNewImage,
1468
1493
  ...value,
1469
1494
  closePollCreationDialog,
1495
+ hasText: !!text,
1470
1496
  openPollCreationDialog,
1471
1497
  sendMessage, // overriding the originally passed in sendMessage
1472
1498
  showPollCreationDialog,
@@ -1492,3 +1518,10 @@ export const useMessageInputContext = () => {
1492
1518
 
1493
1519
  return contextValue;
1494
1520
  };
1521
+
1522
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
1523
+ const useStableCallback = <T extends Function>(callback: T): T => {
1524
+ const ref = useRef<T>(callback);
1525
+ ref.current = callback;
1526
+ return useCallback(((...args: unknown[]) => ref.current(...args)) as unknown as T, []);
1527
+ };