@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
@@ -6,10 +6,12 @@ import { useDispatch } from 'react-redux';
6
6
  import MessageList from './MessageList';
7
7
  import SendInput from '../styled/SendInput';
8
8
  import {
9
+ clearReadBoundary,
9
10
  clearVisibleRoom,
10
11
  deleteRoomMessage,
11
12
  setEditAction,
12
13
  setLastViewedTimestamp,
14
+ setReadBoundary,
13
15
  setVisibleRoom,
14
16
  } from '../../roomStore/roomsSlice';
15
17
  import Loader from '../styled/Loader';
@@ -20,6 +22,7 @@ import NewChatModal from '../Modals/NewChatModal/NewChatModal';
20
22
  import { EditWrapper } from './EditWrapper';
21
23
  import { EmptyChatIllustration } from '../../assets/EmptyChatIllustration';
22
24
  import { getIconColor } from '../../helpers/getIconColor';
25
+ import { getChatBackgroundColor } from '../../helpers/getChatBackground';
23
26
  import { ChooseChatMessage } from './ChooseChatMessage';
24
27
  import { useRoomUrl } from '../../hooks/useRoomUrl';
25
28
  import { useSendMessage } from '../../hooks/useSendMessage';
@@ -27,10 +30,14 @@ import { IConfig } from '../../types/models/config.model';
27
30
  import { useRoomInitialization } from '../../hooks/useRoomInitialization';
28
31
  import { useRoomState } from '../../hooks/useRoomState';
29
32
  import { useChatSettingState } from '../../hooks/useChatSettingState';
33
+ import { isOwnMessage } from '../../helpers/isOwnMessage';
30
34
  import CustomTypingIndicator from '../styled/StyledInputComponents/CustomTypingIndicator';
31
35
  // import {PanGestureHandler} from 'react-native-gesture-handler';
32
36
  import { FlatList } from 'react-native';
33
37
  import {
38
+ AppState,
39
+ AppStateStatus,
40
+ Keyboard,
34
41
  Platform,
35
42
  TouchableWithoutFeedback,
36
43
  View,
@@ -42,6 +49,10 @@ import {
42
49
  } from 'react-native-keyboard-controller';
43
50
  import useComposing from '../../hooks/useComposing';
44
51
  import { store } from '../../roomStore';
52
+ import {
53
+ getFlushBoundaryTs,
54
+ getReadMarkerTimestamp,
55
+ } from '../../helpers/getServerReadTimestamp';
45
56
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
46
57
  import {
47
58
  getInputDockPaddingBottom,
@@ -106,6 +117,45 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
106
117
  configWithEventHandlers || storeConfig,
107
118
  );
108
119
 
120
+ // Under the sticky keyboard strategy, the input dock's position is
121
+ // driven by KeyboardStickyView's native-animated offset. If the app
122
+ // is backgrounded while the keyboard-close animation hasn't finished,
123
+ // the OS removes the keyboard from the app-switcher snapshot but the
124
+ // shared value hasn't caught up to "closed" yet, so the input appears
125
+ // to float in that preview.
126
+ //
127
+ // NOTE on what this does and doesn't fix: iOS actually captures that
128
+ // preview during the active→inactive transition, BEFORE 'background'
129
+ // fires — so dismissing here on 'background' lands too late to affect
130
+ // the snapshot already taken, and is effectively a no-op for the exact
131
+ // iOS symptom in bug #37. An earlier version keyed this off 'inactive'
132
+ // instead, which does land in time, but 'inactive' also fires for
133
+ // Control Center, share sheets, and permission prompts — none of which
134
+ // should close the user's keyboard — so that traded a rare cosmetic
135
+ // preview glitch for a much more common false dismissal. Kept on
136
+ // 'background': it still resets the offset for genuine backgrounding
137
+ // (home button, app switch) and for Android's recents preview (RN's
138
+ // AppState has no 'inactive' there), at the cost of leaving the iOS
139
+ // switcher-preview glitch itself unresolved. Both symptoms are cosmetic
140
+ // per the QA report, which explicitly accepted leaving this imperfect
141
+ // rather than risk destabilizing the sticky strategy. Sticky-only;
142
+ // doesn't touch the other keyboard strategies.
143
+ const stickyInputEnabled =
144
+ !configWithEventHandlers?.disableKeyboardAvoidingView &&
145
+ !!configWithEventHandlers?.keyboardStickyInput;
146
+ useEffect(() => {
147
+ if (!stickyInputEnabled) {
148
+ return;
149
+ }
150
+ const onAppStateChange = (nextState: AppStateStatus) => {
151
+ if (nextState === 'background') {
152
+ Keyboard.dismiss();
153
+ }
154
+ };
155
+ const subscription = AppState.addEventListener('change', onAppStateChange);
156
+ return () => subscription.remove();
157
+ }, [stickyInputEnabled]);
158
+
109
159
  const sendMessage = useCallback(
110
160
  (message: string) => {
111
161
  if (!activeRoomJID) {
@@ -170,31 +220,103 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
170
220
  clientRef.current = client;
171
221
  }, [client]);
172
222
 
223
+ // Tracks what the user actually saw: `null` while they're at the
224
+ // bottom (safe to mark everything read), or the timestamp of the
225
+ // newest message visible when they scrolled away from it. Reported
226
+ // by MessageList via onReadBoundaryChange, and mirrored into redux
227
+ // (`rooms.readBoundaries`) rather than kept only in a local ref - it
228
+ // is the single source of truth every "leaving this room" path
229
+ // consults (xmppProvider's AppState background handler, its
230
+ // `isVisible=false` handler, the live `advance()` effect, and
231
+ // `useChatRoomFocus`'s `leaveRoom`), not just this component's own
232
+ // unmount cleanup below. Without a boundary, leaving a room (or
233
+ // backgrounding) while scrolled up stamped `now()` (bug #33) or,
234
+ // after the #38 fix, the newest acked message regardless of scroll
235
+ // position (bug #42) - both silently discard genuinely-unread
236
+ // messages.
237
+ //
238
+ // MessageList reports the boundary from onScroll, which fires on
239
+ // every frame of a drag (the "back at the bottom" branch re-reports
240
+ // `null` each time). Mirror only actual CHANGES into redux: an
241
+ // unconditional dispatch per scroll frame would run the whole
242
+ // middleware chain and, worse, reset persistenceMiddleware's 200 ms
243
+ // debounce on every frame, starving the persisted write for as long
244
+ // as the user keeps scrolling.
245
+ const lastBoundarySentRef = useRef<number | null>(null);
246
+ const handleReadBoundaryChange = useCallback((boundaryTs: number | null) => {
247
+ if (!activeRoomJID) {
248
+ return;
249
+ }
250
+ const next = boundaryTs && boundaryTs > 0 ? boundaryTs : null;
251
+ if (lastBoundarySentRef.current === next) {
252
+ return;
253
+ }
254
+ lastBoundarySentRef.current = next;
255
+ dispatch(setReadBoundary({ jid: activeRoomJID, ts: next }));
256
+ }, [activeRoomJID, dispatch]);
257
+
173
258
  useEffect(() => {
174
259
  if (!activeRoomJID) {
175
260
  return;
176
261
  }
177
262
 
263
+ lastBoundarySentRef.current = null;
264
+ dispatch(setReadBoundary({ jid: activeRoomJID, ts: null }));
178
265
  dispatch(setVisibleRoom({ roomJID: activeRoomJID }));
179
266
  setIsLoadingMore(false);
180
267
  return () => {
181
- const timestamp = new Date().getTime();
182
- dispatch(
183
- setLastViewedTimestamp({
184
- chatJID: activeRoomJID,
185
- timestamp,
186
- }),
268
+ const state = store.getState();
269
+ const rooms = state.rooms?.rooms;
270
+ const heapState = state.roomHeapSlice;
271
+ const boundaryTs = state.rooms?.readBoundaries?.[activeRoomJID] ?? null;
272
+ // getReadMarkerTimestamp honours the boundary (the newest message
273
+ // the user actually reached) when one is set, and otherwise falls
274
+ // back to the newest server-acked message - never the device
275
+ // clock: a fast device clock would write a future marker that the
276
+ // forward-only private-store merge could never correct (bug #38).
277
+ const timestamp = getReadMarkerTimestamp(
278
+ rooms?.[activeRoomJID],
279
+ heapState,
280
+ boundaryTs,
187
281
  );
282
+ if (timestamp > 0) {
283
+ dispatch(
284
+ setLastViewedTimestamp({
285
+ chatJID: activeRoomJID,
286
+ timestamp,
287
+ }),
288
+ );
289
+ }
188
290
  dispatch(clearVisibleRoom());
189
291
  const liveClient = clientRef.current;
190
292
  if (liveClient) {
191
293
  liveClient
192
- .flushLastViewedToPrivateStoreStanza(store.getState().rooms?.rooms, {
294
+ .flushLastViewedToPrivateStoreStanza(rooms, {
193
295
  visibleRoomJID: activeRoomJID,
296
+ // Carry the same boundary to the SERVER marker. Without
297
+ // this the flush defaults to "everything" for the visible
298
+ // room, so messages the user never scrolled down to come
299
+ // back as read on the next login - the local count was
300
+ // right but the server overrode it.
301
+ // Clamped through the same helper as the local stamp -
302
+ // an unclamped boundary would bypass the newest-acked
303
+ // ceiling on the one path where a bad value is permanent
304
+ // (the private-store merge is forward-only, bug #38).
305
+ visibleRoomTs: getFlushBoundaryTs(
306
+ rooms?.[activeRoomJID],
307
+ heapState,
308
+ boundaryTs,
309
+ ),
194
310
  })
195
311
  .catch(() => {});
196
312
  }
197
313
  dispatch(deleteRoomMessage({ roomJID: activeRoomJID, messageId: 'delimiter-new' }));
314
+ // The room is genuinely being left (unmount, or activeRoomJID
315
+ // changed to a different room) - release the boundary now that
316
+ // it's been consumed, so a stale value can't leak into the next
317
+ // time this room becomes visible.
318
+ dispatch(clearReadBoundary({ jid: activeRoomJID }));
319
+ lastBoundarySentRef.current = null;
198
320
  setIsLoadingMore(false);
199
321
  };
200
322
  }, [activeRoomJID, dispatch]);
@@ -230,6 +352,8 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
230
352
  const inputDockPaddingBottom = getInputDockPaddingBottom({
231
353
  platform: Platform.OS,
232
354
  bottomInset: insets.bottom,
355
+ configuredPadding: configWithEventHandlers?.inputDockPaddingBottom,
356
+ hostOwnsLayout: !!configWithEventHandlers?.disableKeyboardAvoidingView,
233
357
  });
234
358
 
235
359
  // Keyboard avoidance is delegated to react-native-keyboard-controller's
@@ -279,7 +403,20 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
279
403
  ? KeyboardStickyView
280
404
  : View;
281
405
  const inputDockProps: any = {
282
- style: { paddingBottom: inputDockPaddingBottom, backgroundColor: '#fff' },
406
+ // The dock carries the composer's white surface all the way to the
407
+ // bottom edge, so it needs the same rounded top and upward shadow —
408
+ // a square white block behind a rounded composer just hid the corners.
409
+ style: {
410
+ paddingBottom: inputDockPaddingBottom,
411
+ backgroundColor: '#fff',
412
+ borderTopLeftRadius: 20,
413
+ borderTopRightRadius: 20,
414
+ shadowColor: '#101828',
415
+ shadowOffset: { width: 0, height: -4 },
416
+ shadowOpacity: 0.06,
417
+ shadowRadius: 12,
418
+ elevation: 8,
419
+ },
283
420
  ...(stickyInput
284
421
  ? { offset: { closed: 0, opened: keyboardVerticalOffset } }
285
422
  : {}),
@@ -288,11 +425,15 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
288
425
  return (
289
426
  <KeyboardWrapper {...keyboardWrapperProps}>
290
427
  <ChatContainer
291
- style={
292
- configWithEventHandlers?.chatRoomStyles
293
- ? (configWithEventHandlers.chatRoomStyles as import('react-native').ViewStyle)
294
- : undefined
295
- }
428
+ // The conversation's own colour, not white: the header's rounded
429
+ // bottom corners and the composer's rounded top corners reveal
430
+ // THIS view, so a white parent made both look square.
431
+ style={[
432
+ { backgroundColor: getChatBackgroundColor(configWithEventHandlers) },
433
+ configWithEventHandlers?.chatRoomStyles as
434
+ | import('react-native').ViewStyle
435
+ | undefined,
436
+ ]}
296
437
  >
297
438
  {!configWithEventHandlers?.disableHeader && (
298
439
  <ChatHeader
@@ -331,7 +472,11 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
331
472
  flex: 1,
332
473
  justifyContent: 'center',
333
474
  alignItems: 'center',
334
- backgroundColor: '#ffffff',
475
+ // Empty rooms used to flip to white, which broke the
476
+ // header's rounded corners in exactly the same way.
477
+ backgroundColor: getChatBackgroundColor(
478
+ configWithEventHandlers
479
+ ),
335
480
  }}
336
481
  >
337
482
  <NoMessagesPlaceholder />
@@ -357,7 +502,7 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
357
502
  CustomMessageComponent ? (
358
503
  <CustomMessageComponent
359
504
  message={decorated.message}
360
- isUser={decorated.message.user.id === user.xmppUsername}
505
+ isUser={isOwnMessage(decorated.message, user)}
361
506
  isReply={false}
362
507
  />
363
508
  ) : null
@@ -404,6 +549,7 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
404
549
  config={configWithEventHandlers}
405
550
  loading={isLoadingMore}
406
551
  isReply={false}
552
+ onReadBoundaryChange={handleReadBoundaryChange}
407
553
  />
408
554
  )}
409
555
  </View>
@@ -1,4 +1,4 @@
1
- import React, {FC, useEffect, useMemo, useState} from 'react';
1
+ import React, {FC, useEffect, useMemo, useRef, useState} from 'react';
2
2
  import {useDispatch, useSelector} from 'react-redux';
3
3
  import ChatRoom from './ChatRoom';
4
4
  import {
@@ -28,17 +28,19 @@ import {
28
28
  setIsLoading,
29
29
  setLastViewedTimestamp,
30
30
  } from '../../roomStore/roomsSlice';
31
- import {refresh} from '../../networking/apiClient';
31
+ import {refreshAuthTokensQuietly} from '../../networking/authRefresh';
32
32
  import RoomList from './RoomList';
33
33
  import {StyledLoaderWrapper} from '../styled/StyledComponents';
34
34
  import Modal from '../Modals/Modal/Modal';
35
35
  import ThreadWrapper from '../Thread/ThreadWrapper';
36
36
  import {ModalWrapper} from '../Modals/ModalWrapper/ModalWrapper';
37
37
  import {useChatSettingState} from '../../hooks/useChatSettingState';
38
+ import { usePendingNotification } from '../../hooks/usePendingNotification';
38
39
  import {DeviceEventEmitter, Pressable, Text, View} from 'react-native';
39
40
  import {pushLog as devPushLog} from '../../utils/devLogger';
40
41
  import {normalizeRoomJid} from '../../helpers/normalizeRoomJid';
41
42
  import {buildSeedRoom} from '../../helpers/buildSeedRoom';
43
+ import {shallowEqual} from '../../helpers/shallowEqual';
42
44
  import {InteractionsOverlayProvider} from '../MessageBubble/InteractionsOverlay';
43
45
 
44
46
  interface ChatWrapperProps {
@@ -65,6 +67,8 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
65
67
  client: storedClient,
66
68
  } = useChatSettingState();
67
69
 
70
+ usePendingNotification();
71
+
68
72
  const [isInited, setInited] = useState(false);
69
73
  const [showModal, setShowModal] = useState(false);
70
74
  const [errorMsg, setErrorMsg] = useState<string | null>(null);
@@ -186,6 +190,23 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
186
190
  dispatch(addRoom({roomData: buildSeedRoom(seededRoomJID)}));
187
191
  }, [seededRoomJID, seededRoomMissing, dispatch]);
188
192
 
193
+ // Presentational config flags (e.g. `disableHeader`) can change while the
194
+ // chat stays mounted — sync them to redux whenever `config` actually
195
+ // changes, not just at init. Kept separate from the init effect below so
196
+ // toggling a flag doesn't re-run client/token setup. Guarded with a
197
+ // shallow-equal check (not just the `config` reference) because hosts
198
+ // commonly pass an inline object literal (`<Chat config={{...}}/>`) that
199
+ // is a new reference on every render even when nothing in it changed —
200
+ // dispatching unconditionally there would re-render every config
201
+ // consumer (ChatRoom, modals, ...) on every host render.
202
+ const lastSyncedConfigRef = useRef<IConfig | undefined>(undefined);
203
+ useEffect(() => {
204
+ if (config && !shallowEqual(lastSyncedConfigRef.current, config)) {
205
+ lastSyncedConfigRef.current = config;
206
+ dispatch(setConfig(config));
207
+ }
208
+ }, [config, dispatch]);
209
+
189
210
  useEffect(() => {
190
211
  if (roomJID) {
191
212
  dispatch(
@@ -195,6 +216,16 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
195
216
  );
196
217
  }
197
218
 
219
+ // Top-up rotation after the client is up. Deduped inside
220
+ // `refreshAuthTokensQuietly`, so it can no longer race the 401
221
+ // interceptor into a second, parallel rotation — which the backend
222
+ // would read as reuse. Never rejects, hence no `.catch` here.
223
+ const ensureFreshTokens = () => {
224
+ if (config?.refreshTokens?.enabled) {
225
+ refreshAuthTokensQuietly();
226
+ }
227
+ };
228
+
198
229
  const initXmmpClient = async () => {
199
230
  // Only sync config to redux if we have one — passing `undefined`
200
231
  // wipes whatever XmppProvider already set up.
@@ -285,14 +316,7 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
285
316
  devPushLog('warn', 'initializeClient failed (legacy path)', err);
286
317
  }
287
318
  setInited(true);
288
- if (config?.refreshTokens?.enabled) {
289
- // refresh() is fire-and-forget but rejects on bad
290
- // refreshToken / network — surface via .catch instead of
291
- // leaving the rejection unhandled (was bug #4, id:2).
292
- refresh().catch((err) =>
293
- console.warn('refresh failed', err)
294
- );
295
- }
319
+ ensureFreshTokens();
296
320
  } else if (storedClient) {
297
321
  devPushLog('rn', 'ChatWrapper: reusing storedClient');
298
322
  setClient(storedClient);
@@ -307,11 +331,7 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
307
331
  .catch((err: unknown) => console.warn('getRoomsStanza failed', err));
308
332
  }
309
333
  setInited(true);
310
- if (config?.refreshTokens?.enabled) {
311
- refresh().catch((err) =>
312
- console.warn('refresh failed', err)
313
- );
314
- }
334
+ ensureFreshTokens();
315
335
  } else if (client) {
316
336
  devPushLog('rn', 'ChatWrapper: reusing provider client');
317
337
  if (!activeRoomJID) {
@@ -328,11 +348,7 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
328
348
  console.warn('getChatsPrivateStoreRequestStanza failed', err)
329
349
  );
330
350
  setInited(true);
331
- if (config?.refreshTokens?.enabled) {
332
- refresh().catch((err) =>
333
- console.warn('refresh failed', err)
334
- );
335
- }
351
+ ensureFreshTokens();
336
352
  }
337
353
 
338
354
  dispatch(setIsLoading({loading: false}));
@@ -36,6 +36,7 @@ const LoginWrapper: React.FC<LoginWrapperProps> = ({...props}) => {
36
36
  ...authData.data.user,
37
37
  token: authData.data.token,
38
38
  refreshToken: authData.data.refreshToken,
39
+ fileToken: (authData.data as any).fileToken || '',
39
40
  };
40
41
  } catch (error) {
41
42
  console.error('Login failed:', error);
@@ -11,10 +11,13 @@ import {
11
11
  Text,
12
12
  View,
13
13
  } from 'react-native';
14
- import { deriveDisplayFilename, isLikelyAudio } from '../../helpers/mimeToExtension';
14
+ import { isLikelyAudio } from '../../helpers/mimeToExtension';
15
+ import { getDisplayFileName } from '../../helpers/getDisplayFileName';
15
16
  import { FileIcon, PlayIcon } from '../../assets/icons';
16
17
  import { defaultMediaDims } from '../../helpers/mediaDimensions';
17
18
  import { useChatSettingState } from '../../hooks/useChatSettingState';
19
+ import { useFileToken } from '../../hooks/useFileToken';
20
+ import { appendFileToken } from '../../helpers/secureFileUrl';
18
21
 
19
22
  interface MediaMessageProps {
20
23
  mimeType?: string;
@@ -136,22 +139,26 @@ const PendingMediaMessage: React.FC<{
136
139
 
137
140
  const MediaMessage: React.FC<MediaMessageProps> = ({
138
141
  mimeType,
139
- location,
140
- messageText,
142
+ location: rawLocation,
143
+ messageText: rawMessageText,
141
144
  message,
142
145
  isUser,
143
146
  }) => {
147
+ const fileToken = useFileToken();
148
+ const location = appendFileToken(rawLocation, fileToken);
149
+ const messageText = appendFileToken(rawMessageText, fileToken);
150
+
144
151
  if (mimeType) {
145
- const displayName = deriveDisplayFilename({
146
- fileName: message?.fileName,
152
+ const displayName = getDisplayFileName({
147
153
  originalName: (message as any)?.originalName,
148
- url: location || messageText,
149
- mime: mimeType,
154
+ fileName: message?.fileName,
155
+ location: rawLocation || rawMessageText,
156
+ mimetype: mimeType,
150
157
  });
151
158
  const isAudioPayload = isLikelyAudio(
152
159
  mimeType,
153
160
  displayName,
154
- location,
161
+ rawLocation,
155
162
  {
156
163
  duration: (message as any)?.duration,
157
164
  waveForm: (message as any)?.waveForm,
@@ -174,7 +181,12 @@ const MediaMessage: React.FC<MediaMessageProps> = ({
174
181
  return (
175
182
  <CustomMessageImage
176
183
  fileName={displayName}
184
+ originalName={(message as any)?.originalName}
185
+ // Full-size original: opened by the preview modal.
177
186
  fileURL={location || messageText || ''}
187
+ // ...and the thumbnail the bubble actually renders, which is
188
+ // what the web client shows too.
189
+ locationPreview={messageText}
178
190
  mimetype={mimeType}
179
191
  />
180
192
  );
@@ -182,7 +194,13 @@ const MediaMessage: React.FC<MediaMessageProps> = ({
182
194
  return (
183
195
  <CustomMessageVideo
184
196
  fileName={displayName}
197
+ originalName={(message as any)?.originalName}
185
198
  fileURL={location || ''}
199
+ // `messageText` is the message's locationPreview — the poster
200
+ // frame the backend generated for this video. Handing it over
201
+ // lets the bubble render as a still + play badge instead of
202
+ // mounting a video surface per row (see VideoMessage).
203
+ previewURL={messageText}
186
204
  mimetype={mimeType}
187
205
  />
188
206
  );
@@ -1,5 +1,6 @@
1
1
  import React, { FC, Fragment, useMemo } from 'react';
2
2
  import { IConfig, IMessage } from '../../types/types';
3
+ import { isOwnMessage } from '../../helpers/isOwnMessage';
3
4
  import DateLabel from '../styled/DateLabel';
4
5
  import SystemMessage from './SystemMessage';
5
6
  import NewMessageLabel from '../styled/NewMessageLabel';
@@ -46,7 +47,10 @@ export const MessageContainer: FC<MessageContainerProps> = ({
46
47
  isReply,
47
48
  className,
48
49
  }) => {
49
- const isUser = message.user.id === walletAddress;
50
+ // Bug #41: `message.user.id === walletAddress` used to treat two
51
+ // empty/undefined ids as a match, briefly rendering catch-up messages
52
+ // from other users as our own. isOwnMessage() never does that.
53
+ const isUser = isOwnMessage(message, walletAddress);
50
54
 
51
55
  const messageDate = new Date(message.date);
52
56
 
@@ -28,6 +28,8 @@ import Loader from '../styled/Loader';
28
28
  import { ArowDownIcon } from '../../assets/icons';
29
29
  import CustomTypingIndicator from '../styled/StyledInputComponents/CustomTypingIndicator';
30
30
  import { getIconColor } from '../../helpers/getIconColor';
31
+ import { getChatBackgroundColor } from '../../helpers/getChatBackground';
32
+ import { isOwnMessage } from '../../helpers/isOwnMessage';
31
33
 
32
34
  interface MessageListProps<TMessage extends IMessage> {
33
35
  CustomMessage?: React.ComponentType<{
@@ -53,6 +55,15 @@ interface MessageListProps<TMessage extends IMessage> {
53
55
  config?: IConfig;
54
56
  isReply: boolean;
55
57
  activeMessage?: IMessage;
58
+ /**
59
+ * Fired whenever the "read up to" boundary changes: `null` while the
60
+ * user is at the bottom (everything is read), or the timestamp of the
61
+ * newest message they'd actually seen when they scrolled away from it.
62
+ * Lets the host mark only what was actually viewed as read instead of
63
+ * stamping "now" on unmount/leave, which would wrongly clear unread
64
+ * messages the user scrolled up and never got back down to.
65
+ */
66
+ onReadBoundaryChange?: (boundaryTs: number | null) => void;
56
67
  }
57
68
 
58
69
  const MessageList = <TMessage extends IMessage>({
@@ -66,6 +77,7 @@ const MessageList = <TMessage extends IMessage>({
66
77
  loading,
67
78
  isReply,
68
79
  activeMessage,
80
+ onReadBoundaryChange,
69
81
  }: MessageListProps<TMessage>) => {
70
82
  const { composing, messages, composingList } = useRoomState(roomJID)
71
83
  .room! as IRoom;
@@ -332,6 +344,7 @@ const MessageList = <TMessage extends IMessage>({
332
344
  // counter so the badge disappears with the arrow.
333
345
  setUnreadWhileScrolledUp(0);
334
346
  newestSeenTsRef.current = null;
347
+ onReadBoundaryChange?.(null);
335
348
  } else {
336
349
  isUserAtBottomRef.current = false;
337
350
  if (hasUserScrolledRef.current) {
@@ -349,11 +362,12 @@ const MessageList = <TMessage extends IMessage>({
349
362
  },
350
363
  0
351
364
  );
365
+ onReadBoundaryChange?.(newestSeenTsRef.current);
352
366
  }
353
367
  setIsUserAtBottom(false);
354
368
  }
355
369
  },
356
- [memoizedMessages]
370
+ [memoizedMessages, onReadBoundaryChange]
357
371
  );
358
372
 
359
373
  // Keep the badge in sync with messages that arrive while the user is
@@ -382,6 +396,7 @@ const MessageList = <TMessage extends IMessage>({
382
396
  setIsUserAtBottom(true);
383
397
  setUnreadWhileScrolledUp(0);
384
398
  newestSeenTsRef.current = null;
399
+ onReadBoundaryChange?.(null);
385
400
  scrollToBottom();
386
401
  };
387
402
 
@@ -392,6 +407,8 @@ const MessageList = <TMessage extends IMessage>({
392
407
  setIsUserAtBottom(true);
393
408
  setUnreadWhileScrolledUp(0);
394
409
  newestSeenTsRef.current = null;
410
+ onReadBoundaryChange?.(null);
411
+ // eslint-disable-next-line react-hooks/exhaustive-deps
395
412
  }, [roomJID]);
396
413
 
397
414
  const BackgroundImage = useMemo(() => {
@@ -413,7 +430,7 @@ const MessageList = <TMessage extends IMessage>({
413
430
  <View
414
431
  style={[
415
432
  styles.container,
416
- { backgroundColor: config?.backgroundChat?.color || '#F3F6FC' },
433
+ { backgroundColor: getChatBackgroundColor(config) },
417
434
  ]}
418
435
  >
419
436
  <View style={styles.backgroundImageContainer}>{BackgroundImage}</View>
@@ -422,7 +439,7 @@ const MessageList = <TMessage extends IMessage>({
422
439
  {CustomMessage && (
423
440
  <CustomMessage
424
441
  message={activeMessage}
425
- isUser={activeMessage.user.id === user.walletAddress}
442
+ isUser={isOwnMessage(activeMessage, user)}
426
443
  isReply={isReply}
427
444
  />
428
445
  )}
@@ -442,7 +459,9 @@ const MessageList = <TMessage extends IMessage>({
442
459
  onLayout={handleLayout}
443
460
  inverted={true}
444
461
  keyboardShouldPersistTaps="handled"
445
- keyboardDismissMode="interactive"
462
+ keyboardDismissMode={
463
+ config?.keepKeyboardOpenOnScroll ? 'none' : 'interactive'
464
+ }
446
465
  contentContainerStyle={styles.flatListContent}
447
466
  ListFooterComponent={
448
467
  loading && memoizedMessages.length > 15 ? (