@ethora/chat-component-rn 26.5.7 → 26.5.10

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 (371) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/README.md +67 -10
  3. package/index.js +24 -0
  4. package/lib/commonjs/assets/icons.js +5 -1
  5. package/lib/commonjs/assets/icons.js.map +1 -1
  6. package/lib/commonjs/components/ContextMenu/ContextMenuComponents.js +11 -5
  7. package/lib/commonjs/components/ContextMenu/ContextMenuComponents.js.map +1 -1
  8. package/lib/commonjs/components/MainComponents/ChatRoom.js +64 -38
  9. package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
  10. package/lib/commonjs/components/MainComponents/ChatWrapper.js +57 -13
  11. package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
  12. package/lib/commonjs/components/MainComponents/MediaMessage.js +4 -2
  13. package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
  14. package/lib/commonjs/components/MainComponents/MessageContainer.js +2 -2
  15. package/lib/commonjs/components/MainComponents/MessageContainer.js.map +1 -1
  16. package/lib/commonjs/components/MainComponents/MessageList.js +165 -28
  17. package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
  18. package/lib/commonjs/components/MainComponents/ReduxWrapper.js +17 -8
  19. package/lib/commonjs/components/MainComponents/ReduxWrapper.js.map +1 -1
  20. package/lib/commonjs/components/MainComponents/SystemMessage.js +34 -22
  21. package/lib/commonjs/components/MainComponents/SystemMessage.js.map +1 -1
  22. package/lib/commonjs/components/MessageBubble/Message.js +84 -39
  23. package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
  24. package/lib/commonjs/components/MessageBubble/MessageInteractions.js +82 -22
  25. package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
  26. package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js +16 -4
  27. package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
  28. package/lib/commonjs/components/Modals/FilePreviewModal/DocumentViewer.js +104 -0
  29. package/lib/commonjs/components/Modals/FilePreviewModal/DocumentViewer.js.map +1 -0
  30. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +140 -24
  31. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  32. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js +29 -1
  33. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  34. package/lib/commonjs/components/Modals/Modal/Modal.js +5 -1
  35. package/lib/commonjs/components/Modals/Modal/Modal.js.map +1 -1
  36. package/lib/commonjs/components/Modals/ModalWrapper/ModalWrapper.js +77 -47
  37. package/lib/commonjs/components/Modals/ModalWrapper/ModalWrapper.js.map +1 -1
  38. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +3 -3
  39. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  40. package/lib/commonjs/components/Modals/styledModalComponents.js +4 -9
  41. package/lib/commonjs/components/Modals/styledModalComponents.js.map +1 -1
  42. package/lib/commonjs/components/styled/MediaFilePreview.js +47 -28
  43. package/lib/commonjs/components/styled/MediaFilePreview.js.map +1 -1
  44. package/lib/commonjs/components/styled/MessageImage.js +49 -9
  45. package/lib/commonjs/components/styled/MessageImage.js.map +1 -1
  46. package/lib/commonjs/components/styled/NewMessageLabel.js +8 -6
  47. package/lib/commonjs/components/styled/NewMessageLabel.js.map +1 -1
  48. package/lib/commonjs/components/styled/SendInput.js +49 -27
  49. package/lib/commonjs/components/styled/SendInput.js.map +1 -1
  50. package/lib/commonjs/components/styled/StyledInputComponents/MediaComponents.js +14 -4
  51. package/lib/commonjs/components/styled/StyledInputComponents/MediaComponents.js.map +1 -1
  52. package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js +7 -2
  53. package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
  54. package/lib/commonjs/components/styled/UnsupportedType.js +5 -1
  55. package/lib/commonjs/components/styled/UnsupportedType.js.map +1 -1
  56. package/lib/commonjs/components/styled/VideoMessage.js +60 -14
  57. package/lib/commonjs/components/styled/VideoMessage.js.map +1 -1
  58. package/lib/commonjs/context/MessageNotificationContext.js +7 -7
  59. package/lib/commonjs/context/MessageNotificationContext.js.map +1 -1
  60. package/lib/commonjs/context/xmppProvider.js +244 -32
  61. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  62. package/lib/commonjs/helpers/chatAutoEnterer.js +2 -7
  63. package/lib/commonjs/helpers/chatAutoEnterer.js.map +1 -1
  64. package/lib/commonjs/helpers/historyPreloadScheduler.js +4 -1
  65. package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
  66. package/lib/commonjs/helpers/insertMessageWithDelimiter.js +15 -5
  67. package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
  68. package/lib/commonjs/helpers/keyboardLayout.js +18 -0
  69. package/lib/commonjs/helpers/keyboardLayout.js.map +1 -0
  70. package/lib/commonjs/helpers/mediaDimensions.js +51 -0
  71. package/lib/commonjs/helpers/mediaDimensions.js.map +1 -0
  72. package/lib/commonjs/helpers/normalizeRoomJid.js +20 -0
  73. package/lib/commonjs/helpers/normalizeRoomJid.js.map +1 -0
  74. package/lib/commonjs/hooks/useChatRoomFocus.js +87 -0
  75. package/lib/commonjs/hooks/useChatRoomFocus.js.map +1 -0
  76. package/lib/commonjs/hooks/useHeapSender.js +1 -1
  77. package/lib/commonjs/hooks/useHeapSender.js.map +1 -1
  78. package/lib/commonjs/hooks/useLogout.js +3 -3
  79. package/lib/commonjs/hooks/useLogout.js.map +1 -1
  80. package/lib/commonjs/hooks/usePushNotifications.js +6 -2
  81. package/lib/commonjs/hooks/usePushNotifications.js.map +1 -1
  82. package/lib/commonjs/hooks/useRoomState.js +2 -0
  83. package/lib/commonjs/hooks/useRoomState.js.map +1 -1
  84. package/lib/commonjs/hooks/useSendMessage.js +201 -10
  85. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  86. package/lib/commonjs/hooks/useUnreadMessagesCounter.js +12 -14
  87. package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
  88. package/lib/commonjs/main.js +7 -0
  89. package/lib/commonjs/main.js.map +1 -1
  90. package/lib/commonjs/networking/api-requests/auth.api.js +67 -0
  91. package/lib/commonjs/networking/api-requests/auth.api.js.map +1 -1
  92. package/lib/commonjs/networking/apiClient.js +2 -1
  93. package/lib/commonjs/networking/apiClient.js.map +1 -1
  94. package/lib/commonjs/networking/outboundQueue.js +92 -0
  95. package/lib/commonjs/networking/outboundQueue.js.map +1 -0
  96. package/lib/commonjs/networking/xmpp/createTimeoutPromise.xmpp.js +4 -1
  97. package/lib/commonjs/networking/xmpp/createTimeoutPromise.xmpp.js.map +1 -1
  98. package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js +7 -8
  99. package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
  100. package/lib/commonjs/networking/xmpp/getRoomsPaged.xmpp.js +26 -3
  101. package/lib/commonjs/networking/xmpp/getRoomsPaged.xmpp.js.map +1 -1
  102. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js +26 -8
  103. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  104. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js +2 -1
  105. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  106. package/lib/commonjs/networking/xmppClient.js +294 -35
  107. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  108. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js +22 -6
  109. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  110. package/lib/commonjs/roomStore/roomsSlice.js +157 -23
  111. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  112. package/lib/commonjs/utils/installPromiseRejectionTracker.js +83 -0
  113. package/lib/commonjs/utils/installPromiseRejectionTracker.js.map +1 -0
  114. package/lib/commonjs/utils/resendMessage.js +1 -1
  115. package/lib/commonjs/utils/resendMessage.js.map +1 -1
  116. package/lib/module/assets/icons.js +5 -1
  117. package/lib/module/assets/icons.js.map +1 -1
  118. package/lib/module/components/ContextMenu/ContextMenuComponents.js +11 -5
  119. package/lib/module/components/ContextMenu/ContextMenuComponents.js.map +1 -1
  120. package/lib/module/components/MainComponents/ChatRoom.js +65 -39
  121. package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
  122. package/lib/module/components/MainComponents/ChatWrapper.js +57 -13
  123. package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
  124. package/lib/module/components/MainComponents/MediaMessage.js +4 -2
  125. package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
  126. package/lib/module/components/MainComponents/MessageContainer.js +2 -2
  127. package/lib/module/components/MainComponents/MessageContainer.js.map +1 -1
  128. package/lib/module/components/MainComponents/MessageList.js +166 -29
  129. package/lib/module/components/MainComponents/MessageList.js.map +1 -1
  130. package/lib/module/components/MainComponents/ReduxWrapper.js +18 -8
  131. package/lib/module/components/MainComponents/ReduxWrapper.js.map +1 -1
  132. package/lib/module/components/MainComponents/SystemMessage.js +33 -21
  133. package/lib/module/components/MainComponents/SystemMessage.js.map +1 -1
  134. package/lib/module/components/MessageBubble/Message.js +85 -40
  135. package/lib/module/components/MessageBubble/Message.js.map +1 -1
  136. package/lib/module/components/MessageBubble/MessageInteractions.js +84 -24
  137. package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
  138. package/lib/module/components/Modals/AttachSheet/AttachSheet.js +15 -3
  139. package/lib/module/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
  140. package/lib/module/components/Modals/FilePreviewModal/DocumentViewer.js +99 -0
  141. package/lib/module/components/Modals/FilePreviewModal/DocumentViewer.js.map +1 -0
  142. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +143 -25
  143. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  144. package/lib/module/components/Modals/FilePreviewModal/PdfView.js +31 -3
  145. package/lib/module/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  146. package/lib/module/components/Modals/Modal/Modal.js +5 -1
  147. package/lib/module/components/Modals/Modal/Modal.js.map +1 -1
  148. package/lib/module/components/Modals/ModalWrapper/ModalWrapper.js +79 -49
  149. package/lib/module/components/Modals/ModalWrapper/ModalWrapper.js.map +1 -1
  150. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +3 -3
  151. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  152. package/lib/module/components/Modals/styledModalComponents.js +4 -9
  153. package/lib/module/components/Modals/styledModalComponents.js.map +1 -1
  154. package/lib/module/components/styled/MediaFilePreview.js +47 -28
  155. package/lib/module/components/styled/MediaFilePreview.js.map +1 -1
  156. package/lib/module/components/styled/MessageImage.js +51 -11
  157. package/lib/module/components/styled/MessageImage.js.map +1 -1
  158. package/lib/module/components/styled/NewMessageLabel.js +8 -6
  159. package/lib/module/components/styled/NewMessageLabel.js.map +1 -1
  160. package/lib/module/components/styled/SendInput.js +50 -28
  161. package/lib/module/components/styled/SendInput.js.map +1 -1
  162. package/lib/module/components/styled/StyledInputComponents/MediaComponents.js +14 -4
  163. package/lib/module/components/styled/StyledInputComponents/MediaComponents.js.map +1 -1
  164. package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js +7 -2
  165. package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
  166. package/lib/module/components/styled/UnsupportedType.js +5 -1
  167. package/lib/module/components/styled/UnsupportedType.js.map +1 -1
  168. package/lib/module/components/styled/VideoMessage.js +61 -15
  169. package/lib/module/components/styled/VideoMessage.js.map +1 -1
  170. package/lib/module/context/MessageNotificationContext.js +7 -7
  171. package/lib/module/context/MessageNotificationContext.js.map +1 -1
  172. package/lib/module/context/xmppProvider.js +246 -34
  173. package/lib/module/context/xmppProvider.js.map +1 -1
  174. package/lib/module/helpers/chatAutoEnterer.js +2 -7
  175. package/lib/module/helpers/chatAutoEnterer.js.map +1 -1
  176. package/lib/module/helpers/historyPreloadScheduler.js +4 -1
  177. package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
  178. package/lib/module/helpers/insertMessageWithDelimiter.js +15 -5
  179. package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
  180. package/lib/module/helpers/keyboardLayout.js +12 -0
  181. package/lib/module/helpers/keyboardLayout.js.map +1 -0
  182. package/lib/module/helpers/mediaDimensions.js +46 -0
  183. package/lib/module/helpers/mediaDimensions.js.map +1 -0
  184. package/lib/module/helpers/normalizeRoomJid.js +15 -0
  185. package/lib/module/helpers/normalizeRoomJid.js.map +1 -0
  186. package/lib/module/hooks/useChatRoomFocus.js +82 -0
  187. package/lib/module/hooks/useChatRoomFocus.js.map +1 -0
  188. package/lib/module/hooks/useHeapSender.js +1 -1
  189. package/lib/module/hooks/useHeapSender.js.map +1 -1
  190. package/lib/module/hooks/useLogout.js +3 -3
  191. package/lib/module/hooks/useLogout.js.map +1 -1
  192. package/lib/module/hooks/usePushNotifications.js +6 -2
  193. package/lib/module/hooks/usePushNotifications.js.map +1 -1
  194. package/lib/module/hooks/useRoomState.js +2 -0
  195. package/lib/module/hooks/useRoomState.js.map +1 -1
  196. package/lib/module/hooks/useSendMessage.js +203 -12
  197. package/lib/module/hooks/useSendMessage.js.map +1 -1
  198. package/lib/module/hooks/useUnreadMessagesCounter.js +12 -14
  199. package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
  200. package/lib/module/main.js +1 -0
  201. package/lib/module/main.js.map +1 -1
  202. package/lib/module/networking/api-requests/auth.api.js +67 -1
  203. package/lib/module/networking/api-requests/auth.api.js.map +1 -1
  204. package/lib/module/networking/apiClient.js +2 -1
  205. package/lib/module/networking/apiClient.js.map +1 -1
  206. package/lib/module/networking/outboundQueue.js +84 -0
  207. package/lib/module/networking/outboundQueue.js.map +1 -0
  208. package/lib/module/networking/xmpp/createTimeoutPromise.xmpp.js +4 -1
  209. package/lib/module/networking/xmpp/createTimeoutPromise.xmpp.js.map +1 -1
  210. package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js +7 -8
  211. package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
  212. package/lib/module/networking/xmpp/getRoomsPaged.xmpp.js +26 -3
  213. package/lib/module/networking/xmpp/getRoomsPaged.xmpp.js.map +1 -1
  214. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js +26 -8
  215. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  216. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js +2 -1
  217. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  218. package/lib/module/networking/xmppClient.js +294 -35
  219. package/lib/module/networking/xmppClient.js.map +1 -1
  220. package/lib/module/roomStore/Middleware/unreadMidlleware.js +22 -6
  221. package/lib/module/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  222. package/lib/module/roomStore/roomsSlice.js +154 -22
  223. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  224. package/lib/module/utils/installPromiseRejectionTracker.js +78 -0
  225. package/lib/module/utils/installPromiseRejectionTracker.js.map +1 -0
  226. package/lib/module/utils/resendMessage.js +1 -1
  227. package/lib/module/utils/resendMessage.js.map +1 -1
  228. package/lib/typescript/assets/icons.d.ts +8 -4
  229. package/lib/typescript/assets/icons.d.ts.map +1 -1
  230. package/lib/typescript/components/ContextMenu/ContextMenuComponents.d.ts.map +1 -1
  231. package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
  232. package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
  233. package/lib/typescript/components/MainComponents/MediaMessage.d.ts +1 -0
  234. package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
  235. package/lib/typescript/components/MainComponents/MessageContainer.d.ts.map +1 -1
  236. package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
  237. package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts +1 -0
  238. package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts.map +1 -1
  239. package/lib/typescript/components/MainComponents/SystemMessage.d.ts +0 -7
  240. package/lib/typescript/components/MainComponents/SystemMessage.d.ts.map +1 -1
  241. package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
  242. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts +4 -2
  243. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
  244. package/lib/typescript/components/Modals/AttachSheet/AttachSheet.d.ts.map +1 -1
  245. package/lib/typescript/components/Modals/FilePreviewModal/DocumentViewer.d.ts +29 -0
  246. package/lib/typescript/components/Modals/FilePreviewModal/DocumentViewer.d.ts.map +1 -0
  247. package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts +0 -1
  248. package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts.map +1 -1
  249. package/lib/typescript/components/Modals/FilePreviewModal/PdfView.d.ts.map +1 -1
  250. package/lib/typescript/components/Modals/Modal/Modal.d.ts.map +1 -1
  251. package/lib/typescript/components/Modals/ModalWrapper/ModalWrapper.d.ts.map +1 -1
  252. package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
  253. package/lib/typescript/components/Modals/styledModalComponents.d.ts.map +1 -1
  254. package/lib/typescript/components/styled/MediaFilePreview.d.ts.map +1 -1
  255. package/lib/typescript/components/styled/MessageImage.d.ts.map +1 -1
  256. package/lib/typescript/components/styled/NewMessageLabel.d.ts +1 -5
  257. package/lib/typescript/components/styled/NewMessageLabel.d.ts.map +1 -1
  258. package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
  259. package/lib/typescript/components/styled/StyledInputComponents/MediaComponents.d.ts +9 -1
  260. package/lib/typescript/components/styled/StyledInputComponents/MediaComponents.d.ts.map +1 -1
  261. package/lib/typescript/components/styled/StyledInputComponents/StyledInputComponents.d.ts.map +1 -1
  262. package/lib/typescript/components/styled/UnsupportedType.d.ts +1 -0
  263. package/lib/typescript/components/styled/UnsupportedType.d.ts.map +1 -1
  264. package/lib/typescript/components/styled/VideoMessage.d.ts.map +1 -1
  265. package/lib/typescript/context/xmppProvider.d.ts +1 -0
  266. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  267. package/lib/typescript/helpers/chatAutoEnterer.d.ts.map +1 -1
  268. package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
  269. package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
  270. package/lib/typescript/helpers/keyboardLayout.d.ts +9 -0
  271. package/lib/typescript/helpers/keyboardLayout.d.ts.map +1 -0
  272. package/lib/typescript/helpers/mediaDimensions.d.ts +9 -0
  273. package/lib/typescript/helpers/mediaDimensions.d.ts.map +1 -0
  274. package/lib/typescript/helpers/normalizeRoomJid.d.ts +2 -0
  275. package/lib/typescript/helpers/normalizeRoomJid.d.ts.map +1 -0
  276. package/lib/typescript/hooks/useChatRoomFocus.d.ts +42 -0
  277. package/lib/typescript/hooks/useChatRoomFocus.d.ts.map +1 -0
  278. package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
  279. package/lib/typescript/hooks/usePushNotifications.d.ts.map +1 -1
  280. package/lib/typescript/hooks/useRoomState.d.ts +1 -0
  281. package/lib/typescript/hooks/useRoomState.d.ts.map +1 -1
  282. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  283. package/lib/typescript/hooks/useUnreadMessagesCounter.d.ts.map +1 -1
  284. package/lib/typescript/main.d.ts +1 -0
  285. package/lib/typescript/main.d.ts.map +1 -1
  286. package/lib/typescript/networking/api-requests/auth.api.d.ts +3 -0
  287. package/lib/typescript/networking/api-requests/auth.api.d.ts.map +1 -1
  288. package/lib/typescript/networking/apiClient.d.ts.map +1 -1
  289. package/lib/typescript/networking/outboundQueue.d.ts +57 -0
  290. package/lib/typescript/networking/outboundQueue.d.ts.map +1 -0
  291. package/lib/typescript/networking/xmpp/createTimeoutPromise.xmpp.d.ts.map +1 -1
  292. package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts +1 -1
  293. package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts.map +1 -1
  294. package/lib/typescript/networking/xmpp/getRoomsPaged.xmpp.d.ts +1 -1
  295. package/lib/typescript/networking/xmpp/getRoomsPaged.xmpp.d.ts.map +1 -1
  296. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
  297. package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts.map +1 -1
  298. package/lib/typescript/networking/xmppClient.d.ts +33 -4
  299. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  300. package/lib/typescript/roomStore/Middleware/unreadMidlleware.d.ts.map +1 -1
  301. package/lib/typescript/roomStore/roomsSlice.d.ts +8 -1
  302. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  303. package/lib/typescript/types/models/media.model.d.ts +1 -0
  304. package/lib/typescript/types/models/media.model.d.ts.map +1 -1
  305. package/lib/typescript/types/models/xmpp.model.d.ts +1 -1
  306. package/lib/typescript/types/models/xmpp.model.d.ts.map +1 -1
  307. package/lib/typescript/types/types.d.ts +4 -0
  308. package/lib/typescript/types/types.d.ts.map +1 -1
  309. package/lib/typescript/utils/installPromiseRejectionTracker.d.ts +20 -0
  310. package/lib/typescript/utils/installPromiseRejectionTracker.d.ts.map +1 -0
  311. package/lib/typescript/utils/resendMessage.d.ts.map +1 -1
  312. package/package.json +18 -2
  313. package/src/assets/icons.tsx +23 -14
  314. package/src/components/ContextMenu/ContextMenuComponents.tsx +10 -5
  315. package/src/components/MainComponents/ChatRoom.tsx +81 -66
  316. package/src/components/MainComponents/ChatWrapper.tsx +99 -21
  317. package/src/components/MainComponents/MediaMessage.tsx +3 -0
  318. package/src/components/MainComponents/MessageContainer.tsx +4 -2
  319. package/src/components/MainComponents/MessageList.tsx +175 -28
  320. package/src/components/MainComponents/ReduxWrapper.tsx +19 -9
  321. package/src/components/MainComponents/SystemMessage.tsx +38 -26
  322. package/src/components/MessageBubble/Message.tsx +91 -62
  323. package/src/components/MessageBubble/MessageInteractions.tsx +98 -29
  324. package/src/components/Modals/AttachSheet/AttachSheet.tsx +17 -3
  325. package/src/components/Modals/FilePreviewModal/DocumentViewer.tsx +93 -0
  326. package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +152 -25
  327. package/src/components/Modals/FilePreviewModal/PdfView.tsx +32 -4
  328. package/src/components/Modals/Modal/Modal.tsx +4 -1
  329. package/src/components/Modals/ModalWrapper/ModalWrapper.tsx +70 -58
  330. package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +19 -15
  331. package/src/components/Modals/styledModalComponents.tsx +4 -9
  332. package/src/components/styled/MediaFilePreview.tsx +46 -26
  333. package/src/components/styled/MessageImage.tsx +58 -13
  334. package/src/components/styled/NewMessageLabel.tsx +8 -5
  335. package/src/components/styled/SendInput.tsx +64 -29
  336. package/src/components/styled/StyledInputComponents/MediaComponents.tsx +15 -5
  337. package/src/components/styled/StyledInputComponents/StyledInputComponents.tsx +7 -2
  338. package/src/components/styled/UnsupportedType.tsx +7 -1
  339. package/src/components/styled/VideoMessage.tsx +59 -11
  340. package/src/context/MessageNotificationContext.tsx +8 -8
  341. package/src/context/xmppProvider.tsx +247 -30
  342. package/src/helpers/chatAutoEnterer.ts +2 -8
  343. package/src/helpers/historyPreloadScheduler.ts +4 -1
  344. package/src/helpers/insertMessageWithDelimiter.ts +22 -15
  345. package/src/helpers/keyboardLayout.ts +18 -0
  346. package/src/helpers/mediaDimensions.ts +47 -0
  347. package/src/helpers/normalizeRoomJid.ts +6 -0
  348. package/src/hooks/useChatRoomFocus.ts +95 -0
  349. package/src/hooks/useHeapSender.tsx +2 -1
  350. package/src/hooks/useLogout.tsx +3 -3
  351. package/src/hooks/usePushNotifications.ts +21 -8
  352. package/src/hooks/useRoomState.tsx +4 -0
  353. package/src/hooks/useSendMessage.tsx +258 -13
  354. package/src/hooks/useUnreadMessagesCounter.ts +13 -16
  355. package/src/main.ts +1 -0
  356. package/src/networking/api-requests/auth.api.ts +55 -1
  357. package/src/networking/apiClient.ts +2 -1
  358. package/src/networking/outboundQueue.ts +98 -0
  359. package/src/networking/xmpp/createTimeoutPromise.xmpp.ts +5 -1
  360. package/src/networking/xmpp/flushLastViewedToPrivateStore.ts +11 -13
  361. package/src/networking/xmpp/getRoomsPaged.xmpp.ts +27 -3
  362. package/src/networking/xmpp/presenceInRoom.xmpp.ts +24 -9
  363. package/src/networking/xmpp/sendTextMessage.xmpp.ts +2 -1
  364. package/src/networking/xmppClient.ts +317 -43
  365. package/src/roomStore/Middleware/unreadMidlleware.tsx +23 -5
  366. package/src/roomStore/roomsSlice.ts +177 -27
  367. package/src/types/models/media.model.ts +3 -0
  368. package/src/types/models/xmpp.model.ts +2 -1
  369. package/src/types/types.ts +15 -0
  370. package/src/utils/installPromiseRejectionTracker.ts +91 -0
  371. package/src/utils/resendMessage.ts +2 -1
@@ -23,6 +23,64 @@ const enforceMessageCap = (messages: IMessage[]): void => {
23
23
  }
24
24
  };
25
25
 
26
+ // Merge a freshly-fetched recent history page into a room's cached
27
+ // messages instead of REPLACING them — so re-entering the app no longer
28
+ // wipes older history (and the unread derived from it). Mirrors the web
29
+ // SDK's incremental sync:
30
+ // • union + dedupe by message id (the server-authoritative,
31
+ // microsecond-resolution stanza id) — overlapping messages collapse
32
+ // and older cached history is kept;
33
+ // • if the fetched page shares NO id with the cache, a gap has opened
34
+ // (more than a page of new messages arrived while away) and stitching
35
+ // them would leave a hole — so we clear THIS chat's cache and keep
36
+ // just the fresh page;
37
+ // • locally-pending (optimistic) sends are always preserved;
38
+ // • an empty fetch leaves the cache untouched (the old replace wiped it);
39
+ // • the transient 'delimiter-new' marker is dropped (the realtime insert
40
+ // path re-derives it) so it can't mis-sort.
41
+ // `function` (hoisted) so the reducers above can call it regardless of
42
+ // where it sits in the file. msgSortableMs (defined below) is referenced
43
+ // at call time, after module init.
44
+ function mergeHistoryIntoCache(
45
+ existing: IMessage[] | undefined,
46
+ fetched: IMessage[] | undefined
47
+ ): IMessage[] {
48
+ const ex = Array.isArray(existing) ? existing : [];
49
+ const fe = Array.isArray(fetched) ? fetched : [];
50
+
51
+ const pending = ex.filter((m) => m?.pending);
52
+ const realExisting = ex.filter(
53
+ (m) => m && !m.pending && m.id !== 'delimiter-new'
54
+ );
55
+ const realFetched = fe.filter((m) => m && m.id !== 'delimiter-new');
56
+
57
+ // Nothing usable came back → keep the cache exactly as it was.
58
+ if (realFetched.length === 0) {return ex;}
59
+
60
+ const byMs = (a: IMessage, b: IMessage) =>
61
+ msgSortableMs(a) - msgSortableMs(b);
62
+ const capTail = (arr: IMessage[]) =>
63
+ arr.length > RUNTIME_MESSAGE_LIMIT
64
+ ? arr.slice(-RUNTIME_MESSAGE_LIMIT)
65
+ : arr;
66
+
67
+ const existingIds = new Set(realExisting.map((m) => String(m.id)));
68
+ const overlaps = realFetched.some((m) => existingIds.has(String(m.id)));
69
+
70
+ // Cold room, or a gap (no shared id) → can't merge → use the fresh page.
71
+ if (realExisting.length === 0 || !overlaps) {
72
+ return [...capTail(realFetched.slice().sort(byMs)), ...pending];
73
+ }
74
+
75
+ // Overlap → union + dedupe by id. Fetched wins on collision: it carries
76
+ // the freshest server state (reactions / edits / deletions).
77
+ const byId = new Map<string, IMessage>();
78
+ for (const m of realExisting) {byId.set(String(m.id), m);}
79
+ for (const m of realFetched) {byId.set(String(m.id), m);}
80
+ const merged = Array.from(byId.values()).sort(byMs);
81
+ return [...capTail(merged), ...pending];
82
+ }
83
+
26
84
  export interface RoomPreloadPatch {
27
85
  jid: string;
28
86
  messages?: IMessage[];
@@ -34,6 +92,7 @@ export interface RoomPreloadPatch {
34
92
  export interface RoomMessagesState {
35
93
  rooms: { [jid: string]: IRoom };
36
94
  activeRoomJID: string | null;
95
+ visibleRoomJID: string | null;
37
96
  editAction?: EditAction;
38
97
  isLoading: boolean;
39
98
  loadingText?: string;
@@ -44,6 +103,7 @@ export interface RoomMessagesState {
44
103
  const initialState: RoomMessagesState = {
45
104
  rooms: {},
46
105
  activeRoomJID: null,
106
+ visibleRoomJID: null,
47
107
  isLoading: false,
48
108
  editAction: {
49
109
  isEdit: false,
@@ -79,22 +139,77 @@ const reducers = {
79
139
  addRoom(state: WritableDraft<RoomMessagesState>, action: PayloadAction<{ roomData: IRoom }>) {
80
140
  const { roomData } = action.payload;
81
141
  const existing = state.rooms[roomData.jid];
82
- // Preserve a pre-existing lastViewedTimestamp (the private-store
83
- // pull may have landed before /chats/my finished). If neither
84
- // source set one, stamp `Date.now()` so initial REST history
85
- // counts as "seen" — without this default, every back-history
86
- // message read by the unread middleware satisfies `>0` and the
87
- // badge shows the entire room population on first paint.
88
- const lastViewed =
89
- roomData.lastViewedTimestamp ??
90
- existing?.lastViewedTimestamp ??
91
- Date.now();
92
- state.rooms[roomData.jid] = { ...roomData, lastViewedTimestamp: lastViewed };
142
+ // Default-marker resolution (cold-start unread bug):
143
+ // 1. Explicit value on the payload wins.
144
+ // 2. Existing redux value wins (preserves persisted/hydrated
145
+ // markers when the privateStore pull lands before
146
+ // /chats/my).
147
+ // 3. Otherwise, anchor to the *newest known message* in the
148
+ // payload — this marks everything currently in the room
149
+ // as "seen" but lets any NEWER incoming message count as
150
+ // unread. Previously this fell back to `Date.now()`, which
151
+ // stamped a future-leaning marker that hid genuinely-new
152
+ // messages received while the app was closed.
153
+ // 4. If there are no messages at all yet, stamp `0` (=
154
+ // "unknown — let the privateStore hydration set the real
155
+ // marker before any future message arrives").
156
+ let lastViewed: number;
157
+ // Treat an incoming `0` as "unset". stanzaHandlers' addRoom passes
158
+ // `lastViewedTimestamp: 0` as a placeholder; the old `!= null` check
159
+ // let that 0 win and OVERWROTE the persisted/hydrated marker from
160
+ // the previous session, so cold-start showed no unread badge for
161
+ // messages received while the app was closed (bug #19/#20). A real
162
+ // (non-zero) explicit value still wins; otherwise keep the existing
163
+ // value; otherwise anchor to the newest message in the payload.
164
+ if (roomData.lastViewedTimestamp != null && roomData.lastViewedTimestamp !== 0) {
165
+ lastViewed = roomData.lastViewedTimestamp;
166
+ } else if (existing?.lastViewedTimestamp != null) {
167
+ lastViewed = existing.lastViewedTimestamp;
168
+ } else {
169
+ const msgs = roomData.messages || [];
170
+ let newest = 0;
171
+ for (const m of msgs) {
172
+ const t = (m as any)?.messageTimestampMs ||
173
+ (m?.date ? new Date(m.date).getTime() : 0);
174
+ if (t > newest) {newest = t;}
175
+ }
176
+ lastViewed = newest; // 0 if no messages → cold-start safe
177
+ }
178
+ // Preserve cached messages + unread when the incoming room carries
179
+ // none. The /chats/my fetch (rooms.api) builds rooms with
180
+ // `messages: []` and no unread; without this guard, re-entering the
181
+ // app replaced every cached room with an empty one — wiping history
182
+ // AND the unread badge before the history scheduler could re-merge
183
+ // (the user's "it clears cache, unread and messages" bug). New rooms
184
+ // (no existing) fall through to the incoming values. Mirrors
185
+ // addRoomFromApi's preservation.
186
+ const incomingMessages = Array.isArray(roomData.messages)
187
+ ? roomData.messages
188
+ : [];
189
+ const existingMessages = Array.isArray(existing?.messages)
190
+ ? existing!.messages
191
+ : [];
192
+ state.rooms[roomData.jid] = {
193
+ ...roomData,
194
+ messages:
195
+ existingMessages.length > 0 ? existingMessages : incomingMessages,
196
+ lastViewedTimestamp: lastViewed,
197
+ unreadMessages:
198
+ roomData.unreadMessages ?? existing?.unreadMessages ?? 0,
199
+ unreadBaselineTimestamp:
200
+ existing?.unreadBaselineTimestamp ??
201
+ existing?.lastViewedTimestamp ??
202
+ (roomData as any).unreadBaselineTimestamp ??
203
+ 0,
204
+ };
93
205
  },
94
206
  deleteRoom(state: WritableDraft<RoomMessagesState>, action: PayloadAction<{ jid: string }>) {
95
207
  const { jid } = action.payload;
96
208
  if (state.rooms[jid]) {
97
209
  delete state.rooms[jid];
210
+ if (state.visibleRoomJID === jid) {
211
+ state.visibleRoomJID = null;
212
+ }
98
213
  }
99
214
  },
100
215
  updateRoom(
@@ -132,13 +247,23 @@ const reducers = {
132
247
  action: PayloadAction<{ roomJID: string; messageId: string }>
133
248
  ) {
134
249
  const { roomJID, messageId } = action.payload;
135
- if (state.rooms[roomJID]) {
136
- state.rooms[roomJID].messages.map((message) => {
137
- if (message.id === messageId) {
138
- message.isDeleted = true;
139
- }
140
- });
250
+ const room = state.rooms[roomJID];
251
+ if (!room?.messages) {return;}
252
+ // The "New messages" divider is a transient UI marker, not a real
253
+ // message — SPLICE it out so it can be re-inserted for the next
254
+ // unread batch. Marking it isDeleted (like a real message) left it in
255
+ // the array, where insertMessageWithDelimiter's "already present"
256
+ // guard then blocked every future divider (one-shot bug).
257
+ if (messageId === 'delimiter-new') {
258
+ const idx = room.messages.findIndex((m) => m.id === 'delimiter-new');
259
+ if (idx !== -1) {room.messages.splice(idx, 1);}
260
+ return;
141
261
  }
262
+ room.messages.map((message) => {
263
+ if (message.id === messageId) {
264
+ message.isDeleted = true;
265
+ }
266
+ });
142
267
  },
143
268
  setEditAction: (state: WritableDraft<RoomMessagesState>, action: PayloadAction<EditAction | undefined>) => {
144
269
  if (action.payload?.isEdit) {
@@ -199,9 +324,13 @@ const reducers = {
199
324
  if (roomMessages.length === 0 || start) {
200
325
  roomMessages.unshift(message);
201
326
  } else {
202
- const lastViewedTimestamp = state.rooms[roomJID].lastViewedTimestamp
203
- ? new Date(state.rooms[roomJID].lastViewedTimestamp)
204
- : null;
327
+ const lastViewedValue = state.rooms[roomJID].lastViewedTimestamp;
328
+ const lastViewedTimestamp =
329
+ state.visibleRoomJID === roomJID
330
+ ? null
331
+ : lastViewedValue
332
+ ? new Date(lastViewedValue)
333
+ : null;
205
334
 
206
335
  insertMessageWithDelimiter(roomMessages, message, lastViewedTimestamp);
207
336
  }
@@ -216,6 +345,7 @@ const reducers = {
216
345
  },
217
346
  deleteAllRooms(state: WritableDraft<RoomMessagesState>) {
218
347
  state.rooms = {};
348
+ state.visibleRoomJID = null;
219
349
  },
220
350
  setComposing(
221
351
  state: WritableDraft<RoomMessagesState>,
@@ -247,10 +377,12 @@ const reducers = {
247
377
  const { chatJID, timestamp } = action.payload;
248
378
  if (state.rooms[chatJID]) {
249
379
  state.rooms[chatJID].lastViewedTimestamp = timestamp;
250
- // timestamp === 0 means "user is currently viewing this room" —
251
- // unread is cleared. Otherwise count messages received strictly
252
- // after the last-viewed instant.
253
- if (!timestamp) {
380
+ // A non-positive timestamp means "no persisted marker yet" and
381
+ // must not inflate unread from history that predates the first
382
+ // successful private-store hydration. The visible-room state is
383
+ // tracked separately via `visibleRoomJID`; no read/unread meaning
384
+ // is encoded in the timestamp itself anymore.
385
+ if (!(timestamp > 0)) {
254
386
  state.rooms[chatJID].unreadMessages = 0;
255
387
  } else {
256
388
  state.rooms[chatJID].unreadMessages = countNewerMessages(
@@ -286,6 +418,19 @@ const reducers = {
286
418
  // back button from chat → return to RoomList). Mirrors web.
287
419
  state.activeRoomJID = action.payload.roomJID || '';
288
420
  },
421
+ setVisibleRoom: (
422
+ state: WritableDraft<RoomMessagesState>,
423
+ action: PayloadAction<{ roomJID: string | null }>
424
+ ) => {
425
+ state.visibleRoomJID = action.payload.roomJID || null;
426
+ const jid = state.visibleRoomJID;
427
+ if (jid && state.rooms[jid]) {
428
+ state.rooms[jid].unreadMessages = 0;
429
+ }
430
+ },
431
+ clearVisibleRoom: (state: WritableDraft<RoomMessagesState>) => {
432
+ state.visibleRoomJID = null;
433
+ },
289
434
  /**
290
435
  * Stash a JID that a push notification asked us to open before
291
436
  * the rooms list has loaded. The Chat component clears this once
@@ -329,6 +474,7 @@ const reducers = {
329
474
  setLogoutState: (state: WritableDraft<RoomMessagesState>) => {
330
475
  state.rooms = {};
331
476
  state.activeRoomJID = null;
477
+ state.visibleRoomJID = null;
332
478
  state.isLoading = false;
333
479
  },
334
480
  setActiveMessage: (
@@ -425,9 +571,11 @@ const reducers = {
425
571
  room.historyComplete = patch.historyComplete;
426
572
  }
427
573
  if (Array.isArray(patch.messages)) {
428
- // Merge: keep any locally-pending messages, replace the rest.
429
- const pending = room.messages?.filter((m) => m?.pending) || [];
430
- room.messages = [...patch.messages, ...pending];
574
+ // Merge the fetched page into cache by message id rather than
575
+ // replacing — preserves older history + unread on re-entry. Only
576
+ // a true gap (no overlapping id) clears this chat's cache. See
577
+ // mergeHistoryIntoCache.
578
+ room.messages = mergeHistoryIntoCache(room.messages, patch.messages);
431
579
  }
432
580
  }
433
581
  },
@@ -521,6 +669,8 @@ export const {
521
669
  setLastViewedTimestamp,
522
670
  setRoomNoMessages,
523
671
  setCurrentRoom,
672
+ setVisibleRoom,
673
+ clearVisibleRoom,
524
674
  setRoomRole,
525
675
  setLogoutState,
526
676
  setActiveMessage,
@@ -2,4 +2,7 @@ export type MediaFile = {
2
2
  uri: string;
3
3
  type: string;
4
4
  name: string;
5
+ // Byte size when the picker can report it (images/videos/documents).
6
+ // Used to enforce the client-side upload cap before hitting the server.
7
+ size?: number;
5
8
  };
@@ -150,6 +150,7 @@ export interface XmppClientInterface {
150
150
  isReply?: boolean,
151
151
  showInChannel?: boolean,
152
152
  mainMessage?: string,
153
- langSource?: Iso639_1Codes
153
+ langSource?: Iso639_1Codes,
154
+ customId?: string
154
155
  ): void;
155
156
  }
@@ -254,6 +254,14 @@ export interface IConfig {
254
254
  // visibility only — set this flag when you want neither the icon nor
255
255
  // the dropdown to render (e.g. patient-facing apps with a single room).
256
256
  disableChatHeaderBurgerMenuIcon?: boolean;
257
+ // ----- granular gates inside the user-profile modal (chat info →
258
+ // tap a member). Use these to keep the profile section visible
259
+ // but hide individual actions that aren't appropriate for the
260
+ // embedding app (e.g. patient-facing apps that don't allow
261
+ // direct messaging between patients).
262
+ disableMemberProfileActions?: boolean; // hides the whole action block
263
+ hideMemberSendMessageAction?: boolean; // hides only "Message"
264
+ hideMemberCopyIdAction?: boolean; // hides only "Copy User Id"
257
265
  chatHeaderAdditional?: { enabled: boolean; element: any };
258
266
  headerMenu?: () => void;
259
267
  headerChatMenu?: () => void;
@@ -346,6 +354,13 @@ export interface IConfig {
346
354
  disableUserCount?: boolean;
347
355
  disableSentLogic?: boolean;
348
356
  disableTypingIndicator?: boolean;
357
+ // Hide the full-screen "Connection error" overlay (the dark modal with
358
+ // a Retry button shown when bootstrap/connect fails). For patient-facing
359
+ // / kiosk apps where a full-screen error reads as a crash, set this and
360
+ // surface connection state your own way (or let it recover silently —
361
+ // reconnect + re-join now happen automatically). A subtle inline
362
+ // "Connection lost. Retrying…" banner is shown instead.
363
+ disableConnectionErrorOverlay?: boolean;
349
364
  // disableChatInfo already declared above (line ~338) — granular gates
350
365
  // (disableHeader / disableDescription / disableType / hideMembers /
351
366
  // disableMembers / disableChatHeaderMenu). Don't redeclare here.
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Dev-only unhandled-promise-rejection tracker.
3
+ *
4
+ * RN's red-screen for `Uncaught (in promise, id: N)` famously hides the
5
+ * actual rejection's stack trace — it only shows the promise id. When a
6
+ * leak slips past the SDK's coverage, the integrator gets a useless
7
+ * red box that they can't diagnose.
8
+ *
9
+ * This installer attaches a global `unhandledrejection` listener that
10
+ * prints the rejection value AND a stack trace (best-effort) so the
11
+ * source is visible in Metro logs. It's a no-op in production builds.
12
+ *
13
+ * Installed automatically from `ReduxWrapper` on mount. Safe to call
14
+ * multiple times — guarded by a module-level flag.
15
+ *
16
+ * Bug #4 follow-up.
17
+ */
18
+
19
+ declare const __DEV__: boolean | undefined;
20
+
21
+ let installed = false;
22
+
23
+ export function installPromiseRejectionTracker() {
24
+ if (typeof __DEV__ !== 'undefined' && !__DEV__) {return;}
25
+ if (installed) {return;}
26
+ installed = true;
27
+
28
+ // RN's RCTPromise polyfill emits `unhandledrejection` on the global
29
+ // (HermesInternal / global). It also forwards through the
30
+ // `process.on('unhandledRejection', ...)` shim on some builds.
31
+ const g: any = globalThis as any;
32
+
33
+ const onRejection = (eventOrReason: any, maybePromise?: Promise<any>) => {
34
+ // Two calling conventions across RN versions:
35
+ // - `(event)` where event has `.reason` / `.promise`
36
+ // - `(reason, promise)` (older)
37
+ const reason = eventOrReason?.reason ?? eventOrReason;
38
+ const promise = eventOrReason?.promise ?? maybePromise;
39
+ const stack =
40
+ (reason && reason.stack) ||
41
+ new Error('unhandledrejection (captured at handler)').stack;
42
+ // console.WARN (not error): RN's LogBox turns every console.error into
43
+ // a full-screen red overlay. With `allRejections: true` Hermes reports
44
+ // rejections that get handled a microtask later (false positives, e.g.
45
+ // a bare `undefined` rejection during connect teardown), so escalating
46
+ // to a red box was pure noise. warn keeps the trace in Metro/Logs.
47
+ // eslint-disable-next-line no-console
48
+ console.warn(
49
+ '[ethora-rn] UNHANDLED PROMISE REJECTION:',
50
+ typeof reason === 'object' ? JSON.stringify(reason, null, 2) : String(reason),
51
+ '\nstack:',
52
+ stack,
53
+ '\npromise:',
54
+ promise
55
+ );
56
+ };
57
+
58
+ try {
59
+ if (typeof g.addEventListener === 'function') {
60
+ g.addEventListener('unhandledrejection', onRejection);
61
+ }
62
+ } catch {}
63
+ try {
64
+ if (g.process && typeof g.process.on === 'function') {
65
+ g.process.on('unhandledRejection', onRejection);
66
+ }
67
+ } catch {}
68
+ try {
69
+ // Hermes-only hook — newer RN exposes this.
70
+ if (typeof g.HermesInternal?.enablePromiseRejectionTracker === 'function') {
71
+ g.HermesInternal.enablePromiseRejectionTracker({
72
+ allRejections: false,
73
+ onUnhandled: (id: number, error: any) => {
74
+ // warn, not error — see note above. `allRejections: true` fires
75
+ // this for rejections handled a tick later, so a red box here
76
+ // was a false alarm. Stays visible in Metro/Logs as a warning.
77
+ // eslint-disable-next-line no-console
78
+ console.warn(
79
+ `[ethora-rn] Hermes unhandled rejection id=${id}:`,
80
+ error?.message ?? error,
81
+ '\nstack:',
82
+ error?.stack
83
+ );
84
+ },
85
+ onHandled: () => {},
86
+ });
87
+ }
88
+ } catch {}
89
+ }
90
+
91
+ export default installPromiseRejectionTracker;
@@ -62,7 +62,8 @@ export async function resendMessage(
62
62
  message.isReply || false,
63
63
  message.showInChannel === 'true' || false,
64
64
  message.mainMessage || '',
65
- (state.chatSettingStore.langSource as any) || 'en'
65
+ (state.chatSettingStore.langSource as any) || 'en',
66
+ id
66
67
  );
67
68
  } else {
68
69
  client.sendMessage(