@ethora/chat-component-rn 26.8.1 → 26.8.2

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 (604) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/README.md +43 -10
  3. package/lib/commonjs/assets/icons.js +7 -2
  4. package/lib/commonjs/assets/icons.js.map +1 -1
  5. package/lib/commonjs/components/AuthForms/Login.js +4 -4
  6. package/lib/commonjs/components/AuthForms/Login.js.map +1 -1
  7. package/lib/commonjs/components/Header/HeaderRoomList.js +29 -8
  8. package/lib/commonjs/components/Header/HeaderRoomList.js.map +1 -1
  9. package/lib/commonjs/components/MainComponents/ChatHeader.js +9 -3
  10. package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
  11. package/lib/commonjs/components/MainComponents/ChatRoom.js +150 -14
  12. package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
  13. package/lib/commonjs/components/MainComponents/ChatWrapper.js +34 -13
  14. package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
  15. package/lib/commonjs/components/MainComponents/LoginWrapper.js +2 -1
  16. package/lib/commonjs/components/MainComponents/LoginWrapper.js.map +1 -1
  17. package/lib/commonjs/components/MainComponents/MediaMessage.js +29 -9
  18. package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
  19. package/lib/commonjs/components/MainComponents/MessageContainer.js +5 -1
  20. package/lib/commonjs/components/MainComponents/MessageContainer.js.map +1 -1
  21. package/lib/commonjs/components/MainComponents/MessageList.js +13 -5
  22. package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
  23. package/lib/commonjs/components/MainComponents/ProfileImagePlaceholder.js +14 -13
  24. package/lib/commonjs/components/MainComponents/ProfileImagePlaceholder.js.map +1 -1
  25. package/lib/commonjs/components/MainComponents/RoomList.js +208 -35
  26. package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
  27. package/lib/commonjs/components/Menu/HeaderRoomListMenu.js +317 -98
  28. package/lib/commonjs/components/Menu/HeaderRoomListMenu.js.map +1 -1
  29. package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js +322 -110
  30. package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
  31. package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js +546 -203
  32. package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
  33. package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js +226 -0
  34. package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -0
  35. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +69 -27
  36. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  37. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js +2 -1
  38. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  39. package/lib/commonjs/components/Modals/Modal/Modal.js +8 -0
  40. package/lib/commonjs/components/Modals/Modal/Modal.js.map +1 -1
  41. package/lib/commonjs/components/Modals/NewChatModal/ModalContent.js +2 -1
  42. package/lib/commonjs/components/Modals/NewChatModal/ModalContent.js.map +1 -1
  43. package/lib/commonjs/components/Modals/NewChatModal/NewChatModal.js +202 -106
  44. package/lib/commonjs/components/Modals/NewChatModal/NewChatModal.js.map +1 -1
  45. package/lib/commonjs/components/Modals/NewChatModal/UpdNewChatModal.js +8 -0
  46. package/lib/commonjs/components/Modals/NewChatModal/UpdNewChatModal.js.map +1 -1
  47. package/lib/commonjs/components/Modals/ProfileHeader/ProfileHeader.js +563 -0
  48. package/lib/commonjs/components/Modals/ProfileHeader/ProfileHeader.js.map +1 -0
  49. package/lib/commonjs/components/Modals/ProfileHeader/ProfileMenu.js +210 -0
  50. package/lib/commonjs/components/Modals/ProfileHeader/ProfileMenu.js.map +1 -0
  51. package/lib/commonjs/components/Modals/SelectUsersModal/SelectUsersModal.js +4 -2
  52. package/lib/commonjs/components/Modals/SelectUsersModal/SelectUsersModal.js.map +1 -1
  53. package/lib/commonjs/components/Modals/UserProfileModal/EditUserModal.js +7 -21
  54. package/lib/commonjs/components/Modals/UserProfileModal/EditUserModal.js.map +1 -1
  55. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +507 -244
  56. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  57. package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js +74 -46
  58. package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
  59. package/lib/commonjs/components/Modals/styledModalComponents.js +9 -2
  60. package/lib/commonjs/components/Modals/styledModalComponents.js.map +1 -1
  61. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js +21 -7
  62. package/lib/commonjs/components/RoomComponents/ChatRoomItem.js.map +1 -1
  63. package/lib/commonjs/components/RoomComponents/styled/LastMessageFile.js +22 -3
  64. package/lib/commonjs/components/RoomComponents/styled/LastMessageFile.js.map +1 -1
  65. package/lib/commonjs/components/RoomComponents/styled/LastMessagePhoto.js +17 -3
  66. package/lib/commonjs/components/RoomComponents/styled/LastMessagePhoto.js.map +1 -1
  67. package/lib/commonjs/components/RoomComponents/styled/LastMessageVideo.js +17 -3
  68. package/lib/commonjs/components/RoomComponents/styled/LastMessageVideo.js.map +1 -1
  69. package/lib/commonjs/components/VideoCalls/VideoCallSession.js +6 -3
  70. package/lib/commonjs/components/VideoCalls/VideoCallSession.js.map +1 -1
  71. package/lib/commonjs/components/styled/AudioMessage.js +2 -1
  72. package/lib/commonjs/components/styled/AudioMessage.js.map +1 -1
  73. package/lib/commonjs/components/styled/MessageImage.js +37 -9
  74. package/lib/commonjs/components/styled/MessageImage.js.map +1 -1
  75. package/lib/commonjs/components/styled/SendInput.js +80 -11
  76. package/lib/commonjs/components/styled/SendInput.js.map +1 -1
  77. package/lib/commonjs/components/styled/StyledComponents.js +9 -3
  78. package/lib/commonjs/components/styled/StyledComponents.js.map +1 -1
  79. package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js +11 -4
  80. package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
  81. package/lib/commonjs/components/styled/UnsupportedType.js +14 -4
  82. package/lib/commonjs/components/styled/UnsupportedType.js.map +1 -1
  83. package/lib/commonjs/components/styled/VideoMessage.js +119 -61
  84. package/lib/commonjs/components/styled/VideoMessage.js.map +1 -1
  85. package/lib/commonjs/context/xmppProvider.js +184 -59
  86. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  87. package/lib/commonjs/helpers/createMessageFromXml.js +19 -1
  88. package/lib/commonjs/helpers/createMessageFromXml.js.map +1 -1
  89. package/lib/commonjs/helpers/ensureScopedChatCache.js +2 -2
  90. package/lib/commonjs/helpers/ensureScopedChatCache.js.map +1 -1
  91. package/lib/commonjs/helpers/getChatBackground.js +23 -0
  92. package/lib/commonjs/helpers/getChatBackground.js.map +1 -0
  93. package/lib/commonjs/helpers/getDisplayFileName.js +79 -0
  94. package/lib/commonjs/helpers/getDisplayFileName.js.map +1 -0
  95. package/lib/commonjs/helpers/getServerReadTimestamp.js +188 -0
  96. package/lib/commonjs/helpers/getServerReadTimestamp.js.map +1 -0
  97. package/lib/commonjs/helpers/historyPreloadScheduler.js +65 -2
  98. package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
  99. package/lib/commonjs/helpers/initXmppRooms.js +14 -8
  100. package/lib/commonjs/helpers/initXmppRooms.js.map +1 -1
  101. package/lib/commonjs/helpers/insertMessageWithDelimiter.js +51 -9
  102. package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
  103. package/lib/commonjs/helpers/isOwnMessage.js +75 -0
  104. package/lib/commonjs/helpers/isOwnMessage.js.map +1 -0
  105. package/lib/commonjs/helpers/keyboardLayout.js +12 -2
  106. package/lib/commonjs/helpers/keyboardLayout.js.map +1 -1
  107. package/lib/commonjs/helpers/mediaLibraryRuntime.js +31 -0
  108. package/lib/commonjs/helpers/mediaLibraryRuntime.js.map +1 -0
  109. package/lib/commonjs/helpers/mimeToExtension.js +6 -14
  110. package/lib/commonjs/helpers/mimeToExtension.js.map +1 -1
  111. package/lib/commonjs/helpers/msgSortableMs.js +37 -0
  112. package/lib/commonjs/helpers/msgSortableMs.js.map +1 -0
  113. package/lib/commonjs/helpers/persistCrypto.js +122 -0
  114. package/lib/commonjs/helpers/persistCrypto.js.map +1 -0
  115. package/lib/commonjs/helpers/pickImageAsset.js +68 -0
  116. package/lib/commonjs/helpers/pickImageAsset.js.map +1 -0
  117. package/lib/commonjs/helpers/pushPayload.js +71 -0
  118. package/lib/commonjs/helpers/pushPayload.js.map +1 -0
  119. package/lib/commonjs/helpers/resolveInitBeforeLoadUser.js +130 -17
  120. package/lib/commonjs/helpers/resolveInitBeforeLoadUser.js.map +1 -1
  121. package/lib/commonjs/helpers/secureFileUrl.js +101 -0
  122. package/lib/commonjs/helpers/secureFileUrl.js.map +1 -0
  123. package/lib/commonjs/helpers/secureKeyValue.js +83 -0
  124. package/lib/commonjs/helpers/secureKeyValue.js.map +1 -0
  125. package/lib/commonjs/helpers/secureStoreRuntime.js +59 -0
  126. package/lib/commonjs/helpers/secureStoreRuntime.js.map +1 -0
  127. package/lib/commonjs/helpers/secureUserStorage.js +75 -0
  128. package/lib/commonjs/helpers/secureUserStorage.js.map +1 -0
  129. package/lib/commonjs/helpers/shallowEqual.js +36 -0
  130. package/lib/commonjs/helpers/shallowEqual.js.map +1 -0
  131. package/lib/commonjs/helpers/sheetGestures.js +32 -0
  132. package/lib/commonjs/helpers/sheetGestures.js.map +1 -0
  133. package/lib/commonjs/hooks/useChatRoomFocus.js +45 -12
  134. package/lib/commonjs/hooks/useChatRoomFocus.js.map +1 -1
  135. package/lib/commonjs/hooks/useChatWrapperInit.js +30 -10
  136. package/lib/commonjs/hooks/useChatWrapperInit.js.map +1 -1
  137. package/lib/commonjs/hooks/useComposing.js +27 -0
  138. package/lib/commonjs/hooks/useComposing.js.map +1 -1
  139. package/lib/commonjs/hooks/useFileToken.js +10 -0
  140. package/lib/commonjs/hooks/useFileToken.js.map +1 -0
  141. package/lib/commonjs/hooks/useLogout.js +23 -7
  142. package/lib/commonjs/hooks/useLogout.js.map +1 -1
  143. package/lib/commonjs/hooks/usePendingNotification.js +8 -11
  144. package/lib/commonjs/hooks/usePendingNotification.js.map +1 -1
  145. package/lib/commonjs/hooks/useSendMessage.js +50 -14
  146. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  147. package/lib/commonjs/hooks/useUnreadMessagesCounter.js +6 -1
  148. package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
  149. package/lib/commonjs/i18n/strings.js +145 -37
  150. package/lib/commonjs/i18n/strings.js.map +1 -1
  151. package/lib/commonjs/main.js +44 -0
  152. package/lib/commonjs/main.js.map +1 -1
  153. package/lib/commonjs/networking/api-requests/auth.api.js +134 -60
  154. package/lib/commonjs/networking/api-requests/auth.api.js.map +1 -1
  155. package/lib/commonjs/networking/api-requests/roomMembers.api.js +1 -1
  156. package/lib/commonjs/networking/api-requests/roomMembers.api.js.map +1 -1
  157. package/lib/commonjs/networking/api-requests/rooms.api.js +9 -9
  158. package/lib/commonjs/networking/api-requests/rooms.api.js.map +1 -1
  159. package/lib/commonjs/networking/api-requests/user.api.js +68 -9
  160. package/lib/commonjs/networking/api-requests/user.api.js.map +1 -1
  161. package/lib/commonjs/networking/apiClient.js +62 -112
  162. package/lib/commonjs/networking/apiClient.js.map +1 -1
  163. package/lib/commonjs/networking/authRefresh.js +332 -0
  164. package/lib/commonjs/networking/authRefresh.js.map +1 -0
  165. package/lib/commonjs/networking/stanzaHandlers.js +41 -28
  166. package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
  167. package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js +46 -8
  168. package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
  169. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js +8 -1
  170. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  171. package/lib/commonjs/networking/xmpp/subscribeToRoomMessages.xmpp.js +5 -1
  172. package/lib/commonjs/networking/xmpp/subscribeToRoomMessages.xmpp.js.map +1 -1
  173. package/lib/commonjs/networking/xmppClient.js +124 -8
  174. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  175. package/lib/commonjs/roomStore/chatSettingsSlice.js +26 -7
  176. package/lib/commonjs/roomStore/chatSettingsSlice.js.map +1 -1
  177. package/lib/commonjs/roomStore/index.js +35 -2
  178. package/lib/commonjs/roomStore/index.js.map +1 -1
  179. package/lib/commonjs/roomStore/persistence.js +226 -23
  180. package/lib/commonjs/roomStore/persistence.js.map +1 -1
  181. package/lib/commonjs/roomStore/roomsSlice.js +151 -38
  182. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  183. package/lib/commonjs/services/pushSubscriptionService.js +15 -13
  184. package/lib/commonjs/services/pushSubscriptionService.js.map +1 -1
  185. package/lib/commonjs/version.js +1 -1
  186. package/lib/module/assets/icons.js +6 -1
  187. package/lib/module/assets/icons.js.map +1 -1
  188. package/lib/module/components/AuthForms/Login.js +4 -4
  189. package/lib/module/components/AuthForms/Login.js.map +1 -1
  190. package/lib/module/components/Header/HeaderRoomList.js +29 -8
  191. package/lib/module/components/Header/HeaderRoomList.js.map +1 -1
  192. package/lib/module/components/MainComponents/ChatHeader.js +9 -3
  193. package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
  194. package/lib/module/components/MainComponents/ChatRoom.js +152 -16
  195. package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
  196. package/lib/module/components/MainComponents/ChatWrapper.js +35 -14
  197. package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
  198. package/lib/module/components/MainComponents/LoginWrapper.js +2 -1
  199. package/lib/module/components/MainComponents/LoginWrapper.js.map +1 -1
  200. package/lib/module/components/MainComponents/MediaMessage.js +30 -10
  201. package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
  202. package/lib/module/components/MainComponents/MessageContainer.js +5 -1
  203. package/lib/module/components/MainComponents/MessageContainer.js.map +1 -1
  204. package/lib/module/components/MainComponents/MessageList.js +13 -5
  205. package/lib/module/components/MainComponents/MessageList.js.map +1 -1
  206. package/lib/module/components/MainComponents/ProfileImagePlaceholder.js +14 -13
  207. package/lib/module/components/MainComponents/ProfileImagePlaceholder.js.map +1 -1
  208. package/lib/module/components/MainComponents/RoomList.js +207 -35
  209. package/lib/module/components/MainComponents/RoomList.js.map +1 -1
  210. package/lib/module/components/Menu/HeaderRoomListMenu.js +319 -101
  211. package/lib/module/components/Menu/HeaderRoomListMenu.js.map +1 -1
  212. package/lib/module/components/Modals/AttachSheet/AttachSheet.js +313 -113
  213. package/lib/module/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
  214. package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js +549 -207
  215. package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
  216. package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js +223 -0
  217. package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -0
  218. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +70 -28
  219. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  220. package/lib/module/components/Modals/FilePreviewModal/PdfView.js +2 -1
  221. package/lib/module/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  222. package/lib/module/components/Modals/Modal/Modal.js +9 -1
  223. package/lib/module/components/Modals/Modal/Modal.js.map +1 -1
  224. package/lib/module/components/Modals/NewChatModal/ModalContent.js +2 -1
  225. package/lib/module/components/Modals/NewChatModal/ModalContent.js.map +1 -1
  226. package/lib/module/components/Modals/NewChatModal/NewChatModal.js +205 -108
  227. package/lib/module/components/Modals/NewChatModal/NewChatModal.js.map +1 -1
  228. package/lib/module/components/Modals/NewChatModal/UpdNewChatModal.js +8 -0
  229. package/lib/module/components/Modals/NewChatModal/UpdNewChatModal.js.map +1 -1
  230. package/lib/module/components/Modals/ProfileHeader/ProfileHeader.js +555 -0
  231. package/lib/module/components/Modals/ProfileHeader/ProfileHeader.js.map +1 -0
  232. package/lib/module/components/Modals/ProfileHeader/ProfileMenu.js +205 -0
  233. package/lib/module/components/Modals/ProfileHeader/ProfileMenu.js.map +1 -0
  234. package/lib/module/components/Modals/SelectUsersModal/SelectUsersModal.js +4 -2
  235. package/lib/module/components/Modals/SelectUsersModal/SelectUsersModal.js.map +1 -1
  236. package/lib/module/components/Modals/UserProfileModal/EditUserModal.js +9 -23
  237. package/lib/module/components/Modals/UserProfileModal/EditUserModal.js.map +1 -1
  238. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +509 -248
  239. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  240. package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js +76 -48
  241. package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
  242. package/lib/module/components/Modals/styledModalComponents.js +9 -2
  243. package/lib/module/components/Modals/styledModalComponents.js.map +1 -1
  244. package/lib/module/components/RoomComponents/ChatRoomItem.js +21 -7
  245. package/lib/module/components/RoomComponents/ChatRoomItem.js.map +1 -1
  246. package/lib/module/components/RoomComponents/styled/LastMessageFile.js +22 -3
  247. package/lib/module/components/RoomComponents/styled/LastMessageFile.js.map +1 -1
  248. package/lib/module/components/RoomComponents/styled/LastMessagePhoto.js +17 -3
  249. package/lib/module/components/RoomComponents/styled/LastMessagePhoto.js.map +1 -1
  250. package/lib/module/components/RoomComponents/styled/LastMessageVideo.js +17 -3
  251. package/lib/module/components/RoomComponents/styled/LastMessageVideo.js.map +1 -1
  252. package/lib/module/components/VideoCalls/VideoCallSession.js +6 -3
  253. package/lib/module/components/VideoCalls/VideoCallSession.js.map +1 -1
  254. package/lib/module/components/styled/AudioMessage.js +2 -1
  255. package/lib/module/components/styled/AudioMessage.js.map +1 -1
  256. package/lib/module/components/styled/MessageImage.js +37 -9
  257. package/lib/module/components/styled/MessageImage.js.map +1 -1
  258. package/lib/module/components/styled/SendInput.js +81 -12
  259. package/lib/module/components/styled/SendInput.js.map +1 -1
  260. package/lib/module/components/styled/StyledComponents.js +9 -3
  261. package/lib/module/components/styled/StyledComponents.js.map +1 -1
  262. package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js +11 -4
  263. package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
  264. package/lib/module/components/styled/UnsupportedType.js +14 -4
  265. package/lib/module/components/styled/UnsupportedType.js.map +1 -1
  266. package/lib/module/components/styled/VideoMessage.js +120 -62
  267. package/lib/module/components/styled/VideoMessage.js.map +1 -1
  268. package/lib/module/context/xmppProvider.js +184 -60
  269. package/lib/module/context/xmppProvider.js.map +1 -1
  270. package/lib/module/helpers/createMessageFromXml.js +19 -1
  271. package/lib/module/helpers/createMessageFromXml.js.map +1 -1
  272. package/lib/module/helpers/ensureScopedChatCache.js +2 -2
  273. package/lib/module/helpers/ensureScopedChatCache.js.map +1 -1
  274. package/lib/module/helpers/getChatBackground.js +18 -0
  275. package/lib/module/helpers/getChatBackground.js.map +1 -0
  276. package/lib/module/helpers/getDisplayFileName.js +73 -0
  277. package/lib/module/helpers/getDisplayFileName.js.map +1 -0
  278. package/lib/module/helpers/getServerReadTimestamp.js +181 -0
  279. package/lib/module/helpers/getServerReadTimestamp.js.map +1 -0
  280. package/lib/module/helpers/historyPreloadScheduler.js +66 -3
  281. package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
  282. package/lib/module/helpers/initXmppRooms.js +14 -8
  283. package/lib/module/helpers/initXmppRooms.js.map +1 -1
  284. package/lib/module/helpers/insertMessageWithDelimiter.js +52 -9
  285. package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
  286. package/lib/module/helpers/isOwnMessage.js +70 -0
  287. package/lib/module/helpers/isOwnMessage.js.map +1 -0
  288. package/lib/module/helpers/keyboardLayout.js +12 -2
  289. package/lib/module/helpers/keyboardLayout.js.map +1 -1
  290. package/lib/module/helpers/mediaLibraryRuntime.js +25 -0
  291. package/lib/module/helpers/mediaLibraryRuntime.js.map +1 -0
  292. package/lib/module/helpers/mimeToExtension.js +6 -13
  293. package/lib/module/helpers/mimeToExtension.js.map +1 -1
  294. package/lib/module/helpers/msgSortableMs.js +32 -0
  295. package/lib/module/helpers/msgSortableMs.js.map +1 -0
  296. package/lib/module/helpers/persistCrypto.js +115 -0
  297. package/lib/module/helpers/persistCrypto.js.map +1 -0
  298. package/lib/module/helpers/pickImageAsset.js +63 -0
  299. package/lib/module/helpers/pickImageAsset.js.map +1 -0
  300. package/lib/module/helpers/pushPayload.js +63 -0
  301. package/lib/module/helpers/pushPayload.js.map +1 -0
  302. package/lib/module/helpers/resolveInitBeforeLoadUser.js +130 -16
  303. package/lib/module/helpers/resolveInitBeforeLoadUser.js.map +1 -1
  304. package/lib/module/helpers/secureFileUrl.js +91 -0
  305. package/lib/module/helpers/secureFileUrl.js.map +1 -0
  306. package/lib/module/helpers/secureKeyValue.js +75 -0
  307. package/lib/module/helpers/secureKeyValue.js.map +1 -0
  308. package/lib/module/helpers/secureStoreRuntime.js +52 -0
  309. package/lib/module/helpers/secureStoreRuntime.js.map +1 -0
  310. package/lib/module/helpers/secureUserStorage.js +72 -0
  311. package/lib/module/helpers/secureUserStorage.js.map +1 -0
  312. package/lib/module/helpers/shallowEqual.js +31 -0
  313. package/lib/module/helpers/shallowEqual.js.map +1 -0
  314. package/lib/module/helpers/sheetGestures.js +26 -0
  315. package/lib/module/helpers/sheetGestures.js.map +1 -0
  316. package/lib/module/hooks/useChatRoomFocus.js +46 -13
  317. package/lib/module/hooks/useChatRoomFocus.js.map +1 -1
  318. package/lib/module/hooks/useChatWrapperInit.js +30 -10
  319. package/lib/module/hooks/useChatWrapperInit.js.map +1 -1
  320. package/lib/module/hooks/useComposing.js +28 -1
  321. package/lib/module/hooks/useComposing.js.map +1 -1
  322. package/lib/module/hooks/useFileToken.js +5 -0
  323. package/lib/module/hooks/useFileToken.js.map +1 -0
  324. package/lib/module/hooks/useLogout.js +23 -7
  325. package/lib/module/hooks/useLogout.js.map +1 -1
  326. package/lib/module/hooks/usePendingNotification.js +8 -11
  327. package/lib/module/hooks/usePendingNotification.js.map +1 -1
  328. package/lib/module/hooks/useSendMessage.js +52 -16
  329. package/lib/module/hooks/useSendMessage.js.map +1 -1
  330. package/lib/module/hooks/useUnreadMessagesCounter.js +6 -1
  331. package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
  332. package/lib/module/i18n/strings.js +145 -37
  333. package/lib/module/i18n/strings.js.map +1 -1
  334. package/lib/module/main.js +14 -2
  335. package/lib/module/main.js.map +1 -1
  336. package/lib/module/networking/api-requests/auth.api.js +131 -59
  337. package/lib/module/networking/api-requests/auth.api.js.map +1 -1
  338. package/lib/module/networking/api-requests/roomMembers.api.js +1 -1
  339. package/lib/module/networking/api-requests/roomMembers.api.js.map +1 -1
  340. package/lib/module/networking/api-requests/rooms.api.js +9 -9
  341. package/lib/module/networking/api-requests/rooms.api.js.map +1 -1
  342. package/lib/module/networking/api-requests/user.api.js +64 -7
  343. package/lib/module/networking/api-requests/user.api.js.map +1 -1
  344. package/lib/module/networking/apiClient.js +61 -113
  345. package/lib/module/networking/apiClient.js.map +1 -1
  346. package/lib/module/networking/authRefresh.js +321 -0
  347. package/lib/module/networking/authRefresh.js.map +1 -0
  348. package/lib/module/networking/stanzaHandlers.js +41 -28
  349. package/lib/module/networking/stanzaHandlers.js.map +1 -1
  350. package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js +46 -8
  351. package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
  352. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js +8 -1
  353. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  354. package/lib/module/networking/xmpp/subscribeToRoomMessages.xmpp.js +5 -1
  355. package/lib/module/networking/xmpp/subscribeToRoomMessages.xmpp.js.map +1 -1
  356. package/lib/module/networking/xmppClient.js +124 -8
  357. package/lib/module/networking/xmppClient.js.map +1 -1
  358. package/lib/module/roomStore/chatSettingsSlice.js +26 -7
  359. package/lib/module/roomStore/chatSettingsSlice.js.map +1 -1
  360. package/lib/module/roomStore/index.js +37 -4
  361. package/lib/module/roomStore/index.js.map +1 -1
  362. package/lib/module/roomStore/persistence.js +223 -22
  363. package/lib/module/roomStore/persistence.js.map +1 -1
  364. package/lib/module/roomStore/roomsSlice.js +139 -34
  365. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  366. package/lib/module/services/pushSubscriptionService.js +15 -13
  367. package/lib/module/services/pushSubscriptionService.js.map +1 -1
  368. package/lib/module/version.js +1 -1
  369. package/lib/typescript/assets/icons.d.ts +16 -0
  370. package/lib/typescript/assets/icons.d.ts.map +1 -1
  371. package/lib/typescript/components/AuthForms/Login.d.ts.map +1 -1
  372. package/lib/typescript/components/Header/HeaderRoomList.d.ts.map +1 -1
  373. package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
  374. package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
  375. package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
  376. package/lib/typescript/components/MainComponents/LoginWrapper.d.ts.map +1 -1
  377. package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
  378. package/lib/typescript/components/MainComponents/MessageContainer.d.ts.map +1 -1
  379. package/lib/typescript/components/MainComponents/MessageList.d.ts +10 -1
  380. package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
  381. package/lib/typescript/components/MainComponents/ProfileImagePlaceholder.d.ts.map +1 -1
  382. package/lib/typescript/components/MainComponents/RoomList.d.ts +7 -0
  383. package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
  384. package/lib/typescript/components/Menu/HeaderRoomListMenu.d.ts +3 -0
  385. package/lib/typescript/components/Menu/HeaderRoomListMenu.d.ts.map +1 -1
  386. package/lib/typescript/components/Modals/AttachSheet/AttachSheet.d.ts +9 -0
  387. package/lib/typescript/components/Modals/AttachSheet/AttachSheet.d.ts.map +1 -1
  388. package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts +10 -0
  389. package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts.map +1 -1
  390. package/lib/typescript/components/Modals/ChatProfileModal/ReportChatModal.d.ts +9 -0
  391. package/lib/typescript/components/Modals/ChatProfileModal/ReportChatModal.d.ts.map +1 -0
  392. package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts.map +1 -1
  393. package/lib/typescript/components/Modals/FilePreviewModal/PdfView.d.ts.map +1 -1
  394. package/lib/typescript/components/Modals/Modal/Modal.d.ts.map +1 -1
  395. package/lib/typescript/components/Modals/NewChatModal/ModalContent.d.ts +4 -2
  396. package/lib/typescript/components/Modals/NewChatModal/ModalContent.d.ts.map +1 -1
  397. package/lib/typescript/components/Modals/NewChatModal/NewChatModal.d.ts +1 -1
  398. package/lib/typescript/components/Modals/NewChatModal/NewChatModal.d.ts.map +1 -1
  399. package/lib/typescript/components/Modals/NewChatModal/UpdNewChatModal.d.ts.map +1 -1
  400. package/lib/typescript/components/Modals/ProfileHeader/ProfileHeader.d.ts +75 -0
  401. package/lib/typescript/components/Modals/ProfileHeader/ProfileHeader.d.ts.map +1 -0
  402. package/lib/typescript/components/Modals/ProfileHeader/ProfileMenu.d.ts +25 -0
  403. package/lib/typescript/components/Modals/ProfileHeader/ProfileMenu.d.ts.map +1 -0
  404. package/lib/typescript/components/Modals/SelectUsersModal/SelectUsersModal.d.ts +6 -1
  405. package/lib/typescript/components/Modals/SelectUsersModal/SelectUsersModal.d.ts.map +1 -1
  406. package/lib/typescript/components/Modals/UserProfileModal/EditUserModal.d.ts.map +1 -1
  407. package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts +16 -0
  408. package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
  409. package/lib/typescript/components/Modals/UserSettingsModal/UserSettingsModal.d.ts +1 -0
  410. package/lib/typescript/components/Modals/UserSettingsModal/UserSettingsModal.d.ts.map +1 -1
  411. package/lib/typescript/components/Modals/styledModalComponents.d.ts.map +1 -1
  412. package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts.map +1 -1
  413. package/lib/typescript/components/RoomComponents/styled/LastMessageFile.d.ts +1 -1
  414. package/lib/typescript/components/RoomComponents/styled/LastMessageFile.d.ts.map +1 -1
  415. package/lib/typescript/components/RoomComponents/styled/LastMessagePhoto.d.ts +1 -1
  416. package/lib/typescript/components/RoomComponents/styled/LastMessagePhoto.d.ts.map +1 -1
  417. package/lib/typescript/components/RoomComponents/styled/LastMessageVideo.d.ts +1 -1
  418. package/lib/typescript/components/RoomComponents/styled/LastMessageVideo.d.ts.map +1 -1
  419. package/lib/typescript/components/VideoCalls/VideoCallSession.d.ts.map +1 -1
  420. package/lib/typescript/components/styled/AudioMessage.d.ts.map +1 -1
  421. package/lib/typescript/components/styled/MessageImage.d.ts +14 -0
  422. package/lib/typescript/components/styled/MessageImage.d.ts.map +1 -1
  423. package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
  424. package/lib/typescript/components/styled/StyledComponents.d.ts.map +1 -1
  425. package/lib/typescript/components/styled/StyledInputComponents/StyledInputComponents.d.ts.map +1 -1
  426. package/lib/typescript/components/styled/UnsupportedType.d.ts.map +1 -1
  427. package/lib/typescript/components/styled/VideoMessage.d.ts +8 -0
  428. package/lib/typescript/components/styled/VideoMessage.d.ts.map +1 -1
  429. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  430. package/lib/typescript/helpers/createMessageFromXml.d.ts.map +1 -1
  431. package/lib/typescript/helpers/getChatBackground.d.ts +15 -0
  432. package/lib/typescript/helpers/getChatBackground.d.ts.map +1 -0
  433. package/lib/typescript/helpers/getDisplayFileName.d.ts +49 -0
  434. package/lib/typescript/helpers/getDisplayFileName.d.ts.map +1 -0
  435. package/lib/typescript/helpers/getServerReadTimestamp.d.ts +108 -0
  436. package/lib/typescript/helpers/getServerReadTimestamp.d.ts.map +1 -0
  437. package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
  438. package/lib/typescript/helpers/initXmppRooms.d.ts.map +1 -1
  439. package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts +1 -1
  440. package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
  441. package/lib/typescript/helpers/isOwnMessage.d.ts +36 -0
  442. package/lib/typescript/helpers/isOwnMessage.d.ts.map +1 -0
  443. package/lib/typescript/helpers/keyboardLayout.d.ts +5 -1
  444. package/lib/typescript/helpers/keyboardLayout.d.ts.map +1 -1
  445. package/lib/typescript/helpers/mediaLibraryRuntime.d.ts +3 -0
  446. package/lib/typescript/helpers/mediaLibraryRuntime.d.ts.map +1 -0
  447. package/lib/typescript/helpers/mimeToExtension.d.ts +0 -15
  448. package/lib/typescript/helpers/mimeToExtension.d.ts.map +1 -1
  449. package/lib/typescript/helpers/msgSortableMs.d.ts +2 -0
  450. package/lib/typescript/helpers/msgSortableMs.d.ts.map +1 -0
  451. package/lib/typescript/helpers/persistCrypto.d.ts +13 -0
  452. package/lib/typescript/helpers/persistCrypto.d.ts.map +1 -0
  453. package/lib/typescript/helpers/pickImageAsset.d.ts +27 -0
  454. package/lib/typescript/helpers/pickImageAsset.d.ts.map +1 -0
  455. package/lib/typescript/helpers/pushPayload.d.ts +7 -0
  456. package/lib/typescript/helpers/pushPayload.d.ts.map +1 -0
  457. package/lib/typescript/helpers/resolveInitBeforeLoadUser.d.ts.map +1 -1
  458. package/lib/typescript/helpers/secureFileUrl.d.ts +7 -0
  459. package/lib/typescript/helpers/secureFileUrl.d.ts.map +1 -0
  460. package/lib/typescript/helpers/secureKeyValue.d.ts +13 -0
  461. package/lib/typescript/helpers/secureKeyValue.d.ts.map +1 -0
  462. package/lib/typescript/helpers/secureStoreRuntime.d.ts +29 -0
  463. package/lib/typescript/helpers/secureStoreRuntime.d.ts.map +1 -0
  464. package/lib/typescript/helpers/secureUserStorage.d.ts +23 -0
  465. package/lib/typescript/helpers/secureUserStorage.d.ts.map +1 -0
  466. package/lib/typescript/helpers/shallowEqual.d.ts +11 -0
  467. package/lib/typescript/helpers/shallowEqual.d.ts.map +1 -0
  468. package/lib/typescript/helpers/sheetGestures.d.ts +20 -0
  469. package/lib/typescript/helpers/sheetGestures.d.ts.map +1 -0
  470. package/lib/typescript/hooks/useChatRoomFocus.d.ts +4 -1
  471. package/lib/typescript/hooks/useChatRoomFocus.d.ts.map +1 -1
  472. package/lib/typescript/hooks/useChatWrapperInit.d.ts.map +1 -1
  473. package/lib/typescript/hooks/useComposing.d.ts.map +1 -1
  474. package/lib/typescript/hooks/useFileToken.d.ts +2 -0
  475. package/lib/typescript/hooks/useFileToken.d.ts.map +1 -0
  476. package/lib/typescript/hooks/useLogout.d.ts.map +1 -1
  477. package/lib/typescript/hooks/usePendingNotification.d.ts.map +1 -1
  478. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  479. package/lib/typescript/hooks/useUnreadMessagesCounter.d.ts +1 -0
  480. package/lib/typescript/hooks/useUnreadMessagesCounter.d.ts.map +1 -1
  481. package/lib/typescript/i18n/strings.d.ts.map +1 -1
  482. package/lib/typescript/main.d.ts +9 -2
  483. package/lib/typescript/main.d.ts.map +1 -1
  484. package/lib/typescript/networking/api-requests/auth.api.d.ts +3 -1
  485. package/lib/typescript/networking/api-requests/auth.api.d.ts.map +1 -1
  486. package/lib/typescript/networking/api-requests/user.api.d.ts +27 -0
  487. package/lib/typescript/networking/api-requests/user.api.d.ts.map +1 -1
  488. package/lib/typescript/networking/apiClient.d.ts +12 -6
  489. package/lib/typescript/networking/apiClient.d.ts.map +1 -1
  490. package/lib/typescript/networking/authRefresh.d.ts +95 -0
  491. package/lib/typescript/networking/authRefresh.d.ts.map +1 -0
  492. package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
  493. package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts +10 -2
  494. package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts.map +1 -1
  495. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
  496. package/lib/typescript/networking/xmpp/subscribeToRoomMessages.xmpp.d.ts.map +1 -1
  497. package/lib/typescript/networking/xmppClient.d.ts +14 -0
  498. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  499. package/lib/typescript/roomStore/chatSettingsSlice.d.ts +16 -0
  500. package/lib/typescript/roomStore/chatSettingsSlice.d.ts.map +1 -1
  501. package/lib/typescript/roomStore/index.d.ts.map +1 -1
  502. package/lib/typescript/roomStore/persistence.d.ts +18 -1
  503. package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
  504. package/lib/typescript/roomStore/roomsSlice.d.ts +43 -3
  505. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  506. package/lib/typescript/services/pushSubscriptionService.d.ts +1 -1
  507. package/lib/typescript/services/pushSubscriptionService.d.ts.map +1 -1
  508. package/lib/typescript/types/types.d.ts +50 -5
  509. package/lib/typescript/types/types.d.ts.map +1 -1
  510. package/lib/typescript/version.d.ts +1 -1
  511. package/package.json +41 -28
  512. package/src/assets/icons.tsx +48 -9
  513. package/src/components/AuthForms/Login.tsx +3 -3
  514. package/src/components/Header/HeaderRoomList.tsx +29 -7
  515. package/src/components/MainComponents/ChatHeader.tsx +9 -3
  516. package/src/components/MainComponents/ChatRoom.tsx +161 -15
  517. package/src/components/MainComponents/ChatWrapper.tsx +36 -20
  518. package/src/components/MainComponents/LoginWrapper.tsx +1 -0
  519. package/src/components/MainComponents/MediaMessage.tsx +26 -8
  520. package/src/components/MainComponents/MessageContainer.tsx +5 -1
  521. package/src/components/MainComponents/MessageList.tsx +23 -4
  522. package/src/components/MainComponents/ProfileImagePlaceholder.tsx +21 -14
  523. package/src/components/MainComponents/RoomList.tsx +236 -39
  524. package/src/components/Menu/HeaderRoomListMenu.tsx +328 -75
  525. package/src/components/Modals/AttachSheet/AttachSheet.tsx +333 -97
  526. package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +600 -282
  527. package/src/components/Modals/ChatProfileModal/ReportChatModal.tsx +244 -0
  528. package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +79 -38
  529. package/src/components/Modals/FilePreviewModal/PdfView.tsx +2 -1
  530. package/src/components/Modals/Modal/Modal.tsx +7 -0
  531. package/src/components/Modals/NewChatModal/ModalContent.tsx +6 -3
  532. package/src/components/Modals/NewChatModal/NewChatModal.tsx +219 -119
  533. package/src/components/Modals/NewChatModal/UpdNewChatModal.tsx +12 -1
  534. package/src/components/Modals/ProfileHeader/ProfileHeader.tsx +624 -0
  535. package/src/components/Modals/ProfileHeader/ProfileMenu.tsx +217 -0
  536. package/src/components/Modals/SelectUsersModal/SelectUsersModal.tsx +14 -4
  537. package/src/components/Modals/UserProfileModal/EditUserModal.tsx +9 -25
  538. package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +617 -307
  539. package/src/components/Modals/UserSettingsModal/UserSettingsModal.tsx +75 -58
  540. package/src/components/Modals/styledModalComponents.tsx +9 -2
  541. package/src/components/RoomComponents/ChatRoomItem.tsx +18 -3
  542. package/src/components/RoomComponents/styled/LastMessageFile.tsx +28 -4
  543. package/src/components/RoomComponents/styled/LastMessagePhoto.tsx +18 -3
  544. package/src/components/RoomComponents/styled/LastMessageVideo.tsx +18 -3
  545. package/src/components/VideoCalls/VideoCallSession.tsx +8 -3
  546. package/src/components/styled/AudioMessage.tsx +2 -1
  547. package/src/components/styled/MessageImage.tsx +53 -7
  548. package/src/components/styled/SendInput.tsx +83 -12
  549. package/src/components/styled/StyledComponents.ts +9 -3
  550. package/src/components/styled/StyledInputComponents/StyledInputComponents.tsx +11 -4
  551. package/src/components/styled/UnsupportedType.tsx +14 -4
  552. package/src/components/styled/VideoMessage.tsx +131 -54
  553. package/src/context/xmppProvider.tsx +216 -57
  554. package/src/helpers/createMessageFromXml.ts +20 -1
  555. package/src/helpers/ensureScopedChatCache.ts +2 -2
  556. package/src/helpers/getChatBackground.ts +18 -0
  557. package/src/helpers/getDisplayFileName.ts +87 -0
  558. package/src/helpers/getServerReadTimestamp.ts +197 -0
  559. package/src/helpers/historyPreloadScheduler.ts +80 -3
  560. package/src/helpers/initXmppRooms.tsx +14 -10
  561. package/src/helpers/insertMessageWithDelimiter.ts +55 -19
  562. package/src/helpers/isOwnMessage.ts +90 -0
  563. package/src/helpers/keyboardLayout.ts +23 -2
  564. package/src/helpers/mediaLibraryRuntime.ts +25 -0
  565. package/src/helpers/mimeToExtension.ts +6 -22
  566. package/src/helpers/msgSortableMs.ts +25 -0
  567. package/src/helpers/persistCrypto.ts +127 -0
  568. package/src/helpers/pickImageAsset.ts +68 -0
  569. package/src/helpers/pushPayload.ts +62 -0
  570. package/src/helpers/resolveInitBeforeLoadUser.ts +125 -18
  571. package/src/helpers/secureFileUrl.ts +103 -0
  572. package/src/helpers/secureKeyValue.ts +80 -0
  573. package/src/helpers/secureStoreRuntime.ts +62 -0
  574. package/src/helpers/secureUserStorage.ts +80 -0
  575. package/src/helpers/shallowEqual.ts +33 -0
  576. package/src/helpers/sheetGestures.ts +25 -0
  577. package/src/hooks/useChatRoomFocus.ts +49 -9
  578. package/src/hooks/useChatWrapperInit.ts +30 -10
  579. package/src/hooks/useComposing.tsx +37 -1
  580. package/src/hooks/useFileToken.ts +7 -0
  581. package/src/hooks/useLogout.tsx +29 -9
  582. package/src/hooks/usePendingNotification.ts +5 -11
  583. package/src/hooks/useSendMessage.tsx +60 -15
  584. package/src/hooks/useUnreadMessagesCounter.ts +11 -0
  585. package/src/i18n/strings.ts +145 -37
  586. package/src/main.ts +26 -2
  587. package/src/networking/api-requests/auth.api.ts +156 -48
  588. package/src/networking/api-requests/roomMembers.api.ts +1 -1
  589. package/src/networking/api-requests/rooms.api.ts +9 -9
  590. package/src/networking/api-requests/user.api.ts +79 -7
  591. package/src/networking/apiClient.ts +68 -123
  592. package/src/networking/authRefresh.ts +451 -0
  593. package/src/networking/stanzaHandlers.ts +44 -28
  594. package/src/networking/xmpp/flushLastViewedToPrivateStore.ts +71 -10
  595. package/src/networking/xmpp/presenceInRoom.xmpp.ts +6 -1
  596. package/src/networking/xmpp/subscribeToRoomMessages.xmpp.ts +12 -1
  597. package/src/networking/xmppClient.ts +141 -9
  598. package/src/roomStore/chatSettingsSlice.ts +34 -10
  599. package/src/roomStore/index.ts +40 -4
  600. package/src/roomStore/persistence.ts +234 -24
  601. package/src/roomStore/roomsSlice.ts +161 -29
  602. package/src/services/pushSubscriptionService.ts +18 -13
  603. package/src/types/types.ts +72 -5
  604. package/src/version.ts +1 -1
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Optional-dependency bridge for `expo-secure-store` — the Keychain
3
+ * (iOS) / Keystore-backed EncryptedSharedPreferences (Android) API.
4
+ *
5
+ * Mirrors `components/VideoCalls/livekitRuntime.ts`: a plain top-level
6
+ * `import ... from 'expo-secure-store'` is not allowed anywhere in the
7
+ * SDK, since Metro resolves imports at bundle time and a host that
8
+ * hasn't added this optional peer dependency would fail to build over
9
+ * a feature it never opted into. Everything goes through
10
+ * `loadSecureStore()`, which requires the module lazily and returns
11
+ * null when it isn't installed — callers fall back to plain
12
+ * AsyncStorage rather than crash (see `secureKeyValue.ts`).
13
+ */
14
+
15
+ export interface SecureStoreRuntime {
16
+ getItemAsync: (key: string) => Promise<string | null>;
17
+ setItemAsync: (key: string, value: string) => Promise<void>;
18
+ deleteItemAsync: (key: string) => Promise<void>;
19
+ }
20
+
21
+ let cached: SecureStoreRuntime | null | undefined;
22
+
23
+ /**
24
+ * Resolve the SecureStore runtime, or null when the optional native
25
+ * package isn't installed in the host app. Result is memoised
26
+ * (including the failure) so a missing dependency doesn't re-throw on
27
+ * every read/write.
28
+ */
29
+ export const loadSecureStore = (): SecureStoreRuntime | null => {
30
+ if (cached !== undefined) {
31
+ return cached;
32
+ }
33
+
34
+ try {
35
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
36
+ const mod = require('expo-secure-store');
37
+ if (
38
+ typeof mod?.getItemAsync !== 'function' ||
39
+ typeof mod?.setItemAsync !== 'function' ||
40
+ typeof mod?.deleteItemAsync !== 'function'
41
+ ) {
42
+ cached = null;
43
+ } else {
44
+ cached = {
45
+ getItemAsync: mod.getItemAsync,
46
+ setItemAsync: mod.setItemAsync,
47
+ deleteItemAsync: mod.deleteItemAsync,
48
+ };
49
+ }
50
+ } catch {
51
+ cached = null;
52
+ }
53
+
54
+ return cached;
55
+ };
56
+
57
+ export const isSecureStoreAvailable = (): boolean => loadSecureStore() !== null;
58
+
59
+ /** Test seam only. */
60
+ export const __resetSecureStoreRuntimeForTests = (): void => {
61
+ cached = undefined;
62
+ };
@@ -0,0 +1,80 @@
1
+ import { User } from '../types/types';
2
+ import { asyncLocalStorage } from '../hooks/useLocalStorage';
3
+ import { localStorageConstants } from './constants/LOCAL_STORAGE';
4
+ import { secureGet, secureSet, secureRemove } from './secureKeyValue';
5
+
6
+ // Keychain (iOS) / Keystore-backed EncryptedSharedPreferences (Android)
7
+ // keys for the four live bearer credentials on `User`. Deliberately one
8
+ // key per field rather than one JSON blob: expo-secure-store historically
9
+ // caps a single value's size on Android, and four short JWTs each stay
10
+ // comfortably under that ceiling where one combined blob might not.
11
+ const SECRET_KEYS = {
12
+ token: 'ethora_auth_token',
13
+ refreshToken: 'ethora_auth_refresh_token',
14
+ xmppPassword: 'ethora_auth_xmpp_password',
15
+ fileToken: 'ethora_auth_file_token',
16
+ } as const;
17
+
18
+ type SecretField = keyof typeof SECRET_KEYS;
19
+ const SECRET_FIELDS = Object.keys(SECRET_KEYS) as SecretField[];
20
+
21
+ /**
22
+ * Persisted-user storage, split across two backends behind the exact
23
+ * same `{ get, set, remove }` shape `asyncLocalStorage<User>(...)`
24
+ * already exposed — every existing call site swaps in by changing only
25
+ * the constructor call, `get()`/`set()`/`remove()` keep returning/taking
26
+ * a complete `User`.
27
+ *
28
+ * The four live credentials (REST access + refresh token, XMPP
29
+ * password, secure-media fileToken) never touch plain AsyncStorage:
30
+ * they go through `secureGet`/`secureSet`/`secureRemove` (platform
31
+ * Keychain/Keystore, falling back to namespaced AsyncStorage only when
32
+ * the host hasn't installed the optional `expo-secure-store` peer dep).
33
+ * Everything else on `User` — name, avatar, ids, xmppUsername, wallet
34
+ * address, none of it a bearer credential — keeps living under the
35
+ * existing `ETHORA_USER` AsyncStorage key, unchanged.
36
+ */
37
+ export function secureUserStorage() {
38
+ const get = async (): Promise<User | null> => {
39
+ const profile = await asyncLocalStorage<User>(
40
+ localStorageConstants.ETHORA_USER
41
+ ).get();
42
+ if (!profile) {return null;}
43
+
44
+ const secretValues = await Promise.all(
45
+ SECRET_FIELDS.map((field) => secureGet(SECRET_KEYS[field]))
46
+ );
47
+
48
+ const merged: User = { ...profile };
49
+ SECRET_FIELDS.forEach((field, i) => {
50
+ (merged as any)[field] = secretValues[i] || '';
51
+ });
52
+ return merged;
53
+ };
54
+
55
+ const set = async (user: User): Promise<void> => {
56
+ const profile: any = { ...user };
57
+ for (const field of SECRET_FIELDS) {
58
+ profile[field] = '';
59
+ }
60
+
61
+ await Promise.all([
62
+ asyncLocalStorage<User>(localStorageConstants.ETHORA_USER).set(profile),
63
+ ...SECRET_FIELDS.map((field) => {
64
+ const value = user?.[field] as string | undefined;
65
+ return value
66
+ ? secureSet(SECRET_KEYS[field], value)
67
+ : secureRemove(SECRET_KEYS[field]);
68
+ }),
69
+ ]);
70
+ };
71
+
72
+ const remove = async (): Promise<void> => {
73
+ await Promise.all([
74
+ asyncLocalStorage(localStorageConstants.ETHORA_USER).remove(),
75
+ ...SECRET_FIELDS.map((field) => secureRemove(SECRET_KEYS[field])),
76
+ ]);
77
+ };
78
+
79
+ return { get, set, remove };
80
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * One-level shallow equality for plain objects. Used to avoid re-dispatching
3
+ * config into redux on every render just because the host passed a fresh
4
+ * object literal with the same values (e.g. `<Chat config={{...}} />`
5
+ * re-created inline) — reference equality alone would fire far too often,
6
+ * and a deep/JSON comparison risks throwing on non-serializable fields
7
+ * (functions, React elements) that configs legitimately carry.
8
+ */
9
+ export function shallowEqual(a: unknown, b: unknown): boolean {
10
+ if (a === b) {return true;}
11
+ if (
12
+ typeof a !== 'object' ||
13
+ typeof b !== 'object' ||
14
+ a === null ||
15
+ b === null
16
+ ) {
17
+ return false;
18
+ }
19
+ const aKeys = Object.keys(a as Record<string, unknown>);
20
+ const bKeys = Object.keys(b as Record<string, unknown>);
21
+ if (aKeys.length !== bKeys.length) {return false;}
22
+ for (const key of aKeys) {
23
+ if (
24
+ (a as Record<string, unknown>)[key] !==
25
+ (b as Record<string, unknown>)[key]
26
+ ) {
27
+ return false;
28
+ }
29
+ }
30
+ return true;
31
+ }
32
+
33
+ export default shallowEqual;
@@ -0,0 +1,25 @@
1
+ /** @format */
2
+
3
+ /**
4
+ * Shared thresholds for the drag-to-dismiss gesture on bottom sheets (the
5
+ * attach sheet, the profile headers, the room-list menu). Kept in one
6
+ * place so a pull feels identical wherever the user does it — and so the
7
+ * numbers are unit-testable without a touch event.
8
+ */
9
+
10
+ /** Drag past this many points and letting go dismisses the sheet. */
11
+ export const DISMISS_DISTANCE = 90;
12
+ /** …or flick faster than this, however short the drag. */
13
+ export const DISMISS_VELOCITY = 0.8;
14
+
15
+ /**
16
+ * Claim a drag only once it is clearly a downward pull, so a tap on a row
17
+ * still registers and a horizontal swipe stays with whatever scrolls
18
+ * sideways inside the sheet.
19
+ */
20
+ export const shouldClaimVerticalDrag = (dy: number, dx: number) =>
21
+ dy > 6 && Math.abs(dy) > Math.abs(dx) * 1.5;
22
+
23
+ /** Far enough / fast enough to let go of the sheet. */
24
+ export const shouldDismissOnDrag = (dy: number, vy: number) =>
25
+ dy > DISMISS_DISTANCE || vy > DISMISS_VELOCITY;
@@ -1,12 +1,17 @@
1
1
  import { useEffect, useRef } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
3
  import {
4
+ clearReadBoundary,
4
5
  clearVisibleRoom,
5
6
  setCurrentRoom,
6
7
  setLastViewedTimestamp,
7
8
  setVisibleRoom,
8
9
  } from '../roomStore/roomsSlice';
9
10
  import { store } from '../roomStore';
11
+ import {
12
+ getFlushBoundaryTs,
13
+ getReadMarkerTimestamp,
14
+ } from '../helpers/getServerReadTimestamp';
10
15
 
11
16
  interface UseChatRoomFocusOptions {
12
17
  /** The room JID that the consumer's tab/screen is currently showing. */
@@ -32,7 +37,10 @@ interface UseChatRoomFocusOptions {
32
37
  * Without this hook, `useUnread()` will always return 0 for the chat
33
38
  * room because the SDK assumes "mounted == active". With this hook,
34
39
  * focus marks the room visible (clearing the badge) and blur stamps
35
- * `lastViewedTimestamp = Date.now()` so future messages count as unread.
40
+ * `lastViewedTimestamp` to the newest SERVER-acknowledged message so
41
+ * future messages count as unread. Deliberately not `Date.now()`: a
42
+ * device clock running ahead would write a future marker that the
43
+ * forward-only private-store merge could never correct again (bug #38).
36
44
  *
37
45
  * Usage with React Navigation:
38
46
  *
@@ -58,20 +66,52 @@ export const useChatRoomFocus = ({
58
66
  isFocused: false,
59
67
  });
60
68
 
61
- const leaveRoom = (jid: string) => {
62
- const timestamp = Date.now();
63
- dispatch(setLastViewedTimestamp({ chatJID: jid, timestamp }));
69
+ // `clearBoundary`: pass true only when the room the user is leaving is
70
+ // genuinely being released (switching to a different room, or this
71
+ // hook unmounting) - not on a mere same-room blur. `<ChatRoom>`'s
72
+ // MessageList typically stays mounted across a same-room focus loss
73
+ // (the whole point of this hook is that the host keeps `<Chat>`
74
+ // mounted in a hidden tab), so its own scroll-tracking ref is still
75
+ // intact and the redux boundary must stay in sync with it - clearing
76
+ // it here would desync the two.
77
+ const leaveRoom = (jid: string, clearBoundary: boolean) => {
78
+ const state = store.getState();
79
+ const rooms = state.rooms?.rooms;
80
+ const boundaryTs = state.rooms?.readBoundaries?.[jid] ?? null;
81
+ // getReadMarkerTimestamp: honour the boundary (the newest message the
82
+ // user actually reached) when the user left this room scrolled up,
83
+ // otherwise fall back to the newest server-acked message. Only stamp
84
+ // when we actually have something to anchor to - skip rather than
85
+ // fall back to the device clock (bug #38). Ignoring the boundary here
86
+ // would stamp "everything read" regardless of scroll position (bug
87
+ // #42, a regression of #33 reintroduced by #38).
88
+ const timestamp = getReadMarkerTimestamp(rooms?.[jid], state.roomHeapSlice, boundaryTs);
89
+ if (timestamp > 0) {
90
+ dispatch(setLastViewedTimestamp({ chatJID: jid, timestamp }));
91
+ }
64
92
  dispatch(clearVisibleRoom());
65
- const rooms = store.getState().rooms?.rooms;
66
- (store.getState().chatSettingStore as any)?.client
67
- ?.flushLastViewedToPrivateStoreStanza(rooms, { visibleRoomJID: jid })
93
+ (state.chatSettingStore as any)?.client
94
+ ?.flushLastViewedToPrivateStoreStanza(rooms, {
95
+ visibleRoomJID: jid,
96
+ // Carry the same boundary to the SERVER marker - without it the
97
+ // flush defaults to "everything" for the visible room. Clamped
98
+ // through the same helper as the local stamp above.
99
+ visibleRoomTs: getFlushBoundaryTs(
100
+ rooms?.[jid],
101
+ state.roomHeapSlice,
102
+ boundaryTs
103
+ ),
104
+ })
68
105
  .catch(() => {});
106
+ if (clearBoundary) {
107
+ dispatch(clearReadBoundary({ jid }));
108
+ }
69
109
  };
70
110
 
71
111
  useEffect(() => {
72
112
  const prev = prevRef.current;
73
113
  if (prev.isFocused && prev.roomJID && (prev.roomJID !== roomJID || !isFocused)) {
74
- leaveRoom(prev.roomJID);
114
+ leaveRoom(prev.roomJID, prev.roomJID !== roomJID);
75
115
  }
76
116
 
77
117
  if (roomJID && isFocused) {
@@ -86,7 +126,7 @@ export const useChatRoomFocus = ({
86
126
  return () => {
87
127
  const prev = prevRef.current;
88
128
  if (prev.isFocused && prev.roomJID) {
89
- leaveRoom(prev.roomJID);
129
+ leaveRoom(prev.roomJID, true);
90
130
  }
91
131
  };
92
132
  }, []);
@@ -9,9 +9,8 @@ import { AppDispatch, RootState } from '../roomStore';
9
9
  import { useXmppClient } from '../context/xmppProvider';
10
10
  import { chatAutoEnterer } from '../helpers/chatAutoEnterer';
11
11
  import { initRoomsPresence } from '../helpers/initRoomsPresence';
12
- import { updatedChatLastTimestamps } from '../helpers/updatedChatLastTimestamps';
13
12
  import { updateMessagesTillLast } from '../helpers/updateMessagesTillLast';
14
- import { refresh } from '../networking/apiClient';
13
+ import { refreshAuthTokensQuietly } from '../networking/authRefresh';
15
14
  import { setLangSource, setConfig } from '../roomStore/chatSettingsSlice';
16
15
  import { setIsLoading } from '../roomStore/roomsSlice';
17
16
  import { useRoomState } from './useRoomState';
@@ -19,6 +18,7 @@ import { useChatSettingState } from './useChatSettingState';
19
18
  import { isChatIdPresentInArray } from '../helpers/isChatIdPresentInArray';
20
19
  import useGetNewArchRoom from './useGetNewArchRoom';
21
20
  import { getRoomsWithRetry } from '../helpers/getRoomsWithRetry';
21
+ import { shallowEqual } from '../helpers/shallowEqual';
22
22
 
23
23
  interface useChatWrapperInitProps {
24
24
  roomJID: string | null | undefined;
@@ -66,6 +66,20 @@ const useChatWrapperInit = ({
66
66
  };
67
67
  }, [user.xmppPassword]);
68
68
 
69
+ // Presentational config flags (e.g. `disableHeader`) can change while the
70
+ // chat stays mounted — sync them to redux whenever `config` actually
71
+ // changes, not just at init. Shallow-equal guard: an inline object
72
+ // literal from the host is a fresh reference every render even when
73
+ // nothing in it changed, and dispatching unconditionally would re-render
74
+ // every config consumer on every host render.
75
+ const lastSyncedConfigRef = useRef<IConfig | undefined>(undefined);
76
+ useEffect(() => {
77
+ if (!shallowEqual(lastSyncedConfigRef.current, config)) {
78
+ lastSyncedConfigRef.current = config;
79
+ dispatch(setConfig(config));
80
+ }
81
+ }, [config, dispatch]);
82
+
69
83
  const getRoomsWithRertyRequest = async () => {
70
84
  setIsRetrying(true);
71
85
  const retryRooms = await getRoomsWithRetry(
@@ -159,15 +173,21 @@ const useChatWrapperInit = ({
159
173
  }
160
174
  }
161
175
  try {
176
+ // getChatsPrivateStoreRequestStanza hydrates redux itself
177
+ // (dispatch(applyPrivateStoreMarkers(...)) internally,
178
+ // clamped + forward-only) - do not also apply the raw
179
+ // return value here. That used to double-dispatch via
180
+ // updatedChatLastTimestamps' unconditional
181
+ // setLastViewedTimestamp, which has neither the
182
+ // forward-only guard nor the future-marker clamp, so on
183
+ // every reconnect it could silently re-clobber a value
184
+ // the clamp had just corrected (bug #38).
162
185
  const roomTimestampObject: any =
163
186
  await newClient.getChatsPrivateStoreRequestStanza();
164
187
  console.log(
165
188
  'Got chats private store',
166
189
  roomTimestampObject?.length || 0
167
190
  );
168
- if (roomTimestampObject) {
169
- updatedChatLastTimestamps(roomTimestampObject, dispatch);
170
- }
171
191
  if (!hasSyncedHistoryRef.current) {
172
192
  console.log('Updating messages till last');
173
193
  await updateMessagesTillLast(rooms, newClient);
@@ -183,7 +203,7 @@ const useChatWrapperInit = ({
183
203
  }
184
204
 
185
205
  {
186
- config?.refreshTokens?.enabled && refresh();
206
+ config?.refreshTokens?.enabled && refreshAuthTokensQuietly();
187
207
  }
188
208
  } catch (error) {
189
209
  console.error(' Error during initialization', error);
@@ -209,15 +229,15 @@ const useChatWrapperInit = ({
209
229
  setInited(true);
210
230
  console.log(' Getting chats private store for existing client');
211
231
  try {
232
+ // See the "new client" branch above: getChatsPrivateStoreRequestStanza
233
+ // already hydrates redux (clamped + forward-only); do not
234
+ // also apply the raw return value here.
212
235
  const roomTimestampObject: any =
213
236
  await client.getChatsPrivateStoreRequestStanza();
214
237
  console.log(
215
238
  'Got chats private store for existing client',
216
239
  roomTimestampObject?.length || 0
217
240
  );
218
- if (roomTimestampObject) {
219
- updatedChatLastTimestamps(roomTimestampObject, dispatch);
220
- }
221
241
  if (!hasSyncedHistoryRef.current) {
222
242
  console.log(
223
243
  'Updating messages till last for existing client'
@@ -237,7 +257,7 @@ const useChatWrapperInit = ({
237
257
  setConnectionLost(false);
238
258
  }
239
259
  {
240
- config?.refreshTokens?.enabled && refresh();
260
+ config?.refreshTokens?.enabled && refreshAuthTokensQuietly();
241
261
  }
242
262
  }
243
263
  }
@@ -1,4 +1,5 @@
1
- import { useCallback, useEffect, useState } from 'react';
1
+ import { useCallback, useEffect, useRef } from 'react';
2
+ import { AppState, AppStateStatus } from 'react-native';
2
3
  import { useXmppClient } from '../context/xmppProvider';
3
4
  import { useSelector } from 'react-redux';
4
5
  import { RootState } from '../roomStore';
@@ -9,8 +10,16 @@ const useComposing = (config?: IConfig) => {
9
10
  const { client } = useXmppClient();
10
11
  const { activeRoomJID } = useSelector((state: RootState) => state.rooms);
11
12
  const { user } = useChatSettingState();
13
+ // RN keeps a focused TextInput focused when the app is backgrounded or
14
+ // the device is locked — nothing fires `onBlur`, so without this the
15
+ // other participant sees "typing…" for as long as the user is away.
16
+ // Tracks whether the input is *currently* focused, independent of the
17
+ // foreground/background transition, so we know whether to resume
18
+ // composing on return.
19
+ const isFocusedRef = useRef(false);
12
20
 
13
21
  const sendStartComposing = useCallback(() => {
22
+ isFocusedRef.current = true;
14
23
  if (config?.disableTypingIndicator) {
15
24
  return;
16
25
  }
@@ -24,6 +33,7 @@ const useComposing = (config?: IConfig) => {
24
33
  }, [activeRoomJID, client, config?.disableTypingIndicator, user.firstName, user.lastName]);
25
34
 
26
35
  const sendEndComposing = useCallback(() => {
36
+ isFocusedRef.current = false;
27
37
  if (config?.disableTypingIndicator) {
28
38
  return;
29
39
  }
@@ -44,6 +54,32 @@ const useComposing = (config?: IConfig) => {
44
54
  return () => clearTimeout(timerId);
45
55
  }, [sendEndComposing]);
46
56
 
57
+ // Foreground/background transition only — a pause in typing must NOT
58
+ // clear the indicator (that would flicker for a slowly-composing user),
59
+ // so this deliberately does not hook keystroke/idle timing at all.
60
+ useEffect(() => {
61
+ const handleAppStateChange = (nextState: AppStateStatus) => {
62
+ if (nextState !== 'active') {
63
+ if (isFocusedRef.current && !config?.disableTypingIndicator && client) {
64
+ client.sendTypingRequestStanza(
65
+ activeRoomJID || '',
66
+ `${user.firstName} ${user.lastName}`,
67
+ false
68
+ );
69
+ }
70
+ } else if (isFocusedRef.current && !config?.disableTypingIndicator && client) {
71
+ client.sendTypingRequestStanza(
72
+ activeRoomJID || '',
73
+ `${user.firstName} ${user.lastName}`,
74
+ true
75
+ );
76
+ }
77
+ };
78
+
79
+ const subscription = AppState.addEventListener('change', handleAppStateChange);
80
+ return () => subscription.remove();
81
+ }, [activeRoomJID, client, config?.disableTypingIndicator, user.firstName, user.lastName]);
82
+
47
83
  return { sendStartComposing, sendEndComposing };
48
84
  };
49
85
 
@@ -0,0 +1,7 @@
1
+ import { useSelector } from 'react-redux';
2
+ import { RootState } from '../roomStore';
3
+
4
+ export const useFileToken = (): string =>
5
+ useSelector(
6
+ (state: RootState) => state.chatSettingStore.user?.fileToken || ''
7
+ );
@@ -9,7 +9,8 @@ import { clearHeap } from '../roomStore/roomHeapSlice';
9
9
  import { pushSubscriptionService } from '../services/pushSubscriptionService';
10
10
  import { clearRoomsRestCache } from '../networking/api-requests/rooms.api';
11
11
  import { clearPersistedState } from '../roomStore/persistence';
12
- import { localStorageConstants } from '../helpers/constants/LOCAL_STORAGE';
12
+ import { secureUserStorage } from '../helpers/secureUserStorage';
13
+ import { getFlushBoundaryTs } from '../helpers/getServerReadTimestamp';
13
14
 
14
15
  // AsyncStorage keys the library writes but that aren't cleared by any
15
16
  // slice reducer. Listed here so a single logout call wipes the full
@@ -59,10 +60,23 @@ const logoutService = {
59
60
  const client = (state.chatSettingStore as any)?.client;
60
61
  const rooms = state.rooms?.rooms;
61
62
  const visibleRoomJID = state.rooms?.visibleRoomJID || null;
63
+ // The visible room is exempt from `onlyIfNoUnread`'s skip (it's
64
+ // meant to write "read up to now" for whatever's open), so if the
65
+ // user is logging out while scrolled up with unread messages
66
+ // above, the boundary must still be carried through here - same
67
+ // reasoning as every other "leaving a room" path (bug #42).
68
+ const boundaryTs = visibleRoomJID
69
+ ? getFlushBoundaryTs(
70
+ rooms?.[visibleRoomJID],
71
+ state.roomHeapSlice,
72
+ state.rooms?.readBoundaries?.[visibleRoomJID] ?? null
73
+ )
74
+ : undefined;
62
75
  if (client?.flushLastViewedToPrivateStoreStanza) {
63
76
  await Promise.race([
64
77
  client.flushLastViewedToPrivateStoreStanza(rooms, {
65
78
  visibleRoomJID,
79
+ visibleRoomTs: boundaryTs,
66
80
  onlyIfNoUnread: true,
67
81
  }),
68
82
  new Promise((res) => setTimeout(res, 2000)),
@@ -120,17 +134,23 @@ const logoutService = {
120
134
 
121
135
  // 6. Stray keys the slices don't touch.
122
136
  try {
123
- await AsyncStorage.multiRemove([
124
- ...LIBRARY_STRAY_KEYS,
125
- // Belt-and-suspenders: the chat slice's `logout` reducer
126
- // schedules an async remove of ETHORA_USER fire-and-forget;
127
- // re-issue it here so the disk is provably clean before this
128
- // Promise resolves.
129
- localStorageConstants.ETHORA_USER,
130
- ]);
137
+ await AsyncStorage.multiRemove(LIBRARY_STRAY_KEYS);
131
138
  } catch (e) {
132
139
  console.warn('logoutService: stray-key clear failed', e);
133
140
  }
141
+
142
+ // 7. Belt-and-suspenders: the chat slice's `logout` reducer already
143
+ // fires an async ETHORA_USER removal, but re-issue it here (via
144
+ // the same secureUserStorage split the reducer uses) so BOTH the
145
+ // plain-AsyncStorage profile half AND the Keychain/Keystore
146
+ // secrets are provably gone before this Promise resolves — a bare
147
+ // `AsyncStorage.removeItem(ETHORA_USER)` here would only clear the
148
+ // profile half and leave the tokens behind.
149
+ try {
150
+ await secureUserStorage().remove();
151
+ } catch (e) {
152
+ console.warn('logoutService: secure user storage clear failed', e);
153
+ }
134
154
  },
135
155
  };
136
156
 
@@ -4,7 +4,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
4
4
  import { RootState } from '../roomStore';
5
5
  import { setCurrentRoom, clearPendingNotificationJid } from '../roomStore/roomsSlice';
6
6
 
7
- const PENDING_NOTIFICATION_JID_KEY = 'ethora_pending_notification_jid';
7
+ import { PENDING_NOTIFICATION_JID_KEY, readPendingJid } from '../helpers/pushPayload';
8
8
 
9
9
  export function usePendingNotification() {
10
10
  const dispatch = useDispatch();
@@ -21,21 +21,15 @@ export function usePendingNotification() {
21
21
  let jidToOpen = pendingNotificationJid;
22
22
 
23
23
  if (!jidToOpen) {
24
- try {
25
- const storedJid = await AsyncStorage.getItem(PENDING_NOTIFICATION_JID_KEY);
26
- if (storedJid) {
27
- jidToOpen = storedJid;
28
- await AsyncStorage.removeItem(PENDING_NOTIFICATION_JID_KEY);
29
- }
30
- } catch (error) {
31
- console.error('Error reading from AsyncStorage:', error);
32
- }
24
+ jidToOpen = await readPendingJid();
33
25
  }
34
26
 
35
27
  if (jidToOpen) {
36
28
  const room = rooms[jidToOpen];
37
29
  if (room) {
38
- return;
30
+ dispatch(clearPendingNotificationJid());
31
+ AsyncStorage.removeItem(PENDING_NOTIFICATION_JID_KEY).catch(() => undefined);
32
+ dispatch(setCurrentRoom({ roomJID: jidToOpen }));
39
33
  }
40
34
  }
41
35
  };