@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.
- package/CHANGELOG.md +96 -0
- package/README.md +43 -10
- package/lib/commonjs/assets/icons.js +7 -2
- package/lib/commonjs/assets/icons.js.map +1 -1
- package/lib/commonjs/components/AuthForms/Login.js +4 -4
- package/lib/commonjs/components/AuthForms/Login.js.map +1 -1
- package/lib/commonjs/components/Header/HeaderRoomList.js +29 -8
- package/lib/commonjs/components/Header/HeaderRoomList.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatHeader.js +9 -3
- package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatRoom.js +150 -14
- package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatWrapper.js +34 -13
- package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/LoginWrapper.js +2 -1
- package/lib/commonjs/components/MainComponents/LoginWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MediaMessage.js +29 -9
- package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MessageContainer.js +5 -1
- package/lib/commonjs/components/MainComponents/MessageContainer.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MessageList.js +13 -5
- package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ProfileImagePlaceholder.js +14 -13
- package/lib/commonjs/components/MainComponents/ProfileImagePlaceholder.js.map +1 -1
- package/lib/commonjs/components/MainComponents/RoomList.js +208 -35
- package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
- package/lib/commonjs/components/Menu/HeaderRoomListMenu.js +317 -98
- package/lib/commonjs/components/Menu/HeaderRoomListMenu.js.map +1 -1
- package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js +322 -110
- package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js +546 -203
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js +226 -0
- package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -0
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +69 -27
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js +2 -1
- package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
- package/lib/commonjs/components/Modals/Modal/Modal.js +8 -0
- package/lib/commonjs/components/Modals/Modal/Modal.js.map +1 -1
- package/lib/commonjs/components/Modals/NewChatModal/ModalContent.js +2 -1
- package/lib/commonjs/components/Modals/NewChatModal/ModalContent.js.map +1 -1
- package/lib/commonjs/components/Modals/NewChatModal/NewChatModal.js +202 -106
- package/lib/commonjs/components/Modals/NewChatModal/NewChatModal.js.map +1 -1
- package/lib/commonjs/components/Modals/NewChatModal/UpdNewChatModal.js +8 -0
- package/lib/commonjs/components/Modals/NewChatModal/UpdNewChatModal.js.map +1 -1
- package/lib/commonjs/components/Modals/ProfileHeader/ProfileHeader.js +563 -0
- package/lib/commonjs/components/Modals/ProfileHeader/ProfileHeader.js.map +1 -0
- package/lib/commonjs/components/Modals/ProfileHeader/ProfileMenu.js +210 -0
- package/lib/commonjs/components/Modals/ProfileHeader/ProfileMenu.js.map +1 -0
- package/lib/commonjs/components/Modals/SelectUsersModal/SelectUsersModal.js +4 -2
- package/lib/commonjs/components/Modals/SelectUsersModal/SelectUsersModal.js.map +1 -1
- package/lib/commonjs/components/Modals/UserProfileModal/EditUserModal.js +7 -21
- package/lib/commonjs/components/Modals/UserProfileModal/EditUserModal.js.map +1 -1
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +507 -244
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js +74 -46
- package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
- package/lib/commonjs/components/Modals/styledModalComponents.js +9 -2
- package/lib/commonjs/components/Modals/styledModalComponents.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/ChatRoomItem.js +21 -7
- package/lib/commonjs/components/RoomComponents/ChatRoomItem.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/styled/LastMessageFile.js +22 -3
- package/lib/commonjs/components/RoomComponents/styled/LastMessageFile.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/styled/LastMessagePhoto.js +17 -3
- package/lib/commonjs/components/RoomComponents/styled/LastMessagePhoto.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/styled/LastMessageVideo.js +17 -3
- package/lib/commonjs/components/RoomComponents/styled/LastMessageVideo.js.map +1 -1
- package/lib/commonjs/components/VideoCalls/VideoCallSession.js +6 -3
- package/lib/commonjs/components/VideoCalls/VideoCallSession.js.map +1 -1
- package/lib/commonjs/components/styled/AudioMessage.js +2 -1
- package/lib/commonjs/components/styled/AudioMessage.js.map +1 -1
- package/lib/commonjs/components/styled/MessageImage.js +37 -9
- package/lib/commonjs/components/styled/MessageImage.js.map +1 -1
- package/lib/commonjs/components/styled/SendInput.js +80 -11
- package/lib/commonjs/components/styled/SendInput.js.map +1 -1
- package/lib/commonjs/components/styled/StyledComponents.js +9 -3
- package/lib/commonjs/components/styled/StyledComponents.js.map +1 -1
- package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js +11 -4
- package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
- package/lib/commonjs/components/styled/UnsupportedType.js +14 -4
- package/lib/commonjs/components/styled/UnsupportedType.js.map +1 -1
- package/lib/commonjs/components/styled/VideoMessage.js +119 -61
- package/lib/commonjs/components/styled/VideoMessage.js.map +1 -1
- package/lib/commonjs/context/xmppProvider.js +184 -59
- package/lib/commonjs/context/xmppProvider.js.map +1 -1
- package/lib/commonjs/helpers/createMessageFromXml.js +19 -1
- package/lib/commonjs/helpers/createMessageFromXml.js.map +1 -1
- package/lib/commonjs/helpers/ensureScopedChatCache.js +2 -2
- package/lib/commonjs/helpers/ensureScopedChatCache.js.map +1 -1
- package/lib/commonjs/helpers/getChatBackground.js +23 -0
- package/lib/commonjs/helpers/getChatBackground.js.map +1 -0
- package/lib/commonjs/helpers/getDisplayFileName.js +79 -0
- package/lib/commonjs/helpers/getDisplayFileName.js.map +1 -0
- package/lib/commonjs/helpers/getServerReadTimestamp.js +188 -0
- package/lib/commonjs/helpers/getServerReadTimestamp.js.map +1 -0
- package/lib/commonjs/helpers/historyPreloadScheduler.js +65 -2
- package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/commonjs/helpers/initXmppRooms.js +14 -8
- package/lib/commonjs/helpers/initXmppRooms.js.map +1 -1
- package/lib/commonjs/helpers/insertMessageWithDelimiter.js +51 -9
- package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
- package/lib/commonjs/helpers/isOwnMessage.js +75 -0
- package/lib/commonjs/helpers/isOwnMessage.js.map +1 -0
- package/lib/commonjs/helpers/keyboardLayout.js +12 -2
- package/lib/commonjs/helpers/keyboardLayout.js.map +1 -1
- package/lib/commonjs/helpers/mediaLibraryRuntime.js +31 -0
- package/lib/commonjs/helpers/mediaLibraryRuntime.js.map +1 -0
- package/lib/commonjs/helpers/mimeToExtension.js +6 -14
- package/lib/commonjs/helpers/mimeToExtension.js.map +1 -1
- package/lib/commonjs/helpers/msgSortableMs.js +37 -0
- package/lib/commonjs/helpers/msgSortableMs.js.map +1 -0
- package/lib/commonjs/helpers/persistCrypto.js +122 -0
- package/lib/commonjs/helpers/persistCrypto.js.map +1 -0
- package/lib/commonjs/helpers/pickImageAsset.js +68 -0
- package/lib/commonjs/helpers/pickImageAsset.js.map +1 -0
- package/lib/commonjs/helpers/pushPayload.js +71 -0
- package/lib/commonjs/helpers/pushPayload.js.map +1 -0
- package/lib/commonjs/helpers/resolveInitBeforeLoadUser.js +130 -17
- package/lib/commonjs/helpers/resolveInitBeforeLoadUser.js.map +1 -1
- package/lib/commonjs/helpers/secureFileUrl.js +101 -0
- package/lib/commonjs/helpers/secureFileUrl.js.map +1 -0
- package/lib/commonjs/helpers/secureKeyValue.js +83 -0
- package/lib/commonjs/helpers/secureKeyValue.js.map +1 -0
- package/lib/commonjs/helpers/secureStoreRuntime.js +59 -0
- package/lib/commonjs/helpers/secureStoreRuntime.js.map +1 -0
- package/lib/commonjs/helpers/secureUserStorage.js +75 -0
- package/lib/commonjs/helpers/secureUserStorage.js.map +1 -0
- package/lib/commonjs/helpers/shallowEqual.js +36 -0
- package/lib/commonjs/helpers/shallowEqual.js.map +1 -0
- package/lib/commonjs/helpers/sheetGestures.js +32 -0
- package/lib/commonjs/helpers/sheetGestures.js.map +1 -0
- package/lib/commonjs/hooks/useChatRoomFocus.js +45 -12
- package/lib/commonjs/hooks/useChatRoomFocus.js.map +1 -1
- package/lib/commonjs/hooks/useChatWrapperInit.js +30 -10
- package/lib/commonjs/hooks/useChatWrapperInit.js.map +1 -1
- package/lib/commonjs/hooks/useComposing.js +27 -0
- package/lib/commonjs/hooks/useComposing.js.map +1 -1
- package/lib/commonjs/hooks/useFileToken.js +10 -0
- package/lib/commonjs/hooks/useFileToken.js.map +1 -0
- package/lib/commonjs/hooks/useLogout.js +23 -7
- package/lib/commonjs/hooks/useLogout.js.map +1 -1
- package/lib/commonjs/hooks/usePendingNotification.js +8 -11
- package/lib/commonjs/hooks/usePendingNotification.js.map +1 -1
- package/lib/commonjs/hooks/useSendMessage.js +50 -14
- package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
- package/lib/commonjs/hooks/useUnreadMessagesCounter.js +6 -1
- package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
- package/lib/commonjs/i18n/strings.js +145 -37
- package/lib/commonjs/i18n/strings.js.map +1 -1
- package/lib/commonjs/main.js +44 -0
- package/lib/commonjs/main.js.map +1 -1
- package/lib/commonjs/networking/api-requests/auth.api.js +134 -60
- package/lib/commonjs/networking/api-requests/auth.api.js.map +1 -1
- package/lib/commonjs/networking/api-requests/roomMembers.api.js +1 -1
- package/lib/commonjs/networking/api-requests/roomMembers.api.js.map +1 -1
- package/lib/commonjs/networking/api-requests/rooms.api.js +9 -9
- package/lib/commonjs/networking/api-requests/rooms.api.js.map +1 -1
- package/lib/commonjs/networking/api-requests/user.api.js +68 -9
- package/lib/commonjs/networking/api-requests/user.api.js.map +1 -1
- package/lib/commonjs/networking/apiClient.js +62 -112
- package/lib/commonjs/networking/apiClient.js.map +1 -1
- package/lib/commonjs/networking/authRefresh.js +332 -0
- package/lib/commonjs/networking/authRefresh.js.map +1 -0
- package/lib/commonjs/networking/stanzaHandlers.js +41 -28
- package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
- package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js +46 -8
- package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
- package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js +8 -1
- package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/subscribeToRoomMessages.xmpp.js +5 -1
- package/lib/commonjs/networking/xmpp/subscribeToRoomMessages.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmppClient.js +124 -8
- package/lib/commonjs/networking/xmppClient.js.map +1 -1
- package/lib/commonjs/roomStore/chatSettingsSlice.js +26 -7
- package/lib/commonjs/roomStore/chatSettingsSlice.js.map +1 -1
- package/lib/commonjs/roomStore/index.js +35 -2
- package/lib/commonjs/roomStore/index.js.map +1 -1
- package/lib/commonjs/roomStore/persistence.js +226 -23
- package/lib/commonjs/roomStore/persistence.js.map +1 -1
- package/lib/commonjs/roomStore/roomsSlice.js +151 -38
- package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
- package/lib/commonjs/services/pushSubscriptionService.js +15 -13
- package/lib/commonjs/services/pushSubscriptionService.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/module/assets/icons.js +6 -1
- package/lib/module/assets/icons.js.map +1 -1
- package/lib/module/components/AuthForms/Login.js +4 -4
- package/lib/module/components/AuthForms/Login.js.map +1 -1
- package/lib/module/components/Header/HeaderRoomList.js +29 -8
- package/lib/module/components/Header/HeaderRoomList.js.map +1 -1
- package/lib/module/components/MainComponents/ChatHeader.js +9 -3
- package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/module/components/MainComponents/ChatRoom.js +152 -16
- package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/module/components/MainComponents/ChatWrapper.js +35 -14
- package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/LoginWrapper.js +2 -1
- package/lib/module/components/MainComponents/LoginWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/MediaMessage.js +30 -10
- package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
- package/lib/module/components/MainComponents/MessageContainer.js +5 -1
- package/lib/module/components/MainComponents/MessageContainer.js.map +1 -1
- package/lib/module/components/MainComponents/MessageList.js +13 -5
- package/lib/module/components/MainComponents/MessageList.js.map +1 -1
- package/lib/module/components/MainComponents/ProfileImagePlaceholder.js +14 -13
- package/lib/module/components/MainComponents/ProfileImagePlaceholder.js.map +1 -1
- package/lib/module/components/MainComponents/RoomList.js +207 -35
- package/lib/module/components/MainComponents/RoomList.js.map +1 -1
- package/lib/module/components/Menu/HeaderRoomListMenu.js +319 -101
- package/lib/module/components/Menu/HeaderRoomListMenu.js.map +1 -1
- package/lib/module/components/Modals/AttachSheet/AttachSheet.js +313 -113
- package/lib/module/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js +549 -207
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js +223 -0
- package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -0
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +70 -28
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/module/components/Modals/FilePreviewModal/PdfView.js +2 -1
- package/lib/module/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
- package/lib/module/components/Modals/Modal/Modal.js +9 -1
- package/lib/module/components/Modals/Modal/Modal.js.map +1 -1
- package/lib/module/components/Modals/NewChatModal/ModalContent.js +2 -1
- package/lib/module/components/Modals/NewChatModal/ModalContent.js.map +1 -1
- package/lib/module/components/Modals/NewChatModal/NewChatModal.js +205 -108
- package/lib/module/components/Modals/NewChatModal/NewChatModal.js.map +1 -1
- package/lib/module/components/Modals/NewChatModal/UpdNewChatModal.js +8 -0
- package/lib/module/components/Modals/NewChatModal/UpdNewChatModal.js.map +1 -1
- package/lib/module/components/Modals/ProfileHeader/ProfileHeader.js +555 -0
- package/lib/module/components/Modals/ProfileHeader/ProfileHeader.js.map +1 -0
- package/lib/module/components/Modals/ProfileHeader/ProfileMenu.js +205 -0
- package/lib/module/components/Modals/ProfileHeader/ProfileMenu.js.map +1 -0
- package/lib/module/components/Modals/SelectUsersModal/SelectUsersModal.js +4 -2
- package/lib/module/components/Modals/SelectUsersModal/SelectUsersModal.js.map +1 -1
- package/lib/module/components/Modals/UserProfileModal/EditUserModal.js +9 -23
- package/lib/module/components/Modals/UserProfileModal/EditUserModal.js.map +1 -1
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +509 -248
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js +76 -48
- package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
- package/lib/module/components/Modals/styledModalComponents.js +9 -2
- package/lib/module/components/Modals/styledModalComponents.js.map +1 -1
- package/lib/module/components/RoomComponents/ChatRoomItem.js +21 -7
- package/lib/module/components/RoomComponents/ChatRoomItem.js.map +1 -1
- package/lib/module/components/RoomComponents/styled/LastMessageFile.js +22 -3
- package/lib/module/components/RoomComponents/styled/LastMessageFile.js.map +1 -1
- package/lib/module/components/RoomComponents/styled/LastMessagePhoto.js +17 -3
- package/lib/module/components/RoomComponents/styled/LastMessagePhoto.js.map +1 -1
- package/lib/module/components/RoomComponents/styled/LastMessageVideo.js +17 -3
- package/lib/module/components/RoomComponents/styled/LastMessageVideo.js.map +1 -1
- package/lib/module/components/VideoCalls/VideoCallSession.js +6 -3
- package/lib/module/components/VideoCalls/VideoCallSession.js.map +1 -1
- package/lib/module/components/styled/AudioMessage.js +2 -1
- package/lib/module/components/styled/AudioMessage.js.map +1 -1
- package/lib/module/components/styled/MessageImage.js +37 -9
- package/lib/module/components/styled/MessageImage.js.map +1 -1
- package/lib/module/components/styled/SendInput.js +81 -12
- package/lib/module/components/styled/SendInput.js.map +1 -1
- package/lib/module/components/styled/StyledComponents.js +9 -3
- package/lib/module/components/styled/StyledComponents.js.map +1 -1
- package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js +11 -4
- package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
- package/lib/module/components/styled/UnsupportedType.js +14 -4
- package/lib/module/components/styled/UnsupportedType.js.map +1 -1
- package/lib/module/components/styled/VideoMessage.js +120 -62
- package/lib/module/components/styled/VideoMessage.js.map +1 -1
- package/lib/module/context/xmppProvider.js +184 -60
- package/lib/module/context/xmppProvider.js.map +1 -1
- package/lib/module/helpers/createMessageFromXml.js +19 -1
- package/lib/module/helpers/createMessageFromXml.js.map +1 -1
- package/lib/module/helpers/ensureScopedChatCache.js +2 -2
- package/lib/module/helpers/ensureScopedChatCache.js.map +1 -1
- package/lib/module/helpers/getChatBackground.js +18 -0
- package/lib/module/helpers/getChatBackground.js.map +1 -0
- package/lib/module/helpers/getDisplayFileName.js +73 -0
- package/lib/module/helpers/getDisplayFileName.js.map +1 -0
- package/lib/module/helpers/getServerReadTimestamp.js +181 -0
- package/lib/module/helpers/getServerReadTimestamp.js.map +1 -0
- package/lib/module/helpers/historyPreloadScheduler.js +66 -3
- package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/module/helpers/initXmppRooms.js +14 -8
- package/lib/module/helpers/initXmppRooms.js.map +1 -1
- package/lib/module/helpers/insertMessageWithDelimiter.js +52 -9
- package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
- package/lib/module/helpers/isOwnMessage.js +70 -0
- package/lib/module/helpers/isOwnMessage.js.map +1 -0
- package/lib/module/helpers/keyboardLayout.js +12 -2
- package/lib/module/helpers/keyboardLayout.js.map +1 -1
- package/lib/module/helpers/mediaLibraryRuntime.js +25 -0
- package/lib/module/helpers/mediaLibraryRuntime.js.map +1 -0
- package/lib/module/helpers/mimeToExtension.js +6 -13
- package/lib/module/helpers/mimeToExtension.js.map +1 -1
- package/lib/module/helpers/msgSortableMs.js +32 -0
- package/lib/module/helpers/msgSortableMs.js.map +1 -0
- package/lib/module/helpers/persistCrypto.js +115 -0
- package/lib/module/helpers/persistCrypto.js.map +1 -0
- package/lib/module/helpers/pickImageAsset.js +63 -0
- package/lib/module/helpers/pickImageAsset.js.map +1 -0
- package/lib/module/helpers/pushPayload.js +63 -0
- package/lib/module/helpers/pushPayload.js.map +1 -0
- package/lib/module/helpers/resolveInitBeforeLoadUser.js +130 -16
- package/lib/module/helpers/resolveInitBeforeLoadUser.js.map +1 -1
- package/lib/module/helpers/secureFileUrl.js +91 -0
- package/lib/module/helpers/secureFileUrl.js.map +1 -0
- package/lib/module/helpers/secureKeyValue.js +75 -0
- package/lib/module/helpers/secureKeyValue.js.map +1 -0
- package/lib/module/helpers/secureStoreRuntime.js +52 -0
- package/lib/module/helpers/secureStoreRuntime.js.map +1 -0
- package/lib/module/helpers/secureUserStorage.js +72 -0
- package/lib/module/helpers/secureUserStorage.js.map +1 -0
- package/lib/module/helpers/shallowEqual.js +31 -0
- package/lib/module/helpers/shallowEqual.js.map +1 -0
- package/lib/module/helpers/sheetGestures.js +26 -0
- package/lib/module/helpers/sheetGestures.js.map +1 -0
- package/lib/module/hooks/useChatRoomFocus.js +46 -13
- package/lib/module/hooks/useChatRoomFocus.js.map +1 -1
- package/lib/module/hooks/useChatWrapperInit.js +30 -10
- package/lib/module/hooks/useChatWrapperInit.js.map +1 -1
- package/lib/module/hooks/useComposing.js +28 -1
- package/lib/module/hooks/useComposing.js.map +1 -1
- package/lib/module/hooks/useFileToken.js +5 -0
- package/lib/module/hooks/useFileToken.js.map +1 -0
- package/lib/module/hooks/useLogout.js +23 -7
- package/lib/module/hooks/useLogout.js.map +1 -1
- package/lib/module/hooks/usePendingNotification.js +8 -11
- package/lib/module/hooks/usePendingNotification.js.map +1 -1
- package/lib/module/hooks/useSendMessage.js +52 -16
- package/lib/module/hooks/useSendMessage.js.map +1 -1
- package/lib/module/hooks/useUnreadMessagesCounter.js +6 -1
- package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
- package/lib/module/i18n/strings.js +145 -37
- package/lib/module/i18n/strings.js.map +1 -1
- package/lib/module/main.js +14 -2
- package/lib/module/main.js.map +1 -1
- package/lib/module/networking/api-requests/auth.api.js +131 -59
- package/lib/module/networking/api-requests/auth.api.js.map +1 -1
- package/lib/module/networking/api-requests/roomMembers.api.js +1 -1
- package/lib/module/networking/api-requests/roomMembers.api.js.map +1 -1
- package/lib/module/networking/api-requests/rooms.api.js +9 -9
- package/lib/module/networking/api-requests/rooms.api.js.map +1 -1
- package/lib/module/networking/api-requests/user.api.js +64 -7
- package/lib/module/networking/api-requests/user.api.js.map +1 -1
- package/lib/module/networking/apiClient.js +61 -113
- package/lib/module/networking/apiClient.js.map +1 -1
- package/lib/module/networking/authRefresh.js +321 -0
- package/lib/module/networking/authRefresh.js.map +1 -0
- package/lib/module/networking/stanzaHandlers.js +41 -28
- package/lib/module/networking/stanzaHandlers.js.map +1 -1
- package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js +46 -8
- package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
- package/lib/module/networking/xmpp/presenceInRoom.xmpp.js +8 -1
- package/lib/module/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/subscribeToRoomMessages.xmpp.js +5 -1
- package/lib/module/networking/xmpp/subscribeToRoomMessages.xmpp.js.map +1 -1
- package/lib/module/networking/xmppClient.js +124 -8
- package/lib/module/networking/xmppClient.js.map +1 -1
- package/lib/module/roomStore/chatSettingsSlice.js +26 -7
- package/lib/module/roomStore/chatSettingsSlice.js.map +1 -1
- package/lib/module/roomStore/index.js +37 -4
- package/lib/module/roomStore/index.js.map +1 -1
- package/lib/module/roomStore/persistence.js +223 -22
- package/lib/module/roomStore/persistence.js.map +1 -1
- package/lib/module/roomStore/roomsSlice.js +139 -34
- package/lib/module/roomStore/roomsSlice.js.map +1 -1
- package/lib/module/services/pushSubscriptionService.js +15 -13
- package/lib/module/services/pushSubscriptionService.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/typescript/assets/icons.d.ts +16 -0
- package/lib/typescript/assets/icons.d.ts.map +1 -1
- package/lib/typescript/components/AuthForms/Login.d.ts.map +1 -1
- package/lib/typescript/components/Header/HeaderRoomList.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/LoginWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/MessageContainer.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/MessageList.d.ts +10 -1
- package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ProfileImagePlaceholder.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/RoomList.d.ts +7 -0
- package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
- package/lib/typescript/components/Menu/HeaderRoomListMenu.d.ts +3 -0
- package/lib/typescript/components/Menu/HeaderRoomListMenu.d.ts.map +1 -1
- package/lib/typescript/components/Modals/AttachSheet/AttachSheet.d.ts +9 -0
- package/lib/typescript/components/Modals/AttachSheet/AttachSheet.d.ts.map +1 -1
- package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts +10 -0
- package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/ChatProfileModal/ReportChatModal.d.ts +9 -0
- package/lib/typescript/components/Modals/ChatProfileModal/ReportChatModal.d.ts.map +1 -0
- package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/FilePreviewModal/PdfView.d.ts.map +1 -1
- package/lib/typescript/components/Modals/Modal/Modal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/NewChatModal/ModalContent.d.ts +4 -2
- package/lib/typescript/components/Modals/NewChatModal/ModalContent.d.ts.map +1 -1
- package/lib/typescript/components/Modals/NewChatModal/NewChatModal.d.ts +1 -1
- package/lib/typescript/components/Modals/NewChatModal/NewChatModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/NewChatModal/UpdNewChatModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/ProfileHeader/ProfileHeader.d.ts +75 -0
- package/lib/typescript/components/Modals/ProfileHeader/ProfileHeader.d.ts.map +1 -0
- package/lib/typescript/components/Modals/ProfileHeader/ProfileMenu.d.ts +25 -0
- package/lib/typescript/components/Modals/ProfileHeader/ProfileMenu.d.ts.map +1 -0
- package/lib/typescript/components/Modals/SelectUsersModal/SelectUsersModal.d.ts +6 -1
- package/lib/typescript/components/Modals/SelectUsersModal/SelectUsersModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/UserProfileModal/EditUserModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts +16 -0
- package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/UserSettingsModal/UserSettingsModal.d.ts +1 -0
- package/lib/typescript/components/Modals/UserSettingsModal/UserSettingsModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/styledModalComponents.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/styled/LastMessageFile.d.ts +1 -1
- package/lib/typescript/components/RoomComponents/styled/LastMessageFile.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/styled/LastMessagePhoto.d.ts +1 -1
- package/lib/typescript/components/RoomComponents/styled/LastMessagePhoto.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/styled/LastMessageVideo.d.ts +1 -1
- package/lib/typescript/components/RoomComponents/styled/LastMessageVideo.d.ts.map +1 -1
- package/lib/typescript/components/VideoCalls/VideoCallSession.d.ts.map +1 -1
- package/lib/typescript/components/styled/AudioMessage.d.ts.map +1 -1
- package/lib/typescript/components/styled/MessageImage.d.ts +14 -0
- package/lib/typescript/components/styled/MessageImage.d.ts.map +1 -1
- package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
- package/lib/typescript/components/styled/StyledComponents.d.ts.map +1 -1
- package/lib/typescript/components/styled/StyledInputComponents/StyledInputComponents.d.ts.map +1 -1
- package/lib/typescript/components/styled/UnsupportedType.d.ts.map +1 -1
- package/lib/typescript/components/styled/VideoMessage.d.ts +8 -0
- package/lib/typescript/components/styled/VideoMessage.d.ts.map +1 -1
- package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
- package/lib/typescript/helpers/createMessageFromXml.d.ts.map +1 -1
- package/lib/typescript/helpers/getChatBackground.d.ts +15 -0
- package/lib/typescript/helpers/getChatBackground.d.ts.map +1 -0
- package/lib/typescript/helpers/getDisplayFileName.d.ts +49 -0
- package/lib/typescript/helpers/getDisplayFileName.d.ts.map +1 -0
- package/lib/typescript/helpers/getServerReadTimestamp.d.ts +108 -0
- package/lib/typescript/helpers/getServerReadTimestamp.d.ts.map +1 -0
- package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
- package/lib/typescript/helpers/initXmppRooms.d.ts.map +1 -1
- package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts +1 -1
- package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
- package/lib/typescript/helpers/isOwnMessage.d.ts +36 -0
- package/lib/typescript/helpers/isOwnMessage.d.ts.map +1 -0
- package/lib/typescript/helpers/keyboardLayout.d.ts +5 -1
- package/lib/typescript/helpers/keyboardLayout.d.ts.map +1 -1
- package/lib/typescript/helpers/mediaLibraryRuntime.d.ts +3 -0
- package/lib/typescript/helpers/mediaLibraryRuntime.d.ts.map +1 -0
- package/lib/typescript/helpers/mimeToExtension.d.ts +0 -15
- package/lib/typescript/helpers/mimeToExtension.d.ts.map +1 -1
- package/lib/typescript/helpers/msgSortableMs.d.ts +2 -0
- package/lib/typescript/helpers/msgSortableMs.d.ts.map +1 -0
- package/lib/typescript/helpers/persistCrypto.d.ts +13 -0
- package/lib/typescript/helpers/persistCrypto.d.ts.map +1 -0
- package/lib/typescript/helpers/pickImageAsset.d.ts +27 -0
- package/lib/typescript/helpers/pickImageAsset.d.ts.map +1 -0
- package/lib/typescript/helpers/pushPayload.d.ts +7 -0
- package/lib/typescript/helpers/pushPayload.d.ts.map +1 -0
- package/lib/typescript/helpers/resolveInitBeforeLoadUser.d.ts.map +1 -1
- package/lib/typescript/helpers/secureFileUrl.d.ts +7 -0
- package/lib/typescript/helpers/secureFileUrl.d.ts.map +1 -0
- package/lib/typescript/helpers/secureKeyValue.d.ts +13 -0
- package/lib/typescript/helpers/secureKeyValue.d.ts.map +1 -0
- package/lib/typescript/helpers/secureStoreRuntime.d.ts +29 -0
- package/lib/typescript/helpers/secureStoreRuntime.d.ts.map +1 -0
- package/lib/typescript/helpers/secureUserStorage.d.ts +23 -0
- package/lib/typescript/helpers/secureUserStorage.d.ts.map +1 -0
- package/lib/typescript/helpers/shallowEqual.d.ts +11 -0
- package/lib/typescript/helpers/shallowEqual.d.ts.map +1 -0
- package/lib/typescript/helpers/sheetGestures.d.ts +20 -0
- package/lib/typescript/helpers/sheetGestures.d.ts.map +1 -0
- package/lib/typescript/hooks/useChatRoomFocus.d.ts +4 -1
- package/lib/typescript/hooks/useChatRoomFocus.d.ts.map +1 -1
- package/lib/typescript/hooks/useChatWrapperInit.d.ts.map +1 -1
- package/lib/typescript/hooks/useComposing.d.ts.map +1 -1
- package/lib/typescript/hooks/useFileToken.d.ts +2 -0
- package/lib/typescript/hooks/useFileToken.d.ts.map +1 -0
- package/lib/typescript/hooks/useLogout.d.ts.map +1 -1
- package/lib/typescript/hooks/usePendingNotification.d.ts.map +1 -1
- package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/hooks/useUnreadMessagesCounter.d.ts +1 -0
- package/lib/typescript/hooks/useUnreadMessagesCounter.d.ts.map +1 -1
- package/lib/typescript/i18n/strings.d.ts.map +1 -1
- package/lib/typescript/main.d.ts +9 -2
- package/lib/typescript/main.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/auth.api.d.ts +3 -1
- package/lib/typescript/networking/api-requests/auth.api.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/user.api.d.ts +27 -0
- package/lib/typescript/networking/api-requests/user.api.d.ts.map +1 -1
- package/lib/typescript/networking/apiClient.d.ts +12 -6
- package/lib/typescript/networking/apiClient.d.ts.map +1 -1
- package/lib/typescript/networking/authRefresh.d.ts +95 -0
- package/lib/typescript/networking/authRefresh.d.ts.map +1 -0
- package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts +10 -2
- package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/subscribeToRoomMessages.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmppClient.d.ts +14 -0
- package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
- package/lib/typescript/roomStore/chatSettingsSlice.d.ts +16 -0
- package/lib/typescript/roomStore/chatSettingsSlice.d.ts.map +1 -1
- package/lib/typescript/roomStore/index.d.ts.map +1 -1
- package/lib/typescript/roomStore/persistence.d.ts +18 -1
- package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts +43 -3
- package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
- package/lib/typescript/services/pushSubscriptionService.d.ts +1 -1
- package/lib/typescript/services/pushSubscriptionService.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +50 -5
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/lib/typescript/version.d.ts +1 -1
- package/package.json +41 -28
- package/src/assets/icons.tsx +48 -9
- package/src/components/AuthForms/Login.tsx +3 -3
- package/src/components/Header/HeaderRoomList.tsx +29 -7
- package/src/components/MainComponents/ChatHeader.tsx +9 -3
- package/src/components/MainComponents/ChatRoom.tsx +161 -15
- package/src/components/MainComponents/ChatWrapper.tsx +36 -20
- package/src/components/MainComponents/LoginWrapper.tsx +1 -0
- package/src/components/MainComponents/MediaMessage.tsx +26 -8
- package/src/components/MainComponents/MessageContainer.tsx +5 -1
- package/src/components/MainComponents/MessageList.tsx +23 -4
- package/src/components/MainComponents/ProfileImagePlaceholder.tsx +21 -14
- package/src/components/MainComponents/RoomList.tsx +236 -39
- package/src/components/Menu/HeaderRoomListMenu.tsx +328 -75
- package/src/components/Modals/AttachSheet/AttachSheet.tsx +333 -97
- package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +600 -282
- package/src/components/Modals/ChatProfileModal/ReportChatModal.tsx +244 -0
- package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +79 -38
- package/src/components/Modals/FilePreviewModal/PdfView.tsx +2 -1
- package/src/components/Modals/Modal/Modal.tsx +7 -0
- package/src/components/Modals/NewChatModal/ModalContent.tsx +6 -3
- package/src/components/Modals/NewChatModal/NewChatModal.tsx +219 -119
- package/src/components/Modals/NewChatModal/UpdNewChatModal.tsx +12 -1
- package/src/components/Modals/ProfileHeader/ProfileHeader.tsx +624 -0
- package/src/components/Modals/ProfileHeader/ProfileMenu.tsx +217 -0
- package/src/components/Modals/SelectUsersModal/SelectUsersModal.tsx +14 -4
- package/src/components/Modals/UserProfileModal/EditUserModal.tsx +9 -25
- package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +617 -307
- package/src/components/Modals/UserSettingsModal/UserSettingsModal.tsx +75 -58
- package/src/components/Modals/styledModalComponents.tsx +9 -2
- package/src/components/RoomComponents/ChatRoomItem.tsx +18 -3
- package/src/components/RoomComponents/styled/LastMessageFile.tsx +28 -4
- package/src/components/RoomComponents/styled/LastMessagePhoto.tsx +18 -3
- package/src/components/RoomComponents/styled/LastMessageVideo.tsx +18 -3
- package/src/components/VideoCalls/VideoCallSession.tsx +8 -3
- package/src/components/styled/AudioMessage.tsx +2 -1
- package/src/components/styled/MessageImage.tsx +53 -7
- package/src/components/styled/SendInput.tsx +83 -12
- package/src/components/styled/StyledComponents.ts +9 -3
- package/src/components/styled/StyledInputComponents/StyledInputComponents.tsx +11 -4
- package/src/components/styled/UnsupportedType.tsx +14 -4
- package/src/components/styled/VideoMessage.tsx +131 -54
- package/src/context/xmppProvider.tsx +216 -57
- package/src/helpers/createMessageFromXml.ts +20 -1
- package/src/helpers/ensureScopedChatCache.ts +2 -2
- package/src/helpers/getChatBackground.ts +18 -0
- package/src/helpers/getDisplayFileName.ts +87 -0
- package/src/helpers/getServerReadTimestamp.ts +197 -0
- package/src/helpers/historyPreloadScheduler.ts +80 -3
- package/src/helpers/initXmppRooms.tsx +14 -10
- package/src/helpers/insertMessageWithDelimiter.ts +55 -19
- package/src/helpers/isOwnMessage.ts +90 -0
- package/src/helpers/keyboardLayout.ts +23 -2
- package/src/helpers/mediaLibraryRuntime.ts +25 -0
- package/src/helpers/mimeToExtension.ts +6 -22
- package/src/helpers/msgSortableMs.ts +25 -0
- package/src/helpers/persistCrypto.ts +127 -0
- package/src/helpers/pickImageAsset.ts +68 -0
- package/src/helpers/pushPayload.ts +62 -0
- package/src/helpers/resolveInitBeforeLoadUser.ts +125 -18
- package/src/helpers/secureFileUrl.ts +103 -0
- package/src/helpers/secureKeyValue.ts +80 -0
- package/src/helpers/secureStoreRuntime.ts +62 -0
- package/src/helpers/secureUserStorage.ts +80 -0
- package/src/helpers/shallowEqual.ts +33 -0
- package/src/helpers/sheetGestures.ts +25 -0
- package/src/hooks/useChatRoomFocus.ts +49 -9
- package/src/hooks/useChatWrapperInit.ts +30 -10
- package/src/hooks/useComposing.tsx +37 -1
- package/src/hooks/useFileToken.ts +7 -0
- package/src/hooks/useLogout.tsx +29 -9
- package/src/hooks/usePendingNotification.ts +5 -11
- package/src/hooks/useSendMessage.tsx +60 -15
- package/src/hooks/useUnreadMessagesCounter.ts +11 -0
- package/src/i18n/strings.ts +145 -37
- package/src/main.ts +26 -2
- package/src/networking/api-requests/auth.api.ts +156 -48
- package/src/networking/api-requests/roomMembers.api.ts +1 -1
- package/src/networking/api-requests/rooms.api.ts +9 -9
- package/src/networking/api-requests/user.api.ts +79 -7
- package/src/networking/apiClient.ts +68 -123
- package/src/networking/authRefresh.ts +451 -0
- package/src/networking/stanzaHandlers.ts +44 -28
- package/src/networking/xmpp/flushLastViewedToPrivateStore.ts +71 -10
- package/src/networking/xmpp/presenceInRoom.xmpp.ts +6 -1
- package/src/networking/xmpp/subscribeToRoomMessages.xmpp.ts +12 -1
- package/src/networking/xmppClient.ts +141 -9
- package/src/roomStore/chatSettingsSlice.ts +34 -10
- package/src/roomStore/index.ts +40 -4
- package/src/roomStore/persistence.ts +234 -24
- package/src/roomStore/roomsSlice.ts +161 -29
- package/src/services/pushSubscriptionService.ts +18 -13
- package/src/types/types.ts +72 -5
- package/src/version.ts +1 -1
|
@@ -8,9 +8,8 @@ import {
|
|
|
8
8
|
setComposing,
|
|
9
9
|
setCurrentRoom,
|
|
10
10
|
setRoomRole,
|
|
11
|
-
updateRoom,
|
|
12
11
|
} from '../roomStore/roomsSlice';
|
|
13
|
-
import { IRoom
|
|
12
|
+
import { IRoom } from '../types/types';
|
|
14
13
|
import { createMessageFromXml } from '../helpers/createMessageFromXml';
|
|
15
14
|
import { getDataFromXml } from '../helpers/getDataFromXml';
|
|
16
15
|
import { setDeleteModal } from '../roomStore/chatSettingsSlice';
|
|
@@ -238,11 +237,11 @@ const onMessageHistory = async (stanza: any) => {
|
|
|
238
237
|
// what senderJID would have held — fall back to it. createMessageFromXml
|
|
239
238
|
// already derives a display name from the jid when senderFirstName/
|
|
240
239
|
// senderLastName are absent.
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
240
|
+
const forwardedMessage = stanza
|
|
241
|
+
.getChild('result')
|
|
242
|
+
?.getChild('forwarded')
|
|
243
|
+
?.getChild('message');
|
|
244
|
+
const innerFrom = forwardedMessage?.attrs?.from || stanza.attrs.from;
|
|
246
245
|
const senderJID = data?.attrs?.senderJID || innerFrom;
|
|
247
246
|
if (!data?.attrs || !senderJID) {
|
|
248
247
|
// console.log(
|
|
@@ -251,27 +250,44 @@ const onMessageHistory = async (stanza: any) => {
|
|
|
251
250
|
// );
|
|
252
251
|
return;
|
|
253
252
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
//
|
|
259
|
-
//
|
|
260
|
-
//
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
253
|
+
const mergedAttrs = { ...data.attrs };
|
|
254
|
+
if (!mergedAttrs.senderJID) {mergedAttrs.senderJID = senderJID;}
|
|
255
|
+
// The forwarded <message>'s own stanza id is our original send id
|
|
256
|
+
// (what `xmppId` holds on the live/wrapped paths) - capture it so
|
|
257
|
+
// this MAM-replayed message dedupes against its live echo /
|
|
258
|
+
// optimistic pending bubble the same way, instead of never carrying
|
|
259
|
+
// an xmppId at all.
|
|
260
|
+
if (forwardedMessage?.attrs?.id) {mergedAttrs.xmppId = forwardedMessage.attrs.id;}
|
|
261
|
+
const positionalMessage = await createMessageFromXml(
|
|
262
|
+
mergedAttrs,
|
|
263
|
+
body,
|
|
264
|
+
id,
|
|
265
|
+
// Bug #41: pass the resource-bearing occupant `from`
|
|
266
|
+
// (room@conference/sender-id) here, not the outer envelope's
|
|
267
|
+
// `stanza.attrs.from` (which has no resource for a MAM result).
|
|
268
|
+
// createMessageFromXml derives `user.id` from this field's
|
|
269
|
+
// resource - the same authoritative source getDataFromXml uses
|
|
270
|
+
// for live messages - so catch-up rows resolve the correct
|
|
271
|
+
// sender from the very first render instead of needing a later
|
|
272
|
+
// correction once the "official" history fetch lands.
|
|
273
|
+
innerFrom,
|
|
274
|
+
!!deleted
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
// Translations ride on the archived stanza too (<translations> +
|
|
278
|
+
// <translate source>), but the positional parse above only reads
|
|
279
|
+
// <data> attrs + <body>, so every MAM-backfilled message lost them -
|
|
280
|
+
// translation looked dead on every room open. Parse the full stanza
|
|
281
|
+
// the way the realtime path does and carry ONLY those two fields over,
|
|
282
|
+
// so sender/xmppId resolution above (bug #41) stays exactly as is.
|
|
283
|
+
const parsedFull = await getDataFromXml(stanza).catch(() => undefined);
|
|
284
|
+
const rawMessage = {
|
|
285
|
+
...positionalMessage,
|
|
286
|
+
...(parsedFull?.translations
|
|
287
|
+
? { translations: parsedFull.translations }
|
|
288
|
+
: {}),
|
|
289
|
+
...(parsedFull?.langSource ? { langSource: parsedFull.langSource } : {}),
|
|
290
|
+
};
|
|
275
291
|
|
|
276
292
|
// Same call-log transform as the realtime path, applied to archived
|
|
277
293
|
// history so calls received while offline still render as log entries.
|
|
@@ -1,21 +1,45 @@
|
|
|
1
1
|
import { getChatsPrivateStoreRequest } from './getChatsPrivateStoreRequest.xmpp';
|
|
2
2
|
import { setChatsPrivateStoreRequest } from './setChatsPrivateStoreRequest.xmpp';
|
|
3
|
+
import {
|
|
4
|
+
getServerReadTimestamp,
|
|
5
|
+
isCorruptFutureReadMarker,
|
|
6
|
+
type ReadTimestampHeapState,
|
|
7
|
+
} from '../../helpers/getServerReadTimestamp';
|
|
8
|
+
import type { IMessage } from '../../types/types';
|
|
3
9
|
|
|
4
10
|
interface RoomLike {
|
|
5
11
|
jid: string;
|
|
6
12
|
lastViewedTimestamp?: number;
|
|
7
13
|
unreadMessages?: number;
|
|
14
|
+
// Needed to resolve a SERVER-timestamp read marker via
|
|
15
|
+
// getServerReadTimestamp instead of the device clock - see bug #38.
|
|
16
|
+
messages?: IMessage[];
|
|
8
17
|
}
|
|
9
18
|
|
|
10
19
|
interface FlushOpts {
|
|
11
20
|
// When visibleRoomJID is set, treat it as "user just viewed everything
|
|
12
|
-
// up to now" and stamp it with
|
|
13
|
-
//
|
|
21
|
+
// up to now" and stamp it with the newest server-acknowledged message
|
|
22
|
+
// timestamp for that room - even if its in-memory lastViewedTimestamp
|
|
23
|
+
// has not been updated yet.
|
|
14
24
|
visibleRoomJID?: string | null;
|
|
25
|
+
// Explicit read boundary for the visible room, used INSTEAD of the
|
|
26
|
+
// newest-message fallback. ChatRoom passes the timestamp of the newest
|
|
27
|
+
// message the user actually reached when they leave a room while
|
|
28
|
+
// scrolled up - without it, the default writes "read everything" to
|
|
29
|
+
// the server and the messages they never scrolled down to come back as
|
|
30
|
+
// read on the next login, even though the local count was correct.
|
|
31
|
+
// Customer-reported #33 (server half).
|
|
32
|
+
visibleRoomTs?: number | null;
|
|
15
33
|
// If true, only write entries for rooms where unreadMessages === 0
|
|
16
34
|
// (or the visible room). Used at logout time: rooms with outstanding
|
|
17
35
|
// unread keep their old marker so the next login still surfaces them.
|
|
18
36
|
onlyIfNoUnread?: boolean;
|
|
37
|
+
// Pending/failed-send state (store.getState().roomHeapSlice), combined
|
|
38
|
+
// with each room's `messages` to resolve the newest SERVER-acked
|
|
39
|
+
// message timestamp via getServerReadTimestamp. Passed in rather than
|
|
40
|
+
// read from the store here so this module stays a pure function of its
|
|
41
|
+
// arguments - existing jest coverage builds `rooms` by hand.
|
|
42
|
+
heapState?: ReadTimestampHeapState;
|
|
19
43
|
}
|
|
20
44
|
|
|
21
45
|
/**
|
|
@@ -25,8 +49,11 @@ interface FlushOpts {
|
|
|
25
49
|
* each other's entries.
|
|
26
50
|
*
|
|
27
51
|
* Called on: tab change away from chat, AppState background/inactive,
|
|
28
|
-
* and (with onlyIfNoUnread=true) logout. ChatRoom's own unmount path
|
|
29
|
-
*
|
|
52
|
+
* and (with onlyIfNoUnread=true) logout. ChatRoom's own unmount path also
|
|
53
|
+
* goes through this (via flushLastViewedToPrivateStoreStanza) for the
|
|
54
|
+
* single-room case - actionSetTimestampToPrivateStore is a separate,
|
|
55
|
+
* unconditional low-level write primitive kept for direct/external use
|
|
56
|
+
* and is not part of this merge path.
|
|
30
57
|
*/
|
|
31
58
|
export async function flushLastViewedToPrivateStore(
|
|
32
59
|
client: any,
|
|
@@ -34,7 +61,7 @@ export async function flushLastViewedToPrivateStore(
|
|
|
34
61
|
opts: FlushOpts = {}
|
|
35
62
|
): Promise<boolean> {
|
|
36
63
|
if (!client?.client) {return false;}
|
|
37
|
-
const { visibleRoomJID, onlyIfNoUnread } = opts;
|
|
64
|
+
const { visibleRoomJID, visibleRoomTs, onlyIfNoUnread, heapState } = opts;
|
|
38
65
|
const roomList = Object.values(rooms || {});
|
|
39
66
|
if (roomList.length === 0) {return false;}
|
|
40
67
|
|
|
@@ -46,7 +73,6 @@ export async function flushLastViewedToPrivateStore(
|
|
|
46
73
|
}
|
|
47
74
|
if (!storeObj || typeof storeObj !== 'object') {storeObj = {};}
|
|
48
75
|
|
|
49
|
-
const nowMs = Date.now();
|
|
50
76
|
let dirty = false;
|
|
51
77
|
|
|
52
78
|
for (const room of roomList) {
|
|
@@ -54,21 +80,56 @@ export async function flushLastViewedToPrivateStore(
|
|
|
54
80
|
const isVisible = !!visibleRoomJID && room.jid === visibleRoomJID;
|
|
55
81
|
const hasUnread = Number(room.unreadMessages || 0) > 0;
|
|
56
82
|
|
|
57
|
-
//
|
|
58
|
-
//
|
|
83
|
+
// Newest message this room actually has server-side proof of. Used
|
|
84
|
+
// both as the "read up to now" fallback for the visible room and as
|
|
85
|
+
// the yardstick for detecting a corrupt (future) stored marker below
|
|
86
|
+
// - never as a substitute for the device clock (bug #38: a device
|
|
87
|
+
// with a fast clock previously stamped Date.now() here, and once
|
|
88
|
+
// that future value reached the server the forward-only check a few
|
|
89
|
+
// lines down rejected every later correct write, forever).
|
|
90
|
+
const newestAckedMs = getServerReadTimestamp(room as any, heapState);
|
|
91
|
+
|
|
92
|
+
// For the visible room, persist "read up to the newest message we
|
|
93
|
+
// know the server has" - read state is driven by room visibility,
|
|
94
|
+
// not by a sentinel timestamp. The exception is an explicit
|
|
95
|
+
// `visibleRoomTs`: the caller knows the user only read up to a
|
|
96
|
+
// certain point (left the room while scrolled up), so stamping
|
|
97
|
+
// "everything" here would mark genuinely-unread messages as read.
|
|
59
98
|
let ts: number | undefined;
|
|
60
99
|
if (isVisible) {
|
|
61
|
-
ts =
|
|
100
|
+
ts =
|
|
101
|
+
typeof visibleRoomTs === 'number' && visibleRoomTs > 0
|
|
102
|
+
? visibleRoomTs
|
|
103
|
+
: newestAckedMs || undefined;
|
|
62
104
|
} else if (room.lastViewedTimestamp && room.lastViewedTimestamp > 0) {
|
|
63
105
|
ts = room.lastViewedTimestamp;
|
|
64
106
|
}
|
|
65
107
|
|
|
108
|
+
// Nothing to anchor a write to (no boundary, no existing marker, no
|
|
109
|
+
// known messages yet) - skip rather than write a device-clock guess.
|
|
66
110
|
if (!ts) {continue;}
|
|
67
111
|
if (onlyIfNoUnread && hasUnread && !isVisible) {continue;}
|
|
68
112
|
|
|
69
113
|
const prev = storeObj[room.jid];
|
|
70
114
|
const prevNum = prev != null ? Number(prev) : 0;
|
|
71
|
-
|
|
115
|
+
// A currently-stored value that sits well past the newest message we
|
|
116
|
+
// know this room has is not "fresher" - it's a leftover future
|
|
117
|
+
// marker (bug #38). Forward-only logic normally protects a fresher
|
|
118
|
+
// read from being clobbered by a stale fetch, but applied to a
|
|
119
|
+
// corrupt future value it does the opposite: it permanently blocks
|
|
120
|
+
// the correct (smaller) value from ever landing. Detect that case
|
|
121
|
+
// and waive the forward-only check for it specifically; sane values
|
|
122
|
+
// keep the normal forward-only protection.
|
|
123
|
+
//
|
|
124
|
+
// "Well past the newest message we know about" is deliberately NOT
|
|
125
|
+
// sufficient on its own - see isCorruptFutureReadMarker. THIS device's
|
|
126
|
+
// copy of the room can simply be stale (history not synced yet this
|
|
127
|
+
// session), in which case a legitimate marker written by another
|
|
128
|
+
// device that HAS seen newer messages looks exactly like a corrupt
|
|
129
|
+
// one, and "healing" it here would push the server marker BACKWARDS
|
|
130
|
+
// and resurrect already-read messages on every device.
|
|
131
|
+
const prevLooksCorrupt = isCorruptFutureReadMarker(prevNum, newestAckedMs);
|
|
132
|
+
if (!prevLooksCorrupt && Number.isFinite(prevNum) && prevNum >= ts) {continue;}
|
|
72
133
|
storeObj[room.jid] = String(ts);
|
|
73
134
|
dirty = true;
|
|
74
135
|
}
|
|
@@ -70,7 +70,12 @@ export const presenceInRoom = async (
|
|
|
70
70
|
try {
|
|
71
71
|
await createTimeoutPromise(2000, unsubscribe);
|
|
72
72
|
} catch (err) {
|
|
73
|
-
|
|
73
|
+
// The room's reply schedules resolve() `delay` ms later (2000 by
|
|
74
|
+
// default) — the same length as this timeout, so the timeout used
|
|
75
|
+
// to win the race and reject a join that had actually succeeded
|
|
76
|
+
// (allRoomPresences "failed" with undefined on every bootstrap).
|
|
77
|
+
// Only a join that never got an answer is a failure.
|
|
78
|
+
if (!settled) {reject(err);}
|
|
74
79
|
}
|
|
75
80
|
})();
|
|
76
81
|
});
|
|
@@ -2,12 +2,14 @@ import { Client, xml } from '@xmpp/client';
|
|
|
2
2
|
import { Element } from '@xmpp/xml';
|
|
3
3
|
import { createTimeoutPromise } from './createTimeoutPromise.xmpp';
|
|
4
4
|
|
|
5
|
+
let subscribeIdCounter = 0;
|
|
6
|
+
|
|
5
7
|
export async function subscribeToRoomMessages(
|
|
6
8
|
client: Client,
|
|
7
9
|
roomJID: string,
|
|
8
10
|
userNick?: string
|
|
9
11
|
): Promise<boolean> {
|
|
10
|
-
const id = `newSubscription:${Date.now().toString()}`;
|
|
12
|
+
const id = `newSubscription:${Date.now().toString(36)}-${(++subscribeIdCounter).toString(36)}`;
|
|
11
13
|
let stanzaHandler: (stanza: Element) => void;
|
|
12
14
|
|
|
13
15
|
const unsubscribe = () => {
|
|
@@ -33,6 +35,15 @@ export async function subscribeToRoomMessages(
|
|
|
33
35
|
if (stanza.attrs.type === 'result') {
|
|
34
36
|
finish(resolve, true);
|
|
35
37
|
} else if (stanza.attrs.type === 'error') {
|
|
38
|
+
const errorEl = typeof stanza.getChild === 'function' ? stanza.getChild('error') : null;
|
|
39
|
+
const condition = errorEl?.children?.find(
|
|
40
|
+
(c: any) => c?.name && c.name !== 'text'
|
|
41
|
+
) as Element | undefined;
|
|
42
|
+
console.warn(
|
|
43
|
+
'[PushService] MucSub subscribe error for',
|
|
44
|
+
roomJID,
|
|
45
|
+
condition?.name ?? 'unknown'
|
|
46
|
+
);
|
|
36
47
|
finish(resolve, false);
|
|
37
48
|
}
|
|
38
49
|
}
|
|
@@ -32,6 +32,10 @@ import {
|
|
|
32
32
|
enqueueOutboundSend,
|
|
33
33
|
flushOutboundSends,
|
|
34
34
|
} from './outboundQueue';
|
|
35
|
+
import {
|
|
36
|
+
getServerReadTimestamp,
|
|
37
|
+
isCorruptFutureReadMarker,
|
|
38
|
+
} from '../helpers/getServerReadTimestamp';
|
|
35
39
|
|
|
36
40
|
// Canonical production XMPP WSS endpoint (standard wss/443, no port suffix).
|
|
37
41
|
const DEFAULT_DEV_SERVER = 'xmpp.chat.ethora.com';
|
|
@@ -94,6 +98,13 @@ interface MamInFlightEntry {
|
|
|
94
98
|
startedAt: number;
|
|
95
99
|
}
|
|
96
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Floor between two credential rotations driven by reconnects. Well under
|
|
103
|
+
* the XMPP password's one-hour life, but high enough that a link flapping
|
|
104
|
+
* every few seconds rotates once, not thirty times.
|
|
105
|
+
*/
|
|
106
|
+
const CREDENTIALS_REFRESH_MIN_INTERVAL_MS = 60_000;
|
|
107
|
+
|
|
97
108
|
export type XmppCredentialsProvider = () => Promise<{
|
|
98
109
|
username: string;
|
|
99
110
|
password: string;
|
|
@@ -137,6 +148,12 @@ export class XmppClient {
|
|
|
137
148
|
// derived XMPP password after idle). Triggers the credentialsProvider
|
|
138
149
|
// refresh path in reconnect().
|
|
139
150
|
lastAuthError: 'not-authorized' | null = null;
|
|
151
|
+
/**
|
|
152
|
+
* When the credentials currently held were last (re)minted. Drives the
|
|
153
|
+
* throttle in `reconnect()` so a flapping connection can't rotate the
|
|
154
|
+
* session once per flap.
|
|
155
|
+
*/
|
|
156
|
+
private credentialsRefreshedAt = 0;
|
|
140
157
|
private credentialsProvider: XmppCredentialsProvider | null = null;
|
|
141
158
|
private credentialsRefreshInFlight: Promise<void> | null = null;
|
|
142
159
|
// Fired by the provider on every 'online' so it can re-join MUC rooms
|
|
@@ -329,6 +346,7 @@ export class XmppClient {
|
|
|
329
346
|
}
|
|
330
347
|
|
|
331
348
|
initializeClient() {
|
|
349
|
+
this.clientAlreadyStopped = false;
|
|
332
350
|
try {
|
|
333
351
|
const devServer = this.devServer || DEFAULT_DEV_SERVER;
|
|
334
352
|
const url = `wss://${devServer}/ws`;
|
|
@@ -700,14 +718,32 @@ export class XmppClient {
|
|
|
700
718
|
console.log('Attempting to reconnect xmpp client...');
|
|
701
719
|
|
|
702
720
|
try {
|
|
703
|
-
//
|
|
704
|
-
//
|
|
705
|
-
//
|
|
706
|
-
//
|
|
707
|
-
|
|
721
|
+
// Re-mint credentials BEFORE reconnecting.
|
|
722
|
+
//
|
|
723
|
+
// This deliberately no longer waits for a SASL `not-authorized`.
|
|
724
|
+
// The XMPP password expires after an hour, and an expiry does NOT
|
|
725
|
+
// drop an established connection — authentication happens once, at
|
|
726
|
+
// bind. So by the time anything disconnects us (a network blip, a
|
|
727
|
+
// sleeping device, a server restart) the password we still hold may
|
|
728
|
+
// well be dead, and we have no way to know. Reconnecting with it
|
|
729
|
+
// burns a guaranteed-failed bind plus a backoff delay before the
|
|
730
|
+
// old `lastAuthError` path could even start recovering.
|
|
731
|
+
//
|
|
732
|
+
// Throttled, because reconnects are not rare: a flapping link would
|
|
733
|
+
// otherwise rotate the whole session (access + refresh + file token
|
|
734
|
+
// + XMPP password) once per flap. A SASL failure bypasses the
|
|
735
|
+
// throttle — there the credentials are known bad.
|
|
736
|
+
const authFailed = this.lastAuthError === 'not-authorized';
|
|
737
|
+
const staleCreds =
|
|
738
|
+
Date.now() - this.credentialsRefreshedAt >=
|
|
739
|
+
CREDENTIALS_REFRESH_MIN_INTERVAL_MS;
|
|
740
|
+
|
|
741
|
+
if (this.credentialsProvider && (authFailed || staleCreds)) {
|
|
708
742
|
try {
|
|
709
743
|
await this.refreshCredentialsOnce();
|
|
710
744
|
} catch (err) {
|
|
745
|
+
// Offline is the common case here — reconnect with what we
|
|
746
|
+
// have and let the next attempt try again.
|
|
711
747
|
console.warn(
|
|
712
748
|
'XMPP credential refresh failed; reconnecting with cached creds',
|
|
713
749
|
err
|
|
@@ -721,7 +757,10 @@ export class XmppClient {
|
|
|
721
757
|
// `this.client` still points at the old client — i.e. before
|
|
722
758
|
// initializeClient() reassigns it.
|
|
723
759
|
const old = this.client;
|
|
724
|
-
if (old) {
|
|
760
|
+
if (old && this.clientAlreadyStopped) {
|
|
761
|
+
this.detachEventListeners();
|
|
762
|
+
this.clientAlreadyStopped = false;
|
|
763
|
+
} else if (old) {
|
|
725
764
|
this.detachEventListeners();
|
|
726
765
|
// NEVER await a bare stop(): on a half-dead socket (the exact case
|
|
727
766
|
// we're reconnecting for) @xmpp/client's stop() can hang forever
|
|
@@ -736,6 +775,9 @@ export class XmppClient {
|
|
|
736
775
|
await withTimeout(old.stop(), STOP_TIMEOUT_MS);
|
|
737
776
|
}
|
|
738
777
|
this.initializeClient();
|
|
778
|
+
if (this.suspendedForBackground) {
|
|
779
|
+
await this.stopClientQuietly();
|
|
780
|
+
}
|
|
739
781
|
} finally {
|
|
740
782
|
this.reconnecting = false;
|
|
741
783
|
}
|
|
@@ -763,6 +805,7 @@ export class XmppClient {
|
|
|
763
805
|
// creds really are stale we simply get not-authorized again and
|
|
764
806
|
// retry, which is the confirmed-good 26.5.7 behaviour.
|
|
765
807
|
this.updateCredentials(fresh.username, fresh.password);
|
|
808
|
+
this.credentialsRefreshedAt = Date.now();
|
|
766
809
|
this.lastAuthError = null;
|
|
767
810
|
}
|
|
768
811
|
} finally {
|
|
@@ -772,6 +815,56 @@ export class XmppClient {
|
|
|
772
815
|
return this.credentialsRefreshInFlight;
|
|
773
816
|
}
|
|
774
817
|
|
|
818
|
+
private suspendedForBackground = false;
|
|
819
|
+
private clientAlreadyStopped = false;
|
|
820
|
+
|
|
821
|
+
private async stopClientQuietly(): Promise<void> {
|
|
822
|
+
const c: any = this.client;
|
|
823
|
+
if (c) {
|
|
824
|
+
const sock = c.socket;
|
|
825
|
+
if (sock && typeof sock.end === 'function') {
|
|
826
|
+
try {
|
|
827
|
+
sock.end();
|
|
828
|
+
} catch {}
|
|
829
|
+
try {
|
|
830
|
+
if (c.status !== 'offline') c._status?.('offline');
|
|
831
|
+
} catch {}
|
|
832
|
+
} else {
|
|
833
|
+
await withTimeout(
|
|
834
|
+
Promise.resolve(c.stop()).catch(() => undefined),
|
|
835
|
+
STOP_TIMEOUT_MS
|
|
836
|
+
);
|
|
837
|
+
}
|
|
838
|
+
this.clientAlreadyStopped = true;
|
|
839
|
+
}
|
|
840
|
+
this.status = 'offline';
|
|
841
|
+
this.presencesReady = false;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
async suspend(): Promise<void> {
|
|
845
|
+
if (this.suspendedForBackground) {return;}
|
|
846
|
+
this.suspendedForBackground = true;
|
|
847
|
+
this.suppressReconnect = true;
|
|
848
|
+
if (this.reconnectTimer) {
|
|
849
|
+
clearTimeout(this.reconnectTimer);
|
|
850
|
+
this.reconnectTimer = null;
|
|
851
|
+
}
|
|
852
|
+
await this.stopClientQuietly();
|
|
853
|
+
console.log('XMPP suspended (background).');
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
/** Back in the foreground: allow reconnects again and reconnect at once. */
|
|
857
|
+
resume(): void {
|
|
858
|
+
if (!this.suspendedForBackground) {return;}
|
|
859
|
+
this.suspendedForBackground = false;
|
|
860
|
+
this.suppressReconnect = false;
|
|
861
|
+
this.forceReconnect();
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
get isSuspended(): boolean {
|
|
865
|
+
return this.suspendedForBackground;
|
|
866
|
+
}
|
|
867
|
+
|
|
775
868
|
async disconnect(options?: { suppressReconnect?: boolean }): Promise<void> {
|
|
776
869
|
if (options?.suppressReconnect) {this.suppressReconnect = true;}
|
|
777
870
|
return this.close();
|
|
@@ -971,9 +1064,37 @@ export class XmppClient {
|
|
|
971
1064
|
// `getChatsPrivateStoreRequest` directly and intentionally skip this.
|
|
972
1065
|
if (markers && typeof markers === 'object') {
|
|
973
1066
|
const normalized: Record<string, number> = {};
|
|
1067
|
+
const roomsState = store.getState().rooms?.rooms || {};
|
|
1068
|
+
const heapState = store.getState().roomHeapSlice;
|
|
974
1069
|
for (const jid of Object.keys(markers as Record<string, unknown>)) {
|
|
975
1070
|
const n = Number((markers as Record<string, unknown>)[jid]);
|
|
976
|
-
if (jid
|
|
1071
|
+
if (!jid || !Number.isFinite(n) || n <= 0) {continue;}
|
|
1072
|
+
// Defensive clamp (bug #38): a marker written while some
|
|
1073
|
+
// device's clock was ahead can land in the future relative to
|
|
1074
|
+
// the newest message the server actually has for this room.
|
|
1075
|
+
// The redux merge (applyPrivateStoreMarkers) and the
|
|
1076
|
+
// server-side merge (flushLastViewedToPrivateStore) both treat
|
|
1077
|
+
// "newer" as "better", so an uncorrected future value would
|
|
1078
|
+
// block every later correct write forever - useUnread() would
|
|
1079
|
+
// report 0 for that room on every cold start. When we already
|
|
1080
|
+
// know this room's messages locally, clamp an implausible
|
|
1081
|
+
// marker down to the newest one we actually have instead of
|
|
1082
|
+
// trusting the server value verbatim.
|
|
1083
|
+
//
|
|
1084
|
+
// "Implausible" needs BOTH "past the newest message we know
|
|
1085
|
+
// about" AND "past real time" (isCorruptFutureReadMarker):
|
|
1086
|
+
// this device's cache for a room is routinely stale, and
|
|
1087
|
+
// clamping on staleness alone would drag a perfectly good
|
|
1088
|
+
// marker written by another device backwards.
|
|
1089
|
+
const room = roomsState[jid];
|
|
1090
|
+
const newestKnownMs = room
|
|
1091
|
+
? getServerReadTimestamp(room, heapState)
|
|
1092
|
+
: 0;
|
|
1093
|
+
if (isCorruptFutureReadMarker(n, newestKnownMs)) {
|
|
1094
|
+
normalized[jid] = newestKnownMs;
|
|
1095
|
+
} else {
|
|
1096
|
+
normalized[jid] = n;
|
|
1097
|
+
}
|
|
977
1098
|
}
|
|
978
1099
|
if (Object.keys(normalized).length > 0) {
|
|
979
1100
|
store.dispatch(applyPrivateStoreMarkers(normalized));
|
|
@@ -1007,11 +1128,22 @@ export class XmppClient {
|
|
|
1007
1128
|
// src/networking/xmpp/flushLastViewedToPrivateStore.ts for details.
|
|
1008
1129
|
async flushLastViewedToPrivateStoreStanza(
|
|
1009
1130
|
rooms: Record<string, any> | null | undefined,
|
|
1010
|
-
opts: {
|
|
1131
|
+
opts: {
|
|
1132
|
+
visibleRoomJID?: string | null;
|
|
1133
|
+
visibleRoomTs?: number | null;
|
|
1134
|
+
onlyIfNoUnread?: boolean;
|
|
1135
|
+
} = {}
|
|
1011
1136
|
) {
|
|
1012
1137
|
if (this.disableLastRead) {return false;}
|
|
1013
1138
|
try {
|
|
1014
|
-
|
|
1139
|
+
// Auto-inject the pending/failed-send heap so every caller gets
|
|
1140
|
+
// getServerReadTimestamp's exclusion of optimistic messages for
|
|
1141
|
+
// free, without needing to reach into the redux store themselves.
|
|
1142
|
+
const heapState = store.getState().roomHeapSlice;
|
|
1143
|
+
return await flushLastViewedToPrivateStore(this, rooms, {
|
|
1144
|
+
...opts,
|
|
1145
|
+
heapState,
|
|
1146
|
+
});
|
|
1015
1147
|
} catch {
|
|
1016
1148
|
return false;
|
|
1017
1149
|
}
|
|
@@ -11,8 +11,7 @@ import {
|
|
|
11
11
|
} from '../types/types';
|
|
12
12
|
import { Iso639_1Codes } from '../types/models/language.model';
|
|
13
13
|
import type { TranslateMode } from '../utils/translateModePolicy';
|
|
14
|
-
import {
|
|
15
|
-
import { asyncLocalStorage } from '../hooks/useLocalStorage';
|
|
14
|
+
import { secureUserStorage } from '../helpers/secureUserStorage';
|
|
16
15
|
|
|
17
16
|
export interface ChatState {
|
|
18
17
|
user: User;
|
|
@@ -34,12 +33,15 @@ export interface ChatState {
|
|
|
34
33
|
|
|
35
34
|
export const unpackAndTransform = (input?: User): User => {
|
|
36
35
|
return {
|
|
37
|
-
|
|
36
|
+
// Was hardcoded to '' — every setUser dropped the user's own bio, so
|
|
37
|
+
// the profile's About section could never show one.
|
|
38
|
+
description: input?.description || '',
|
|
38
39
|
token: input?.token || '',
|
|
39
40
|
profileImage: input?.profileImage || '',
|
|
40
41
|
_id: input?._id || '',
|
|
41
42
|
walletAddress: input?.defaultWallet?.walletAddress || '',
|
|
42
43
|
xmppPassword: input?.xmppPassword || '',
|
|
44
|
+
fileToken: input?.fileToken || '',
|
|
43
45
|
refreshToken: input?.refreshToken || '',
|
|
44
46
|
firstName: input?.firstName || '',
|
|
45
47
|
lastName: input?.lastName || '',
|
|
@@ -73,6 +75,7 @@ const initialState: ChatState = {
|
|
|
73
75
|
_id: '',
|
|
74
76
|
walletAddress: '',
|
|
75
77
|
xmppPassword: '',
|
|
78
|
+
fileToken: '',
|
|
76
79
|
refreshToken: '',
|
|
77
80
|
firstName: '',
|
|
78
81
|
lastName: '',
|
|
@@ -111,9 +114,7 @@ const initialState: ChatState = {
|
|
|
111
114
|
const reducers = {
|
|
112
115
|
setUser: (state: WritableDraft<ChatState>, action: PayloadAction<User>) => {
|
|
113
116
|
state.user = unpackAndTransform(action.payload);
|
|
114
|
-
|
|
115
|
-
unpackAndTransform(action.payload)
|
|
116
|
-
);
|
|
117
|
+
secureUserStorage().set(unpackAndTransform(action.payload));
|
|
117
118
|
},
|
|
118
119
|
updateUser(state: WritableDraft<ChatState>, action: PayloadAction<{ updates: Partial<User> }>) {
|
|
119
120
|
const { updates } = action.payload;
|
|
@@ -146,14 +147,37 @@ const reducers = {
|
|
|
146
147
|
setSelectedUser: (state: WritableDraft<ChatState>, action: PayloadAction<IUser | undefined>) => {
|
|
147
148
|
state.selectedUser = action.payload;
|
|
148
149
|
},
|
|
150
|
+
/**
|
|
151
|
+
* Token rotation. Dispatched from ONE place only — `authRefresh` —
|
|
152
|
+
* which awaits the AsyncStorage write immediately afterwards, before
|
|
153
|
+
* resolving its promise.
|
|
154
|
+
*
|
|
155
|
+
* The reducer used to fire its own best-effort write here. That was
|
|
156
|
+
* both redundant and racy (two writers, no ordering), and a
|
|
157
|
+
* fire-and-forget write can be lost if the app dies right after a
|
|
158
|
+
* rotation — which on a backend with reuse detection means the next
|
|
159
|
+
* launch presents a burned token. Persistence now belongs to the
|
|
160
|
+
* caller, which can actually await it.
|
|
161
|
+
*/
|
|
149
162
|
refreshTokens: (
|
|
150
163
|
state: WritableDraft<ChatState>,
|
|
151
|
-
action: PayloadAction<{
|
|
164
|
+
action: PayloadAction<{
|
|
165
|
+
token: string;
|
|
166
|
+
refreshToken: string;
|
|
167
|
+
xmppPassword?: string;
|
|
168
|
+
fileToken?: string;
|
|
169
|
+
}>
|
|
152
170
|
) => {
|
|
153
171
|
state.user.refreshToken = action.payload.refreshToken;
|
|
154
172
|
state.user.token = action.payload.token;
|
|
155
|
-
|
|
156
|
-
|
|
173
|
+
|
|
174
|
+
if (action.payload.xmppPassword) {
|
|
175
|
+
state.user.xmppPassword = action.payload.xmppPassword;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (action.payload.fileToken) {
|
|
179
|
+
state.user.fileToken = action.payload.fileToken;
|
|
180
|
+
}
|
|
157
181
|
},
|
|
158
182
|
logout: (state: WritableDraft<ChatState>) => {
|
|
159
183
|
state.user = unpackAndTransform();
|
|
@@ -161,7 +185,7 @@ const reducers = {
|
|
|
161
185
|
state.client = undefined;
|
|
162
186
|
state.langSource = undefined;
|
|
163
187
|
state.translateMode = undefined;
|
|
164
|
-
|
|
188
|
+
secureUserStorage().remove();
|
|
165
189
|
},
|
|
166
190
|
setLangSource: (
|
|
167
191
|
state: WritableDraft<ChatState>,
|