@ethora/chat-component-rn 26.9.0 → 26.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (761) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +19 -0
  3. package/lib/commonjs/assets/icons.js +2 -2
  4. package/lib/commonjs/assets/icons.js.map +1 -1
  5. package/lib/commonjs/components/Header/HeaderRoomList.js +22 -6
  6. package/lib/commonjs/components/Header/HeaderRoomList.js.map +1 -1
  7. package/lib/commonjs/components/InputComponents/Search.js +38 -1
  8. package/lib/commonjs/components/InputComponents/Search.js.map +1 -1
  9. package/lib/commonjs/components/MainComponents/ArchivedMessageCard.js +166 -0
  10. package/lib/commonjs/components/MainComponents/ArchivedMessageCard.js.map +1 -0
  11. package/lib/commonjs/components/MainComponents/ChatHeader.js +22 -5
  12. package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
  13. package/lib/commonjs/components/MainComponents/ChatRoom.js +56 -25
  14. package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
  15. package/lib/commonjs/components/MainComponents/ChatWrapper.js +53 -4
  16. package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
  17. package/lib/commonjs/components/MainComponents/MediaMessage.js +18 -3
  18. package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
  19. package/lib/commonjs/components/MainComponents/MessageList.js +739 -42
  20. package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
  21. package/lib/commonjs/components/MainComponents/MessageSearchButton.js +58 -0
  22. package/lib/commonjs/components/MainComponents/MessageSearchButton.js.map +1 -0
  23. package/lib/commonjs/components/MainComponents/ReduxWrapper.js +15 -6
  24. package/lib/commonjs/components/MainComponents/ReduxWrapper.js.map +1 -1
  25. package/lib/commonjs/components/MainComponents/RoomList.js +110 -1
  26. package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
  27. package/lib/commonjs/components/Menu/HeaderRoomListMenu.js +14 -3
  28. package/lib/commonjs/components/Menu/HeaderRoomListMenu.js.map +1 -1
  29. package/lib/commonjs/components/MessageBubble/BubbleHighlight.js +112 -0
  30. package/lib/commonjs/components/MessageBubble/BubbleHighlight.js.map +1 -0
  31. package/lib/commonjs/components/MessageBubble/Message.js +169 -125
  32. package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
  33. package/lib/commonjs/components/MessageBubble/MessageInteractions.js +98 -78
  34. package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
  35. package/lib/commonjs/components/MessageBubble/messageMenuLayout.js +50 -0
  36. package/lib/commonjs/components/MessageBubble/messageMenuLayout.js.map +1 -0
  37. package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js +73 -37
  38. package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
  39. package/lib/commonjs/components/Modals/MessageSearchModal/MessageHitResults.js +253 -0
  40. package/lib/commonjs/components/Modals/MessageSearchModal/MessageHitResults.js.map +1 -0
  41. package/lib/commonjs/components/Modals/MessageSearchModal/MessageSearchModal.js +488 -0
  42. package/lib/commonjs/components/Modals/MessageSearchModal/MessageSearchModal.js.map +1 -0
  43. package/lib/commonjs/components/Modals/MessageSearchModal/openHit.js +51 -0
  44. package/lib/commonjs/components/Modals/MessageSearchModal/openHit.js.map +1 -0
  45. package/lib/commonjs/components/Modals/MessageSearchModal/resolveSender.js +47 -0
  46. package/lib/commonjs/components/Modals/MessageSearchModal/resolveSender.js.map +1 -0
  47. package/lib/commonjs/components/Modals/MessageSearchModal/searchFilters.js +83 -0
  48. package/lib/commonjs/components/Modals/MessageSearchModal/searchFilters.js.map +1 -0
  49. package/lib/commonjs/components/Modals/MessageSearchModal/snippet.js +61 -0
  50. package/lib/commonjs/components/Modals/MessageSearchModal/snippet.js.map +1 -0
  51. package/lib/commonjs/components/Modals/MessageSearchModal/useMessageSearch.js +136 -0
  52. package/lib/commonjs/components/Modals/MessageSearchModal/useMessageSearch.js.map +1 -0
  53. package/lib/commonjs/components/Modals/PublicChatsModal/PublicChatsModal.js +306 -0
  54. package/lib/commonjs/components/Modals/PublicChatsModal/PublicChatsModal.js.map +1 -0
  55. package/lib/commonjs/components/Modals/PublicChatsModal/publicChatsLogic.js +36 -0
  56. package/lib/commonjs/components/Modals/PublicChatsModal/publicChatsLogic.js.map +1 -0
  57. package/lib/commonjs/components/Modals/SelectUsersModal/SelectUsersModal.js +8 -1
  58. package/lib/commonjs/components/Modals/SelectUsersModal/SelectUsersModal.js.map +1 -1
  59. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js +13 -2
  60. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js.map +1 -1
  61. package/lib/commonjs/components/RoomComponents/SwipeableRoomRow.js +38 -6
  62. package/lib/commonjs/components/RoomComponents/SwipeableRoomRow.js.map +1 -1
  63. package/lib/commonjs/components/Thread/ThreadHeader.js +3 -1
  64. package/lib/commonjs/components/Thread/ThreadHeader.js.map +1 -1
  65. package/lib/commonjs/components/Thread/ThreadWrapper.js +90 -10
  66. package/lib/commonjs/components/Thread/ThreadWrapper.js.map +1 -1
  67. package/lib/commonjs/components/styled/AudioDecoderHost.js +338 -0
  68. package/lib/commonjs/components/styled/AudioDecoderHost.js.map +1 -0
  69. package/lib/commonjs/components/styled/AudioMessage.js +493 -420
  70. package/lib/commonjs/components/styled/AudioMessage.js.map +1 -1
  71. package/lib/commonjs/components/styled/SendInput.js +31 -5
  72. package/lib/commonjs/components/styled/SendInput.js.map +1 -1
  73. package/lib/commonjs/context/MessageNotificationContext.js +14 -4
  74. package/lib/commonjs/context/MessageNotificationContext.js.map +1 -1
  75. package/lib/commonjs/context/xmppProvider.js +54 -79
  76. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  77. package/lib/commonjs/helpers/audioWaveform.js +165 -0
  78. package/lib/commonjs/helpers/audioWaveform.js.map +1 -0
  79. package/lib/commonjs/helpers/backgroundJoinSweep.js +36 -0
  80. package/lib/commonjs/helpers/backgroundJoinSweep.js.map +1 -0
  81. package/lib/commonjs/helpers/bubbleHighlight.js +44 -0
  82. package/lib/commonjs/helpers/bubbleHighlight.js.map +1 -0
  83. package/lib/commonjs/helpers/checkUniqueUsers.js +14 -12
  84. package/lib/commonjs/helpers/checkUniqueUsers.js.map +1 -1
  85. package/lib/commonjs/helpers/constants/MODAL_COMPONENTS.js +5 -1
  86. package/lib/commonjs/helpers/constants/MODAL_COMPONENTS.js.map +1 -1
  87. package/lib/commonjs/helpers/constants/MODAL_TYPES.js +3 -1
  88. package/lib/commonjs/helpers/constants/MODAL_TYPES.js.map +1 -1
  89. package/lib/commonjs/helpers/createRoomFromApi.js +40 -3
  90. package/lib/commonjs/helpers/createRoomFromApi.js.map +1 -1
  91. package/lib/commonjs/helpers/dedupeMembers.js +34 -0
  92. package/lib/commonjs/helpers/dedupeMembers.js.map +1 -0
  93. package/lib/commonjs/helpers/ethoraLogger.js +56 -0
  94. package/lib/commonjs/helpers/ethoraLogger.js.map +1 -0
  95. package/lib/commonjs/helpers/getUnnamedUsers.js +9 -4
  96. package/lib/commonjs/helpers/getUnnamedUsers.js.map +1 -1
  97. package/lib/commonjs/helpers/historyPreloadConfig.js +44 -0
  98. package/lib/commonjs/helpers/historyPreloadConfig.js.map +1 -0
  99. package/lib/commonjs/helpers/historyPreloadScheduler.js +372 -137
  100. package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
  101. package/lib/commonjs/helpers/initRoomsPresence.js +17 -5
  102. package/lib/commonjs/helpers/initRoomsPresence.js.map +1 -1
  103. package/lib/commonjs/helpers/insertMessageWithDelimiter.js +5 -0
  104. package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
  105. package/lib/commonjs/helpers/isLikelyMucJid.js +67 -0
  106. package/lib/commonjs/helpers/isLikelyMucJid.js.map +1 -0
  107. package/lib/commonjs/helpers/isMessageSearchEnabled.js +18 -0
  108. package/lib/commonjs/helpers/isMessageSearchEnabled.js.map +1 -0
  109. package/lib/commonjs/helpers/joiningRoom.js +14 -0
  110. package/lib/commonjs/helpers/joiningRoom.js.map +1 -0
  111. package/lib/commonjs/helpers/jumpThread.js +100 -0
  112. package/lib/commonjs/helpers/jumpThread.js.map +1 -0
  113. package/lib/commonjs/helpers/jumpToMessage.js +58 -0
  114. package/lib/commonjs/helpers/jumpToMessage.js.map +1 -0
  115. package/lib/commonjs/helpers/jumpWindow.js +187 -0
  116. package/lib/commonjs/helpers/jumpWindow.js.map +1 -0
  117. package/lib/commonjs/helpers/loadRoomHistory.js +75 -0
  118. package/lib/commonjs/helpers/loadRoomHistory.js.map +1 -0
  119. package/lib/commonjs/helpers/notificationPolicy.js +77 -0
  120. package/lib/commonjs/helpers/notificationPolicy.js.map +1 -0
  121. package/lib/commonjs/helpers/openRoomAtMessage.js +47 -0
  122. package/lib/commonjs/helpers/openRoomAtMessage.js.map +1 -0
  123. package/lib/commonjs/helpers/openThreadForJump.js +72 -0
  124. package/lib/commonjs/helpers/openThreadForJump.js.map +1 -0
  125. package/lib/commonjs/helpers/parseMessageReference.js +27 -8
  126. package/lib/commonjs/helpers/parseMessageReference.js.map +1 -1
  127. package/lib/commonjs/helpers/publicChatsEntry.js +17 -0
  128. package/lib/commonjs/helpers/publicChatsEntry.js.map +1 -0
  129. package/lib/commonjs/helpers/roomActivityScore.js +37 -0
  130. package/lib/commonjs/helpers/roomActivityScore.js.map +1 -0
  131. package/lib/commonjs/helpers/roomUserCount.js +36 -0
  132. package/lib/commonjs/helpers/roomUserCount.js.map +1 -0
  133. package/lib/commonjs/helpers/runConfiguredHistoryPreload.js +68 -0
  134. package/lib/commonjs/helpers/runConfiguredHistoryPreload.js.map +1 -0
  135. package/lib/commonjs/helpers/sessionAppId.js +24 -0
  136. package/lib/commonjs/helpers/sessionAppId.js.map +1 -0
  137. package/lib/commonjs/helpers/timestamp.js +43 -0
  138. package/lib/commonjs/helpers/timestamp.js.map +1 -0
  139. package/lib/commonjs/helpers/userResolver.js +517 -0
  140. package/lib/commonjs/helpers/userResolver.js.map +1 -0
  141. package/lib/commonjs/helpers/xmppIdShape.js +52 -0
  142. package/lib/commonjs/helpers/xmppIdShape.js.map +1 -0
  143. package/lib/commonjs/hooks/useChatWrapperInit.js +27 -5
  144. package/lib/commonjs/hooks/useChatWrapperInit.js.map +1 -1
  145. package/lib/commonjs/hooks/useHeapSender.js +54 -3
  146. package/lib/commonjs/hooks/useHeapSender.js.map +1 -1
  147. package/lib/commonjs/hooks/useJumpToMessage.js +411 -0
  148. package/lib/commonjs/hooks/useJumpToMessage.js.map +1 -0
  149. package/lib/commonjs/hooks/useMessageLoaderQueue.js +32 -5
  150. package/lib/commonjs/hooks/useMessageLoaderQueue.js.map +1 -1
  151. package/lib/commonjs/hooks/useMessageQueue.js +13 -5
  152. package/lib/commonjs/hooks/useMessageQueue.js.map +1 -1
  153. package/lib/commonjs/hooks/useRoomDirectory.js +29 -0
  154. package/lib/commonjs/hooks/useRoomDirectory.js.map +1 -0
  155. package/lib/commonjs/hooks/useRoomInitialization.js +27 -5
  156. package/lib/commonjs/hooks/useRoomInitialization.js.map +1 -1
  157. package/lib/commonjs/hooks/useRoomMute.js +62 -0
  158. package/lib/commonjs/hooks/useRoomMute.js.map +1 -0
  159. package/lib/commonjs/hooks/useRoomState.js +3 -1
  160. package/lib/commonjs/hooks/useRoomState.js.map +1 -1
  161. package/lib/commonjs/hooks/useSendMessage.js +13 -3
  162. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  163. package/lib/commonjs/i18n/strings.js +318 -6
  164. package/lib/commonjs/i18n/strings.js.map +1 -1
  165. package/lib/commonjs/networking/api-requests/messageSearch.api.js +87 -0
  166. package/lib/commonjs/networking/api-requests/messageSearch.api.js.map +1 -0
  167. package/lib/commonjs/networking/api-requests/publicChats.api.js +48 -0
  168. package/lib/commonjs/networking/api-requests/publicChats.api.js.map +1 -0
  169. package/lib/commonjs/networking/api-requests/roomMembers.api.js +253 -4
  170. package/lib/commonjs/networking/api-requests/roomMembers.api.js.map +1 -1
  171. package/lib/commonjs/networking/api-requests/rooms.api.js +48 -12
  172. package/lib/commonjs/networking/api-requests/rooms.api.js.map +1 -1
  173. package/lib/commonjs/networking/api-requests/xmppToken.api.js +71 -0
  174. package/lib/commonjs/networking/api-requests/xmppToken.api.js.map +1 -0
  175. package/lib/commonjs/networking/ethoraEvents.js +227 -0
  176. package/lib/commonjs/networking/ethoraEvents.js.map +1 -0
  177. package/lib/commonjs/networking/stanzaHandlers.js +153 -16
  178. package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
  179. package/lib/commonjs/networking/xmpp/allRoomPresences.xmpp.js +124 -3
  180. package/lib/commonjs/networking/xmpp/allRoomPresences.xmpp.js.map +1 -1
  181. package/lib/commonjs/networking/xmpp/getHistory.xmpp.js +319 -35
  182. package/lib/commonjs/networking/xmpp/getHistory.xmpp.js.map +1 -1
  183. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js +7 -0
  184. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  185. package/lib/commonjs/networking/xmpp/historyCursor.js +101 -0
  186. package/lib/commonjs/networking/xmpp/historyCursor.js.map +1 -0
  187. package/lib/commonjs/networking/xmpp/mamQueryIds.js +17 -0
  188. package/lib/commonjs/networking/xmpp/mamQueryIds.js.map +1 -0
  189. package/lib/commonjs/networking/xmpp/mamRouter.js +24 -9
  190. package/lib/commonjs/networking/xmpp/mamRouter.js.map +1 -1
  191. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js +70 -65
  192. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  193. package/lib/commonjs/networking/xmpp/roomJoinSweep.js +389 -0
  194. package/lib/commonjs/networking/xmpp/roomJoinSweep.js.map +1 -0
  195. package/lib/commonjs/networking/xmpp/sendMediaMessage.xmpp.js +0 -1
  196. package/lib/commonjs/networking/xmpp/sendMediaMessage.xmpp.js.map +1 -1
  197. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js +0 -1
  198. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  199. package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +0 -1
  200. package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
  201. package/lib/commonjs/networking/xmppClient.js +269 -41
  202. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  203. package/lib/commonjs/networking/xmppCredentials.js +80 -0
  204. package/lib/commonjs/networking/xmppCredentials.js.map +1 -0
  205. package/lib/commonjs/roomStore/Middleware/jumpThreadMiddleware.js +158 -0
  206. package/lib/commonjs/roomStore/Middleware/jumpThreadMiddleware.js.map +1 -0
  207. package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js +6 -0
  208. package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
  209. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js +45 -7
  210. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  211. package/lib/commonjs/roomStore/chatSettingsSlice.js +15 -1
  212. package/lib/commonjs/roomStore/chatSettingsSlice.js.map +1 -1
  213. package/lib/commonjs/roomStore/index.js +13 -3
  214. package/lib/commonjs/roomStore/index.js.map +1 -1
  215. package/lib/commonjs/roomStore/persistence.js +48 -1
  216. package/lib/commonjs/roomStore/persistence.js.map +1 -1
  217. package/lib/commonjs/roomStore/roomsSlice.js +474 -60
  218. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  219. package/lib/commonjs/roomStore/safeKey.js +44 -0
  220. package/lib/commonjs/roomStore/safeKey.js.map +1 -0
  221. package/lib/commonjs/roomStore/usersSetCap.js +37 -0
  222. package/lib/commonjs/roomStore/usersSetCap.js.map +1 -0
  223. package/lib/commonjs/version.js +1 -1
  224. package/lib/commonjs/version.js.map +1 -1
  225. package/lib/module/assets/icons.js +1 -1
  226. package/lib/module/assets/icons.js.map +1 -1
  227. package/lib/module/components/Header/HeaderRoomList.js +23 -7
  228. package/lib/module/components/Header/HeaderRoomList.js.map +1 -1
  229. package/lib/module/components/InputComponents/Search.js +39 -2
  230. package/lib/module/components/InputComponents/Search.js.map +1 -1
  231. package/lib/module/components/MainComponents/ArchivedMessageCard.js +161 -0
  232. package/lib/module/components/MainComponents/ArchivedMessageCard.js.map +1 -0
  233. package/lib/module/components/MainComponents/ChatHeader.js +22 -5
  234. package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
  235. package/lib/module/components/MainComponents/ChatRoom.js +57 -26
  236. package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
  237. package/lib/module/components/MainComponents/ChatWrapper.js +54 -5
  238. package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
  239. package/lib/module/components/MainComponents/MediaMessage.js +18 -3
  240. package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
  241. package/lib/module/components/MainComponents/MessageList.js +740 -42
  242. package/lib/module/components/MainComponents/MessageList.js.map +1 -1
  243. package/lib/module/components/MainComponents/MessageSearchButton.js +48 -0
  244. package/lib/module/components/MainComponents/MessageSearchButton.js.map +1 -0
  245. package/lib/module/components/MainComponents/ReduxWrapper.js +15 -7
  246. package/lib/module/components/MainComponents/ReduxWrapper.js.map +1 -1
  247. package/lib/module/components/MainComponents/RoomList.js +111 -2
  248. package/lib/module/components/MainComponents/RoomList.js.map +1 -1
  249. package/lib/module/components/Menu/HeaderRoomListMenu.js +15 -4
  250. package/lib/module/components/Menu/HeaderRoomListMenu.js.map +1 -1
  251. package/lib/module/components/MessageBubble/BubbleHighlight.js +106 -0
  252. package/lib/module/components/MessageBubble/BubbleHighlight.js.map +1 -0
  253. package/lib/module/components/MessageBubble/Message.js +172 -127
  254. package/lib/module/components/MessageBubble/Message.js.map +1 -1
  255. package/lib/module/components/MessageBubble/MessageInteractions.js +98 -78
  256. package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
  257. package/lib/module/components/MessageBubble/messageMenuLayout.js +45 -0
  258. package/lib/module/components/MessageBubble/messageMenuLayout.js.map +1 -0
  259. package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js +74 -38
  260. package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
  261. package/lib/module/components/Modals/MessageSearchModal/MessageHitResults.js +243 -0
  262. package/lib/module/components/Modals/MessageSearchModal/MessageHitResults.js.map +1 -0
  263. package/lib/module/components/Modals/MessageSearchModal/MessageSearchModal.js +482 -0
  264. package/lib/module/components/Modals/MessageSearchModal/MessageSearchModal.js.map +1 -0
  265. package/lib/module/components/Modals/MessageSearchModal/openHit.js +45 -0
  266. package/lib/module/components/Modals/MessageSearchModal/openHit.js.map +1 -0
  267. package/lib/module/components/Modals/MessageSearchModal/resolveSender.js +41 -0
  268. package/lib/module/components/Modals/MessageSearchModal/resolveSender.js.map +1 -0
  269. package/lib/module/components/Modals/MessageSearchModal/searchFilters.js +74 -0
  270. package/lib/module/components/Modals/MessageSearchModal/searchFilters.js.map +1 -0
  271. package/lib/module/components/Modals/MessageSearchModal/snippet.js +57 -0
  272. package/lib/module/components/Modals/MessageSearchModal/snippet.js.map +1 -0
  273. package/lib/module/components/Modals/MessageSearchModal/useMessageSearch.js +131 -0
  274. package/lib/module/components/Modals/MessageSearchModal/useMessageSearch.js.map +1 -0
  275. package/lib/module/components/Modals/PublicChatsModal/PublicChatsModal.js +300 -0
  276. package/lib/module/components/Modals/PublicChatsModal/PublicChatsModal.js.map +1 -0
  277. package/lib/module/components/Modals/PublicChatsModal/publicChatsLogic.js +30 -0
  278. package/lib/module/components/Modals/PublicChatsModal/publicChatsLogic.js.map +1 -0
  279. package/lib/module/components/Modals/SelectUsersModal/SelectUsersModal.js +8 -1
  280. package/lib/module/components/Modals/SelectUsersModal/SelectUsersModal.js.map +1 -1
  281. package/lib/module/components/RoomComponents/ChatRoomItem.js +14 -3
  282. package/lib/module/components/RoomComponents/ChatRoomItem.js.map +1 -1
  283. package/lib/module/components/RoomComponents/SwipeableRoomRow.js +39 -7
  284. package/lib/module/components/RoomComponents/SwipeableRoomRow.js.map +1 -1
  285. package/lib/module/components/Thread/ThreadHeader.js +3 -1
  286. package/lib/module/components/Thread/ThreadHeader.js.map +1 -1
  287. package/lib/module/components/Thread/ThreadWrapper.js +89 -9
  288. package/lib/module/components/Thread/ThreadWrapper.js.map +1 -1
  289. package/lib/module/components/styled/AudioDecoderHost.js +332 -0
  290. package/lib/module/components/styled/AudioDecoderHost.js.map +1 -0
  291. package/lib/module/components/styled/AudioMessage.js +495 -422
  292. package/lib/module/components/styled/AudioMessage.js.map +1 -1
  293. package/lib/module/components/styled/SendInput.js +32 -6
  294. package/lib/module/components/styled/SendInput.js.map +1 -1
  295. package/lib/module/context/MessageNotificationContext.js +15 -5
  296. package/lib/module/context/MessageNotificationContext.js.map +1 -1
  297. package/lib/module/context/xmppProvider.js +54 -79
  298. package/lib/module/context/xmppProvider.js.map +1 -1
  299. package/lib/module/helpers/audioWaveform.js +153 -0
  300. package/lib/module/helpers/audioWaveform.js.map +1 -0
  301. package/lib/module/helpers/backgroundJoinSweep.js +30 -0
  302. package/lib/module/helpers/backgroundJoinSweep.js.map +1 -0
  303. package/lib/module/helpers/bubbleHighlight.js +38 -0
  304. package/lib/module/helpers/bubbleHighlight.js.map +1 -0
  305. package/lib/module/helpers/checkUniqueUsers.js +15 -13
  306. package/lib/module/helpers/checkUniqueUsers.js.map +1 -1
  307. package/lib/module/helpers/constants/MODAL_COMPONENTS.js +5 -1
  308. package/lib/module/helpers/constants/MODAL_COMPONENTS.js.map +1 -1
  309. package/lib/module/helpers/constants/MODAL_TYPES.js +3 -1
  310. package/lib/module/helpers/constants/MODAL_TYPES.js.map +1 -1
  311. package/lib/module/helpers/createRoomFromApi.js +37 -3
  312. package/lib/module/helpers/createRoomFromApi.js.map +1 -1
  313. package/lib/module/helpers/dedupeMembers.js +28 -0
  314. package/lib/module/helpers/dedupeMembers.js.map +1 -0
  315. package/lib/module/helpers/ethoraLogger.js +52 -0
  316. package/lib/module/helpers/ethoraLogger.js.map +1 -0
  317. package/lib/module/helpers/getUnnamedUsers.js +9 -4
  318. package/lib/module/helpers/getUnnamedUsers.js.map +1 -1
  319. package/lib/module/helpers/historyPreloadConfig.js +39 -0
  320. package/lib/module/helpers/historyPreloadConfig.js.map +1 -0
  321. package/lib/module/helpers/historyPreloadScheduler.js +368 -134
  322. package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
  323. package/lib/module/helpers/initRoomsPresence.js +18 -5
  324. package/lib/module/helpers/initRoomsPresence.js.map +1 -1
  325. package/lib/module/helpers/insertMessageWithDelimiter.js +5 -0
  326. package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
  327. package/lib/module/helpers/isLikelyMucJid.js +60 -0
  328. package/lib/module/helpers/isLikelyMucJid.js.map +1 -0
  329. package/lib/module/helpers/isMessageSearchEnabled.js +13 -0
  330. package/lib/module/helpers/isMessageSearchEnabled.js.map +1 -0
  331. package/lib/module/helpers/joiningRoom.js +9 -0
  332. package/lib/module/helpers/joiningRoom.js.map +1 -0
  333. package/lib/module/helpers/jumpThread.js +83 -0
  334. package/lib/module/helpers/jumpThread.js.map +1 -0
  335. package/lib/module/helpers/jumpToMessage.js +52 -0
  336. package/lib/module/helpers/jumpToMessage.js.map +1 -0
  337. package/lib/module/helpers/jumpWindow.js +177 -0
  338. package/lib/module/helpers/jumpWindow.js.map +1 -0
  339. package/lib/module/helpers/loadRoomHistory.js +69 -0
  340. package/lib/module/helpers/loadRoomHistory.js.map +1 -0
  341. package/lib/module/helpers/notificationPolicy.js +70 -0
  342. package/lib/module/helpers/notificationPolicy.js.map +1 -0
  343. package/lib/module/helpers/openRoomAtMessage.js +41 -0
  344. package/lib/module/helpers/openRoomAtMessage.js.map +1 -0
  345. package/lib/module/helpers/openThreadForJump.js +68 -0
  346. package/lib/module/helpers/openThreadForJump.js.map +1 -0
  347. package/lib/module/helpers/parseMessageReference.js +26 -6
  348. package/lib/module/helpers/parseMessageReference.js.map +1 -1
  349. package/lib/module/helpers/publicChatsEntry.js +12 -0
  350. package/lib/module/helpers/publicChatsEntry.js.map +1 -0
  351. package/lib/module/helpers/roomActivityScore.js +30 -0
  352. package/lib/module/helpers/roomActivityScore.js.map +1 -0
  353. package/lib/module/helpers/roomUserCount.js +29 -0
  354. package/lib/module/helpers/roomUserCount.js.map +1 -0
  355. package/lib/module/helpers/runConfiguredHistoryPreload.js +63 -0
  356. package/lib/module/helpers/runConfiguredHistoryPreload.js.map +1 -0
  357. package/lib/module/helpers/sessionAppId.js +20 -0
  358. package/lib/module/helpers/sessionAppId.js.map +1 -0
  359. package/lib/module/helpers/timestamp.js +37 -0
  360. package/lib/module/helpers/timestamp.js.map +1 -0
  361. package/lib/module/helpers/userResolver.js +503 -0
  362. package/lib/module/helpers/userResolver.js.map +1 -0
  363. package/lib/module/helpers/xmppIdShape.js +46 -0
  364. package/lib/module/helpers/xmppIdShape.js.map +1 -0
  365. package/lib/module/hooks/useChatWrapperInit.js +16 -5
  366. package/lib/module/hooks/useChatWrapperInit.js.map +1 -1
  367. package/lib/module/hooks/useHeapSender.js +54 -3
  368. package/lib/module/hooks/useHeapSender.js.map +1 -1
  369. package/lib/module/hooks/useJumpToMessage.js +389 -0
  370. package/lib/module/hooks/useJumpToMessage.js.map +1 -0
  371. package/lib/module/hooks/useMessageLoaderQueue.js +32 -5
  372. package/lib/module/hooks/useMessageLoaderQueue.js.map +1 -1
  373. package/lib/module/hooks/useMessageQueue.js +13 -5
  374. package/lib/module/hooks/useMessageQueue.js.map +1 -1
  375. package/lib/module/hooks/useRoomDirectory.js +24 -0
  376. package/lib/module/hooks/useRoomDirectory.js.map +1 -0
  377. package/lib/module/hooks/useRoomInitialization.js +29 -7
  378. package/lib/module/hooks/useRoomInitialization.js.map +1 -1
  379. package/lib/module/hooks/useRoomMute.js +58 -0
  380. package/lib/module/hooks/useRoomMute.js.map +1 -0
  381. package/lib/module/hooks/useRoomState.js +3 -1
  382. package/lib/module/hooks/useRoomState.js.map +1 -1
  383. package/lib/module/hooks/useSendMessage.js +13 -3
  384. package/lib/module/hooks/useSendMessage.js.map +1 -1
  385. package/lib/module/i18n/strings.js +318 -6
  386. package/lib/module/i18n/strings.js.map +1 -1
  387. package/lib/module/networking/api-requests/messageSearch.api.js +81 -0
  388. package/lib/module/networking/api-requests/messageSearch.api.js.map +1 -0
  389. package/lib/module/networking/api-requests/publicChats.api.js +43 -0
  390. package/lib/module/networking/api-requests/publicChats.api.js.map +1 -0
  391. package/lib/module/networking/api-requests/roomMembers.api.js +248 -4
  392. package/lib/module/networking/api-requests/roomMembers.api.js.map +1 -1
  393. package/lib/module/networking/api-requests/rooms.api.js +48 -12
  394. package/lib/module/networking/api-requests/rooms.api.js.map +1 -1
  395. package/lib/module/networking/api-requests/xmppToken.api.js +66 -0
  396. package/lib/module/networking/api-requests/xmppToken.api.js.map +1 -0
  397. package/lib/module/networking/ethoraEvents.js +220 -0
  398. package/lib/module/networking/ethoraEvents.js.map +1 -0
  399. package/lib/module/networking/stanzaHandlers.js +155 -18
  400. package/lib/module/networking/stanzaHandlers.js.map +1 -1
  401. package/lib/module/networking/xmpp/allRoomPresences.xmpp.js +125 -3
  402. package/lib/module/networking/xmpp/allRoomPresences.xmpp.js.map +1 -1
  403. package/lib/module/networking/xmpp/getHistory.xmpp.js +318 -35
  404. package/lib/module/networking/xmpp/getHistory.xmpp.js.map +1 -1
  405. package/lib/module/networking/xmpp/handleStanzas.xmpp.js +7 -0
  406. package/lib/module/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  407. package/lib/module/networking/xmpp/historyCursor.js +95 -0
  408. package/lib/module/networking/xmpp/historyCursor.js.map +1 -0
  409. package/lib/module/networking/xmpp/mamQueryIds.js +12 -0
  410. package/lib/module/networking/xmpp/mamQueryIds.js.map +1 -0
  411. package/lib/module/networking/xmpp/mamRouter.js +22 -8
  412. package/lib/module/networking/xmpp/mamRouter.js.map +1 -1
  413. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js +68 -62
  414. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  415. package/lib/module/networking/xmpp/roomJoinSweep.js +385 -0
  416. package/lib/module/networking/xmpp/roomJoinSweep.js.map +1 -0
  417. package/lib/module/networking/xmpp/sendMediaMessage.xmpp.js +0 -1
  418. package/lib/module/networking/xmpp/sendMediaMessage.xmpp.js.map +1 -1
  419. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js +0 -1
  420. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  421. package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +0 -1
  422. package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
  423. package/lib/module/networking/xmppClient.js +269 -41
  424. package/lib/module/networking/xmppClient.js.map +1 -1
  425. package/lib/module/networking/xmppCredentials.js +76 -0
  426. package/lib/module/networking/xmppCredentials.js.map +1 -0
  427. package/lib/module/roomStore/Middleware/jumpThreadMiddleware.js +153 -0
  428. package/lib/module/roomStore/Middleware/jumpThreadMiddleware.js.map +1 -0
  429. package/lib/module/roomStore/Middleware/reactionsMiddleware.js +6 -0
  430. package/lib/module/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
  431. package/lib/module/roomStore/Middleware/unreadMidlleware.js +46 -7
  432. package/lib/module/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  433. package/lib/module/roomStore/chatSettingsSlice.js +13 -0
  434. package/lib/module/roomStore/chatSettingsSlice.js.map +1 -1
  435. package/lib/module/roomStore/index.js +7 -3
  436. package/lib/module/roomStore/index.js.map +1 -1
  437. package/lib/module/roomStore/persistence.js +46 -1
  438. package/lib/module/roomStore/persistence.js.map +1 -1
  439. package/lib/module/roomStore/roomsSlice.js +459 -58
  440. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  441. package/lib/module/roomStore/safeKey.js +37 -0
  442. package/lib/module/roomStore/safeKey.js.map +1 -0
  443. package/lib/module/roomStore/usersSetCap.js +32 -0
  444. package/lib/module/roomStore/usersSetCap.js.map +1 -0
  445. package/lib/module/version.js +1 -1
  446. package/lib/module/version.js.map +1 -1
  447. package/lib/typescript/assets/icons.d.ts +4 -0
  448. package/lib/typescript/assets/icons.d.ts.map +1 -1
  449. package/lib/typescript/components/Header/HeaderRoomList.d.ts.map +1 -1
  450. package/lib/typescript/components/InputComponents/Search.d.ts.map +1 -1
  451. package/lib/typescript/components/MainComponents/ArchivedMessageCard.d.ts +12 -0
  452. package/lib/typescript/components/MainComponents/ArchivedMessageCard.d.ts.map +1 -0
  453. package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
  454. package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
  455. package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
  456. package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
  457. package/lib/typescript/components/MainComponents/MessageList.d.ts +22 -1
  458. package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
  459. package/lib/typescript/components/MainComponents/MessageSearchButton.d.ts +7 -0
  460. package/lib/typescript/components/MainComponents/MessageSearchButton.d.ts.map +1 -0
  461. package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts.map +1 -1
  462. package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
  463. package/lib/typescript/components/Menu/HeaderRoomListMenu.d.ts.map +1 -1
  464. package/lib/typescript/components/MessageBubble/BubbleHighlight.d.ts +12 -0
  465. package/lib/typescript/components/MessageBubble/BubbleHighlight.d.ts.map +1 -0
  466. package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
  467. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts +5 -0
  468. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
  469. package/lib/typescript/components/MessageBubble/messageMenuLayout.d.ts +29 -0
  470. package/lib/typescript/components/MessageBubble/messageMenuLayout.d.ts.map +1 -0
  471. package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts +2 -0
  472. package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts.map +1 -1
  473. package/lib/typescript/components/Modals/MessageSearchModal/MessageHitResults.d.ts +44 -0
  474. package/lib/typescript/components/Modals/MessageSearchModal/MessageHitResults.d.ts.map +1 -0
  475. package/lib/typescript/components/Modals/MessageSearchModal/MessageSearchModal.d.ts +12 -0
  476. package/lib/typescript/components/Modals/MessageSearchModal/MessageSearchModal.d.ts.map +1 -0
  477. package/lib/typescript/components/Modals/MessageSearchModal/openHit.d.ts +15 -0
  478. package/lib/typescript/components/Modals/MessageSearchModal/openHit.d.ts.map +1 -0
  479. package/lib/typescript/components/Modals/MessageSearchModal/resolveSender.d.ts +34 -0
  480. package/lib/typescript/components/Modals/MessageSearchModal/resolveSender.d.ts.map +1 -0
  481. package/lib/typescript/components/Modals/MessageSearchModal/searchFilters.d.ts +41 -0
  482. package/lib/typescript/components/Modals/MessageSearchModal/searchFilters.d.ts.map +1 -0
  483. package/lib/typescript/components/Modals/MessageSearchModal/snippet.d.ts +15 -0
  484. package/lib/typescript/components/Modals/MessageSearchModal/snippet.d.ts.map +1 -0
  485. package/lib/typescript/components/Modals/MessageSearchModal/useMessageSearch.d.ts +23 -0
  486. package/lib/typescript/components/Modals/MessageSearchModal/useMessageSearch.d.ts.map +1 -0
  487. package/lib/typescript/components/Modals/PublicChatsModal/PublicChatsModal.d.ts +16 -0
  488. package/lib/typescript/components/Modals/PublicChatsModal/PublicChatsModal.d.ts.map +1 -0
  489. package/lib/typescript/components/Modals/PublicChatsModal/publicChatsLogic.d.ts +14 -0
  490. package/lib/typescript/components/Modals/PublicChatsModal/publicChatsLogic.d.ts.map +1 -0
  491. package/lib/typescript/components/Modals/SelectUsersModal/SelectUsersModal.d.ts.map +1 -1
  492. package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts.map +1 -1
  493. package/lib/typescript/components/RoomComponents/SwipeableRoomRow.d.ts +5 -1
  494. package/lib/typescript/components/RoomComponents/SwipeableRoomRow.d.ts.map +1 -1
  495. package/lib/typescript/components/Thread/ThreadHeader.d.ts.map +1 -1
  496. package/lib/typescript/components/Thread/ThreadWrapper.d.ts +1 -0
  497. package/lib/typescript/components/Thread/ThreadWrapper.d.ts.map +1 -1
  498. package/lib/typescript/components/styled/AudioDecoderHost.d.ts +39 -0
  499. package/lib/typescript/components/styled/AudioDecoderHost.d.ts.map +1 -0
  500. package/lib/typescript/components/styled/AudioMessage.d.ts +14 -1
  501. package/lib/typescript/components/styled/AudioMessage.d.ts.map +1 -1
  502. package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
  503. package/lib/typescript/context/MessageNotificationContext.d.ts.map +1 -1
  504. package/lib/typescript/context/xmppProvider.d.ts +2 -0
  505. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  506. package/lib/typescript/helpers/audioWaveform.d.ts +54 -0
  507. package/lib/typescript/helpers/audioWaveform.d.ts.map +1 -0
  508. package/lib/typescript/helpers/backgroundJoinSweep.d.ts +14 -0
  509. package/lib/typescript/helpers/backgroundJoinSweep.d.ts.map +1 -0
  510. package/lib/typescript/helpers/bubbleHighlight.d.ts +17 -0
  511. package/lib/typescript/helpers/bubbleHighlight.d.ts.map +1 -0
  512. package/lib/typescript/helpers/checkUniqueUsers.d.ts +2 -2
  513. package/lib/typescript/helpers/checkUniqueUsers.d.ts.map +1 -1
  514. package/lib/typescript/helpers/constants/MODAL_COMPONENTS.d.ts.map +1 -1
  515. package/lib/typescript/helpers/constants/MODAL_TYPES.d.ts +2 -0
  516. package/lib/typescript/helpers/constants/MODAL_TYPES.d.ts.map +1 -1
  517. package/lib/typescript/helpers/createRoomFromApi.d.ts +25 -0
  518. package/lib/typescript/helpers/createRoomFromApi.d.ts.map +1 -1
  519. package/lib/typescript/helpers/dedupeMembers.d.ts +11 -0
  520. package/lib/typescript/helpers/dedupeMembers.d.ts.map +1 -0
  521. package/lib/typescript/helpers/ethoraLogger.d.ts +13 -0
  522. package/lib/typescript/helpers/ethoraLogger.d.ts.map +1 -0
  523. package/lib/typescript/helpers/getUnnamedUsers.d.ts.map +1 -1
  524. package/lib/typescript/helpers/historyPreloadConfig.d.ts +26 -0
  525. package/lib/typescript/helpers/historyPreloadConfig.d.ts.map +1 -0
  526. package/lib/typescript/helpers/historyPreloadScheduler.d.ts +8 -4
  527. package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
  528. package/lib/typescript/helpers/initRoomsPresence.d.ts +7 -0
  529. package/lib/typescript/helpers/initRoomsPresence.d.ts.map +1 -1
  530. package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
  531. package/lib/typescript/helpers/isLikelyMucJid.d.ts +19 -0
  532. package/lib/typescript/helpers/isLikelyMucJid.d.ts.map +1 -0
  533. package/lib/typescript/helpers/isMessageSearchEnabled.d.ts +12 -0
  534. package/lib/typescript/helpers/isMessageSearchEnabled.d.ts.map +1 -0
  535. package/lib/typescript/helpers/joiningRoom.d.ts +7 -0
  536. package/lib/typescript/helpers/joiningRoom.d.ts.map +1 -0
  537. package/lib/typescript/helpers/jumpThread.d.ts +48 -0
  538. package/lib/typescript/helpers/jumpThread.d.ts.map +1 -0
  539. package/lib/typescript/helpers/jumpToMessage.d.ts +26 -0
  540. package/lib/typescript/helpers/jumpToMessage.d.ts.map +1 -0
  541. package/lib/typescript/helpers/jumpWindow.d.ts +74 -0
  542. package/lib/typescript/helpers/jumpWindow.d.ts.map +1 -0
  543. package/lib/typescript/helpers/loadRoomHistory.d.ts +34 -0
  544. package/lib/typescript/helpers/loadRoomHistory.d.ts.map +1 -0
  545. package/lib/typescript/helpers/notificationPolicy.d.ts +42 -0
  546. package/lib/typescript/helpers/notificationPolicy.d.ts.map +1 -0
  547. package/lib/typescript/helpers/openRoomAtMessage.d.ts +17 -0
  548. package/lib/typescript/helpers/openRoomAtMessage.d.ts.map +1 -0
  549. package/lib/typescript/helpers/openThreadForJump.d.ts +27 -0
  550. package/lib/typescript/helpers/openThreadForJump.d.ts.map +1 -0
  551. package/lib/typescript/helpers/parseMessageReference.d.ts +18 -5
  552. package/lib/typescript/helpers/parseMessageReference.d.ts.map +1 -1
  553. package/lib/typescript/helpers/publicChatsEntry.d.ts +11 -0
  554. package/lib/typescript/helpers/publicChatsEntry.d.ts.map +1 -0
  555. package/lib/typescript/helpers/roomActivityScore.d.ts +5 -0
  556. package/lib/typescript/helpers/roomActivityScore.d.ts.map +1 -0
  557. package/lib/typescript/helpers/roomUserCount.d.ts +20 -0
  558. package/lib/typescript/helpers/roomUserCount.d.ts.map +1 -0
  559. package/lib/typescript/helpers/runConfiguredHistoryPreload.d.ts +21 -0
  560. package/lib/typescript/helpers/runConfiguredHistoryPreload.d.ts.map +1 -0
  561. package/lib/typescript/helpers/sessionAppId.d.ts +8 -0
  562. package/lib/typescript/helpers/sessionAppId.d.ts.map +1 -0
  563. package/lib/typescript/helpers/timestamp.d.ts +3 -0
  564. package/lib/typescript/helpers/timestamp.d.ts.map +1 -0
  565. package/lib/typescript/helpers/userResolver.d.ts +58 -0
  566. package/lib/typescript/helpers/userResolver.d.ts.map +1 -0
  567. package/lib/typescript/helpers/xmppIdShape.d.ts +10 -0
  568. package/lib/typescript/helpers/xmppIdShape.d.ts.map +1 -0
  569. package/lib/typescript/hooks/useChatWrapperInit.d.ts +2 -0
  570. package/lib/typescript/hooks/useChatWrapperInit.d.ts.map +1 -1
  571. package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
  572. package/lib/typescript/hooks/useJumpToMessage.d.ts +116 -0
  573. package/lib/typescript/hooks/useJumpToMessage.d.ts.map +1 -0
  574. package/lib/typescript/hooks/useMessageLoaderQueue.d.ts.map +1 -1
  575. package/lib/typescript/hooks/useMessageQueue.d.ts.map +1 -1
  576. package/lib/typescript/hooks/useRoomDirectory.d.ts +12 -0
  577. package/lib/typescript/hooks/useRoomDirectory.d.ts.map +1 -0
  578. package/lib/typescript/hooks/useRoomInitialization.d.ts.map +1 -1
  579. package/lib/typescript/hooks/useRoomMute.d.ts +8 -0
  580. package/lib/typescript/hooks/useRoomMute.d.ts.map +1 -0
  581. package/lib/typescript/hooks/useRoomState.d.ts +1 -0
  582. package/lib/typescript/hooks/useRoomState.d.ts.map +1 -1
  583. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  584. package/lib/typescript/i18n/strings.d.ts.map +1 -1
  585. package/lib/typescript/networking/api-requests/messageSearch.api.d.ts +57 -0
  586. package/lib/typescript/networking/api-requests/messageSearch.api.d.ts.map +1 -0
  587. package/lib/typescript/networking/api-requests/publicChats.api.d.ts +24 -0
  588. package/lib/typescript/networking/api-requests/publicChats.api.d.ts.map +1 -0
  589. package/lib/typescript/networking/api-requests/roomMembers.api.d.ts +19 -1
  590. package/lib/typescript/networking/api-requests/roomMembers.api.d.ts.map +1 -1
  591. package/lib/typescript/networking/api-requests/rooms.api.d.ts.map +1 -1
  592. package/lib/typescript/networking/api-requests/xmppToken.api.d.ts +2 -0
  593. package/lib/typescript/networking/api-requests/xmppToken.api.d.ts.map +1 -0
  594. package/lib/typescript/networking/ethoraEvents.d.ts +45 -0
  595. package/lib/typescript/networking/ethoraEvents.d.ts.map +1 -0
  596. package/lib/typescript/networking/stanzaHandlers.d.ts +1 -1
  597. package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
  598. package/lib/typescript/networking/xmpp/allRoomPresences.xmpp.d.ts +32 -1
  599. package/lib/typescript/networking/xmpp/allRoomPresences.xmpp.d.ts.map +1 -1
  600. package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts +64 -0
  601. package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts.map +1 -1
  602. package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
  603. package/lib/typescript/networking/xmpp/historyCursor.d.ts +35 -0
  604. package/lib/typescript/networking/xmpp/historyCursor.d.ts.map +1 -0
  605. package/lib/typescript/networking/xmpp/mamQueryIds.d.ts +10 -0
  606. package/lib/typescript/networking/xmpp/mamQueryIds.d.ts.map +1 -0
  607. package/lib/typescript/networking/xmpp/mamRouter.d.ts +7 -0
  608. package/lib/typescript/networking/xmpp/mamRouter.d.ts.map +1 -1
  609. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts +13 -2
  610. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
  611. package/lib/typescript/networking/xmpp/roomJoinSweep.d.ts +82 -0
  612. package/lib/typescript/networking/xmpp/roomJoinSweep.d.ts.map +1 -0
  613. package/lib/typescript/networking/xmpp/sendMediaMessage.xmpp.d.ts.map +1 -1
  614. package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts.map +1 -1
  615. package/lib/typescript/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts.map +1 -1
  616. package/lib/typescript/networking/xmppClient.d.ts +90 -4
  617. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  618. package/lib/typescript/networking/xmppCredentials.d.ts +12 -0
  619. package/lib/typescript/networking/xmppCredentials.d.ts.map +1 -0
  620. package/lib/typescript/roomStore/Middleware/jumpThreadMiddleware.d.ts +3 -0
  621. package/lib/typescript/roomStore/Middleware/jumpThreadMiddleware.d.ts.map +1 -0
  622. package/lib/typescript/roomStore/Middleware/reactionsMiddleware.d.ts.map +1 -1
  623. package/lib/typescript/roomStore/Middleware/unreadMidlleware.d.ts.map +1 -1
  624. package/lib/typescript/roomStore/chatSettingsSlice.d.ts +8 -1
  625. package/lib/typescript/roomStore/chatSettingsSlice.d.ts.map +1 -1
  626. package/lib/typescript/roomStore/index.d.ts +2 -1
  627. package/lib/typescript/roomStore/index.d.ts.map +1 -1
  628. package/lib/typescript/roomStore/persistence.d.ts +8 -0
  629. package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
  630. package/lib/typescript/roomStore/roomsSlice.d.ts +138 -2
  631. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  632. package/lib/typescript/roomStore/safeKey.d.ts +13 -0
  633. package/lib/typescript/roomStore/safeKey.d.ts.map +1 -0
  634. package/lib/typescript/roomStore/usersSetCap.d.ts +16 -0
  635. package/lib/typescript/roomStore/usersSetCap.d.ts.map +1 -0
  636. package/lib/typescript/types/models/media.model.d.ts +2 -0
  637. package/lib/typescript/types/models/media.model.d.ts.map +1 -1
  638. package/lib/typescript/types/models/room.model.d.ts +18 -5
  639. package/lib/typescript/types/models/room.model.d.ts.map +1 -1
  640. package/lib/typescript/types/models/xmpp.model.d.ts +8 -1
  641. package/lib/typescript/types/models/xmpp.model.d.ts.map +1 -1
  642. package/lib/typescript/types/types.d.ts +90 -5
  643. package/lib/typescript/types/types.d.ts.map +1 -1
  644. package/lib/typescript/version.d.ts +1 -1
  645. package/lib/typescript/version.d.ts.map +1 -1
  646. package/package.json +1 -1
  647. package/src/assets/icons.tsx +13 -0
  648. package/src/components/Header/HeaderRoomList.tsx +21 -4
  649. package/src/components/InputComponents/Search.tsx +33 -0
  650. package/src/components/MainComponents/ArchivedMessageCard.tsx +139 -0
  651. package/src/components/MainComponents/ChatHeader.tsx +19 -3
  652. package/src/components/MainComponents/ChatRoom.tsx +60 -23
  653. package/src/components/MainComponents/ChatWrapper.tsx +50 -9
  654. package/src/components/MainComponents/MediaMessage.tsx +17 -0
  655. package/src/components/MainComponents/MessageList.tsx +823 -84
  656. package/src/components/MainComponents/MessageSearchButton.tsx +48 -0
  657. package/src/components/MainComponents/ReduxWrapper.tsx +16 -5
  658. package/src/components/MainComponents/RoomList.tsx +125 -0
  659. package/src/components/Menu/HeaderRoomListMenu.tsx +26 -2
  660. package/src/components/MessageBubble/BubbleHighlight.tsx +106 -0
  661. package/src/components/MessageBubble/Message.tsx +265 -177
  662. package/src/components/MessageBubble/MessageInteractions.tsx +109 -86
  663. package/src/components/MessageBubble/messageMenuLayout.ts +59 -0
  664. package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +92 -21
  665. package/src/components/Modals/MessageSearchModal/MessageHitResults.tsx +271 -0
  666. package/src/components/Modals/MessageSearchModal/MessageSearchModal.tsx +487 -0
  667. package/src/components/Modals/MessageSearchModal/openHit.ts +50 -0
  668. package/src/components/Modals/MessageSearchModal/resolveSender.ts +57 -0
  669. package/src/components/Modals/MessageSearchModal/searchFilters.ts +109 -0
  670. package/src/components/Modals/MessageSearchModal/snippet.ts +58 -0
  671. package/src/components/Modals/MessageSearchModal/useMessageSearch.ts +151 -0
  672. package/src/components/Modals/PublicChatsModal/PublicChatsModal.tsx +288 -0
  673. package/src/components/Modals/PublicChatsModal/publicChatsLogic.ts +36 -0
  674. package/src/components/Modals/SelectUsersModal/SelectUsersModal.tsx +8 -1
  675. package/src/components/RoomComponents/ChatRoomItem.tsx +16 -3
  676. package/src/components/RoomComponents/SwipeableRoomRow.tsx +39 -6
  677. package/src/components/Thread/ThreadHeader.tsx +3 -1
  678. package/src/components/Thread/ThreadWrapper.tsx +96 -10
  679. package/src/components/styled/AudioDecoderHost.tsx +351 -0
  680. package/src/components/styled/AudioMessage.tsx +482 -425
  681. package/src/components/styled/SendInput.tsx +42 -4
  682. package/src/context/MessageNotificationContext.tsx +19 -5
  683. package/src/context/xmppProvider.tsx +56 -91
  684. package/src/helpers/audioWaveform.ts +142 -0
  685. package/src/helpers/backgroundJoinSweep.ts +35 -0
  686. package/src/helpers/bubbleHighlight.ts +47 -0
  687. package/src/helpers/checkUniqueUsers.tsx +15 -17
  688. package/src/helpers/constants/MODAL_COMPONENTS.tsx +4 -0
  689. package/src/helpers/constants/MODAL_TYPES.ts +3 -0
  690. package/src/helpers/createRoomFromApi.tsx +45 -4
  691. package/src/helpers/dedupeMembers.ts +29 -0
  692. package/src/helpers/ethoraLogger.ts +50 -0
  693. package/src/helpers/getUnnamedUsers.ts +7 -4
  694. package/src/helpers/historyPreloadConfig.ts +68 -0
  695. package/src/helpers/historyPreloadScheduler.ts +437 -199
  696. package/src/helpers/initRoomsPresence.ts +20 -7
  697. package/src/helpers/insertMessageWithDelimiter.ts +3 -0
  698. package/src/helpers/isLikelyMucJid.ts +72 -0
  699. package/src/helpers/isMessageSearchEnabled.ts +18 -0
  700. package/src/helpers/joiningRoom.ts +13 -0
  701. package/src/helpers/jumpThread.ts +102 -0
  702. package/src/helpers/jumpToMessage.ts +57 -0
  703. package/src/helpers/jumpWindow.ts +212 -0
  704. package/src/helpers/loadRoomHistory.ts +83 -0
  705. package/src/helpers/notificationPolicy.ts +82 -0
  706. package/src/helpers/openRoomAtMessage.ts +38 -0
  707. package/src/helpers/openThreadForJump.ts +96 -0
  708. package/src/helpers/parseMessageReference.ts +37 -8
  709. package/src/helpers/publicChatsEntry.ts +15 -0
  710. package/src/helpers/roomActivityScore.ts +45 -0
  711. package/src/helpers/roomUserCount.ts +44 -0
  712. package/src/helpers/runConfiguredHistoryPreload.ts +76 -0
  713. package/src/helpers/sessionAppId.ts +17 -0
  714. package/src/helpers/timestamp.ts +44 -0
  715. package/src/helpers/userResolver.ts +542 -0
  716. package/src/helpers/xmppIdShape.ts +46 -0
  717. package/src/hooks/useChatWrapperInit.ts +22 -4
  718. package/src/hooks/useHeapSender.tsx +54 -3
  719. package/src/hooks/useJumpToMessage.ts +538 -0
  720. package/src/hooks/useMessageLoaderQueue.tsx +40 -4
  721. package/src/hooks/useMessageQueue.ts +9 -5
  722. package/src/hooks/useRoomDirectory.ts +39 -0
  723. package/src/hooks/useRoomInitialization.tsx +33 -7
  724. package/src/hooks/useRoomMute.ts +42 -0
  725. package/src/hooks/useRoomState.tsx +6 -0
  726. package/src/hooks/useSendMessage.tsx +14 -2
  727. package/src/i18n/strings.ts +312 -0
  728. package/src/networking/api-requests/messageSearch.api.ts +130 -0
  729. package/src/networking/api-requests/publicChats.api.ts +71 -0
  730. package/src/networking/api-requests/roomMembers.api.ts +263 -11
  731. package/src/networking/api-requests/rooms.api.ts +52 -12
  732. package/src/networking/api-requests/xmppToken.api.ts +62 -0
  733. package/src/networking/ethoraEvents.ts +262 -0
  734. package/src/networking/stanzaHandlers.ts +145 -19
  735. package/src/networking/xmpp/allRoomPresences.xmpp.ts +155 -5
  736. package/src/networking/xmpp/getHistory.xmpp.ts +433 -47
  737. package/src/networking/xmpp/handleStanzas.xmpp.ts +8 -0
  738. package/src/networking/xmpp/historyCursor.ts +124 -0
  739. package/src/networking/xmpp/mamQueryIds.ts +11 -0
  740. package/src/networking/xmpp/mamRouter.ts +24 -10
  741. package/src/networking/xmpp/presenceInRoom.xmpp.ts +91 -68
  742. package/src/networking/xmpp/roomJoinSweep.ts +412 -0
  743. package/src/networking/xmpp/sendMediaMessage.xmpp.ts +0 -1
  744. package/src/networking/xmpp/sendTextMessage.xmpp.ts +0 -1
  745. package/src/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.ts +0 -1
  746. package/src/networking/xmppClient.ts +323 -47
  747. package/src/networking/xmppCredentials.ts +87 -0
  748. package/src/roomStore/Middleware/jumpThreadMiddleware.ts +163 -0
  749. package/src/roomStore/Middleware/reactionsMiddleware.tsx +4 -0
  750. package/src/roomStore/Middleware/unreadMidlleware.tsx +59 -11
  751. package/src/roomStore/chatSettingsSlice.ts +11 -0
  752. package/src/roomStore/index.ts +10 -3
  753. package/src/roomStore/persistence.ts +54 -0
  754. package/src/roomStore/roomsSlice.ts +547 -65
  755. package/src/roomStore/safeKey.ts +49 -0
  756. package/src/roomStore/usersSetCap.ts +37 -0
  757. package/src/types/models/media.model.ts +4 -0
  758. package/src/types/models/room.model.ts +18 -5
  759. package/src/types/models/xmpp.model.ts +15 -1
  760. package/src/types/types.ts +95 -5
  761. package/src/version.ts +1 -1
@@ -3,17 +3,20 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.mergeUsersSet = exports.editRoomMessage = exports.deleteRoomMessage = exports.deleteRoom = exports.deleteAllRooms = exports.default = exports.compareStanzaIds = exports.clearVisibleRoom = exports.clearReadBoundary = exports.clearPendingNotificationJid = exports.applyRoomsPreloadBatch = exports.applyReactionToMessage = exports.applyPrivateStoreMarkers = exports.addRooms = exports.addRoomViaApi = exports.addRoomMessages = exports.addRoomMessage = exports.addRoom = exports.UNREAD_CAP_PAGE = exports.RUNTIME_MESSAGE_LIMIT = exports.RUNTIME_MESSAGE_CEILING = void 0;
6
+ exports.mergeUsersSet = exports.editRoomMessage = exports.deleteRoomMessage = exports.deleteRoom = exports.deleteAllRooms = exports.default = exports.compareStanzaIds = exports.clearVisibleRoom = exports.clearReadBoundary = exports.clearPendingNotificationJid = exports.clearPendingJump = exports.clearJumpWindow = exports.clearJoiningRoom = exports.clearArchivedMessage = exports.applyRoomsPreloadBatch = exports.applyReactionToMessage = exports.applyPrivateStoreMarkers = exports.appendJumpWindowMessages = exports.addRooms = exports.addRoomViaApi = exports.addRoomMessages = exports.addRoomMessage = exports.addRoomFromApi = exports.addRoom = exports.UNREAD_CAP_PAGE = exports.RUNTIME_MESSAGE_LIMIT = exports.RUNTIME_MESSAGE_CEILING = exports.JUMP_WINDOW_MAX_MESSAGES = void 0;
7
7
  Object.defineProperty(exports, "msgSortableMs", {
8
8
  enumerable: true,
9
9
  get: function () {
10
10
  return _msgSortableMs.msgSortableMs;
11
11
  }
12
12
  });
13
- exports.updateRoom = exports.setVisibleRoom = exports.setUnreadSyncing = exports.setUnreadCounts = exports.setRoomRole = exports.setRoomNoMessages = exports.setRoomMessages = exports.setReadBoundary = exports.setReactions = exports.setPendingNotificationJid = exports.setLogoutState = exports.setLastViewedTimestamp = exports.setIsLoading = exports.setEditAction = exports.setCurrentRoom = exports.setComposing = exports.setCloseActiveMessage = exports.setActiveMessage = exports.roomsStore = void 0;
13
+ exports.updateRoom = exports.showArchivedMessage = exports.setVisibleRoom = exports.setUnreadSyncing = exports.setUnreadCounts = exports.setRoomRole = exports.setRoomNoMessages = exports.setRoomMessages = exports.setReadBoundary = exports.setReactions = exports.setPendingNotificationJid = exports.setMessageTranslation = exports.setLogoutState = exports.setLastViewedTimestamp = exports.setJumpWindow = exports.setJoiningRoom = exports.setIsLoading = exports.setEditAction = exports.setCurrentRoom = exports.setComposing = exports.setCloseActiveMessage = exports.setActiveMessage = exports.roomsStore = exports.requestJumpToMessage = exports.removeRoomMessage = exports.prependJumpWindowMessages = void 0;
14
14
  var _toolkit = require("@reduxjs/toolkit");
15
15
  var _insertMessageWithDelimiter = require("../helpers/insertMessageWithDelimiter");
16
16
  var _msgSortableMs = require("../helpers/msgSortableMs");
17
+ var _safeKey = require("./safeKey");
18
+ var _usersSetCap = require("./usersSetCap");
19
+ var _roomUserCount = require("../helpers/roomUserCount");
17
20
  var _pushSubscriptionService = require("../services/pushSubscriptionService");
18
21
  // Per-room runtime message cap. Mirrors the persistence layer's
19
22
  // MESSAGE_LIMIT so what's in memory matches what's on disk; otherwise
@@ -155,6 +158,65 @@ const insertRoomMessage = (state, roomJID, message, start) => {
155
158
  atHead
156
159
  };
157
160
  };
161
+
162
+ /**
163
+ * Keeps the jump window's separate copy of a message in step with the live
164
+ * list: an echo of a message the reader sees flips it from "sending" to
165
+ * delivered there too, call-log entries collapse per callId, and (only for a
166
+ * live single-message add, `allowAppend`) a reader parked at the LIVE END of
167
+ * a window (hasNewer false) sees what arrives next. While hasNewer is true
168
+ * the window is not adjacent to the tail and the message waits in
169
+ * room.messages until the reader returns to live.
170
+ */
171
+ const syncJumpWindowWithMessage = (state, roomJID, message, start, allowAppend) => {
172
+ const win = state.jumpWindow;
173
+ if (!win || win.roomJID !== roomJID || isCallSignalMessage(message)) {
174
+ return;
175
+ }
176
+ const incomingCallLog = message.callLog;
177
+ if (incomingCallLog?.callId) {
178
+ const wi = win.messages.findIndex(msg => msg.callLog?.callId === incomingCallLog.callId);
179
+ if (wi !== -1) {
180
+ const wExisting = win.messages[wi];
181
+ const wMerged = mergeCallLogEntries(wExisting, message);
182
+ if (wMerged !== wExisting) {
183
+ win.messages[wi] = wMerged;
184
+ }
185
+ return;
186
+ }
187
+ }
188
+ if (win.messages.length === 0) {
189
+ return;
190
+ }
191
+ const isKnownMessage = msg => msg.id === message.id || !!message.xmppId && msg.id === message.xmppId || !!msg.xmppId && msg.xmppId === message.id;
192
+ const wi = win.messages.findIndex(isKnownMessage);
193
+ if (wi !== -1) {
194
+ const prev = win.messages[wi];
195
+ const next = {
196
+ ...prev
197
+ };
198
+ for (const [key, value] of Object.entries(message)) {
199
+ if (value !== undefined && (0, _safeKey.isSafeKey)(key)) {
200
+ next[key] = value;
201
+ }
202
+ }
203
+ // The sender identity captured on first insert wins, as in the live
204
+ // list (the echo parses a different id form).
205
+ next.user = prev.user;
206
+ next.pending = false;
207
+ win.messages[wi] = next;
208
+ } else if (allowAppend && !win.hasNewer && !start) {
209
+ win.messages.push({
210
+ ...message
211
+ });
212
+ if (win.messages.length > JUMP_WINDOW_MAX_MESSAGES) {
213
+ win.messages = win.messages.slice(-JUMP_WINDOW_MAX_MESSAGES);
214
+ const oldest = Number(win.messages[0].id);
215
+ win.olderCursor = Number.isFinite(oldest) ? oldest : win.olderCursor;
216
+ win.hasOlder = true;
217
+ }
218
+ }
219
+ };
158
220
  const capAfterGrowth = (messages, lengthBefore, atHead) => {
159
221
  if (atHead) {
160
222
  enforceMessageCap(messages, RUNTIME_MESSAGE_CEILING);
@@ -176,6 +238,9 @@ const bumpLastMessageTimestamp = (state, roomJID, message) => {
176
238
  }
177
239
  };
178
240
  const upsertRoom = (state, roomData) => {
241
+ if (!(0, _safeKey.isSafeKey)(roomData?.jid)) {
242
+ return;
243
+ }
179
244
  const existing = state.rooms[roomData.jid];
180
245
  let lastViewed;
181
246
  const serverMarker = state.privateStoreMarkers?.[roomData.jid] || 0;
@@ -200,11 +265,17 @@ const upsertRoom = (state, roomData) => {
200
265
  const existingMessages = Array.isArray(existing?.messages) ? existing.messages : [];
201
266
  state.rooms[roomData.jid] = {
202
267
  ...roomData,
268
+ usersCnt: resolveIncomingUsersCnt(roomData, existing),
269
+ // A seed for the room-list preview: take the freshest API value but
270
+ // never let a payload without one erase what is already there.
271
+ lastMessage: roomData.lastMessage ?? existing?.lastMessage,
272
+ ...resolveApiUnread(state, roomData.jid, roomData, existing),
203
273
  icon: roomData.icon !== undefined ? roomData.icon : existing?.icon,
204
274
  roomBg: roomData.roomBg !== undefined ? roomData.roomBg : existing?.roomBg,
205
275
  messages: existingMessages.length > 0 ? existingMessages : incomingMessages,
206
276
  lastViewedTimestamp: lastViewed,
207
- unreadMessages: roomData.unreadMessages ?? existing?.unreadMessages ?? 0,
277
+ // A server-seeded count must not badge a room that is open right now.
278
+ unreadMessages: roomData.apiUnreadCount !== undefined && (state.activeRoomJID === roomData.jid || state.visibleRoomJID === roomData.jid) ? existing?.unreadMessages ?? 0 : roomData.unreadMessages ?? existing?.unreadMessages ?? 0,
208
279
  unreadBaselineTimestamp: existing?.unreadBaselineTimestamp ?? existing?.lastViewedTimestamp ?? roomData.unreadBaselineTimestamp ?? 0
209
280
  };
210
281
  };
@@ -375,6 +446,40 @@ function mergeHistoryIntoCache(existing, fetched) {
375
446
  const merged = collapseCallLogDuplicates(Array.from(byId.values()).sort(byMs));
376
447
  return [...capTail(merged), ...pending];
377
448
  }
449
+
450
+ /** A message found in the archive that the chat cannot show in place. */
451
+
452
+ /** A request to scroll a room's transcript to one message. */
453
+
454
+ /**
455
+ * A short slice of a room's archive around one message, shown INSTEAD of the
456
+ * live list while the reader is away from the tail (a search jump to a message
457
+ * far back). Separate from room.messages on purpose: it is not contiguous with
458
+ * the live history, so it must not touch messageStats or historyComplete.
459
+ * Never persisted.
460
+ */
461
+
462
+ /** The window is trimmed on the far side past this many messages. */
463
+ const JUMP_WINDOW_MAX_MESSAGES = exports.JUMP_WINDOW_MAX_MESSAGES = 300;
464
+ const mergeWindowMessages = (a, b) => {
465
+ const seen = new Set();
466
+ const merged = [];
467
+ for (const message of [...a, ...b]) {
468
+ const key = String(message.id);
469
+ if (seen.has(key)) {
470
+ continue;
471
+ }
472
+ seen.add(key);
473
+ merged.push(message);
474
+ }
475
+ const num = message => {
476
+ const id = Number(message.id);
477
+ return Number.isFinite(id) && id > 0 ? id : new Date(message.date).getTime();
478
+ };
479
+ // Archive ids are microsecond stanza ids and ascending in time; fall back to
480
+ // the date when an id is not numeric.
481
+ return merged.sort((x, y) => num(x) - num(y));
482
+ };
378
483
  const initialState = {
379
484
  rooms: {},
380
485
  activeRoomJID: null,
@@ -389,14 +494,89 @@ const initialState = {
389
494
  },
390
495
  pendingNotificationJid: null,
391
496
  privateStoreMarkers: {},
497
+ pendingJump: null,
498
+ joiningRoomJID: null,
392
499
  readBoundaries: {},
500
+ usersSet: {},
501
+ jumpWindow: null,
502
+ archivedMessage: null,
393
503
  pendingReactions: {}
394
504
  };
395
505
  const isValidRoomJid = jid => {
396
- if (typeof jid !== 'string' || !jid) return false;
397
- if (!jid.includes('@')) return false;
506
+ if (!(0, _safeKey.isSafeKey)(jid)) {
507
+ return false;
508
+ }
509
+ if (!jid.includes('@')) {
510
+ return false;
511
+ }
398
512
  return true;
399
513
  };
514
+
515
+ /**
516
+ * Visits every stored copy of one message: the live copy in
517
+ * state.rooms[jid].messages and, when a jump window is open on that room, the
518
+ * window's separate copy. The window is a second list of the same messages, so
519
+ * every reducer that mutates ONE message must go through this or the reader
520
+ * sees stale edits/reactions/delivery state while away from the live tail.
521
+ * `matches` is an id, or a predicate when a reducer also matches on xmppId.
522
+ */
523
+ const forEachMessageCopy = (state, jid, matches, fn) => {
524
+ const pred = typeof matches === 'function' ? matches : message => message.id === matches;
525
+ const live = state.rooms[jid]?.messages;
526
+ if (Array.isArray(live)) {
527
+ for (const message of live) {
528
+ if (pred(message)) {
529
+ fn(message);
530
+ }
531
+ }
532
+ }
533
+ const win = state.jumpWindow;
534
+ if (win && win.roomJID === jid && Array.isArray(win.messages)) {
535
+ for (const message of win.messages) {
536
+ if (pred(message)) {
537
+ fn(message);
538
+ }
539
+ }
540
+ }
541
+ };
542
+
543
+ /**
544
+ * usersCnt after a /chats/my refresh. The API reports the true total in
545
+ * `usersCnt` but at most 30 `members` for a big room, so the members array
546
+ * length is only a floor; and a count already known (a larger one from an
547
+ * earlier response or a live join) is never lowered by a refresh.
548
+ */
549
+ const resolveIncomingUsersCnt = (incoming, existing) => {
550
+ const apiTotal = typeof incoming.usersCnt === 'number' && incoming.usersCnt > 0 ? incoming.usersCnt : 0;
551
+ const membersLen = Array.isArray(incoming.members) ? incoming.members.length : 0;
552
+ const next = Math.max(apiTotal, membersLen);
553
+ return Math.max(next, existing ? (0, _roomUserCount.getRoomUserCount)(existing) : 0);
554
+ };
555
+
556
+ /**
557
+ * The server-reported unread snapshot of a room after an incoming /chats/my
558
+ * item: the freshest API value wins while the user is not looking at the
559
+ * room; one being read right now keeps none. Absent from the response =
560
+ * keep what an earlier, richer response set.
561
+ */
562
+ const resolveApiUnread = (state, jid, incoming, existing) => {
563
+ if (state.activeRoomJID === jid || state.visibleRoomJID === jid) {
564
+ return {
565
+ apiUnreadCount: undefined,
566
+ apiUnreadSeededAt: undefined
567
+ };
568
+ }
569
+ if (incoming.apiUnreadCount !== undefined) {
570
+ return {
571
+ apiUnreadCount: incoming.apiUnreadCount,
572
+ apiUnreadSeededAt: incoming.apiUnreadSeededAt ?? Date.now()
573
+ };
574
+ }
575
+ return {
576
+ apiUnreadCount: existing?.apiUnreadCount,
577
+ apiUnreadSeededAt: existing?.apiUnreadSeededAt
578
+ };
579
+ };
400
580
  const addRoomViaApi = exports.addRoomViaApi = (0, _toolkit.createAsyncThunk)('roomMessages/addRoomViaApi', async ({
401
581
  room,
402
582
  xmpp
@@ -449,6 +629,9 @@ const reducers = {
449
629
  const {
450
630
  jid
451
631
  } = action.payload;
632
+ if (!(0, _safeKey.isSafeKey)(jid)) {
633
+ return;
634
+ }
452
635
  if (state.rooms[jid]) {
453
636
  delete state.rooms[jid];
454
637
  if (state.visibleRoomJID === jid) {
@@ -461,19 +644,40 @@ const reducers = {
461
644
  jid,
462
645
  updates
463
646
  } = action.payload;
647
+ if (!(0, _safeKey.isSafeKey)(jid)) {
648
+ return;
649
+ }
464
650
  const existingRoom = state.rooms[jid];
465
- if (existingRoom) {
466
- state.rooms[jid] = {
467
- ...existingRoom,
468
- ...updates
469
- };
651
+ if (!existingRoom) {
652
+ return;
470
653
  }
654
+ const merged = {
655
+ ...existingRoom,
656
+ ...updates
657
+ };
658
+ if (typeof updates.usersCnt === 'number') {
659
+ // An explicit count (a live join or leave) is taken as given, with the
660
+ // known members as a floor.
661
+ const newMembers = Array.isArray(updates.members) ? updates.members : existingRoom.members;
662
+ const floor = Array.isArray(newMembers) ? newMembers.length : 0;
663
+ merged.usersCnt = Math.max(updates.usersCnt, floor);
664
+ } else if (Array.isArray(updates.members)) {
665
+ // A members-only refresh of a truncated big room (usersCnt > the
666
+ // first page) must not collapse the true total to the page length.
667
+ const prevMembers = Array.isArray(existingRoom.members) ? existingRoom.members.length : 0;
668
+ const prevCnt = typeof existingRoom.usersCnt === 'number' ? existingRoom.usersCnt : 0;
669
+ merged.usersCnt = prevCnt > prevMembers ? Math.max(prevCnt, updates.members.length) : updates.members.length;
670
+ }
671
+ state.rooms[jid] = merged;
471
672
  },
472
673
  setRoomMessages(state, action) {
473
674
  const {
474
675
  roomJID,
475
676
  messages
476
677
  } = action.payload;
678
+ if (!(0, _safeKey.isSafeKey)(roomJID)) {
679
+ return;
680
+ }
477
681
  if (state.rooms[roomJID]) {
478
682
  // Cap to the runtime limit on replace too — guards against a
479
683
  // single MAM page returning more than the limit (would balloon
@@ -487,6 +691,9 @@ const reducers = {
487
691
  roomJID,
488
692
  messageId
489
693
  } = action.payload;
694
+ if (!(0, _safeKey.isSafeKey)(roomJID)) {
695
+ return;
696
+ }
490
697
  const room = state.rooms[roomJID];
491
698
  if (!room?.messages) {
492
699
  return;
@@ -503,11 +710,9 @@ const reducers = {
503
710
  }
504
711
  return;
505
712
  }
506
- room.messages.map(message => {
507
- if (message.id === messageId) {
508
- message.isDeleted = true;
509
- message.reaction = undefined;
510
- }
713
+ forEachMessageCopy(state, roomJID, messageId, message => {
714
+ message.isDeleted = true;
715
+ message.reaction = undefined;
511
716
  });
512
717
  },
513
718
  setEditAction: (state, action) => {
@@ -528,30 +733,77 @@ const reducers = {
528
733
  messageId,
529
734
  text
530
735
  } = action.payload;
531
- if (state.rooms[roomJID]) {
532
- state.rooms[roomJID].messages.map(message => {
533
- if (message.id === messageId) {
534
- message.body = text;
535
- // Flag the correction so the bubble can render an "edited" marker.
536
- // Covers both the author's own edit and edits from other users —
537
- // every <replace> echo flows through here.
538
- message.isEdited = true;
539
- }
540
- });
736
+ if (!(0, _safeKey.isSafeKey)(roomJID)) {
737
+ return;
738
+ }
739
+ // Edited in place on every copy (live list and jump window).
740
+ forEachMessageCopy(state, roomJID, messageId, message => {
741
+ message.body = text;
742
+ // Flag the correction so the bubble can render an "edited" marker.
743
+ // Covers both the author's own edit and edits from other users -
744
+ // every <replace> echo flows through here.
745
+ message.isEdited = true;
746
+ });
747
+ },
748
+ /**
749
+ * Hard removal, unlike `deleteRoomMessage`'s tombstone. For optimistic
750
+ * messages that never made it onto the wire.
751
+ */
752
+ removeRoomMessage(state, action) {
753
+ const {
754
+ roomJID,
755
+ messageId
756
+ } = action.payload;
757
+ if (!(0, _safeKey.isSafeKey)(roomJID)) {
758
+ return;
759
+ }
760
+ if (state.rooms[roomJID]?.messages) {
761
+ state.rooms[roomJID].messages = state.rooms[roomJID].messages.filter(message => message.id !== messageId);
762
+ }
763
+ const win = state.jumpWindow;
764
+ if (win && win.roomJID === roomJID) {
765
+ win.messages = win.messages.filter(message => message.id !== messageId);
541
766
  }
542
767
  },
768
+ /**
769
+ * Caches one translation onto the message it belongs to, keyed by the
770
+ * locale tag the translate service echoed back. Applied to the live
771
+ * copy and the jump window's copy.
772
+ */
773
+ setMessageTranslation(state, action) {
774
+ const {
775
+ roomJID,
776
+ messageId,
777
+ locale,
778
+ entry
779
+ } = action.payload;
780
+ if (!(0, _safeKey.isSafeKey)(roomJID) || !(0, _safeKey.isSafeKey)(locale)) {
781
+ return;
782
+ }
783
+ forEachMessageCopy(state, roomJID, messageId, message => {
784
+ if (!message.translations) {
785
+ message.translations = {};
786
+ }
787
+ message.translations[locale] = entry;
788
+ });
789
+ },
543
790
  addRoomMessage(state, action) {
544
791
  const {
545
792
  roomJID,
546
793
  message,
547
794
  start
548
795
  } = action.payload;
796
+ if (!(0, _safeKey.isSafeKey)(roomJID)) {
797
+ return;
798
+ }
549
799
  const lengthBefore = state.rooms[roomJID]?.messages?.length || 0;
550
800
  const outcome = insertRoomMessage(state, roomJID, message, start);
551
801
  if (outcome.grew) {
552
802
  capAfterGrowth(state.rooms[roomJID].messages, lengthBefore, outcome.atHead);
553
803
  }
554
804
  bumpLastMessageTimestamp(state, roomJID, message);
805
+ // Keep the jump window's copy in step with the live list.
806
+ syncJumpWindowWithMessage(state, roomJID, message, start, true);
555
807
  },
556
808
  /**
557
809
  * A whole page of messages (a MAM history page) in ONE action: the same
@@ -565,7 +817,7 @@ const reducers = {
565
817
  messages,
566
818
  start
567
819
  } = action.payload;
568
- if (!state.rooms[roomJID] || !Array.isArray(messages)) {
820
+ if (!(0, _safeKey.isSafeKey)(roomJID) || !state.rooms[roomJID] || !Array.isArray(messages)) {
569
821
  return;
570
822
  }
571
823
  const lengthBefore = state.rooms[roomJID].messages?.length || 0;
@@ -583,6 +835,9 @@ const reducers = {
583
835
  if (!newest || Number(message?.id) > Number(newest.id)) {
584
836
  newest = message;
585
837
  }
838
+ // History pages never append to a reader's jump window (they are not
839
+ // "the newest message"); they only refresh copies it already holds.
840
+ syncJumpWindowWithMessage(state, roomJID, message, start, false);
586
841
  }
587
842
  if (grew) {
588
843
  // A page that only prepended older history is never trimmed.
@@ -594,6 +849,7 @@ const reducers = {
594
849
  },
595
850
  deleteAllRooms(state) {
596
851
  state.rooms = {};
852
+ state.jumpWindow = null;
597
853
  state.visibleRoomJID = null;
598
854
  state.privateStoreMarkers = {};
599
855
  state.readBoundaries = {};
@@ -605,6 +861,9 @@ const reducers = {
605
861
  composing,
606
862
  composingList
607
863
  } = action.payload;
864
+ if (!(0, _safeKey.isSafeKey)(chatJID) || !state.rooms[chatJID]) {
865
+ return;
866
+ }
608
867
  state.rooms[chatJID].composing = composing;
609
868
  state.rooms[chatJID].composingList = composingList;
610
869
  },
@@ -614,7 +873,7 @@ const reducers = {
614
873
  loading,
615
874
  loadingText
616
875
  } = action.payload;
617
- if (chatJID && state.rooms?.[chatJID]) {
876
+ if ((0, _safeKey.isSafeKey)(chatJID) && state.rooms?.[chatJID]) {
618
877
  state.rooms[chatJID].isLoading = loading;
619
878
  }
620
879
  state.isLoading = loading;
@@ -628,7 +887,7 @@ const reducers = {
628
887
  chatJID,
629
888
  timestamp
630
889
  } = action.payload;
631
- if (state.rooms[chatJID]) {
890
+ if ((0, _safeKey.isSafeKey)(chatJID) && state.rooms[chatJID]) {
632
891
  state.rooms[chatJID].lastViewedTimestamp = timestamp;
633
892
  // A non-positive timestamp means "no persisted marker yet" and
634
893
  // must not inflate unread from history that predates the first
@@ -679,7 +938,7 @@ const reducers = {
679
938
  }
680
939
  for (const jid of Object.keys(markers)) {
681
940
  const ts = Number(markers[jid]);
682
- if (!jid || !Number.isFinite(ts) || ts <= 0) {
941
+ if (!(0, _safeKey.isSafeKey)(jid) || !Number.isFinite(ts) || ts <= 0) {
683
942
  continue;
684
943
  }
685
944
  const room = state.rooms[jid];
@@ -723,7 +982,7 @@ const reducers = {
723
982
  jid,
724
983
  ts
725
984
  } = action.payload;
726
- if (!jid) {
985
+ if (!(0, _safeKey.isSafeKey)(jid)) {
727
986
  return;
728
987
  }
729
988
  if (!state.readBoundaries) {
@@ -745,7 +1004,7 @@ const reducers = {
745
1004
  const {
746
1005
  jid
747
1006
  } = action.payload;
748
- if (jid && state.readBoundaries) {
1007
+ if ((0, _safeKey.isSafeKey)(jid) && state.readBoundaries) {
749
1008
  delete state.readBoundaries[jid];
750
1009
  }
751
1010
  },
@@ -754,7 +1013,7 @@ const reducers = {
754
1013
  chatJID,
755
1014
  role
756
1015
  } = action.payload;
757
- if (state.rooms[chatJID]) {
1016
+ if ((0, _safeKey.isSafeKey)(chatJID) && state.rooms[chatJID]) {
758
1017
  state.rooms[chatJID].role = role;
759
1018
  }
760
1019
  },
@@ -763,20 +1022,40 @@ const reducers = {
763
1022
  value,
764
1023
  chatJID
765
1024
  } = action.payload;
766
- if (chatJID) {
1025
+ if ((0, _safeKey.isSafeKey)(chatJID) && state.rooms[chatJID]) {
767
1026
  state.rooms[chatJID].noMessages = value;
768
1027
  }
769
1028
  },
770
1029
  setCurrentRoom: (state, action) => {
771
1030
  // Accept null/empty so callers can clear the active room (e.g.
772
1031
  // back button from chat → return to RoomList). Mirrors web.
773
- state.activeRoomJID = action.payload.roomJID || '';
1032
+ const {
1033
+ roomJID
1034
+ } = action.payload;
1035
+ if (roomJID && !(0, _safeKey.isSafeKey)(roomJID)) {
1036
+ return;
1037
+ }
1038
+ state.activeRoomJID = roomJID || '';
1039
+ // Opening a room reads it: the server's earlier unread count no longer
1040
+ // applies (the unread middleware would otherwise bring it back the
1041
+ // moment the user leaves the room again).
1042
+ if (roomJID && state.rooms[roomJID]?.apiUnreadCount !== undefined) {
1043
+ state.rooms[roomJID].apiUnreadCount = undefined;
1044
+ state.rooms[roomJID].apiUnreadSeededAt = undefined;
1045
+ state.rooms[roomJID].unreadMessages = 0;
1046
+ }
774
1047
  },
775
1048
  setVisibleRoom: (state, action) => {
776
- state.visibleRoomJID = action.payload.roomJID || null;
1049
+ const requested = action.payload.roomJID;
1050
+ if (requested && !(0, _safeKey.isSafeKey)(requested)) {
1051
+ return;
1052
+ }
1053
+ state.visibleRoomJID = requested || null;
777
1054
  const jid = state.visibleRoomJID;
778
1055
  if (jid && state.rooms[jid]) {
779
1056
  state.rooms[jid].unreadMessages = 0;
1057
+ state.rooms[jid].apiUnreadCount = undefined;
1058
+ state.rooms[jid].apiUnreadSeededAt = undefined;
780
1059
  }
781
1060
  },
782
1061
  clearVisibleRoom: state => {
@@ -799,6 +1078,81 @@ const reducers = {
799
1078
  clearPendingNotificationJid: state => {
800
1079
  state.pendingNotificationJid = null;
801
1080
  },
1081
+ requestJumpToMessage: (state, action) => {
1082
+ const ids = action.payload.ids.filter(Boolean);
1083
+ const canMatchByContent = Boolean(action.payload.createdAt && action.payload.body);
1084
+ if (!action.payload.roomJID || ids.length === 0 && !canMatchByContent) {
1085
+ return;
1086
+ }
1087
+ state.pendingJump = {
1088
+ roomJID: action.payload.roomJID,
1089
+ ids,
1090
+ createdAt: action.payload.createdAt,
1091
+ body: action.payload.body,
1092
+ preview: action.payload.preview,
1093
+ at: Date.now()
1094
+ };
1095
+ },
1096
+ clearPendingJump: state => {
1097
+ state.pendingJump = null;
1098
+ },
1099
+ showArchivedMessage: (state, action) => {
1100
+ state.archivedMessage = action.payload;
1101
+ },
1102
+ clearArchivedMessage: state => {
1103
+ state.archivedMessage = null;
1104
+ },
1105
+ setJumpWindow: (state, action) => {
1106
+ state.jumpWindow = {
1107
+ ...action.payload,
1108
+ messages: mergeWindowMessages(action.payload.messages, [])
1109
+ };
1110
+ },
1111
+ prependJumpWindowMessages: (state, action) => {
1112
+ const win = state.jumpWindow;
1113
+ if (!win || win.roomJID !== action.payload.roomJID) {
1114
+ return;
1115
+ }
1116
+ win.messages = mergeWindowMessages(action.payload.messages, win.messages);
1117
+ win.olderCursor = action.payload.olderCursor;
1118
+ win.hasOlder = action.payload.hasOlder;
1119
+ if (win.messages.length > JUMP_WINDOW_MAX_MESSAGES) {
1120
+ // Reader is going up: drop the far (newest) side and page it again if
1121
+ // they come back down.
1122
+ win.messages = win.messages.slice(0, JUMP_WINDOW_MAX_MESSAGES);
1123
+ const newest = Number(win.messages[win.messages.length - 1].id);
1124
+ win.newerCursor = Number.isFinite(newest) ? newest : win.newerCursor;
1125
+ win.hasNewer = true;
1126
+ }
1127
+ },
1128
+ appendJumpWindowMessages: (state, action) => {
1129
+ const win = state.jumpWindow;
1130
+ if (!win || win.roomJID !== action.payload.roomJID) {
1131
+ return;
1132
+ }
1133
+ win.messages = mergeWindowMessages(win.messages, action.payload.messages);
1134
+ win.newerCursor = action.payload.newerCursor;
1135
+ win.hasNewer = action.payload.hasNewer;
1136
+ if (win.messages.length > JUMP_WINDOW_MAX_MESSAGES) {
1137
+ win.messages = win.messages.slice(-JUMP_WINDOW_MAX_MESSAGES);
1138
+ const oldest = Number(win.messages[0].id);
1139
+ win.olderCursor = Number.isFinite(oldest) ? oldest : win.olderCursor;
1140
+ win.hasOlder = true;
1141
+ }
1142
+ },
1143
+ clearJumpWindow: state => {
1144
+ state.jumpWindow = null;
1145
+ },
1146
+ setJoiningRoom: (state, action) => {
1147
+ state.joiningRoomJID = action.payload || null;
1148
+ },
1149
+ // Only clears when it still names that room, so a slow join for a room
1150
+ // the user already left cannot wipe the join of the current one.
1151
+ clearJoiningRoom: (state, action) => {
1152
+ if (state.joiningRoomJID === action.payload) {
1153
+ state.joiningRoomJID = null;
1154
+ }
1155
+ },
802
1156
  /**
803
1157
  * Stamp a message in `state.rooms[roomJID].messages` with an updated
804
1158
  * reactions list. The reactionsMiddleware listens for this action to
@@ -813,13 +1167,21 @@ const reducers = {
813
1167
  data,
814
1168
  latestReactionTimestamp
815
1169
  } = action.payload;
816
- if (!from) {
1170
+ if (!(0, _safeKey.isSafeKey)(roomJID) || !from) {
817
1171
  return;
818
1172
  }
819
- const room = state.rooms[roomJID];
820
- const target = room?.messages?.find(msg => msg?.id === messageId || msg?.xmppId === messageId);
821
- if (target) {
822
- applyReactionToMessage(target, from, reactions, data, latestReactionTimestamp);
1173
+ // `fromId` becomes a property name on the message's reaction map.
1174
+ const fromId = String(from).split('/')[0].split('@')[0];
1175
+ if (!(0, _safeKey.isSafeKey)(fromId)) {
1176
+ return;
1177
+ }
1178
+ let found = false;
1179
+ // Applied on every stored copy (live list and jump window).
1180
+ forEachMessageCopy(state, roomJID, msg => msg?.id === messageId || msg?.xmppId === messageId, message => {
1181
+ found = true;
1182
+ applyReactionToMessage(message, from, reactions, data, latestReactionTimestamp);
1183
+ });
1184
+ if (found) {
823
1185
  return;
824
1186
  }
825
1187
  // The message is not loaded (yet): keep the reaction for it.
@@ -846,27 +1208,42 @@ const reducers = {
846
1208
  state.isUnreadSyncing = false;
847
1209
  state.privateStoreMarkers = {};
848
1210
  state.readBoundaries = {};
1211
+ state.usersSet = {};
1212
+ state.jumpWindow = null;
1213
+ state.archivedMessage = null;
1214
+ state.pendingJump = null;
849
1215
  },
850
1216
  setActiveMessage: (state, action) => {
851
1217
  const {
852
1218
  id,
853
1219
  chatJID
854
1220
  } = action.payload;
855
- state.rooms[chatJID].messages.map(message => {
856
- if (message.id === id) {
857
- message.activeMessage = true;
858
- } else {
859
- message.activeMessage = false;
860
- }
861
- });
1221
+ if (!(0, _safeKey.isSafeKey)(chatJID) || !state.rooms[chatJID]) {
1222
+ return;
1223
+ }
1224
+ const flag = message => {
1225
+ message.activeMessage = message.id === id;
1226
+ };
1227
+ state.rooms[chatJID].messages.forEach(flag);
1228
+ if (state.jumpWindow?.roomJID === chatJID) {
1229
+ state.jumpWindow.messages.forEach(flag);
1230
+ }
862
1231
  },
863
1232
  setCloseActiveMessage: (state, action) => {
864
1233
  const {
865
1234
  chatJID
866
1235
  } = action.payload;
867
- state.rooms[chatJID].messages.map(message => {
1236
+ if (!(0, _safeKey.isSafeKey)(chatJID) || !state.rooms[chatJID]) {
1237
+ return;
1238
+ }
1239
+ state.rooms[chatJID].messages.forEach(message => {
868
1240
  message.activeMessage = false;
869
1241
  });
1242
+ if (state.jumpWindow?.roomJID === chatJID) {
1243
+ state.jumpWindow.messages.forEach(message => {
1244
+ message.activeMessage = false;
1245
+ });
1246
+ }
870
1247
  },
871
1248
  /**
872
1249
  * Batched update used by the history preload scheduler. Each patch is
@@ -885,15 +1262,14 @@ const reducers = {
885
1262
  ...existing,
886
1263
  ...room,
887
1264
  title: room.title || existing?.title || room.title,
888
- usersCnt: (() => {
889
- const incoming = typeof room.usersCnt === 'number' && room.usersCnt > 0 ? room.usersCnt : 0;
890
- const previous = typeof existing?.usersCnt === 'number' && existing.usersCnt > 0 ? existing.usersCnt : 0;
891
- if (incoming === 0 && previous === 0) return room.usersCnt;
892
- return Math.max(incoming, previous);
893
- })(),
1265
+ usersCnt: resolveIncomingUsersCnt(room, existing),
894
1266
  icon: room.icon ?? existing?.icon,
895
1267
  messages: existingMessages.length > 0 ? existingMessages : incomingMessages,
1268
+ // A seed for the room-list preview (the API's `lastMessage`): take the
1269
+ // freshest value, never let a refresh without one erase it.
1270
+ lastMessage: room.lastMessage ?? existing?.lastMessage,
896
1271
  unreadMessages: existing?.unreadMessages ?? room.unreadMessages ?? 0,
1272
+ ...resolveApiUnread(state, room.jid, room, existing),
897
1273
  lastViewedTimestamp: existing?.lastViewedTimestamp ?? room.lastViewedTimestamp ?? 0,
898
1274
  unreadBaselineTimestamp: existing?.unreadBaselineTimestamp ?? existing?.lastViewedTimestamp ?? room.unreadBaselineTimestamp ?? room.lastViewedTimestamp ?? 0,
899
1275
  composingList: existing?.composingList ?? room.composingList,
@@ -909,8 +1285,11 @@ const reducers = {
909
1285
  rooms
910
1286
  } = action.payload;
911
1287
  for (const patch of rooms) {
1288
+ if (!(0, _safeKey.isSafeKey)(patch?.jid)) {
1289
+ continue;
1290
+ }
912
1291
  const room = state.rooms[patch.jid];
913
- if (!room) {
1292
+ if (!room || typeof room !== 'object' || Array.isArray(room)) {
914
1293
  continue;
915
1294
  }
916
1295
  if (typeof patch.historyPreloadState !== 'undefined') {
@@ -922,6 +1301,12 @@ const reducers = {
922
1301
  if (typeof patch.historyComplete !== 'undefined') {
923
1302
  room.historyComplete = patch.historyComplete;
924
1303
  }
1304
+ if (patch.messageStats) {
1305
+ room.messageStats = {
1306
+ ...room.messageStats,
1307
+ ...patch.messageStats
1308
+ };
1309
+ }
925
1310
  if (Array.isArray(patch.messages)) {
926
1311
  for (const m of patch.messages) {
927
1312
  takePendingReactions(state, patch.jid, m);
@@ -939,10 +1324,13 @@ const reducers = {
939
1324
  // part and the full jid so either lookup style hits — a message's
940
1325
  // `user.id` can be either depending on how it was parsed.
941
1326
  mergeUsersSet(state, action) {
942
- state.usersSet = {
943
- ...(state.usersSet || {}),
944
- ...action.payload.members
945
- };
1327
+ // A real merge with a cap: fresh entries win (and move to the newest
1328
+ // position), entries fetched lazily earlier stay, the oldest-inserted
1329
+ // are evicted past USERS_SET_CAP. Unsafe keys are skipped.
1330
+ if (!state.usersSet || typeof state.usersSet !== 'object') {
1331
+ state.usersSet = {};
1332
+ }
1333
+ (0, _usersSetCap.mergeUsersSet)(state.usersSet, action.payload?.members || {});
946
1334
  }
947
1335
  };
948
1336
  const roomsStore = exports.roomsStore = (0, _toolkit.createSlice)({
@@ -1062,11 +1450,37 @@ const {
1062
1450
  setUnreadCounts,
1063
1451
  setPendingNotificationJid,
1064
1452
  clearPendingNotificationJid,
1453
+ requestJumpToMessage,
1454
+ clearPendingJump,
1455
+ setJoiningRoom,
1456
+ clearJoiningRoom,
1065
1457
  setReactions,
1066
- mergeUsersSet
1458
+ mergeUsersSet,
1459
+ removeRoomMessage,
1460
+ addRoomFromApi,
1461
+ setMessageTranslation,
1462
+ showArchivedMessage,
1463
+ clearArchivedMessage,
1464
+ setJumpWindow,
1465
+ prependJumpWindowMessages,
1466
+ appendJumpWindowMessages,
1467
+ clearJumpWindow
1067
1468
  } = roomsStore.actions;
1469
+ exports.clearJumpWindow = clearJumpWindow;
1470
+ exports.appendJumpWindowMessages = appendJumpWindowMessages;
1471
+ exports.prependJumpWindowMessages = prependJumpWindowMessages;
1472
+ exports.setJumpWindow = setJumpWindow;
1473
+ exports.clearArchivedMessage = clearArchivedMessage;
1474
+ exports.showArchivedMessage = showArchivedMessage;
1475
+ exports.setMessageTranslation = setMessageTranslation;
1476
+ exports.addRoomFromApi = addRoomFromApi;
1477
+ exports.removeRoomMessage = removeRoomMessage;
1068
1478
  exports.mergeUsersSet = mergeUsersSet;
1069
1479
  exports.setReactions = setReactions;
1480
+ exports.clearJoiningRoom = clearJoiningRoom;
1481
+ exports.setJoiningRoom = setJoiningRoom;
1482
+ exports.clearPendingJump = clearPendingJump;
1483
+ exports.requestJumpToMessage = requestJumpToMessage;
1070
1484
  exports.clearPendingNotificationJid = clearPendingNotificationJid;
1071
1485
  exports.setPendingNotificationJid = setPendingNotificationJid;
1072
1486
  exports.setUnreadCounts = setUnreadCounts;