@ethora/chat-component-rn 26.8.5 → 26.8.6

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 (373) hide show
  1. package/README.md +55 -0
  2. package/lib/commonjs/assets/emojiData.js +40 -0
  3. package/lib/commonjs/assets/emojiData.js.map +1 -0
  4. package/lib/commonjs/assets/icons.js +1 -1
  5. package/lib/commonjs/assets/icons.js.map +1 -1
  6. package/lib/commonjs/components/MainComponents/ChatHeader.js +7 -9
  7. package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
  8. package/lib/commonjs/components/MainComponents/ChatRoom.js +24 -23
  9. package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
  10. package/lib/commonjs/components/MainComponents/ChatWrapper.js +22 -16
  11. package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
  12. package/lib/commonjs/components/MainComponents/MessageContainer.js +4 -12
  13. package/lib/commonjs/components/MainComponents/MessageContainer.js.map +1 -1
  14. package/lib/commonjs/components/MainComponents/MessageList.js +110 -35
  15. package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
  16. package/lib/commonjs/components/MainComponents/RoomList.js +32 -29
  17. package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
  18. package/lib/commonjs/components/MainComponents/RoomStack.js +133 -65
  19. package/lib/commonjs/components/MainComponents/RoomStack.js.map +1 -1
  20. package/lib/commonjs/components/MainComponents/SystemMessage.js +6 -2
  21. package/lib/commonjs/components/MainComponents/SystemMessage.js.map +1 -1
  22. package/lib/commonjs/components/MessageBubble/Avatar.js +5 -1
  23. package/lib/commonjs/components/MessageBubble/Avatar.js.map +1 -1
  24. package/lib/commonjs/components/MessageBubble/BottomReplyContainer.js +17 -21
  25. package/lib/commonjs/components/MessageBubble/BottomReplyContainer.js.map +1 -1
  26. package/lib/commonjs/components/MessageBubble/EmojiPickerSheet.js +447 -0
  27. package/lib/commonjs/components/MessageBubble/EmojiPickerSheet.js.map +1 -0
  28. package/lib/commonjs/components/MessageBubble/Message.js +200 -132
  29. package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
  30. package/lib/commonjs/components/MessageBubble/MessageInteractions.js +213 -12
  31. package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
  32. package/lib/commonjs/components/MessageBubble/MessageReaction.js +113 -94
  33. package/lib/commonjs/components/MessageBubble/MessageReaction.js.map +1 -1
  34. package/lib/commonjs/components/MessageBubble/MessageReply.js +66 -24
  35. package/lib/commonjs/components/MessageBubble/MessageReply.js.map +1 -1
  36. package/lib/commonjs/components/Modals/Modal/SwipeBackLayer.js +76 -44
  37. package/lib/commonjs/components/Modals/Modal/SwipeBackLayer.js.map +1 -1
  38. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js +5 -4
  39. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js.map +1 -1
  40. package/lib/commonjs/components/RoomComponents/styled/LastMessageEmoji.js +8 -9
  41. package/lib/commonjs/components/RoomComponents/styled/LastMessageEmoji.js.map +1 -1
  42. package/lib/commonjs/components/Thread/ThreadWrapper.js +265 -152
  43. package/lib/commonjs/components/Thread/ThreadWrapper.js.map +1 -1
  44. package/lib/commonjs/components/styled/DateLabel.js +6 -3
  45. package/lib/commonjs/components/styled/DateLabel.js.map +1 -1
  46. package/lib/commonjs/context/MessageNotificationContext.js +188 -9
  47. package/lib/commonjs/context/MessageNotificationContext.js.map +1 -1
  48. package/lib/commonjs/context/xmppProvider.js +22 -7
  49. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  50. package/lib/commonjs/helpers/createRoomFromApi.js +36 -2
  51. package/lib/commonjs/helpers/createRoomFromApi.js.map +1 -1
  52. package/lib/commonjs/helpers/emoji.js +51 -0
  53. package/lib/commonjs/helpers/emoji.js.map +1 -0
  54. package/lib/commonjs/helpers/haptics.js +29 -0
  55. package/lib/commonjs/helpers/haptics.js.map +1 -0
  56. package/lib/commonjs/helpers/historyPreloadScheduler.js +32 -66
  57. package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
  58. package/lib/commonjs/helpers/insertMessageWithDelimiter.js +21 -12
  59. package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
  60. package/lib/commonjs/helpers/mamReactions.js +57 -0
  61. package/lib/commonjs/helpers/mamReactions.js.map +1 -0
  62. package/lib/commonjs/helpers/parseMessageReference.js +42 -0
  63. package/lib/commonjs/helpers/parseMessageReference.js.map +1 -0
  64. package/lib/commonjs/helpers/reactionsConfig.js +17 -0
  65. package/lib/commonjs/helpers/reactionsConfig.js.map +1 -0
  66. package/lib/commonjs/helpers/updateMessagesTillLast.js +17 -2
  67. package/lib/commonjs/helpers/updateMessagesTillLast.js.map +1 -1
  68. package/lib/commonjs/hooks/useHeapSender.js +3 -1
  69. package/lib/commonjs/hooks/useHeapSender.js.map +1 -1
  70. package/lib/commonjs/hooks/useMessageHeapState.js +3 -2
  71. package/lib/commonjs/hooks/useMessageHeapState.js.map +1 -1
  72. package/lib/commonjs/hooks/useRoomInitialization.js +16 -7
  73. package/lib/commonjs/hooks/useRoomInitialization.js.map +1 -1
  74. package/lib/commonjs/hooks/useSendMessage.js +14 -8
  75. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  76. package/lib/commonjs/hooks/useUnreadMessagesCounter.js +1 -1
  77. package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
  78. package/lib/commonjs/networking/stanzaHandlers.js +106 -50
  79. package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
  80. package/lib/commonjs/networking/xmpp/getHistory.xmpp.js +29 -74
  81. package/lib/commonjs/networking/xmpp/getHistory.xmpp.js.map +1 -1
  82. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js +4 -0
  83. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  84. package/lib/commonjs/networking/xmpp/mamRouter.js +186 -0
  85. package/lib/commonjs/networking/xmpp/mamRouter.js.map +1 -0
  86. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js +41 -4
  87. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  88. package/lib/commonjs/networking/xmppClient.js +98 -23
  89. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  90. package/lib/commonjs/roomStore/Middleware/newMessageMidlleware.js +29 -34
  91. package/lib/commonjs/roomStore/Middleware/newMessageMidlleware.js.map +1 -1
  92. package/lib/commonjs/roomStore/Middleware/perfMiddleware.js +51 -0
  93. package/lib/commonjs/roomStore/Middleware/perfMiddleware.js.map +1 -0
  94. package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js +66 -43
  95. package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
  96. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js +88 -68
  97. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  98. package/lib/commonjs/roomStore/index.js +18 -14
  99. package/lib/commonjs/roomStore/index.js.map +1 -1
  100. package/lib/commonjs/roomStore/persistBackend.js +96 -0
  101. package/lib/commonjs/roomStore/persistBackend.js.map +1 -0
  102. package/lib/commonjs/roomStore/persistence.js +245 -50
  103. package/lib/commonjs/roomStore/persistence.js.map +1 -1
  104. package/lib/commonjs/roomStore/roomsSlice.js +282 -136
  105. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  106. package/lib/commonjs/theme/theme.js +3 -0
  107. package/lib/commonjs/theme/theme.js.map +1 -1
  108. package/lib/commonjs/utils/devLogger.js +14 -0
  109. package/lib/commonjs/utils/devLogger.js.map +1 -1
  110. package/lib/commonjs/version.js +1 -1
  111. package/lib/module/assets/emojiData.js +36 -0
  112. package/lib/module/assets/emojiData.js.map +1 -0
  113. package/lib/module/assets/icons.js +1 -1
  114. package/lib/module/assets/icons.js.map +1 -1
  115. package/lib/module/components/MainComponents/ChatHeader.js +8 -10
  116. package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
  117. package/lib/module/components/MainComponents/ChatRoom.js +25 -24
  118. package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
  119. package/lib/module/components/MainComponents/ChatWrapper.js +23 -17
  120. package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
  121. package/lib/module/components/MainComponents/MessageContainer.js +7 -14
  122. package/lib/module/components/MainComponents/MessageContainer.js.map +1 -1
  123. package/lib/module/components/MainComponents/MessageList.js +110 -35
  124. package/lib/module/components/MainComponents/MessageList.js.map +1 -1
  125. package/lib/module/components/MainComponents/RoomList.js +32 -29
  126. package/lib/module/components/MainComponents/RoomList.js.map +1 -1
  127. package/lib/module/components/MainComponents/RoomStack.js +131 -63
  128. package/lib/module/components/MainComponents/RoomStack.js.map +1 -1
  129. package/lib/module/components/MainComponents/SystemMessage.js +6 -2
  130. package/lib/module/components/MainComponents/SystemMessage.js.map +1 -1
  131. package/lib/module/components/MessageBubble/Avatar.js +5 -1
  132. package/lib/module/components/MessageBubble/Avatar.js.map +1 -1
  133. package/lib/module/components/MessageBubble/BottomReplyContainer.js +18 -22
  134. package/lib/module/components/MessageBubble/BottomReplyContainer.js.map +1 -1
  135. package/lib/module/components/MessageBubble/EmojiPickerSheet.js +438 -0
  136. package/lib/module/components/MessageBubble/EmojiPickerSheet.js.map +1 -0
  137. package/lib/module/components/MessageBubble/Message.js +203 -134
  138. package/lib/module/components/MessageBubble/Message.js.map +1 -1
  139. package/lib/module/components/MessageBubble/MessageInteractions.js +215 -14
  140. package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
  141. package/lib/module/components/MessageBubble/MessageReaction.js +115 -94
  142. package/lib/module/components/MessageBubble/MessageReaction.js.map +1 -1
  143. package/lib/module/components/MessageBubble/MessageReply.js +65 -24
  144. package/lib/module/components/MessageBubble/MessageReply.js.map +1 -1
  145. package/lib/module/components/Modals/Modal/SwipeBackLayer.js +76 -44
  146. package/lib/module/components/Modals/Modal/SwipeBackLayer.js.map +1 -1
  147. package/lib/module/components/RoomComponents/ChatRoomItem.js +5 -4
  148. package/lib/module/components/RoomComponents/ChatRoomItem.js.map +1 -1
  149. package/lib/module/components/RoomComponents/styled/LastMessageEmoji.js +8 -9
  150. package/lib/module/components/RoomComponents/styled/LastMessageEmoji.js.map +1 -1
  151. package/lib/module/components/Thread/ThreadWrapper.js +264 -152
  152. package/lib/module/components/Thread/ThreadWrapper.js.map +1 -1
  153. package/lib/module/components/styled/DateLabel.js +6 -3
  154. package/lib/module/components/styled/DateLabel.js.map +1 -1
  155. package/lib/module/context/MessageNotificationContext.js +190 -11
  156. package/lib/module/context/MessageNotificationContext.js.map +1 -1
  157. package/lib/module/context/xmppProvider.js +22 -7
  158. package/lib/module/context/xmppProvider.js.map +1 -1
  159. package/lib/module/helpers/createRoomFromApi.js +36 -2
  160. package/lib/module/helpers/createRoomFromApi.js.map +1 -1
  161. package/lib/module/helpers/emoji.js +44 -0
  162. package/lib/module/helpers/emoji.js.map +1 -0
  163. package/lib/module/helpers/haptics.js +24 -0
  164. package/lib/module/helpers/haptics.js.map +1 -0
  165. package/lib/module/helpers/historyPreloadScheduler.js +32 -66
  166. package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
  167. package/lib/module/helpers/insertMessageWithDelimiter.js +21 -12
  168. package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
  169. package/lib/module/helpers/mamReactions.js +51 -0
  170. package/lib/module/helpers/mamReactions.js.map +1 -0
  171. package/lib/module/helpers/parseMessageReference.js +37 -0
  172. package/lib/module/helpers/parseMessageReference.js.map +1 -0
  173. package/lib/module/helpers/reactionsConfig.js +10 -0
  174. package/lib/module/helpers/reactionsConfig.js.map +1 -0
  175. package/lib/module/helpers/updateMessagesTillLast.js +17 -2
  176. package/lib/module/helpers/updateMessagesTillLast.js.map +1 -1
  177. package/lib/module/hooks/useHeapSender.js +3 -1
  178. package/lib/module/hooks/useHeapSender.js.map +1 -1
  179. package/lib/module/hooks/useMessageHeapState.js +3 -2
  180. package/lib/module/hooks/useMessageHeapState.js.map +1 -1
  181. package/lib/module/hooks/useRoomInitialization.js +17 -8
  182. package/lib/module/hooks/useRoomInitialization.js.map +1 -1
  183. package/lib/module/hooks/useSendMessage.js +14 -8
  184. package/lib/module/hooks/useSendMessage.js.map +1 -1
  185. package/lib/module/hooks/useUnreadMessagesCounter.js +1 -1
  186. package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
  187. package/lib/module/networking/stanzaHandlers.js +107 -51
  188. package/lib/module/networking/stanzaHandlers.js.map +1 -1
  189. package/lib/module/networking/xmpp/getHistory.xmpp.js +29 -74
  190. package/lib/module/networking/xmpp/getHistory.xmpp.js.map +1 -1
  191. package/lib/module/networking/xmpp/handleStanzas.xmpp.js +4 -0
  192. package/lib/module/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  193. package/lib/module/networking/xmpp/mamRouter.js +175 -0
  194. package/lib/module/networking/xmpp/mamRouter.js.map +1 -0
  195. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js +38 -2
  196. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  197. package/lib/module/networking/xmppClient.js +99 -24
  198. package/lib/module/networking/xmppClient.js.map +1 -1
  199. package/lib/module/roomStore/Middleware/newMessageMidlleware.js +29 -34
  200. package/lib/module/roomStore/Middleware/newMessageMidlleware.js.map +1 -1
  201. package/lib/module/roomStore/Middleware/perfMiddleware.js +45 -0
  202. package/lib/module/roomStore/Middleware/perfMiddleware.js.map +1 -0
  203. package/lib/module/roomStore/Middleware/reactionsMiddleware.js +66 -43
  204. package/lib/module/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
  205. package/lib/module/roomStore/Middleware/unreadMidlleware.js +89 -69
  206. package/lib/module/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  207. package/lib/module/roomStore/index.js +19 -15
  208. package/lib/module/roomStore/index.js.map +1 -1
  209. package/lib/module/roomStore/persistBackend.js +89 -0
  210. package/lib/module/roomStore/persistBackend.js.map +1 -0
  211. package/lib/module/roomStore/persistence.js +245 -48
  212. package/lib/module/roomStore/persistence.js.map +1 -1
  213. package/lib/module/roomStore/roomsSlice.js +275 -134
  214. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  215. package/lib/module/theme/theme.js +3 -0
  216. package/lib/module/theme/theme.js.map +1 -1
  217. package/lib/module/utils/devLogger.js +13 -0
  218. package/lib/module/utils/devLogger.js.map +1 -1
  219. package/lib/module/version.js +1 -1
  220. package/lib/typescript/assets/emojiData.d.ts +8 -0
  221. package/lib/typescript/assets/emojiData.d.ts.map +1 -0
  222. package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
  223. package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
  224. package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
  225. package/lib/typescript/components/MainComponents/MessageContainer.d.ts +2 -2
  226. package/lib/typescript/components/MainComponents/MessageContainer.d.ts.map +1 -1
  227. package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
  228. package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
  229. package/lib/typescript/components/MainComponents/RoomStack.d.ts +7 -2
  230. package/lib/typescript/components/MainComponents/RoomStack.d.ts.map +1 -1
  231. package/lib/typescript/components/MainComponents/SystemMessage.d.ts.map +1 -1
  232. package/lib/typescript/components/MessageBubble/Avatar.d.ts +2 -0
  233. package/lib/typescript/components/MessageBubble/Avatar.d.ts.map +1 -1
  234. package/lib/typescript/components/MessageBubble/BottomReplyContainer.d.ts.map +1 -1
  235. package/lib/typescript/components/MessageBubble/EmojiPickerSheet.d.ts +11 -0
  236. package/lib/typescript/components/MessageBubble/EmojiPickerSheet.d.ts.map +1 -0
  237. package/lib/typescript/components/MessageBubble/Message.d.ts +2 -2
  238. package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
  239. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts +2 -0
  240. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
  241. package/lib/typescript/components/MessageBubble/MessageReaction.d.ts +1 -0
  242. package/lib/typescript/components/MessageBubble/MessageReaction.d.ts.map +1 -1
  243. package/lib/typescript/components/MessageBubble/MessageReply.d.ts +7 -7
  244. package/lib/typescript/components/MessageBubble/MessageReply.d.ts.map +1 -1
  245. package/lib/typescript/components/Modals/Modal/SwipeBackLayer.d.ts +2 -1
  246. package/lib/typescript/components/Modals/Modal/SwipeBackLayer.d.ts.map +1 -1
  247. package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts +2 -2
  248. package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts.map +1 -1
  249. package/lib/typescript/components/RoomComponents/styled/LastMessageEmoji.d.ts +3 -6
  250. package/lib/typescript/components/RoomComponents/styled/LastMessageEmoji.d.ts.map +1 -1
  251. package/lib/typescript/components/Thread/ThreadWrapper.d.ts +7 -1
  252. package/lib/typescript/components/Thread/ThreadWrapper.d.ts.map +1 -1
  253. package/lib/typescript/components/styled/DateLabel.d.ts +1 -0
  254. package/lib/typescript/components/styled/DateLabel.d.ts.map +1 -1
  255. package/lib/typescript/context/MessageNotificationContext.d.ts.map +1 -1
  256. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  257. package/lib/typescript/helpers/createRoomFromApi.d.ts.map +1 -1
  258. package/lib/typescript/helpers/emoji.d.ts +6 -0
  259. package/lib/typescript/helpers/emoji.d.ts.map +1 -0
  260. package/lib/typescript/helpers/haptics.d.ts +3 -0
  261. package/lib/typescript/helpers/haptics.d.ts.map +1 -0
  262. package/lib/typescript/helpers/historyPreloadScheduler.d.ts +1 -0
  263. package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
  264. package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
  265. package/lib/typescript/helpers/mamReactions.d.ts +13 -0
  266. package/lib/typescript/helpers/mamReactions.d.ts.map +1 -0
  267. package/lib/typescript/helpers/parseMessageReference.d.ts +16 -0
  268. package/lib/typescript/helpers/parseMessageReference.d.ts.map +1 -0
  269. package/lib/typescript/helpers/reactionsConfig.d.ts +5 -0
  270. package/lib/typescript/helpers/reactionsConfig.d.ts.map +1 -0
  271. package/lib/typescript/helpers/updateMessagesTillLast.d.ts.map +1 -1
  272. package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
  273. package/lib/typescript/hooks/useMessageHeapState.d.ts.map +1 -1
  274. package/lib/typescript/hooks/useRoomInitialization.d.ts +2 -2
  275. package/lib/typescript/hooks/useRoomInitialization.d.ts.map +1 -1
  276. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  277. package/lib/typescript/networking/stanzaHandlers.d.ts +4 -2
  278. package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
  279. package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts +3 -1
  280. package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts.map +1 -1
  281. package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
  282. package/lib/typescript/networking/xmpp/mamRouter.d.ts +23 -0
  283. package/lib/typescript/networking/xmpp/mamRouter.d.ts.map +1 -0
  284. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts +1 -0
  285. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
  286. package/lib/typescript/networking/xmppClient.d.ts +22 -1
  287. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  288. package/lib/typescript/roomStore/Middleware/newMessageMidlleware.d.ts.map +1 -1
  289. package/lib/typescript/roomStore/Middleware/perfMiddleware.d.ts +4 -0
  290. package/lib/typescript/roomStore/Middleware/perfMiddleware.d.ts.map +1 -0
  291. package/lib/typescript/roomStore/Middleware/reactionsMiddleware.d.ts +9 -0
  292. package/lib/typescript/roomStore/Middleware/reactionsMiddleware.d.ts.map +1 -1
  293. package/lib/typescript/roomStore/Middleware/unreadMidlleware.d.ts.map +1 -1
  294. package/lib/typescript/roomStore/index.d.ts.map +1 -1
  295. package/lib/typescript/roomStore/persistBackend.d.ts +11 -0
  296. package/lib/typescript/roomStore/persistBackend.d.ts.map +1 -0
  297. package/lib/typescript/roomStore/persistence.d.ts +5 -6
  298. package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
  299. package/lib/typescript/roomStore/roomsSlice.d.ts +41 -1
  300. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  301. package/lib/typescript/theme/theme.d.ts +4 -1
  302. package/lib/typescript/theme/theme.d.ts.map +1 -1
  303. package/lib/typescript/types/models/message.model.d.ts +4 -0
  304. package/lib/typescript/types/models/message.model.d.ts.map +1 -1
  305. package/lib/typescript/types/models/room.model.d.ts +16 -0
  306. package/lib/typescript/types/models/room.model.d.ts.map +1 -1
  307. package/lib/typescript/types/models/xmpp.model.d.ts +6 -1
  308. package/lib/typescript/types/models/xmpp.model.d.ts.map +1 -1
  309. package/lib/typescript/types/types.d.ts +15 -3
  310. package/lib/typescript/types/types.d.ts.map +1 -1
  311. package/lib/typescript/utils/devLogger.d.ts +8 -0
  312. package/lib/typescript/utils/devLogger.d.ts.map +1 -1
  313. package/lib/typescript/version.d.ts +1 -1
  314. package/package.json +10 -1
  315. package/src/assets/emojiData.ts +2146 -0
  316. package/src/assets/icons.tsx +5 -5
  317. package/src/components/MainComponents/ChatHeader.tsx +16 -7
  318. package/src/components/MainComponents/ChatRoom.tsx +35 -29
  319. package/src/components/MainComponents/ChatWrapper.tsx +28 -10
  320. package/src/components/MainComponents/MessageContainer.tsx +7 -15
  321. package/src/components/MainComponents/MessageList.tsx +96 -43
  322. package/src/components/MainComponents/RoomList.tsx +28 -29
  323. package/src/components/MainComponents/RoomStack.tsx +156 -83
  324. package/src/components/MainComponents/SystemMessage.tsx +6 -2
  325. package/src/components/MessageBubble/Avatar.tsx +7 -1
  326. package/src/components/MessageBubble/BottomReplyContainer.tsx +19 -21
  327. package/src/components/MessageBubble/EmojiPickerSheet.tsx +468 -0
  328. package/src/components/MessageBubble/Message.tsx +146 -87
  329. package/src/components/MessageBubble/MessageInteractions.tsx +213 -12
  330. package/src/components/MessageBubble/MessageReaction.tsx +120 -96
  331. package/src/components/MessageBubble/MessageReply.tsx +65 -32
  332. package/src/components/Modals/Modal/SwipeBackLayer.tsx +114 -63
  333. package/src/components/RoomComponents/ChatRoomItem.tsx +11 -4
  334. package/src/components/RoomComponents/styled/LastMessageEmoji.tsx +7 -8
  335. package/src/components/Thread/ThreadWrapper.tsx +274 -198
  336. package/src/components/styled/DateLabel.tsx +7 -3
  337. package/src/context/MessageNotificationContext.tsx +205 -7
  338. package/src/context/xmppProvider.tsx +29 -9
  339. package/src/helpers/createRoomFromApi.tsx +37 -1
  340. package/src/helpers/emoji.ts +39 -0
  341. package/src/helpers/haptics.ts +19 -0
  342. package/src/helpers/historyPreloadScheduler.ts +37 -69
  343. package/src/helpers/insertMessageWithDelimiter.ts +23 -16
  344. package/src/helpers/mamReactions.ts +59 -0
  345. package/src/helpers/parseMessageReference.ts +38 -0
  346. package/src/helpers/reactionsConfig.ts +13 -0
  347. package/src/helpers/updateMessagesTillLast.tsx +14 -2
  348. package/src/hooks/useHeapSender.tsx +3 -2
  349. package/src/hooks/useMessageHeapState.tsx +6 -2
  350. package/src/hooks/useRoomInitialization.tsx +32 -15
  351. package/src/hooks/useSendMessage.tsx +18 -11
  352. package/src/hooks/useUnreadMessagesCounter.ts +1 -1
  353. package/src/networking/stanzaHandlers.ts +116 -60
  354. package/src/networking/xmpp/getHistory.xmpp.ts +44 -106
  355. package/src/networking/xmpp/handleStanzas.xmpp.ts +2 -0
  356. package/src/networking/xmpp/mamRouter.ts +176 -0
  357. package/src/networking/xmpp/presenceInRoom.xmpp.ts +46 -3
  358. package/src/networking/xmppClient.ts +105 -20
  359. package/src/roomStore/Middleware/newMessageMidlleware.tsx +35 -38
  360. package/src/roomStore/Middleware/perfMiddleware.ts +50 -0
  361. package/src/roomStore/Middleware/reactionsMiddleware.tsx +53 -52
  362. package/src/roomStore/Middleware/unreadMidlleware.tsx +92 -80
  363. package/src/roomStore/index.ts +28 -27
  364. package/src/roomStore/persistBackend.ts +96 -0
  365. package/src/roomStore/persistence.ts +280 -73
  366. package/src/roomStore/roomsSlice.ts +304 -155
  367. package/src/theme/theme.ts +10 -1
  368. package/src/types/models/message.model.ts +4 -0
  369. package/src/types/models/room.model.ts +17 -0
  370. package/src/types/models/xmpp.model.ts +4 -2
  371. package/src/types/types.ts +15 -3
  372. package/src/utils/devLogger.ts +16 -0
  373. package/src/version.ts +1 -1
@@ -305,18 +305,18 @@ export const DeleteIcon = ({
305
305
  </Svg>
306
306
  );
307
307
 
308
- export const CopyIcon = ({ color = '#8C8C8C', ...props }) => (
308
+ export const CopyIcon = ({ color = '#1F1F1F', ...props }) => (
309
309
  <Svg width="24" height="24" viewBox="0 0 24 24" fill="none" {...props}>
310
310
  <Path
311
311
  d="M8 4V16C8 16.5304 8.21071 17.0391 8.58579 17.4142C8.96086 17.7893 9.46957 18 10 18H18C18.5304 18 19.0391 17.7893 19.4142 17.4142C19.7893 17.0391 20 16.5304 20 16V7.242C20 6.97556 19.9467 6.71181 19.8433 6.46624C19.7399 6.22068 19.5885 5.99824 19.398 5.812L16.083 2.57C15.7094 2.20466 15.2076 2.00007 14.685 2H10C9.46957 2 8.96086 2.21071 8.58579 2.58579C8.21071 2.96086 8 3.46957 8 4Z"
312
- stroke="#1F1F1F"
312
+ stroke={color}
313
313
  strokeWidth="2"
314
314
  strokeLinecap="round"
315
315
  strokeLinejoin="round"
316
316
  />
317
317
  <Path
318
318
  d="M16 18V20C16 20.5304 15.7893 21.0391 15.4142 21.4142C15.0391 21.7893 14.5304 22 14 22H6C5.46957 22 4.96086 21.7893 4.58579 21.4142C4.21071 21.0391 4 20.5304 4 20V9C4 8.46957 4.21071 7.96086 4.58579 7.58579C4.96086 7.21071 5.46957 7 6 7H8"
319
- stroke="#1F1F1F"
319
+ stroke={color}
320
320
  strokeWidth="2"
321
321
  strokeLinecap="round"
322
322
  strokeLinejoin="round"
@@ -324,11 +324,11 @@ export const CopyIcon = ({ color = '#8C8C8C', ...props }) => (
324
324
  </Svg>
325
325
  );
326
326
 
327
- export const ReplyIcon = ({ color = '#8C8C8C', ...props }) => (
327
+ export const ReplyIcon = ({ color = '#1F1F1F', ...props }) => (
328
328
  <Svg width="24" height="24" viewBox="0 0 24 24" fill="none" {...props}>
329
329
  <Path
330
330
  d="M9.89797 7.51968C9.9311 7.5051 9.96737 7.49907 10.0034 7.50217C10.0395 7.50526 10.0742 7.51737 10.1044 7.53738C10.1346 7.55739 10.1592 7.58467 10.1761 7.6167C10.193 7.64873 10.2015 7.68448 10.201 7.72068V9.45018C10.201 9.6491 10.28 9.83986 10.4206 9.98051C10.5613 10.1212 10.7521 10.2002 10.951 10.2002C11.9515 10.2002 13.9705 10.2077 15.901 11.4332C17.377 12.3692 18.886 14.0732 19.7935 17.2472C18.2635 15.7727 16.516 14.9732 14.986 14.5487C14.0456 14.2884 13.0791 14.1345 12.1045 14.0897C11.7056 14.0709 11.3059 14.0749 10.9075 14.1017H10.888L10.8805 14.1032L10.951 14.8502L10.876 14.1032C10.6908 14.1218 10.5192 14.2085 10.3945 14.3466C10.2698 14.4846 10.2008 14.6641 10.201 14.8502V16.5797C10.201 16.7417 10.036 16.8437 9.89797 16.7807L3.92197 12.3812L3.85897 12.3392C3.82635 12.3196 3.79936 12.2919 3.78063 12.2588C3.76189 12.2256 3.75204 12.1882 3.75204 12.1502C3.75204 12.1121 3.76189 12.0747 3.78063 12.0416C3.79936 12.0085 3.82635 11.9808 3.85897 11.9612L3.92197 11.9192L9.89797 7.51968ZM11.701 15.5792C11.804 15.5792 11.9155 15.5822 12.0355 15.5882C12.6865 15.6182 13.5865 15.7172 14.5855 15.9947C16.5745 16.5467 18.9295 17.7977 20.4955 20.6147C20.5802 20.7667 20.7151 20.8846 20.8771 20.9481C21.0392 21.0116 21.2183 21.0167 21.3837 20.9626C21.5492 20.9086 21.6907 20.7986 21.7839 20.6517C21.8772 20.5047 21.9165 20.3299 21.895 20.1572C21.199 14.5922 19.066 11.6642 16.705 10.1672C14.8375 8.98218 12.9145 8.75418 11.701 8.71068V7.72068C11.7011 7.41179 11.6179 7.10858 11.46 6.84305C11.3022 6.57753 11.0756 6.35953 10.8042 6.21207C10.5327 6.06461 10.2265 5.99314 9.91788 6.00522C9.60922 6.01729 9.30954 6.11246 9.05047 6.28068L3.05947 10.6907C2.81179 10.8453 2.60753 11.0604 2.46591 11.3157C2.3243 11.571 2.25 11.8582 2.25 12.1502C2.25 12.4422 2.3243 12.7293 2.46591 12.9847C2.60753 13.24 2.81179 13.4551 3.05947 13.6097L9.05047 18.0197C9.30954 18.1879 9.60922 18.2831 9.91788 18.2951C10.2265 18.3072 10.5327 18.2358 10.8042 18.0883C11.0756 17.9408 11.3022 17.7228 11.46 17.4573C11.6179 17.1918 11.7011 16.8886 11.701 16.5797V15.5792Z"
331
- fill="#1F1F1F"
331
+ fill={color}
332
332
  />
333
333
  </Svg>
334
334
  );
@@ -16,7 +16,8 @@ import Button from '../styled/Button';
16
16
  import { BackIcon, BurgerMenuIcon } from '../../assets/icons';
17
17
  import { CallButtons } from '../VideoCalls/CallButtons';
18
18
  import { LanguageSelectorButton } from './LanguageSelectorButton';
19
- import { useDispatch } from 'react-redux';
19
+ import { useDispatch, useSelector, useStore } from 'react-redux';
20
+ import type { RootState } from '../../roomStore';
20
21
  import Composing from '../styled/StyledInputComponents/Composing';
21
22
  import {
22
23
  deleteRoom,
@@ -27,7 +28,6 @@ import { useXmppClient } from '../../context/xmppProvider';
27
28
  import { setActiveModal } from '../../roomStore/chatSettingsSlice';
28
29
  import { MODAL_TYPES } from '../../helpers/constants/MODAL_TYPES';
29
30
  import { RoomMenu } from '../MenuRoom/MenuRoom';
30
- import { useRoomState } from '../../hooks/useRoomState';
31
31
  import { useChatSettingState } from '../../hooks/useChatSettingState';
32
32
  import { useFileToken } from '../../hooks/useFileToken';
33
33
  import { appendFileToken } from '../../helpers/secureFileUrl';
@@ -51,10 +51,18 @@ const ChatHeader: React.FC<ChatHeaderProps> = ({
51
51
  const dispatch = useDispatch();
52
52
  const { client } = useXmppClient();
53
53
 
54
- const { roomsList, activeRoomJID } = useRoomState(currentRoom.jid);
55
- const roomState = useRoomState(currentRoom.jid).room;
56
- const composing = roomState?.composing;
54
+ const reduxStore = useStore<RootState>();
55
+ const activeRoomJID = useSelector(
56
+ (state: RootState) => state.rooms.activeRoomJID
57
+ );
58
+ const roomState = useSelector((state: RootState) =>
59
+ currentRoom?.jid ? state.rooms.rooms?.[currentRoom.jid] : undefined
60
+ );
57
61
  const { config } = useChatSettingState();
62
+ const roomsList = useSelector((state: RootState) =>
63
+ config?.chatHeaderBurgerMenu ? state.rooms.rooms : null
64
+ );
65
+ const composing = roomState?.composing;
58
66
  const theme = useTheme();
59
67
  const t = useT();
60
68
 
@@ -67,11 +75,12 @@ const ChatHeader: React.FC<ChatHeaderProps> = ({
67
75
  client?.leaveTheRoomStanza(activeRoomJID!);
68
76
  dispatch(deleteRoom({ jid: activeRoomJID! }));
69
77
 
70
- const nextRoomJID = Object.keys(roomsList)[0] || null;
78
+ const nextRoomJID =
79
+ Object.keys(reduxStore.getState().rooms.rooms || {})[0] || null;
71
80
  if (nextRoomJID) {
72
81
  dispatch(setCurrentRoom({ roomJID: nextRoomJID }));
73
82
  }
74
- }, [activeRoomJID, roomsList, dispatch, client]);
83
+ }, [activeRoomJID, reduxStore, dispatch, client]);
75
84
 
76
85
  const handleHeaderChatMenu = () => {
77
86
  Keyboard.dismiss();
@@ -2,7 +2,8 @@
2
2
 
3
3
  import React, { useState, useEffect, useCallback, useRef } from 'react';
4
4
  import { ChatContainer, NonRoomChat } from '../styled/StyledComponents';
5
- import { useDispatch } from 'react-redux';
5
+ import { useDispatch, useSelector, useStore } from 'react-redux';
6
+ import type { RootState } from '../../roomStore';
6
7
  import MessageList from './MessageList';
7
8
  import SendInput from '../styled/SendInput';
8
9
  import {
@@ -27,8 +28,8 @@ import { ChooseChatMessage } from './ChooseChatMessage';
27
28
  import { useRoomUrl } from '../../hooks/useRoomUrl';
28
29
  import { useSendMessage } from '../../hooks/useSendMessage';
29
30
  import { IConfig } from '../../types/models/config.model';
31
+ import type { IMessage } from '../../types/types';
30
32
  import { useRoomInitialization } from '../../hooks/useRoomInitialization';
31
- import { useRoomState } from '../../hooks/useRoomState';
32
33
  import { useChatSettingState } from '../../hooks/useChatSettingState';
33
34
  import { useTheme } from '../../hooks/useTheme';
34
35
  import { isOwnMessage } from '../../helpers/isOwnMessage';
@@ -73,6 +74,8 @@ interface ChatRoomProps {
73
74
  eventHandlers?: IConfig['eventHandlers'];
74
75
  }
75
76
 
77
+ const EMPTY_MESSAGES: IMessage[] = [];
78
+
76
79
  const ChatRoom: React.FC<ChatRoomProps> = React.memo(
77
80
  ({
78
81
  CustomMessageComponent,
@@ -104,14 +107,22 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
104
107
  return storeConfig;
105
108
  }, [storeConfig, propsEventHandlers]);
106
109
 
107
- const {
108
- roomsList,
109
- activeRoomJID,
110
- editAction,
111
- loading,
112
- globalLoading,
113
- roomMessages,
114
- } = useRoomState();
110
+ const reduxStore = useStore<RootState>();
111
+ const activeRoomJID = useSelector(
112
+ (state: RootState) => state.rooms.activeRoomJID,
113
+ );
114
+ const activeRoom = useSelector((state: RootState) =>
115
+ activeRoomJID ? state.rooms.rooms?.[activeRoomJID] : undefined,
116
+ );
117
+ const hasRooms = useSelector(
118
+ (state: RootState) => Object.keys(state.rooms.rooms || {}).length > 0,
119
+ );
120
+ const editAction = useSelector((state: RootState) => state.rooms.editAction);
121
+ const globalLoading = useSelector(
122
+ (state: RootState) => state.rooms.isLoading,
123
+ );
124
+ const loading = !!activeRoom?.isLoading;
125
+ const roomMessages = activeRoom?.messages || EMPTY_MESSAGES;
115
126
  const {
116
127
  sendMessage: sendMs,
117
128
  sendMedia: sendMessageMedia,
@@ -183,15 +194,12 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
183
194
 
184
195
  const loadMoreMessages = useCallback(
185
196
  async (chatJID: string, max: number, idOfMessageBefore?: number) => {
186
- if (isLoadingMore || roomsList?.[chatJID]?.historyComplete) {return;}
197
+ const room = reduxStore.getState().rooms.rooms?.[chatJID];
198
+ if (isLoadingMore || room?.historyComplete) {return;}
187
199
  const lastMsgId =
188
200
  typeof idOfMessageBefore !== 'string'
189
201
  ? idOfMessageBefore
190
- : Number(
191
- roomsList[chatJID].messages[
192
- roomsList[chatJID].messages.length - 2
193
- ]?.id,
194
- );
202
+ : Number(room?.messages?.[(room?.messages?.length || 0) - 2]?.id);
195
203
  setIsLoadingMore(true);
196
204
  try {
197
205
  // Return the promise so MessageList's `await loadMoreMessages`
@@ -205,7 +213,7 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
205
213
  }
206
214
  },
207
215
  // eslint-disable-next-line react-hooks/exhaustive-deps
208
- [client?.client?.jid, isLoadingMore, roomsList],
216
+ [client?.client?.jid, isLoadingMore, reduxStore],
209
217
  );
210
218
 
211
219
  const onCloseEdit = () => {
@@ -331,12 +339,10 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
331
339
 
332
340
  useRoomInitialization(
333
341
  activeRoomJID || '',
334
- roomsList,
335
342
  (configWithEventHandlers || storeConfig || {}) as IConfig,
336
- roomMessages.length,
337
343
  );
338
344
 
339
- if (Object.keys(roomsList)?.length < 1 && !loading && !globalLoading) {
345
+ if (!hasRooms && !loading && !globalLoading) {
340
346
  return (
341
347
  <NonRoomChat>
342
348
  {/* <Text>No room. Let's create one!</Text> */}
@@ -345,7 +351,7 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
345
351
  );
346
352
  }
347
353
 
348
- if (!activeRoomJID || !roomsList?.[activeRoomJID]) {
354
+ if (!activeRoomJID || !activeRoom) {
349
355
  return <ChooseChatMessage />;
350
356
  }
351
357
 
@@ -465,7 +471,7 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
465
471
  >
466
472
  {!configWithEventHandlers?.disableHeader && (
467
473
  <ChatHeader
468
- currentRoom={roomsList[activeRoomJID]}
474
+ currentRoom={activeRoom}
469
475
  handleBackClick={handleBackClick}
470
476
  />
471
477
  )}
@@ -482,7 +488,7 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
482
488
  >
483
489
  <Loader color={configWithEventHandlers?.colors?.primary} />
484
490
  </View>
485
- ) : Object.keys(roomsList).length < 1 || !activeRoomJID ? (
491
+ ) : !hasRooms || !activeRoomJID ? (
486
492
  <View
487
493
  style={{
488
494
  flex: 1,
@@ -544,18 +550,18 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
544
550
  resetNewMessageCounter: () => {},
545
551
  }}
546
552
  typingIndicator={
547
- roomsList[activeRoomJID]?.composing ? (
553
+ activeRoom?.composing ? (
548
554
  configWithEventHandlers?.customTypingIndicator
549
555
  ?.customComponent ? (
550
556
  <configWithEventHandlers.customTypingIndicator.customComponent
551
557
  usersTyping={
552
- roomsList[activeRoomJID]?.composingList || []
558
+ activeRoom?.composingList || []
553
559
  }
554
560
  text={
555
561
  typeof configWithEventHandlers.customTypingIndicator
556
562
  .text === 'function'
557
563
  ? configWithEventHandlers.customTypingIndicator.text(
558
- roomsList[activeRoomJID]?.composingList || [],
564
+ activeRoom?.composingList || [],
559
565
  )
560
566
  : configWithEventHandlers.customTypingIndicator
561
567
  .text || 'Typing...'
@@ -624,10 +630,10 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
624
630
  'overlay' ||
625
631
  configWithEventHandlers.customTypingIndicator.position ===
626
632
  'floating') &&
627
- roomsList[activeRoomJID]?.composing && (
633
+ activeRoom?.composing && (
628
634
  <CustomTypingIndicator
629
635
  usersTyping={
630
- roomsList[activeRoomJID]?.composingList || ['User']
636
+ activeRoom?.composingList || ['User']
631
637
  }
632
638
  text={configWithEventHandlers.customTypingIndicator.text}
633
639
  position={
@@ -637,7 +643,7 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
637
643
  customComponent={
638
644
  configWithEventHandlers.customTypingIndicator.customComponent
639
645
  }
640
- isVisible={roomsList[activeRoomJID]?.composing || false}
646
+ isVisible={activeRoom?.composing || false}
641
647
  />
642
648
  )}
643
649
  </ChatContainer>
@@ -1,4 +1,4 @@
1
- import React, {FC, useEffect, useMemo, useRef, useState} from 'react';
1
+ import React, {FC, useCallback, useEffect, useMemo, useRef, useState} from 'react';
2
2
  import {useDispatch, useSelector} from 'react-redux';
3
3
  import ChatRoom from './ChatRoom';
4
4
  import {RoomStack, RoomStackHandle} from './RoomStack';
@@ -72,6 +72,9 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
72
72
  usePendingNotification();
73
73
  const theme = useTheme();
74
74
  const roomStackRef = useRef<RoomStackHandle>(null);
75
+ // Stable, so ChatRoom's React.memo holds across this root's re-renders.
76
+ // (A hook: must stay above the early LoginForm return.)
77
+ const popRoom = useCallback(() => roomStackRef.current?.pop(), []);
75
78
 
76
79
  const [isInited, setInited] = useState(false);
77
80
  const [showModal, setShowModal] = useState(false);
@@ -94,15 +97,18 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
94
97
  initMode,
95
98
  } = useXmppClient();
96
99
 
97
- const {rooms, activeRoomJID} = useSelector((state: RootState) => state.rooms);
100
+ const rooms = useSelector((state: RootState) => state.rooms.rooms);
101
+ const activeRoomJID = useSelector(
102
+ (state: RootState) => state.rooms.activeRoomJID,
103
+ );
104
+ const activeRoomMessages = useSelector((state: RootState) =>
105
+ activeRoomJID ? state.rooms.rooms[activeRoomJID]?.messages : undefined,
106
+ );
98
107
 
99
- const activeMessage = useMemo(() => {
100
- if (activeRoomJID) {
101
- return rooms[activeRoomJID]?.messages?.find(
102
- message => message?.activeMessage,
103
- );
104
- }
105
- }, [rooms, activeRoomJID]);
108
+ const activeMessage = useMemo(
109
+ () => activeRoomMessages?.find(message => message?.activeMessage),
110
+ [activeRoomMessages],
111
+ );
106
112
 
107
113
  const handleChangeChat = (chat: IRoom) => {
108
114
  dispatch(setCurrentRoom({roomJID: chat.jid}));
@@ -438,6 +444,16 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
438
444
  // List mode: the room is pushed over the list and can be swiped back
439
445
  // (RoomStack). With `roomJID` / `disableRooms` there is no list to return to.
440
446
  const listMode = !config?.disableRooms && !roomJID;
447
+
448
+ // The open thread, over the room (a message with `activeMessage` set).
449
+ const threadView = activeMessage ? (
450
+ <ThreadWrapper
451
+ key={activeMessage.id}
452
+ activeMessage={activeMessage}
453
+ user={user}
454
+ customMessageComponent={CustomMessageComponent || Message}
455
+ />
456
+ ) : null;
441
457
  const backToList = () => {
442
458
  dispatch(setCurrentRoom({ roomJID: '' }));
443
459
  };
@@ -529,8 +545,9 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
529
545
  CustomMessageComponent={
530
546
  CustomMessageComponent || Message
531
547
  }
532
- handleBackClick={() => roomStackRef.current?.pop()}
548
+ handleBackClick={popRoom}
533
549
  />
550
+ {threadView}
534
551
  </ChatWrapperBox>
535
552
  )
536
553
  }
@@ -543,6 +560,7 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
543
560
  <ChatRoom
544
561
  CustomMessageComponent={CustomMessageComponent || Message}
545
562
  />
563
+ {threadView}
546
564
  </ChatWrapperBox>
547
565
  )}
548
566
  </InteractionsOverlayProvider>
@@ -1,4 +1,4 @@
1
- import React, { FC, Fragment, useMemo } from 'react';
1
+ import React, { FC, Fragment, memo, useMemo } from 'react';
2
2
  import { IConfig, IMessage } from '../../types/types';
3
3
  import { isOwnMessage } from '../../helpers/isOwnMessage';
4
4
  import DateLabel from '../styled/DateLabel';
@@ -6,9 +6,6 @@ import SystemMessage from './SystemMessage';
6
6
  import NewMessageLabel from '../styled/NewMessageLabel';
7
7
  import {
8
8
  Message,
9
- MessageText,
10
- MessageTimestamp,
11
- UserName,
12
9
  } from '../styled/StyledComponents';
13
10
  import { View } from 'react-native';
14
11
 
@@ -35,7 +32,7 @@ interface MessageContainerProps {
35
32
  className?: string;
36
33
  }
37
34
 
38
- export const MessageContainer: FC<MessageContainerProps> = ({
35
+ const MessageContainerImpl: FC<MessageContainerProps> = ({
39
36
  CustomMessage,
40
37
  CustomDaySeparator,
41
38
  CustomNewMessageLabel,
@@ -101,28 +98,23 @@ export const MessageContainer: FC<MessageContainerProps> = ({
101
98
  <DateLabel date={messageDate} colors={config?.colors} />
102
99
  )
103
100
  ) : null}
101
+
104
102
  <MessageComponent
105
103
  message={message}
106
104
  isUser={isUser}
107
105
  isReply={isReply}
108
106
  className={className}
109
107
  >
110
- {!CustomMessage ? (
111
- <>
112
- <MessageTimestamp>
113
- {messageDate.toLocaleTimeString()}
114
- </MessageTimestamp>
115
- <UserName>{message.user.name}: </UserName>
116
- <MessageText>{message.body}</MessageText>
117
- </>
118
- ) : (
108
+ {CustomMessage ? (
119
109
  <MessageComponent
120
110
  message={message}
121
111
  isUser={isUser}
122
112
  isReply={isReply}
123
113
  />
124
- )}
114
+ ) : null}
125
115
  </MessageComponent>
126
116
  </View>
127
117
  );
128
118
  };
119
+
120
+ export const MessageContainer = memo(MessageContainerImpl);
@@ -23,7 +23,8 @@ import { msgSortableMs } from '../../roomStore/roomsSlice';
23
23
  import Composing from '../styled/StyledInputComponents/Composing';
24
24
  import TreadLabel from '../styled/TreadLabel';
25
25
  import { MessageContainer } from './MessageContainer';
26
- import { useRoomState } from '../../hooks/useRoomState';
26
+ import { useSelector } from 'react-redux';
27
+ import type { RootState } from '../../roomStore';
27
28
  import Loader from '../styled/Loader';
28
29
  import { ArowDownIcon } from '../../assets/icons';
29
30
  import CustomTypingIndicator from '../styled/StyledInputComponents/CustomTypingIndicator';
@@ -67,6 +68,43 @@ interface MessageListProps<TMessage extends IMessage> {
67
68
  onReadBoundaryChange?: (boundaryTs: number | null) => void;
68
69
  }
69
70
 
71
+ const mainIdCache = new WeakMap<object, string | null>();
72
+ const mainMessageIdOf = (m: IMessage): string | null => {
73
+ if (!m?.mainMessage) {return null;}
74
+ const cached = mainIdCache.get(m);
75
+ if (cached !== undefined) {return cached;}
76
+ let id: string | null = null;
77
+ try {
78
+ const parsed = JSON.parse(m.mainMessage);
79
+ id = parsed?.id != null ? String(parsed.id) : null;
80
+ } catch {
81
+ id = null;
82
+ }
83
+ mainIdCache.set(m, id);
84
+ return id;
85
+ };
86
+
87
+ const sortKeyCache = new WeakMap<object, number>();
88
+ const sortKeyOf = (m: IMessage): number => {
89
+ const cached = sortKeyCache.get(m);
90
+ if (cached !== undefined) {return cached;}
91
+ const key = new Date(m?.date as any).getTime() || 0;
92
+ sortKeyCache.set(m, key);
93
+ return key;
94
+ };
95
+
96
+ const dayKeyCache = new WeakMap<object, string>();
97
+ const dayKeyOf = (m: IMessage): string => {
98
+ const cached = dayKeyCache.get(m);
99
+ if (cached !== undefined) {return cached;}
100
+ const key = new Date(m.date).toDateString();
101
+ dayKeyCache.set(m, key);
102
+ return key;
103
+ };
104
+
105
+ const keyExtractor = (item: IMessage) => String(item.id);
106
+ const EMPTY_LIST: IMessage[] = [];
107
+
70
108
  const MessageList = <TMessage extends IMessage>({
71
109
  CustomMessage,
72
110
  CustomDaySeparator,
@@ -80,8 +118,12 @@ const MessageList = <TMessage extends IMessage>({
80
118
  activeMessage,
81
119
  onReadBoundaryChange,
82
120
  }: MessageListProps<TMessage>) => {
83
- const { composing, messages, composingList } = useRoomState(roomJID)
84
- .room! as IRoom;
121
+ const room = useSelector(
122
+ (state: RootState) => state.rooms.rooms?.[roomJID]
123
+ ) as IRoom | undefined;
124
+ const composing = room?.composing;
125
+ const composingList = room?.composingList;
126
+ const messages = room?.messages || EMPTY_LIST;
85
127
  const theme = useTheme();
86
128
  const [isUserAtBottom, setIsUserAtBottom] = useState(true);
87
129
  const [showNewMessageIndicator, setShowNewMessageIndicator] = useState(false);
@@ -107,17 +149,22 @@ const MessageList = <TMessage extends IMessage>({
107
149
  const flatListRef = useRef<FlatList<IMessage>>(null);
108
150
 
109
151
  const addReplyMessages = useMemo(() => {
152
+ const repliesByParent = new Map<string, IMessage[]>();
153
+ for (const mess of messages) {
154
+ if (!mess?.mainMessage || mess.isDeleted) {continue;}
155
+ const parentId = mainMessageIdOf(mess);
156
+ if (!parentId) {continue;}
157
+ const list = repliesByParent.get(parentId);
158
+ if (list) {
159
+ list.push(mess);
160
+ } else {
161
+ repliesByParent.set(parentId, [mess]);
162
+ }
163
+ }
164
+ if (repliesByParent.size === 0) {return messages;}
110
165
  return messages.map((message: IMessage) => {
111
- const newMessage = {
112
- ...message,
113
- reply: messages.filter(
114
- (mess: IMessage) =>
115
- !!mess.mainMessage &&
116
- JSON.parse(mess.mainMessage).id === message.id &&
117
- !mess.isDeleted
118
- ),
119
- };
120
- return newMessage;
166
+ const reply = repliesByParent.get(String(message.id));
167
+ return reply ? { ...message, reply } : message;
121
168
  });
122
169
  }, [messages]);
123
170
 
@@ -134,7 +181,7 @@ const MessageList = <TMessage extends IMessage>({
134
181
  item.isReply &&
135
182
  item.isReply === 'true' &&
136
183
  item.mainMessage &&
137
- JSON.parse(item.mainMessage).id === activeMessage?.id
184
+ mainMessageIdOf(item) === String(activeMessage?.id)
138
185
  );
139
186
  } else {
140
187
  filtered = nonDeletedMessages.filter(
@@ -154,14 +201,21 @@ const MessageList = <TMessage extends IMessage>({
154
201
  // settles. Sorting here makes each render a stable, ordered view —
155
202
  // even mid-stream — so the user sees them appear from oldest to
156
203
  // newest with no swap animation.
157
- const sorted = filtered.slice().sort((a, b) => {
158
- const aNum = new Date(a?.date as any).getTime() || 0;
159
- const bNum = new Date(b?.date as any).getTime() || 0;
160
- return aNum - bNum;
161
- });
162
- const deduped = Array.from(
163
- new Map(sorted.map((m) => [m.id, m])).values()
164
- );
204
+ let sorted = filtered;
205
+ for (let i = 1; i < filtered.length; i++) {
206
+ if (sortKeyOf(filtered[i - 1]) > sortKeyOf(filtered[i])) {
207
+ sorted = filtered.slice().sort((a, b) => sortKeyOf(a) - sortKeyOf(b));
208
+ break;
209
+ }
210
+ }
211
+ const seen = new Set<string>();
212
+ const deduped: IMessage[] = [];
213
+ for (const m of sorted) {
214
+ const key = String(m.id);
215
+ if (seen.has(key)) {continue;}
216
+ seen.add(key);
217
+ deduped.push(m);
218
+ }
165
219
  return deduped;
166
220
  }, [addReplyMessages, isReply, roomJID, activeMessage]);
167
221
 
@@ -244,8 +298,21 @@ const MessageList = <TMessage extends IMessage>({
244
298
  return withDivider;
245
299
  }, [memoizedMessages, isUserAtBottom, roomJID, unreadWhileScrolledUp]);
246
300
 
301
+ const dateLabelIds = useMemo(() => {
302
+ const ids = new Set<string>();
303
+ let nextDay: string | null = null;
304
+ for (let i = dataMessages.length - 1; i >= 0; i--) {
305
+ const item = dataMessages[i];
306
+ if (String(item.id).startsWith('delimiter-new')) {continue;}
307
+ const day = dayKeyOf(item);
308
+ if (nextDay === null || day !== nextDay) {ids.add(String(item.id));}
309
+ nextDay = day;
310
+ }
311
+ return ids;
312
+ }, [dataMessages]);
313
+
247
314
  const renderMessage = useCallback(
248
- ({ item, index }: { item: IMessage; index: number }) => {
315
+ ({ item }: { item: IMessage }) => {
249
316
  if (String(item.id).startsWith('delimiter-new')) {
250
317
  return (
251
318
  <MessageContainer
@@ -262,24 +329,7 @@ const MessageList = <TMessage extends IMessage>({
262
329
  );
263
330
  }
264
331
 
265
- const messageDate = new Date(item.date).toDateString();
266
- let showDateLabel = false;
267
-
268
- let nextMessage = null;
269
- for (let i = index + 1; i < dataMessages.length; i++) {
270
- const candidate = dataMessages[i];
271
- if (!String(candidate.id).startsWith('delimiter-new')) {
272
- nextMessage = candidate;
273
- break;
274
- }
275
- }
276
- const nextMessageDate = nextMessage
277
- ? new Date(nextMessage.date).toDateString()
278
- : null;
279
-
280
- if (!nextMessage || messageDate !== nextMessageDate) {
281
- showDateLabel = true;
282
- }
332
+ const showDateLabel = dateLabelIds.has(String(item.id));
283
333
 
284
334
  return (
285
335
  <MessageContainer
@@ -301,7 +351,7 @@ const MessageList = <TMessage extends IMessage>({
301
351
  CustomDaySeparator,
302
352
  CustomMessage,
303
353
  CustomNewMessageLabel,
304
- dataMessages,
354
+ dateLabelIds,
305
355
  isReply,
306
356
  user.xmppUsername,
307
357
  user.walletAddress,
@@ -452,7 +502,10 @@ const MessageList = <TMessage extends IMessage>({
452
502
  ref={flatListRef}
453
503
  data={dataMessages}
454
504
  renderItem={renderMessage}
455
- keyExtractor={(item) => item.id.toString()}
505
+ keyExtractor={keyExtractor}
506
+ initialNumToRender={15}
507
+ maxToRenderPerBatch={10}
508
+ windowSize={7}
456
509
  onEndReached={handleLoadMore}
457
510
  onScroll={handleScroll}
458
511
  onContentSizeChange={handleContentSizeChange}