@ethora/chat-component-rn 26.9.1 → 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 (760) hide show
  1. package/CHANGELOG.md +30 -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 +31 -1
  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 +41 -77
  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 +288 -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 +31 -1
  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 +42 -78
  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 +288 -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.map +1 -1
  505. package/lib/typescript/helpers/audioWaveform.d.ts +54 -0
  506. package/lib/typescript/helpers/audioWaveform.d.ts.map +1 -0
  507. package/lib/typescript/helpers/backgroundJoinSweep.d.ts +14 -0
  508. package/lib/typescript/helpers/backgroundJoinSweep.d.ts.map +1 -0
  509. package/lib/typescript/helpers/bubbleHighlight.d.ts +17 -0
  510. package/lib/typescript/helpers/bubbleHighlight.d.ts.map +1 -0
  511. package/lib/typescript/helpers/checkUniqueUsers.d.ts +2 -2
  512. package/lib/typescript/helpers/checkUniqueUsers.d.ts.map +1 -1
  513. package/lib/typescript/helpers/constants/MODAL_COMPONENTS.d.ts.map +1 -1
  514. package/lib/typescript/helpers/constants/MODAL_TYPES.d.ts +2 -0
  515. package/lib/typescript/helpers/constants/MODAL_TYPES.d.ts.map +1 -1
  516. package/lib/typescript/helpers/createRoomFromApi.d.ts +25 -0
  517. package/lib/typescript/helpers/createRoomFromApi.d.ts.map +1 -1
  518. package/lib/typescript/helpers/dedupeMembers.d.ts +11 -0
  519. package/lib/typescript/helpers/dedupeMembers.d.ts.map +1 -0
  520. package/lib/typescript/helpers/ethoraLogger.d.ts +13 -0
  521. package/lib/typescript/helpers/ethoraLogger.d.ts.map +1 -0
  522. package/lib/typescript/helpers/getUnnamedUsers.d.ts.map +1 -1
  523. package/lib/typescript/helpers/historyPreloadConfig.d.ts +26 -0
  524. package/lib/typescript/helpers/historyPreloadConfig.d.ts.map +1 -0
  525. package/lib/typescript/helpers/historyPreloadScheduler.d.ts +8 -4
  526. package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
  527. package/lib/typescript/helpers/initRoomsPresence.d.ts +7 -0
  528. package/lib/typescript/helpers/initRoomsPresence.d.ts.map +1 -1
  529. package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
  530. package/lib/typescript/helpers/isLikelyMucJid.d.ts +19 -0
  531. package/lib/typescript/helpers/isLikelyMucJid.d.ts.map +1 -0
  532. package/lib/typescript/helpers/isMessageSearchEnabled.d.ts +12 -0
  533. package/lib/typescript/helpers/isMessageSearchEnabled.d.ts.map +1 -0
  534. package/lib/typescript/helpers/joiningRoom.d.ts +7 -0
  535. package/lib/typescript/helpers/joiningRoom.d.ts.map +1 -0
  536. package/lib/typescript/helpers/jumpThread.d.ts +48 -0
  537. package/lib/typescript/helpers/jumpThread.d.ts.map +1 -0
  538. package/lib/typescript/helpers/jumpToMessage.d.ts +26 -0
  539. package/lib/typescript/helpers/jumpToMessage.d.ts.map +1 -0
  540. package/lib/typescript/helpers/jumpWindow.d.ts +74 -0
  541. package/lib/typescript/helpers/jumpWindow.d.ts.map +1 -0
  542. package/lib/typescript/helpers/loadRoomHistory.d.ts +34 -0
  543. package/lib/typescript/helpers/loadRoomHistory.d.ts.map +1 -0
  544. package/lib/typescript/helpers/notificationPolicy.d.ts +42 -0
  545. package/lib/typescript/helpers/notificationPolicy.d.ts.map +1 -0
  546. package/lib/typescript/helpers/openRoomAtMessage.d.ts +17 -0
  547. package/lib/typescript/helpers/openRoomAtMessage.d.ts.map +1 -0
  548. package/lib/typescript/helpers/openThreadForJump.d.ts +27 -0
  549. package/lib/typescript/helpers/openThreadForJump.d.ts.map +1 -0
  550. package/lib/typescript/helpers/parseMessageReference.d.ts +18 -5
  551. package/lib/typescript/helpers/parseMessageReference.d.ts.map +1 -1
  552. package/lib/typescript/helpers/publicChatsEntry.d.ts +11 -0
  553. package/lib/typescript/helpers/publicChatsEntry.d.ts.map +1 -0
  554. package/lib/typescript/helpers/roomActivityScore.d.ts +5 -0
  555. package/lib/typescript/helpers/roomActivityScore.d.ts.map +1 -0
  556. package/lib/typescript/helpers/roomUserCount.d.ts +20 -0
  557. package/lib/typescript/helpers/roomUserCount.d.ts.map +1 -0
  558. package/lib/typescript/helpers/runConfiguredHistoryPreload.d.ts +21 -0
  559. package/lib/typescript/helpers/runConfiguredHistoryPreload.d.ts.map +1 -0
  560. package/lib/typescript/helpers/sessionAppId.d.ts +8 -0
  561. package/lib/typescript/helpers/sessionAppId.d.ts.map +1 -0
  562. package/lib/typescript/helpers/timestamp.d.ts +3 -0
  563. package/lib/typescript/helpers/timestamp.d.ts.map +1 -0
  564. package/lib/typescript/helpers/userResolver.d.ts +58 -0
  565. package/lib/typescript/helpers/userResolver.d.ts.map +1 -0
  566. package/lib/typescript/helpers/xmppIdShape.d.ts +10 -0
  567. package/lib/typescript/helpers/xmppIdShape.d.ts.map +1 -0
  568. package/lib/typescript/hooks/useChatWrapperInit.d.ts +2 -0
  569. package/lib/typescript/hooks/useChatWrapperInit.d.ts.map +1 -1
  570. package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
  571. package/lib/typescript/hooks/useJumpToMessage.d.ts +116 -0
  572. package/lib/typescript/hooks/useJumpToMessage.d.ts.map +1 -0
  573. package/lib/typescript/hooks/useMessageLoaderQueue.d.ts.map +1 -1
  574. package/lib/typescript/hooks/useMessageQueue.d.ts.map +1 -1
  575. package/lib/typescript/hooks/useRoomDirectory.d.ts +12 -0
  576. package/lib/typescript/hooks/useRoomDirectory.d.ts.map +1 -0
  577. package/lib/typescript/hooks/useRoomInitialization.d.ts.map +1 -1
  578. package/lib/typescript/hooks/useRoomMute.d.ts +8 -0
  579. package/lib/typescript/hooks/useRoomMute.d.ts.map +1 -0
  580. package/lib/typescript/hooks/useRoomState.d.ts +1 -0
  581. package/lib/typescript/hooks/useRoomState.d.ts.map +1 -1
  582. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  583. package/lib/typescript/i18n/strings.d.ts.map +1 -1
  584. package/lib/typescript/networking/api-requests/messageSearch.api.d.ts +57 -0
  585. package/lib/typescript/networking/api-requests/messageSearch.api.d.ts.map +1 -0
  586. package/lib/typescript/networking/api-requests/publicChats.api.d.ts +24 -0
  587. package/lib/typescript/networking/api-requests/publicChats.api.d.ts.map +1 -0
  588. package/lib/typescript/networking/api-requests/roomMembers.api.d.ts +19 -1
  589. package/lib/typescript/networking/api-requests/roomMembers.api.d.ts.map +1 -1
  590. package/lib/typescript/networking/api-requests/rooms.api.d.ts.map +1 -1
  591. package/lib/typescript/networking/api-requests/xmppToken.api.d.ts +2 -0
  592. package/lib/typescript/networking/api-requests/xmppToken.api.d.ts.map +1 -0
  593. package/lib/typescript/networking/ethoraEvents.d.ts +45 -0
  594. package/lib/typescript/networking/ethoraEvents.d.ts.map +1 -0
  595. package/lib/typescript/networking/stanzaHandlers.d.ts +1 -1
  596. package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
  597. package/lib/typescript/networking/xmpp/allRoomPresences.xmpp.d.ts +32 -1
  598. package/lib/typescript/networking/xmpp/allRoomPresences.xmpp.d.ts.map +1 -1
  599. package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts +64 -0
  600. package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts.map +1 -1
  601. package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
  602. package/lib/typescript/networking/xmpp/historyCursor.d.ts +35 -0
  603. package/lib/typescript/networking/xmpp/historyCursor.d.ts.map +1 -0
  604. package/lib/typescript/networking/xmpp/mamQueryIds.d.ts +10 -0
  605. package/lib/typescript/networking/xmpp/mamQueryIds.d.ts.map +1 -0
  606. package/lib/typescript/networking/xmpp/mamRouter.d.ts +7 -0
  607. package/lib/typescript/networking/xmpp/mamRouter.d.ts.map +1 -1
  608. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts +13 -2
  609. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
  610. package/lib/typescript/networking/xmpp/roomJoinSweep.d.ts +82 -0
  611. package/lib/typescript/networking/xmpp/roomJoinSweep.d.ts.map +1 -0
  612. package/lib/typescript/networking/xmpp/sendMediaMessage.xmpp.d.ts.map +1 -1
  613. package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts.map +1 -1
  614. package/lib/typescript/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts.map +1 -1
  615. package/lib/typescript/networking/xmppClient.d.ts +90 -4
  616. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  617. package/lib/typescript/networking/xmppCredentials.d.ts +12 -0
  618. package/lib/typescript/networking/xmppCredentials.d.ts.map +1 -0
  619. package/lib/typescript/roomStore/Middleware/jumpThreadMiddleware.d.ts +3 -0
  620. package/lib/typescript/roomStore/Middleware/jumpThreadMiddleware.d.ts.map +1 -0
  621. package/lib/typescript/roomStore/Middleware/reactionsMiddleware.d.ts.map +1 -1
  622. package/lib/typescript/roomStore/Middleware/unreadMidlleware.d.ts.map +1 -1
  623. package/lib/typescript/roomStore/chatSettingsSlice.d.ts +8 -1
  624. package/lib/typescript/roomStore/chatSettingsSlice.d.ts.map +1 -1
  625. package/lib/typescript/roomStore/index.d.ts +2 -1
  626. package/lib/typescript/roomStore/index.d.ts.map +1 -1
  627. package/lib/typescript/roomStore/persistence.d.ts +8 -0
  628. package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
  629. package/lib/typescript/roomStore/roomsSlice.d.ts +138 -2
  630. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  631. package/lib/typescript/roomStore/safeKey.d.ts +13 -0
  632. package/lib/typescript/roomStore/safeKey.d.ts.map +1 -0
  633. package/lib/typescript/roomStore/usersSetCap.d.ts +16 -0
  634. package/lib/typescript/roomStore/usersSetCap.d.ts.map +1 -0
  635. package/lib/typescript/types/models/media.model.d.ts +2 -0
  636. package/lib/typescript/types/models/media.model.d.ts.map +1 -1
  637. package/lib/typescript/types/models/room.model.d.ts +18 -5
  638. package/lib/typescript/types/models/room.model.d.ts.map +1 -1
  639. package/lib/typescript/types/models/xmpp.model.d.ts +8 -1
  640. package/lib/typescript/types/models/xmpp.model.d.ts.map +1 -1
  641. package/lib/typescript/types/types.d.ts +88 -5
  642. package/lib/typescript/types/types.d.ts.map +1 -1
  643. package/lib/typescript/version.d.ts +1 -1
  644. package/lib/typescript/version.d.ts.map +1 -1
  645. package/package.json +1 -1
  646. package/src/assets/icons.tsx +13 -0
  647. package/src/components/Header/HeaderRoomList.tsx +21 -4
  648. package/src/components/InputComponents/Search.tsx +33 -0
  649. package/src/components/MainComponents/ArchivedMessageCard.tsx +139 -0
  650. package/src/components/MainComponents/ChatHeader.tsx +19 -3
  651. package/src/components/MainComponents/ChatRoom.tsx +60 -23
  652. package/src/components/MainComponents/ChatWrapper.tsx +23 -4
  653. package/src/components/MainComponents/MediaMessage.tsx +17 -0
  654. package/src/components/MainComponents/MessageList.tsx +823 -84
  655. package/src/components/MainComponents/MessageSearchButton.tsx +48 -0
  656. package/src/components/MainComponents/ReduxWrapper.tsx +16 -5
  657. package/src/components/MainComponents/RoomList.tsx +125 -0
  658. package/src/components/Menu/HeaderRoomListMenu.tsx +26 -2
  659. package/src/components/MessageBubble/BubbleHighlight.tsx +106 -0
  660. package/src/components/MessageBubble/Message.tsx +265 -177
  661. package/src/components/MessageBubble/MessageInteractions.tsx +109 -86
  662. package/src/components/MessageBubble/messageMenuLayout.ts +59 -0
  663. package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +92 -21
  664. package/src/components/Modals/MessageSearchModal/MessageHitResults.tsx +271 -0
  665. package/src/components/Modals/MessageSearchModal/MessageSearchModal.tsx +487 -0
  666. package/src/components/Modals/MessageSearchModal/openHit.ts +50 -0
  667. package/src/components/Modals/MessageSearchModal/resolveSender.ts +57 -0
  668. package/src/components/Modals/MessageSearchModal/searchFilters.ts +109 -0
  669. package/src/components/Modals/MessageSearchModal/snippet.ts +58 -0
  670. package/src/components/Modals/MessageSearchModal/useMessageSearch.ts +151 -0
  671. package/src/components/Modals/PublicChatsModal/PublicChatsModal.tsx +288 -0
  672. package/src/components/Modals/PublicChatsModal/publicChatsLogic.ts +36 -0
  673. package/src/components/Modals/SelectUsersModal/SelectUsersModal.tsx +8 -1
  674. package/src/components/RoomComponents/ChatRoomItem.tsx +16 -3
  675. package/src/components/RoomComponents/SwipeableRoomRow.tsx +39 -6
  676. package/src/components/Thread/ThreadHeader.tsx +3 -1
  677. package/src/components/Thread/ThreadWrapper.tsx +96 -10
  678. package/src/components/styled/AudioDecoderHost.tsx +351 -0
  679. package/src/components/styled/AudioMessage.tsx +482 -425
  680. package/src/components/styled/SendInput.tsx +42 -4
  681. package/src/context/MessageNotificationContext.tsx +19 -5
  682. package/src/context/xmppProvider.tsx +44 -91
  683. package/src/helpers/audioWaveform.ts +142 -0
  684. package/src/helpers/backgroundJoinSweep.ts +35 -0
  685. package/src/helpers/bubbleHighlight.ts +47 -0
  686. package/src/helpers/checkUniqueUsers.tsx +15 -17
  687. package/src/helpers/constants/MODAL_COMPONENTS.tsx +4 -0
  688. package/src/helpers/constants/MODAL_TYPES.ts +3 -0
  689. package/src/helpers/createRoomFromApi.tsx +45 -4
  690. package/src/helpers/dedupeMembers.ts +29 -0
  691. package/src/helpers/ethoraLogger.ts +50 -0
  692. package/src/helpers/getUnnamedUsers.ts +7 -4
  693. package/src/helpers/historyPreloadConfig.ts +68 -0
  694. package/src/helpers/historyPreloadScheduler.ts +437 -199
  695. package/src/helpers/initRoomsPresence.ts +20 -7
  696. package/src/helpers/insertMessageWithDelimiter.ts +3 -0
  697. package/src/helpers/isLikelyMucJid.ts +72 -0
  698. package/src/helpers/isMessageSearchEnabled.ts +18 -0
  699. package/src/helpers/joiningRoom.ts +13 -0
  700. package/src/helpers/jumpThread.ts +102 -0
  701. package/src/helpers/jumpToMessage.ts +57 -0
  702. package/src/helpers/jumpWindow.ts +212 -0
  703. package/src/helpers/loadRoomHistory.ts +83 -0
  704. package/src/helpers/notificationPolicy.ts +82 -0
  705. package/src/helpers/openRoomAtMessage.ts +38 -0
  706. package/src/helpers/openThreadForJump.ts +96 -0
  707. package/src/helpers/parseMessageReference.ts +37 -8
  708. package/src/helpers/publicChatsEntry.ts +15 -0
  709. package/src/helpers/roomActivityScore.ts +45 -0
  710. package/src/helpers/roomUserCount.ts +44 -0
  711. package/src/helpers/runConfiguredHistoryPreload.ts +76 -0
  712. package/src/helpers/sessionAppId.ts +17 -0
  713. package/src/helpers/timestamp.ts +44 -0
  714. package/src/helpers/userResolver.ts +542 -0
  715. package/src/helpers/xmppIdShape.ts +46 -0
  716. package/src/hooks/useChatWrapperInit.ts +22 -4
  717. package/src/hooks/useHeapSender.tsx +54 -3
  718. package/src/hooks/useJumpToMessage.ts +538 -0
  719. package/src/hooks/useMessageLoaderQueue.tsx +40 -4
  720. package/src/hooks/useMessageQueue.ts +9 -5
  721. package/src/hooks/useRoomDirectory.ts +39 -0
  722. package/src/hooks/useRoomInitialization.tsx +33 -7
  723. package/src/hooks/useRoomMute.ts +42 -0
  724. package/src/hooks/useRoomState.tsx +6 -0
  725. package/src/hooks/useSendMessage.tsx +14 -2
  726. package/src/i18n/strings.ts +282 -0
  727. package/src/networking/api-requests/messageSearch.api.ts +130 -0
  728. package/src/networking/api-requests/publicChats.api.ts +71 -0
  729. package/src/networking/api-requests/roomMembers.api.ts +263 -11
  730. package/src/networking/api-requests/rooms.api.ts +52 -12
  731. package/src/networking/api-requests/xmppToken.api.ts +62 -0
  732. package/src/networking/ethoraEvents.ts +262 -0
  733. package/src/networking/stanzaHandlers.ts +145 -19
  734. package/src/networking/xmpp/allRoomPresences.xmpp.ts +155 -5
  735. package/src/networking/xmpp/getHistory.xmpp.ts +433 -47
  736. package/src/networking/xmpp/handleStanzas.xmpp.ts +8 -0
  737. package/src/networking/xmpp/historyCursor.ts +124 -0
  738. package/src/networking/xmpp/mamQueryIds.ts +11 -0
  739. package/src/networking/xmpp/mamRouter.ts +24 -10
  740. package/src/networking/xmpp/presenceInRoom.xmpp.ts +91 -68
  741. package/src/networking/xmpp/roomJoinSweep.ts +412 -0
  742. package/src/networking/xmpp/sendMediaMessage.xmpp.ts +0 -1
  743. package/src/networking/xmpp/sendTextMessage.xmpp.ts +0 -1
  744. package/src/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.ts +0 -1
  745. package/src/networking/xmppClient.ts +323 -47
  746. package/src/networking/xmppCredentials.ts +87 -0
  747. package/src/roomStore/Middleware/jumpThreadMiddleware.ts +163 -0
  748. package/src/roomStore/Middleware/reactionsMiddleware.tsx +4 -0
  749. package/src/roomStore/Middleware/unreadMidlleware.tsx +59 -11
  750. package/src/roomStore/chatSettingsSlice.ts +11 -0
  751. package/src/roomStore/index.ts +10 -3
  752. package/src/roomStore/persistence.ts +54 -0
  753. package/src/roomStore/roomsSlice.ts +547 -65
  754. package/src/roomStore/safeKey.ts +49 -0
  755. package/src/roomStore/usersSetCap.ts +37 -0
  756. package/src/types/models/media.model.ts +4 -0
  757. package/src/types/models/room.model.ts +18 -5
  758. package/src/types/models/xmpp.model.ts +15 -1
  759. package/src/types/types.ts +93 -5
  760. package/src/version.ts +1 -1
@@ -7,6 +7,10 @@ import {
7
7
  RUNTIME_MESSAGE_LIMIT,
8
8
  } from '../roomStore/roomsSlice';
9
9
  import { IMessage, IRoom } from '../types/types';
10
+ import {
11
+ getMessageTimestamp,
12
+ getRoomLastActivityScore,
13
+ } from './roomActivityScore';
10
14
 
11
15
  interface HistoryPreloadSchedulerOptions {
12
16
  client: XmppClient;
@@ -19,6 +23,15 @@ interface HistoryPreloadSchedulerOptions {
19
23
  selectedRoomJid?: string | null;
20
24
  defaultRoomJids?: string[];
21
25
  forceReload?: boolean;
26
+ // State stamped on successfully preloaded rooms. The staged flow's first
27
+ // (preview) pass uses 'partial' so the second, bigger-page pass still
28
+ // processes those rooms; only 'done' short-circuits future preloads.
29
+ completionState?: 'done' | 'partial';
30
+ // Preview pass: skip rooms that already have a list preview (loaded
31
+ // messages, or an API `lastMessage` seed from /chats/my). The pass exists
32
+ // only to fill that preview, so for those rooms it would be a wasted MAM
33
+ // query. `roomLimit` then counts the rooms that actually needed one.
34
+ skipApiPreview?: boolean;
22
35
  }
23
36
 
24
37
  interface QueueItem {
@@ -33,28 +46,38 @@ const DEFAULT_CONCURRENCY = 3;
33
46
  const DEFAULT_PAGE_SIZE = 10;
34
47
  const DEFAULT_RETRY_LIMIT = 2;
35
48
  const DEFAULT_FIRST_WAVE = 30;
36
- const BACKGROUND_BATCH_PAUSE_MS = 400;
49
+ // Past the first wave a worker rests this long between rooms, so a long
50
+ // background sweep does not saturate the socket a user is also chatting on.
51
+ const BACKGROUND_ROOM_PAUSE_MS = 400;
52
+ // When the first page is entirely unread (every fetched message is newer
53
+ // than `lastViewedTimestamp`), the true unread count could be far bigger
54
+ // than `pageSize` - `useUnread()` only ever sees what's been loaded. Page
55
+ // further back, up to this many extra fetches, until we either find the
56
+ // boundary or give up (`unreadCapped` then stays true so callers at least
57
+ // know the count is a floor, not exact). Customer-reported #34.
58
+ const MAX_UNREAD_CATCHUP_PAGES = 8;
59
+ // How many older pages one room may pull when its newest page has rows but
60
+ // nothing displayable (reactions / receipts only). Bounds the worst case.
61
+ const MAX_EMPTY_PAGE_FOLLOWS = 4;
62
+ const FOLLOW_PAGE_SIZE = 10;
63
+ // A room's first MAM page waits at most this long for its (deduped) join.
64
+ const JOIN_BEFORE_FETCH_TIMEOUT_MS = 3000;
65
+
66
+ // Marker for "MAM returned an empty page for a room the server hasn't
67
+ // declared complete" - retried like a failure, but never terminal.
68
+ const EMPTY_PAGE_ERROR = 'history_empty_page';
37
69
 
38
70
  const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
39
71
 
40
72
  declare const __DEV__: boolean | undefined;
41
73
 
42
- const messageTimestamp = (m: IMessage): number => {
43
- if (!m) {return 0;}
44
- const t = (m as any).timestamp;
45
- if (Number.isFinite(t) && t > 0) {return Number(t);}
46
- const id = Number(m.id);
47
- if (Number.isFinite(id) && id > 0) {return id;}
48
- return 0;
49
- };
74
+ const messageTimestamp = (m: IMessage): number => getMessageTimestamp(m);
50
75
 
51
- const getRoomLastActivityScore = (room: IRoom): number => {
52
- const fromMessages = room?.messages?.length
53
- ? room.messages.reduce((max, m) => Math.max(max, messageTimestamp(m)), 0)
54
- : 0;
55
- const fromStamp = Number(room?.lastMessageTimestamp) || 0;
56
- const fromSeed = Number(room?.lastMessage?.id) || 0;
57
- return Math.max(fromMessages, fromStamp, fromSeed);
76
+ // Store keys that can be a room (`local@domain`); root-slice keys that leak
77
+ // into `rooms.rooms` from corrupted persisted state have no `@`.
78
+ const isRoomKey = (jid: string): boolean => {
79
+ const at = jid.indexOf('@');
80
+ return at > 0 && at < jid.length - 1;
58
81
  };
59
82
 
60
83
  const computeUnreadCapped = (
@@ -102,13 +125,63 @@ const shouldPauseForVisibility = (): boolean => {
102
125
  return AppState.currentState !== 'active';
103
126
  };
104
127
 
128
+ // A room list preview that came from /chats/my: a seeded `lastMessage` and no
129
+ // loaded messages. Exported for the scheduler's tests.
130
+ export const hasApiPreview = (room?: IRoom): boolean =>
131
+ !!room &&
132
+ (room.messages?.length ?? 0) === 0 &&
133
+ !!String(room.lastMessage?.body || '').trim();
134
+
135
+ // Anything the room list can already render a preview from.
136
+ const hasListPreview = (room?: IRoom): boolean =>
137
+ !!room &&
138
+ ((room.messages?.length ?? 0) > 0 ||
139
+ !!String(room.lastMessage?.body || '').trim());
140
+
141
+ // Sweeps of one client run one after the other (the staged flow's preview
142
+ // and full-page passes, a bootstrap racing the chat wrapper's own start).
143
+ // CHAINED, not deduped onto one promise: each caller carries its own
144
+ // pageSize/completionState, so handing a late caller someone else's promise
145
+ // would silently skip its work; the per-room historyPreloadState guard makes
146
+ // the follow-up cheap wherever an earlier sweep already did the job.
147
+ const preloadChainByClient = new Map<string, Promise<void>>();
148
+ // The "unread syncing" flag stays up while ANY sweep runs (a counter, not a
149
+ // per-sweep toggle, so chained sweeps do not flicker it off between them).
150
+ let activeSweeps = 0;
151
+
152
+ const getClientKey = (client: XmppClient): string =>
153
+ (client as any)?.client?.jid?.toString?.() ||
154
+ (client as any)?.username ||
155
+ 'xmpp-client';
156
+
105
157
  /**
106
- * Background-loads message history for every room into the redux store,
107
- * prioritized by selected/default rooms then by last activity. Coalesces
108
- * with the XMPP client's MAM queue (so the active-room scroll fetch wins).
109
- * Mirrors the web `runHistoryPreloadScheduler`.
158
+ * Background-loads message history into the redux store. Rooms are picked by
159
+ * selected/default rooms first, then by recent activity; a room the user
160
+ * opens while the sweep runs jumps the queue. Coalesces with the XMPP
161
+ * client's MAM queue (so the active-room scroll fetch wins).
110
162
  */
111
- export const runHistoryPreloadScheduler = async (
163
+ export const runHistoryPreloadScheduler = (
164
+ options: HistoryPreloadSchedulerOptions
165
+ ): Promise<void> => {
166
+ const clientKey = getClientKey(options.client);
167
+ const previous = preloadChainByClient.get(clientKey) || Promise.resolve();
168
+
169
+ const run = previous
170
+ .catch(() => {})
171
+ .then(() => runHistoryPreloadSweep(options));
172
+
173
+ const tracked = run
174
+ .catch(() => {})
175
+ .finally(() => {
176
+ if (preloadChainByClient.get(clientKey) === tracked) {
177
+ preloadChainByClient.delete(clientKey);
178
+ }
179
+ });
180
+ preloadChainByClient.set(clientKey, tracked);
181
+ return run;
182
+ };
183
+
184
+ const runHistoryPreloadSweep = async (
112
185
  options: HistoryPreloadSchedulerOptions
113
186
  ): Promise<void> => {
114
187
  const {
@@ -122,210 +195,375 @@ export const runHistoryPreloadScheduler = async (
122
195
  selectedRoomJid = null,
123
196
  defaultRoomJids = [],
124
197
  forceReload = false,
198
+ completionState = 'done',
199
+ skipApiPreview = false,
125
200
  } = options;
126
201
 
127
202
  if (signal?.aborted) {return;}
128
203
 
129
204
  const startedAt = Date.now();
130
205
  let firstWaveLogged = false;
206
+ let started = 0;
131
207
  const devLog = (msg: string) => {
132
208
  if (typeof __DEV__ !== 'undefined' && __DEV__) {console.log(msg);}
133
209
  };
134
210
 
135
- store.dispatch(setUnreadSyncing(true));
211
+ activeSweeps += 1;
212
+ if (activeSweeps === 1) {store.dispatch(setUnreadSyncing(true));}
136
213
  try {
214
+ await runSweepBody();
215
+ } finally {
216
+ devLog(`[preload] finished in ${Date.now() - startedAt}ms`);
217
+ activeSweeps -= 1;
218
+ if (activeSweeps === 0) {store.dispatch(setUnreadSyncing(false));}
219
+ }
137
220
 
138
- const state = store.getState();
139
- const rooms = (state.rooms.rooms || {}) as Record<string, IRoom>;
140
- const defaultSet = new Set(defaultRoomJids);
141
-
142
- const sortedQueue: QueueItem[] = Object.entries(rooms)
143
- .map(([jid, room]: [string, IRoom]) => ({
144
- jid,
145
- priority: getRoomPriority(jid, room, selectedRoomJid, defaultSet),
146
- activityScore: getRoomLastActivityScore(room),
147
- attempts: 0,
148
- readyAt: Date.now(),
149
- }))
150
- .sort((a, b) => {
151
- if (a.priority !== b.priority) {return a.priority - b.priority;}
152
- if (a.activityScore !== b.activityScore) {
153
- return b.activityScore - a.activityScore;
154
- }
155
- return a.jid.localeCompare(b.jid);
156
- });
157
-
158
- const queue: QueueItem[] =
159
- roomLimit && roomLimit > 0
160
- ? sortedQueue.slice(0, roomLimit)
161
- : sortedQueue;
162
-
163
- const inFlightByRoom = new Map<string, Promise<void>>();
164
- let consecutiveErrorCount = 0;
165
- let started = 0;
166
- devLog(
167
- `[preload] ${queue.length} rooms queued, first wave ${Math.min(firstWave, queue.length)}, page ${pageSize}`
168
- );
169
-
170
- while (queue.length > 0) {
171
- if (signal?.aborted) {return;}
172
-
173
- if (!client.isActiveRoomGateOpen()) {
174
- await sleep(80);
175
- continue;
176
- }
177
- if (shouldPauseForVisibility()) {
178
- await sleep(250);
179
- continue;
180
- }
181
-
182
- const now = Date.now();
183
- const readyItems = queue.filter(
184
- (item) => item.readyAt <= now && !inFlightByRoom.has(item.jid)
185
- );
186
- if (readyItems.length === 0) {
187
- await sleep(60);
188
- continue;
189
- }
190
-
191
- const batch = readyItems.slice(0, Math.max(1, concurrency));
192
- const inBackgroundWave = started >= firstWave;
193
- if (inBackgroundWave && !firstWaveLogged) {
194
- firstWaveLogged = true;
195
- devLog(`[preload] first wave done in ${Date.now() - startedAt}ms`);
196
- }
197
- started += batch.length;
198
-
199
- // Snapshot each room's historyPreloadState BEFORE marking the
200
- // batch as 'loading'. Without this snapshot the per-task
201
- // `currentRoom.historyPreloadState === 'done'` skip check below
202
- // is dead — the dispatch immediately overwrites 'done' with
203
- // 'loading', so the task never sees the original value and
204
- // always re-fetches.
205
- const preBatchPreloadStateByJid = new Map<string, string | undefined>(
206
- batch.map((item) => [
207
- item.jid,
208
- store.getState().rooms.rooms[item.jid]?.historyPreloadState,
209
- ])
221
+ async function runSweepBody(): Promise<void> {
222
+ const rooms = (store.getState().rooms.rooms || {}) as Record<string, IRoom>;
223
+ const defaultSet = new Set(defaultRoomJids);
224
+
225
+ const sortedQueue: QueueItem[] = Object.entries(rooms)
226
+ .filter(([jid]) => isRoomKey(jid))
227
+ .map(([jid, room]: [string, IRoom]) => ({
228
+ jid,
229
+ priority: getRoomPriority(jid, room, selectedRoomJid, defaultSet),
230
+ activityScore: getRoomLastActivityScore(room),
231
+ attempts: 0,
232
+ readyAt: Date.now(),
233
+ }))
234
+ .sort((a, b) => {
235
+ if (a.priority !== b.priority) {return a.priority - b.priority;}
236
+ if (a.activityScore !== b.activityScore) {
237
+ return b.activityScore - a.activityScore;
238
+ }
239
+ return a.jid.localeCompare(b.jid);
240
+ });
241
+ // Top-N by recent activity FIRST, then drop what needs no work.
242
+ // Filtering 'done' rooms before the cut would let every reconnect slide
243
+ // the window down the list (the 8 done rooms vanish, the next 8 get
244
+ // preloaded), so "top N" would quietly grow into "all" over a few
245
+ // reconnects. The preview pass is the exception: it counts rooms that
246
+ // still LACK a preview, because a room the API gave no `lastMessage`
247
+ // for ranks at the bottom of an activity sort and would otherwise never
248
+ // get one.
249
+ const needsWork = (item: QueueItem): boolean => {
250
+ const room = rooms[item.jid];
251
+ if (!forceReload && room?.historyPreloadState === 'done') {return false;}
252
+ if (skipApiPreview && hasListPreview(room)) {return false;}
253
+ return true;
254
+ };
255
+ const withLimit = (items: QueueItem[]) =>
256
+ roomLimit && roomLimit > 0 ? items.slice(0, roomLimit) : items;
257
+ const queue: QueueItem[] = skipApiPreview
258
+ ? withLimit(sortedQueue.filter(needsWork))
259
+ : withLimit(sortedQueue).filter(needsWork);
260
+
261
+ const inFlightByRoom = new Map<string, Promise<void>>();
262
+ let consecutiveErrorCount = 0;
263
+ devLog(
264
+ `[preload] ${queue.length} rooms queued, first wave ${Math.min(firstWave, queue.length)}, page ${pageSize}`
210
265
  );
211
266
 
212
- store.dispatch(
213
- applyRoomsPreloadBatch({
214
- rooms: batch.map((item) => ({
215
- jid: item.jid,
216
- historyPreloadState: 'loading',
217
- })),
218
- })
219
- );
267
+ // Rooms that no longer need this sweep's work: preloaded by another path
268
+ // (the user opened them, a parallel bootstrap, an earlier sweep) or gone.
269
+ // Checked when an item is PICKED, before the 'loading' flag is written:
270
+ // flagging a batch 'loading' first and asking "already done?" after could
271
+ // never be true, so every reconnect refetched done rooms and flickered
272
+ // them through 'loading'.
273
+ const isSatisfied = (jid: string): boolean => {
274
+ const current = store.getState().rooms.rooms[jid];
275
+ if (!current) {return true;}
276
+ if (forceReload) {return false;}
277
+ return current.historyPreloadState === 'done';
278
+ };
279
+
280
+ const pickNext = (): QueueItem | null => {
281
+ const now = Date.now();
282
+ const activeJid = store.getState().rooms.activeRoomJID;
283
+ // A room the user opened while the sweep runs jumps the queue.
284
+ let best = -1;
285
+ for (let index = 0; index < queue.length; index += 1) {
286
+ const item = queue[index];
287
+ if (item.readyAt > now || inFlightByRoom.has(item.jid)) {continue;}
288
+ if (best === -1) {
289
+ best = index;
290
+ continue;
291
+ }
292
+ if (activeJid && item.jid === activeJid) {
293
+ best = index;
294
+ break;
295
+ }
296
+ }
297
+ if (best === -1) {return null;}
298
+ return queue.splice(best, 1)[0];
299
+ };
300
+
301
+ const processItem = async (item: QueueItem): Promise<void> => {
302
+ if (isSatisfied(item.jid)) {
303
+ // Nothing to fetch. Leave the state alone: stamping 'done' on a room
304
+ // that is merely missing would resurrect it as a ghost entry.
305
+ return;
306
+ }
220
307
 
221
- await Promise.all(
222
- batch.map(async (item) => {
223
- const queueIndex = queue.findIndex((queued) => queued.jid === item.jid);
224
- if (queueIndex !== -1) {queue.splice(queueIndex, 1);}
225
-
226
- const task = (async () => {
227
- const currentRoom = store.getState().rooms.rooms[item.jid];
228
- const preState = preBatchPreloadStateByJid.get(item.jid);
229
- if (
230
- !currentRoom ||
231
- (!forceReload && preState === 'done')
232
- ) {
233
- store.dispatch(
234
- applyRoomsPreloadBatch({
235
- rooms: [{ jid: item.jid, historyPreloadState: 'done' }],
236
- })
237
- );
238
- return;
308
+ store.dispatch(
309
+ applyRoomsPreloadBatch({
310
+ rooms: [{ jid: item.jid, historyPreloadState: 'loading' }],
311
+ })
312
+ );
313
+
314
+ try {
315
+ // MAM does not need the room joined, but a room that is not joined
316
+ // yet gets its (deduped) join first, best effort: the join sweep may
317
+ // not have reached it, and a members-only archive wants it.
318
+ try {
319
+ await (client as any).ensureRoomPresence?.(item.jid, {
320
+ timeoutMs: JOIN_BEFORE_FETCH_TIMEOUT_MS,
321
+ source: 'background',
322
+ // The sweep merges pages itself (one batch per room, with gap and
323
+ // unread detection): the MAM router must not apply them as well.
324
+ selfApplied: true,
325
+ });
326
+ } catch {}
327
+ if (signal?.aborted) {return;}
328
+
329
+ const fetchPage = (max: number, before?: number) =>
330
+ client.getHistoryStanza(item.jid, max, before, undefined, {
331
+ coalesceRoom: true,
332
+ skipIfPreloaded: !forceReload,
333
+ source: 'background',
334
+ });
335
+
336
+ let fetchedMessages = await fetchPage(pageSize);
337
+ if (signal?.aborted) {return;}
338
+ if (typeof fetchedMessages === 'undefined') {
339
+ throw new Error('history_timeout');
340
+ }
341
+
342
+ // A page can hold rows and still yield nothing displayable: a room
343
+ // whose newest archive rows are reactions or receipts parses to an
344
+ // empty list. That page is inconclusive, not a failure. Follow the
345
+ // server's RSM cursor (stored as messageStats.firstMessageTimestamp)
346
+ // to older pages until something displayable turns up, the archive
347
+ // is exhausted or the budget is spent.
348
+ let pagesFetched = 1;
349
+ let followedCursor = false;
350
+ let lastCursor: number | undefined;
351
+ while (
352
+ fetchedMessages.length === 0 &&
353
+ pagesFetched < MAX_EMPTY_PAGE_FOLLOWS + 1
354
+ ) {
355
+ const roomNow = store.getState().rooms.rooms[item.jid];
356
+ if (roomNow?.historyComplete === true) {break;}
357
+ const cursor = roomNow?.messageStats?.firstMessageTimestamp;
358
+ // No cursor means the server returned no rows at all (not joined /
359
+ // archive not ready): nothing to follow, the retry path handles it.
360
+ if (!cursor || !Number.isFinite(cursor) || cursor === lastCursor) {
361
+ break;
239
362
  }
240
-
241
- try {
242
- const fetchedMessages = await client.getHistoryStanza(
243
- item.jid,
244
- pageSize,
245
- undefined,
246
- undefined,
247
- {
248
- coalesceRoom: true,
249
- skipIfPreloaded: !forceReload,
250
- source: 'background',
251
- selfApplied: true,
252
- }
253
- );
254
- if (signal?.aborted) {return;}
255
- if (typeof fetchedMessages === 'undefined') {
256
- throw new Error('history_timeout');
257
- }
258
-
259
- const nextRoom = store.getState().rooms.rooms[item.jid];
260
- const combined: IMessage[] = fetchedMessages || [];
261
-
262
- // `mergeHistoryIntoCache` (roomsSlice) caps whatever we dispatch
263
- // here to the newest RUNTIME_MESSAGE_LIMIT messages before it
264
- // ever reaches `unreadMiddleware` — so a catch-up fetch that
265
- // pulled the true boundary can still have it silently dropped
266
- // by that cap, leaving a falsely-confident `unreadCapped:false`
267
- // (bug #34's failure mode again, just one layer downstream).
268
- // Simulate that cap here so the flag reflects what will
269
- // actually survive, not just what this fetch retrieved.
270
- const simulatedStored =
271
- combined.length > RUNTIME_MESSAGE_LIMIT
272
- ? combined.slice(-RUNTIME_MESSAGE_LIMIT)
273
- : combined;
274
- const unreadCapped = computeUnreadCapped(
275
- nextRoom,
276
- simulatedStored,
277
- pageSize
278
- );
279
-
363
+ lastCursor = cursor;
364
+ followedCursor = true;
365
+ const older = await fetchPage(
366
+ Math.max(pageSize, FOLLOW_PAGE_SIZE),
367
+ cursor
368
+ );
369
+ if (signal?.aborted) {return;}
370
+ if (typeof older === 'undefined') {throw new Error('history_timeout');}
371
+ pagesFetched += 1;
372
+ fetchedMessages = older;
373
+ }
374
+
375
+ const nextRoom = store.getState().rooms.rooms[item.jid];
376
+
377
+ // An empty page for a room the server hasn't declared complete is
378
+ // almost always "not joined / archive not ready yet", not "this room
379
+ // has no messages". Marking it 'done' froze the room with an empty
380
+ // transcript forever. When the cursor was followed and the budget
381
+ // ran out the archive does have rows (just none displayable yet),
382
+ // so that settles as 'partial' straight away; without a cursor the
383
+ // sweep retries.
384
+ const isInconclusiveEmptyPage =
385
+ fetchedMessages.length === 0 && nextRoom?.historyComplete !== true;
386
+ if (isInconclusiveEmptyPage) {
387
+ if (followedCursor) {
280
388
  store.dispatch(
281
389
  applyRoomsPreloadBatch({
282
- rooms: [
283
- {
284
- jid: item.jid,
285
- messages: combined,
286
- unreadCapped,
287
- historyPreloadState: 'done',
288
- },
289
- ],
390
+ rooms: [{ jid: item.jid, historyPreloadState: 'partial' }],
290
391
  })
291
392
  );
292
393
  consecutiveErrorCount = 0;
293
- } catch {
294
- const retries = item.attempts + 1;
295
- const canRetry = retries <= retryLimit;
296
- if (canRetry) {
297
- const jitter = Math.floor(Math.random() * 120);
298
- const backoff = Math.min(1600, 240 * 2 ** item.attempts) + jitter;
299
- queue.push({
300
- ...item,
301
- attempts: retries,
302
- readyAt: Date.now() + backoff,
303
- });
304
- } else {
305
- store.dispatch(
306
- applyRoomsPreloadBatch({
307
- rooms: [{ jid: item.jid, historyPreloadState: 'error' }],
308
- })
309
- );
394
+ return;
395
+ }
396
+ throw new Error(EMPTY_PAGE_ERROR);
397
+ }
398
+
399
+ let combined: IMessage[] = fetchedMessages;
400
+ const lastViewed = Number(nextRoom?.lastViewedTimestamp) || 0;
401
+
402
+ // The first page was entirely unread: keep paging older until a
403
+ // message at/before `lastViewedTimestamp` (the true boundary) is
404
+ // found or the catch-up budget runs out, so the count isn't silently
405
+ // truncated at `pageSize`.
406
+ if (
407
+ lastViewed > 0 &&
408
+ computeUnreadCapped(nextRoom, combined, pageSize)
409
+ ) {
410
+ let lastPageLen = combined.length;
411
+ let extraPages = 0;
412
+ while (
413
+ extraPages < MAX_UNREAD_CATCHUP_PAGES &&
414
+ lastPageLen >= pageSize &&
415
+ !signal?.aborted
416
+ ) {
417
+ const oldestId = combined.reduce<number | null>((min, m) => {
418
+ const idNum = Number((m as any)?.id);
419
+ if (!Number.isFinite(idNum)) {return min;}
420
+ return min === null || idNum < min ? idNum : min;
421
+ }, null);
422
+ if (oldestId === null) {break;}
423
+
424
+ let older: IMessage[] | undefined;
425
+ try {
426
+ older = await fetchPage(pageSize, oldestId);
427
+ } catch {
428
+ break;
310
429
  }
311
- consecutiveErrorCount += 1;
312
- if (consecutiveErrorCount >= 3) {
313
- await sleep(300);
314
- consecutiveErrorCount = 0;
430
+ if (!older || !older.length) {break;}
431
+
432
+ combined = [...older, ...combined];
433
+ lastPageLen = older.length;
434
+ extraPages++;
435
+
436
+ const oldestTs = combined.reduce<number>((minTs, m) => {
437
+ const ts = messageTimestamp(m);
438
+ return ts > 0 ? Math.min(minTs, ts) : minTs;
439
+ }, Number.MAX_SAFE_INTEGER);
440
+ if (oldestTs !== Number.MAX_SAFE_INTEGER && oldestTs <= lastViewed) {
441
+ break;
315
442
  }
316
443
  }
317
- })();
318
-
444
+ }
445
+
446
+ // `mergeHistoryIntoCache` (roomsSlice) caps whatever we dispatch to
447
+ // the newest RUNTIME_MESSAGE_LIMIT messages before it reaches
448
+ // `unreadMiddleware`, so a catch-up that pulled the true boundary can
449
+ // still have it dropped by that cap (bug #34's failure mode one layer
450
+ // downstream). Simulate the cap so the flag reflects what survives.
451
+ const simulatedStored =
452
+ combined.length > RUNTIME_MESSAGE_LIMIT
453
+ ? combined.slice(-RUNTIME_MESSAGE_LIMIT)
454
+ : combined;
455
+ const unreadCapped = computeUnreadCapped(
456
+ nextRoom,
457
+ simulatedStored,
458
+ pageSize
459
+ );
460
+
461
+ store.dispatch(
462
+ applyRoomsPreloadBatch({
463
+ rooms: [
464
+ {
465
+ jid: item.jid,
466
+ messages: combined,
467
+ unreadCapped,
468
+ historyPreloadState: completionState,
469
+ },
470
+ ],
471
+ })
472
+ );
473
+ consecutiveErrorCount = 0;
474
+ } catch (error) {
475
+ const isEmptyPage = (error as Error)?.message === EMPTY_PAGE_ERROR;
476
+ const retries = item.attempts + 1;
477
+ const canRetry = retries <= retryLimit;
478
+
479
+ if (canRetry) {
480
+ const jitter = Math.floor(Math.random() * 120);
481
+ const backoff = Math.min(1600, 240 * 2 ** item.attempts) + jitter;
482
+ queue.push({
483
+ ...item,
484
+ attempts: retries,
485
+ readyAt: Date.now() + backoff,
486
+ });
487
+ } else {
488
+ store.dispatch(
489
+ applyRoomsPreloadBatch({
490
+ rooms: [
491
+ {
492
+ jid: item.jid,
493
+ // An empty page is inconclusive, not a failure: keep it
494
+ // retryable so a later pass (or opening the room) can
495
+ // still fill it in. Real failures end 'error' (retryable
496
+ // by the next sweep too).
497
+ historyPreloadState: isEmptyPage ? 'partial' : 'error',
498
+ },
499
+ ],
500
+ })
501
+ );
502
+ }
503
+
504
+ // An empty page says nothing about connection health: only real
505
+ // failures trip the circuit breaker below.
506
+ if (isEmptyPage) {return;}
507
+ consecutiveErrorCount += 1;
508
+ if (consecutiveErrorCount >= 3) {
509
+ await sleep(300);
510
+ consecutiveErrorCount = 0;
511
+ }
512
+ }
513
+ };
514
+
515
+ // A worker pool, not batches: one slow room (a 10 s MAM timeout) must not
516
+ // idle the other slots. Each worker pulls the next room the moment it is
517
+ // free.
518
+ let activeWorkers = 0;
519
+ const worker = async (): Promise<void> => {
520
+ while (true) {
521
+ if (signal?.aborted) {return;}
522
+ if (queue.length === 0 && activeWorkers === 0) {return;}
523
+
524
+ if (!client.isActiveRoomGateOpen()) {
525
+ await sleep(80);
526
+ continue;
527
+ }
528
+ if (shouldPauseForVisibility()) {
529
+ await sleep(250);
530
+ continue;
531
+ }
532
+
533
+ const item = pickNext();
534
+ if (!item) {
535
+ // Queue is empty (another worker may still push a retry) or every
536
+ // remaining item is backing off / in flight.
537
+ if (queue.length === 0 && activeWorkers === 0) {return;}
538
+ await sleep(60);
539
+ continue;
540
+ }
541
+
542
+ activeWorkers += 1;
543
+ started += 1;
544
+ const task = processItem(item);
319
545
  inFlightByRoom.set(item.jid, task);
320
- await task.finally(() => inFlightByRoom.delete(item.jid));
321
- })
322
- );
546
+ try {
547
+ await task;
548
+ } finally {
549
+ inFlightByRoom.delete(item.jid);
550
+ activeWorkers -= 1;
551
+ }
552
+
553
+ // Yield to the JS event loop (no requestIdleCallback in RN); past the
554
+ // first wave, rest a little between rooms.
555
+ const inBackgroundWave = started >= firstWave;
556
+ if (inBackgroundWave && !firstWaveLogged) {
557
+ firstWaveLogged = true;
558
+ devLog(`[preload] first wave done in ${Date.now() - startedAt}ms`);
559
+ }
560
+ await sleep(inBackgroundWave ? BACKGROUND_ROOM_PAUSE_MS : 0);
561
+ }
562
+ };
323
563
 
324
- await sleep(inBackgroundWave ? BACKGROUND_BATCH_PAUSE_MS : 0);
325
- }
326
- } finally {
327
- devLog(`[preload] finished in ${Date.now() - startedAt}ms`);
328
- store.dispatch(setUnreadSyncing(false));
564
+ await Promise.all(
565
+ Array.from({ length: Math.max(1, concurrency) }, () => worker())
566
+ );
329
567
  }
330
568
  };
331
569