@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
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional-dependency bridge for `expo-secure-store` — the Keychain
|
|
3
|
+
* (iOS) / Keystore-backed EncryptedSharedPreferences (Android) API.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors `components/VideoCalls/livekitRuntime.ts`: a plain top-level
|
|
6
|
+
* `import ... from 'expo-secure-store'` is not allowed anywhere in the
|
|
7
|
+
* SDK, since Metro resolves imports at bundle time and a host that
|
|
8
|
+
* hasn't added this optional peer dependency would fail to build over
|
|
9
|
+
* a feature it never opted into. Everything goes through
|
|
10
|
+
* `loadSecureStore()`, which requires the module lazily and returns
|
|
11
|
+
* null when it isn't installed — callers fall back to plain
|
|
12
|
+
* AsyncStorage rather than crash (see `secureKeyValue.ts`).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export interface SecureStoreRuntime {
|
|
16
|
+
getItemAsync: (key: string) => Promise<string | null>;
|
|
17
|
+
setItemAsync: (key: string, value: string) => Promise<void>;
|
|
18
|
+
deleteItemAsync: (key: string) => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let cached: SecureStoreRuntime | null | undefined;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the SecureStore runtime, or null when the optional native
|
|
25
|
+
* package isn't installed in the host app. Result is memoised
|
|
26
|
+
* (including the failure) so a missing dependency doesn't re-throw on
|
|
27
|
+
* every read/write.
|
|
28
|
+
*/
|
|
29
|
+
export const loadSecureStore = (): SecureStoreRuntime | null => {
|
|
30
|
+
if (cached !== undefined) {
|
|
31
|
+
return cached;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
36
|
+
const mod = require('expo-secure-store');
|
|
37
|
+
if (
|
|
38
|
+
typeof mod?.getItemAsync !== 'function' ||
|
|
39
|
+
typeof mod?.setItemAsync !== 'function' ||
|
|
40
|
+
typeof mod?.deleteItemAsync !== 'function'
|
|
41
|
+
) {
|
|
42
|
+
cached = null;
|
|
43
|
+
} else {
|
|
44
|
+
cached = {
|
|
45
|
+
getItemAsync: mod.getItemAsync,
|
|
46
|
+
setItemAsync: mod.setItemAsync,
|
|
47
|
+
deleteItemAsync: mod.deleteItemAsync,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
} catch {
|
|
51
|
+
cached = null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return cached;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const isSecureStoreAvailable = (): boolean => loadSecureStore() !== null;
|
|
58
|
+
|
|
59
|
+
/** Test seam only. */
|
|
60
|
+
export const __resetSecureStoreRuntimeForTests = (): void => {
|
|
61
|
+
cached = undefined;
|
|
62
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { User } from '../types/types';
|
|
2
|
+
import { asyncLocalStorage } from '../hooks/useLocalStorage';
|
|
3
|
+
import { localStorageConstants } from './constants/LOCAL_STORAGE';
|
|
4
|
+
import { secureGet, secureSet, secureRemove } from './secureKeyValue';
|
|
5
|
+
|
|
6
|
+
// Keychain (iOS) / Keystore-backed EncryptedSharedPreferences (Android)
|
|
7
|
+
// keys for the four live bearer credentials on `User`. Deliberately one
|
|
8
|
+
// key per field rather than one JSON blob: expo-secure-store historically
|
|
9
|
+
// caps a single value's size on Android, and four short JWTs each stay
|
|
10
|
+
// comfortably under that ceiling where one combined blob might not.
|
|
11
|
+
const SECRET_KEYS = {
|
|
12
|
+
token: 'ethora_auth_token',
|
|
13
|
+
refreshToken: 'ethora_auth_refresh_token',
|
|
14
|
+
xmppPassword: 'ethora_auth_xmpp_password',
|
|
15
|
+
fileToken: 'ethora_auth_file_token',
|
|
16
|
+
} as const;
|
|
17
|
+
|
|
18
|
+
type SecretField = keyof typeof SECRET_KEYS;
|
|
19
|
+
const SECRET_FIELDS = Object.keys(SECRET_KEYS) as SecretField[];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Persisted-user storage, split across two backends behind the exact
|
|
23
|
+
* same `{ get, set, remove }` shape `asyncLocalStorage<User>(...)`
|
|
24
|
+
* already exposed — every existing call site swaps in by changing only
|
|
25
|
+
* the constructor call, `get()`/`set()`/`remove()` keep returning/taking
|
|
26
|
+
* a complete `User`.
|
|
27
|
+
*
|
|
28
|
+
* The four live credentials (REST access + refresh token, XMPP
|
|
29
|
+
* password, secure-media fileToken) never touch plain AsyncStorage:
|
|
30
|
+
* they go through `secureGet`/`secureSet`/`secureRemove` (platform
|
|
31
|
+
* Keychain/Keystore, falling back to namespaced AsyncStorage only when
|
|
32
|
+
* the host hasn't installed the optional `expo-secure-store` peer dep).
|
|
33
|
+
* Everything else on `User` — name, avatar, ids, xmppUsername, wallet
|
|
34
|
+
* address, none of it a bearer credential — keeps living under the
|
|
35
|
+
* existing `ETHORA_USER` AsyncStorage key, unchanged.
|
|
36
|
+
*/
|
|
37
|
+
export function secureUserStorage() {
|
|
38
|
+
const get = async (): Promise<User | null> => {
|
|
39
|
+
const profile = await asyncLocalStorage<User>(
|
|
40
|
+
localStorageConstants.ETHORA_USER
|
|
41
|
+
).get();
|
|
42
|
+
if (!profile) {return null;}
|
|
43
|
+
|
|
44
|
+
const secretValues = await Promise.all(
|
|
45
|
+
SECRET_FIELDS.map((field) => secureGet(SECRET_KEYS[field]))
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const merged: User = { ...profile };
|
|
49
|
+
SECRET_FIELDS.forEach((field, i) => {
|
|
50
|
+
(merged as any)[field] = secretValues[i] || '';
|
|
51
|
+
});
|
|
52
|
+
return merged;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const set = async (user: User): Promise<void> => {
|
|
56
|
+
const profile: any = { ...user };
|
|
57
|
+
for (const field of SECRET_FIELDS) {
|
|
58
|
+
profile[field] = '';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
await Promise.all([
|
|
62
|
+
asyncLocalStorage<User>(localStorageConstants.ETHORA_USER).set(profile),
|
|
63
|
+
...SECRET_FIELDS.map((field) => {
|
|
64
|
+
const value = user?.[field] as string | undefined;
|
|
65
|
+
return value
|
|
66
|
+
? secureSet(SECRET_KEYS[field], value)
|
|
67
|
+
: secureRemove(SECRET_KEYS[field]);
|
|
68
|
+
}),
|
|
69
|
+
]);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const remove = async (): Promise<void> => {
|
|
73
|
+
await Promise.all([
|
|
74
|
+
asyncLocalStorage(localStorageConstants.ETHORA_USER).remove(),
|
|
75
|
+
...SECRET_FIELDS.map((field) => secureRemove(SECRET_KEYS[field])),
|
|
76
|
+
]);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return { get, set, remove };
|
|
80
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-level shallow equality for plain objects. Used to avoid re-dispatching
|
|
3
|
+
* config into redux on every render just because the host passed a fresh
|
|
4
|
+
* object literal with the same values (e.g. `<Chat config={{...}} />`
|
|
5
|
+
* re-created inline) — reference equality alone would fire far too often,
|
|
6
|
+
* and a deep/JSON comparison risks throwing on non-serializable fields
|
|
7
|
+
* (functions, React elements) that configs legitimately carry.
|
|
8
|
+
*/
|
|
9
|
+
export function shallowEqual(a: unknown, b: unknown): boolean {
|
|
10
|
+
if (a === b) {return true;}
|
|
11
|
+
if (
|
|
12
|
+
typeof a !== 'object' ||
|
|
13
|
+
typeof b !== 'object' ||
|
|
14
|
+
a === null ||
|
|
15
|
+
b === null
|
|
16
|
+
) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const aKeys = Object.keys(a as Record<string, unknown>);
|
|
20
|
+
const bKeys = Object.keys(b as Record<string, unknown>);
|
|
21
|
+
if (aKeys.length !== bKeys.length) {return false;}
|
|
22
|
+
for (const key of aKeys) {
|
|
23
|
+
if (
|
|
24
|
+
(a as Record<string, unknown>)[key] !==
|
|
25
|
+
(b as Record<string, unknown>)[key]
|
|
26
|
+
) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default shallowEqual;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** @format */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared thresholds for the drag-to-dismiss gesture on bottom sheets (the
|
|
5
|
+
* attach sheet, the profile headers, the room-list menu). Kept in one
|
|
6
|
+
* place so a pull feels identical wherever the user does it — and so the
|
|
7
|
+
* numbers are unit-testable without a touch event.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Drag past this many points and letting go dismisses the sheet. */
|
|
11
|
+
export const DISMISS_DISTANCE = 90;
|
|
12
|
+
/** …or flick faster than this, however short the drag. */
|
|
13
|
+
export const DISMISS_VELOCITY = 0.8;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Claim a drag only once it is clearly a downward pull, so a tap on a row
|
|
17
|
+
* still registers and a horizontal swipe stays with whatever scrolls
|
|
18
|
+
* sideways inside the sheet.
|
|
19
|
+
*/
|
|
20
|
+
export const shouldClaimVerticalDrag = (dy: number, dx: number) =>
|
|
21
|
+
dy > 6 && Math.abs(dy) > Math.abs(dx) * 1.5;
|
|
22
|
+
|
|
23
|
+
/** Far enough / fast enough to let go of the sheet. */
|
|
24
|
+
export const shouldDismissOnDrag = (dy: number, vy: number) =>
|
|
25
|
+
dy > DISMISS_DISTANCE || vy > DISMISS_VELOCITY;
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
2
|
import { useDispatch } from 'react-redux';
|
|
3
3
|
import {
|
|
4
|
+
clearReadBoundary,
|
|
4
5
|
clearVisibleRoom,
|
|
5
6
|
setCurrentRoom,
|
|
6
7
|
setLastViewedTimestamp,
|
|
7
8
|
setVisibleRoom,
|
|
8
9
|
} from '../roomStore/roomsSlice';
|
|
9
10
|
import { store } from '../roomStore';
|
|
11
|
+
import {
|
|
12
|
+
getFlushBoundaryTs,
|
|
13
|
+
getReadMarkerTimestamp,
|
|
14
|
+
} from '../helpers/getServerReadTimestamp';
|
|
10
15
|
|
|
11
16
|
interface UseChatRoomFocusOptions {
|
|
12
17
|
/** The room JID that the consumer's tab/screen is currently showing. */
|
|
@@ -32,7 +37,10 @@ interface UseChatRoomFocusOptions {
|
|
|
32
37
|
* Without this hook, `useUnread()` will always return 0 for the chat
|
|
33
38
|
* room because the SDK assumes "mounted == active". With this hook,
|
|
34
39
|
* focus marks the room visible (clearing the badge) and blur stamps
|
|
35
|
-
* `lastViewedTimestamp
|
|
40
|
+
* `lastViewedTimestamp` to the newest SERVER-acknowledged message so
|
|
41
|
+
* future messages count as unread. Deliberately not `Date.now()`: a
|
|
42
|
+
* device clock running ahead would write a future marker that the
|
|
43
|
+
* forward-only private-store merge could never correct again (bug #38).
|
|
36
44
|
*
|
|
37
45
|
* Usage with React Navigation:
|
|
38
46
|
*
|
|
@@ -58,20 +66,52 @@ export const useChatRoomFocus = ({
|
|
|
58
66
|
isFocused: false,
|
|
59
67
|
});
|
|
60
68
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
// `clearBoundary`: pass true only when the room the user is leaving is
|
|
70
|
+
// genuinely being released (switching to a different room, or this
|
|
71
|
+
// hook unmounting) - not on a mere same-room blur. `<ChatRoom>`'s
|
|
72
|
+
// MessageList typically stays mounted across a same-room focus loss
|
|
73
|
+
// (the whole point of this hook is that the host keeps `<Chat>`
|
|
74
|
+
// mounted in a hidden tab), so its own scroll-tracking ref is still
|
|
75
|
+
// intact and the redux boundary must stay in sync with it - clearing
|
|
76
|
+
// it here would desync the two.
|
|
77
|
+
const leaveRoom = (jid: string, clearBoundary: boolean) => {
|
|
78
|
+
const state = store.getState();
|
|
79
|
+
const rooms = state.rooms?.rooms;
|
|
80
|
+
const boundaryTs = state.rooms?.readBoundaries?.[jid] ?? null;
|
|
81
|
+
// getReadMarkerTimestamp: honour the boundary (the newest message the
|
|
82
|
+
// user actually reached) when the user left this room scrolled up,
|
|
83
|
+
// otherwise fall back to the newest server-acked message. Only stamp
|
|
84
|
+
// when we actually have something to anchor to - skip rather than
|
|
85
|
+
// fall back to the device clock (bug #38). Ignoring the boundary here
|
|
86
|
+
// would stamp "everything read" regardless of scroll position (bug
|
|
87
|
+
// #42, a regression of #33 reintroduced by #38).
|
|
88
|
+
const timestamp = getReadMarkerTimestamp(rooms?.[jid], state.roomHeapSlice, boundaryTs);
|
|
89
|
+
if (timestamp > 0) {
|
|
90
|
+
dispatch(setLastViewedTimestamp({ chatJID: jid, timestamp }));
|
|
91
|
+
}
|
|
64
92
|
dispatch(clearVisibleRoom());
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
93
|
+
(state.chatSettingStore as any)?.client
|
|
94
|
+
?.flushLastViewedToPrivateStoreStanza(rooms, {
|
|
95
|
+
visibleRoomJID: jid,
|
|
96
|
+
// Carry the same boundary to the SERVER marker - without it the
|
|
97
|
+
// flush defaults to "everything" for the visible room. Clamped
|
|
98
|
+
// through the same helper as the local stamp above.
|
|
99
|
+
visibleRoomTs: getFlushBoundaryTs(
|
|
100
|
+
rooms?.[jid],
|
|
101
|
+
state.roomHeapSlice,
|
|
102
|
+
boundaryTs
|
|
103
|
+
),
|
|
104
|
+
})
|
|
68
105
|
.catch(() => {});
|
|
106
|
+
if (clearBoundary) {
|
|
107
|
+
dispatch(clearReadBoundary({ jid }));
|
|
108
|
+
}
|
|
69
109
|
};
|
|
70
110
|
|
|
71
111
|
useEffect(() => {
|
|
72
112
|
const prev = prevRef.current;
|
|
73
113
|
if (prev.isFocused && prev.roomJID && (prev.roomJID !== roomJID || !isFocused)) {
|
|
74
|
-
leaveRoom(prev.roomJID);
|
|
114
|
+
leaveRoom(prev.roomJID, prev.roomJID !== roomJID);
|
|
75
115
|
}
|
|
76
116
|
|
|
77
117
|
if (roomJID && isFocused) {
|
|
@@ -86,7 +126,7 @@ export const useChatRoomFocus = ({
|
|
|
86
126
|
return () => {
|
|
87
127
|
const prev = prevRef.current;
|
|
88
128
|
if (prev.isFocused && prev.roomJID) {
|
|
89
|
-
leaveRoom(prev.roomJID);
|
|
129
|
+
leaveRoom(prev.roomJID, true);
|
|
90
130
|
}
|
|
91
131
|
};
|
|
92
132
|
}, []);
|
|
@@ -9,9 +9,8 @@ import { AppDispatch, RootState } from '../roomStore';
|
|
|
9
9
|
import { useXmppClient } from '../context/xmppProvider';
|
|
10
10
|
import { chatAutoEnterer } from '../helpers/chatAutoEnterer';
|
|
11
11
|
import { initRoomsPresence } from '../helpers/initRoomsPresence';
|
|
12
|
-
import { updatedChatLastTimestamps } from '../helpers/updatedChatLastTimestamps';
|
|
13
12
|
import { updateMessagesTillLast } from '../helpers/updateMessagesTillLast';
|
|
14
|
-
import {
|
|
13
|
+
import { refreshAuthTokensQuietly } from '../networking/authRefresh';
|
|
15
14
|
import { setLangSource, setConfig } from '../roomStore/chatSettingsSlice';
|
|
16
15
|
import { setIsLoading } from '../roomStore/roomsSlice';
|
|
17
16
|
import { useRoomState } from './useRoomState';
|
|
@@ -19,6 +18,7 @@ import { useChatSettingState } from './useChatSettingState';
|
|
|
19
18
|
import { isChatIdPresentInArray } from '../helpers/isChatIdPresentInArray';
|
|
20
19
|
import useGetNewArchRoom from './useGetNewArchRoom';
|
|
21
20
|
import { getRoomsWithRetry } from '../helpers/getRoomsWithRetry';
|
|
21
|
+
import { shallowEqual } from '../helpers/shallowEqual';
|
|
22
22
|
|
|
23
23
|
interface useChatWrapperInitProps {
|
|
24
24
|
roomJID: string | null | undefined;
|
|
@@ -66,6 +66,20 @@ const useChatWrapperInit = ({
|
|
|
66
66
|
};
|
|
67
67
|
}, [user.xmppPassword]);
|
|
68
68
|
|
|
69
|
+
// Presentational config flags (e.g. `disableHeader`) can change while the
|
|
70
|
+
// chat stays mounted — sync them to redux whenever `config` actually
|
|
71
|
+
// changes, not just at init. Shallow-equal guard: an inline object
|
|
72
|
+
// literal from the host is a fresh reference every render even when
|
|
73
|
+
// nothing in it changed, and dispatching unconditionally would re-render
|
|
74
|
+
// every config consumer on every host render.
|
|
75
|
+
const lastSyncedConfigRef = useRef<IConfig | undefined>(undefined);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (!shallowEqual(lastSyncedConfigRef.current, config)) {
|
|
78
|
+
lastSyncedConfigRef.current = config;
|
|
79
|
+
dispatch(setConfig(config));
|
|
80
|
+
}
|
|
81
|
+
}, [config, dispatch]);
|
|
82
|
+
|
|
69
83
|
const getRoomsWithRertyRequest = async () => {
|
|
70
84
|
setIsRetrying(true);
|
|
71
85
|
const retryRooms = await getRoomsWithRetry(
|
|
@@ -159,15 +173,21 @@ const useChatWrapperInit = ({
|
|
|
159
173
|
}
|
|
160
174
|
}
|
|
161
175
|
try {
|
|
176
|
+
// getChatsPrivateStoreRequestStanza hydrates redux itself
|
|
177
|
+
// (dispatch(applyPrivateStoreMarkers(...)) internally,
|
|
178
|
+
// clamped + forward-only) - do not also apply the raw
|
|
179
|
+
// return value here. That used to double-dispatch via
|
|
180
|
+
// updatedChatLastTimestamps' unconditional
|
|
181
|
+
// setLastViewedTimestamp, which has neither the
|
|
182
|
+
// forward-only guard nor the future-marker clamp, so on
|
|
183
|
+
// every reconnect it could silently re-clobber a value
|
|
184
|
+
// the clamp had just corrected (bug #38).
|
|
162
185
|
const roomTimestampObject: any =
|
|
163
186
|
await newClient.getChatsPrivateStoreRequestStanza();
|
|
164
187
|
console.log(
|
|
165
188
|
'Got chats private store',
|
|
166
189
|
roomTimestampObject?.length || 0
|
|
167
190
|
);
|
|
168
|
-
if (roomTimestampObject) {
|
|
169
|
-
updatedChatLastTimestamps(roomTimestampObject, dispatch);
|
|
170
|
-
}
|
|
171
191
|
if (!hasSyncedHistoryRef.current) {
|
|
172
192
|
console.log('Updating messages till last');
|
|
173
193
|
await updateMessagesTillLast(rooms, newClient);
|
|
@@ -183,7 +203,7 @@ const useChatWrapperInit = ({
|
|
|
183
203
|
}
|
|
184
204
|
|
|
185
205
|
{
|
|
186
|
-
config?.refreshTokens?.enabled &&
|
|
206
|
+
config?.refreshTokens?.enabled && refreshAuthTokensQuietly();
|
|
187
207
|
}
|
|
188
208
|
} catch (error) {
|
|
189
209
|
console.error(' Error during initialization', error);
|
|
@@ -209,15 +229,15 @@ const useChatWrapperInit = ({
|
|
|
209
229
|
setInited(true);
|
|
210
230
|
console.log(' Getting chats private store for existing client');
|
|
211
231
|
try {
|
|
232
|
+
// See the "new client" branch above: getChatsPrivateStoreRequestStanza
|
|
233
|
+
// already hydrates redux (clamped + forward-only); do not
|
|
234
|
+
// also apply the raw return value here.
|
|
212
235
|
const roomTimestampObject: any =
|
|
213
236
|
await client.getChatsPrivateStoreRequestStanza();
|
|
214
237
|
console.log(
|
|
215
238
|
'Got chats private store for existing client',
|
|
216
239
|
roomTimestampObject?.length || 0
|
|
217
240
|
);
|
|
218
|
-
if (roomTimestampObject) {
|
|
219
|
-
updatedChatLastTimestamps(roomTimestampObject, dispatch);
|
|
220
|
-
}
|
|
221
241
|
if (!hasSyncedHistoryRef.current) {
|
|
222
242
|
console.log(
|
|
223
243
|
'Updating messages till last for existing client'
|
|
@@ -237,7 +257,7 @@ const useChatWrapperInit = ({
|
|
|
237
257
|
setConnectionLost(false);
|
|
238
258
|
}
|
|
239
259
|
{
|
|
240
|
-
config?.refreshTokens?.enabled &&
|
|
260
|
+
config?.refreshTokens?.enabled && refreshAuthTokensQuietly();
|
|
241
261
|
}
|
|
242
262
|
}
|
|
243
263
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { useCallback, useEffect,
|
|
1
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
2
|
+
import { AppState, AppStateStatus } from 'react-native';
|
|
2
3
|
import { useXmppClient } from '../context/xmppProvider';
|
|
3
4
|
import { useSelector } from 'react-redux';
|
|
4
5
|
import { RootState } from '../roomStore';
|
|
@@ -9,8 +10,16 @@ const useComposing = (config?: IConfig) => {
|
|
|
9
10
|
const { client } = useXmppClient();
|
|
10
11
|
const { activeRoomJID } = useSelector((state: RootState) => state.rooms);
|
|
11
12
|
const { user } = useChatSettingState();
|
|
13
|
+
// RN keeps a focused TextInput focused when the app is backgrounded or
|
|
14
|
+
// the device is locked — nothing fires `onBlur`, so without this the
|
|
15
|
+
// other participant sees "typing…" for as long as the user is away.
|
|
16
|
+
// Tracks whether the input is *currently* focused, independent of the
|
|
17
|
+
// foreground/background transition, so we know whether to resume
|
|
18
|
+
// composing on return.
|
|
19
|
+
const isFocusedRef = useRef(false);
|
|
12
20
|
|
|
13
21
|
const sendStartComposing = useCallback(() => {
|
|
22
|
+
isFocusedRef.current = true;
|
|
14
23
|
if (config?.disableTypingIndicator) {
|
|
15
24
|
return;
|
|
16
25
|
}
|
|
@@ -24,6 +33,7 @@ const useComposing = (config?: IConfig) => {
|
|
|
24
33
|
}, [activeRoomJID, client, config?.disableTypingIndicator, user.firstName, user.lastName]);
|
|
25
34
|
|
|
26
35
|
const sendEndComposing = useCallback(() => {
|
|
36
|
+
isFocusedRef.current = false;
|
|
27
37
|
if (config?.disableTypingIndicator) {
|
|
28
38
|
return;
|
|
29
39
|
}
|
|
@@ -44,6 +54,32 @@ const useComposing = (config?: IConfig) => {
|
|
|
44
54
|
return () => clearTimeout(timerId);
|
|
45
55
|
}, [sendEndComposing]);
|
|
46
56
|
|
|
57
|
+
// Foreground/background transition only — a pause in typing must NOT
|
|
58
|
+
// clear the indicator (that would flicker for a slowly-composing user),
|
|
59
|
+
// so this deliberately does not hook keystroke/idle timing at all.
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
const handleAppStateChange = (nextState: AppStateStatus) => {
|
|
62
|
+
if (nextState !== 'active') {
|
|
63
|
+
if (isFocusedRef.current && !config?.disableTypingIndicator && client) {
|
|
64
|
+
client.sendTypingRequestStanza(
|
|
65
|
+
activeRoomJID || '',
|
|
66
|
+
`${user.firstName} ${user.lastName}`,
|
|
67
|
+
false
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
} else if (isFocusedRef.current && !config?.disableTypingIndicator && client) {
|
|
71
|
+
client.sendTypingRequestStanza(
|
|
72
|
+
activeRoomJID || '',
|
|
73
|
+
`${user.firstName} ${user.lastName}`,
|
|
74
|
+
true
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const subscription = AppState.addEventListener('change', handleAppStateChange);
|
|
80
|
+
return () => subscription.remove();
|
|
81
|
+
}, [activeRoomJID, client, config?.disableTypingIndicator, user.firstName, user.lastName]);
|
|
82
|
+
|
|
47
83
|
return { sendStartComposing, sendEndComposing };
|
|
48
84
|
};
|
|
49
85
|
|
package/src/hooks/useLogout.tsx
CHANGED
|
@@ -9,7 +9,8 @@ import { clearHeap } from '../roomStore/roomHeapSlice';
|
|
|
9
9
|
import { pushSubscriptionService } from '../services/pushSubscriptionService';
|
|
10
10
|
import { clearRoomsRestCache } from '../networking/api-requests/rooms.api';
|
|
11
11
|
import { clearPersistedState } from '../roomStore/persistence';
|
|
12
|
-
import {
|
|
12
|
+
import { secureUserStorage } from '../helpers/secureUserStorage';
|
|
13
|
+
import { getFlushBoundaryTs } from '../helpers/getServerReadTimestamp';
|
|
13
14
|
|
|
14
15
|
// AsyncStorage keys the library writes but that aren't cleared by any
|
|
15
16
|
// slice reducer. Listed here so a single logout call wipes the full
|
|
@@ -59,10 +60,23 @@ const logoutService = {
|
|
|
59
60
|
const client = (state.chatSettingStore as any)?.client;
|
|
60
61
|
const rooms = state.rooms?.rooms;
|
|
61
62
|
const visibleRoomJID = state.rooms?.visibleRoomJID || null;
|
|
63
|
+
// The visible room is exempt from `onlyIfNoUnread`'s skip (it's
|
|
64
|
+
// meant to write "read up to now" for whatever's open), so if the
|
|
65
|
+
// user is logging out while scrolled up with unread messages
|
|
66
|
+
// above, the boundary must still be carried through here - same
|
|
67
|
+
// reasoning as every other "leaving a room" path (bug #42).
|
|
68
|
+
const boundaryTs = visibleRoomJID
|
|
69
|
+
? getFlushBoundaryTs(
|
|
70
|
+
rooms?.[visibleRoomJID],
|
|
71
|
+
state.roomHeapSlice,
|
|
72
|
+
state.rooms?.readBoundaries?.[visibleRoomJID] ?? null
|
|
73
|
+
)
|
|
74
|
+
: undefined;
|
|
62
75
|
if (client?.flushLastViewedToPrivateStoreStanza) {
|
|
63
76
|
await Promise.race([
|
|
64
77
|
client.flushLastViewedToPrivateStoreStanza(rooms, {
|
|
65
78
|
visibleRoomJID,
|
|
79
|
+
visibleRoomTs: boundaryTs,
|
|
66
80
|
onlyIfNoUnread: true,
|
|
67
81
|
}),
|
|
68
82
|
new Promise((res) => setTimeout(res, 2000)),
|
|
@@ -120,17 +134,23 @@ const logoutService = {
|
|
|
120
134
|
|
|
121
135
|
// 6. Stray keys the slices don't touch.
|
|
122
136
|
try {
|
|
123
|
-
await AsyncStorage.multiRemove(
|
|
124
|
-
...LIBRARY_STRAY_KEYS,
|
|
125
|
-
// Belt-and-suspenders: the chat slice's `logout` reducer
|
|
126
|
-
// schedules an async remove of ETHORA_USER fire-and-forget;
|
|
127
|
-
// re-issue it here so the disk is provably clean before this
|
|
128
|
-
// Promise resolves.
|
|
129
|
-
localStorageConstants.ETHORA_USER,
|
|
130
|
-
]);
|
|
137
|
+
await AsyncStorage.multiRemove(LIBRARY_STRAY_KEYS);
|
|
131
138
|
} catch (e) {
|
|
132
139
|
console.warn('logoutService: stray-key clear failed', e);
|
|
133
140
|
}
|
|
141
|
+
|
|
142
|
+
// 7. Belt-and-suspenders: the chat slice's `logout` reducer already
|
|
143
|
+
// fires an async ETHORA_USER removal, but re-issue it here (via
|
|
144
|
+
// the same secureUserStorage split the reducer uses) so BOTH the
|
|
145
|
+
// plain-AsyncStorage profile half AND the Keychain/Keystore
|
|
146
|
+
// secrets are provably gone before this Promise resolves — a bare
|
|
147
|
+
// `AsyncStorage.removeItem(ETHORA_USER)` here would only clear the
|
|
148
|
+
// profile half and leave the tokens behind.
|
|
149
|
+
try {
|
|
150
|
+
await secureUserStorage().remove();
|
|
151
|
+
} catch (e) {
|
|
152
|
+
console.warn('logoutService: secure user storage clear failed', e);
|
|
153
|
+
}
|
|
134
154
|
},
|
|
135
155
|
};
|
|
136
156
|
|
|
@@ -4,7 +4,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
|
4
4
|
import { RootState } from '../roomStore';
|
|
5
5
|
import { setCurrentRoom, clearPendingNotificationJid } from '../roomStore/roomsSlice';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
import { PENDING_NOTIFICATION_JID_KEY, readPendingJid } from '../helpers/pushPayload';
|
|
8
8
|
|
|
9
9
|
export function usePendingNotification() {
|
|
10
10
|
const dispatch = useDispatch();
|
|
@@ -21,21 +21,15 @@ export function usePendingNotification() {
|
|
|
21
21
|
let jidToOpen = pendingNotificationJid;
|
|
22
22
|
|
|
23
23
|
if (!jidToOpen) {
|
|
24
|
-
|
|
25
|
-
const storedJid = await AsyncStorage.getItem(PENDING_NOTIFICATION_JID_KEY);
|
|
26
|
-
if (storedJid) {
|
|
27
|
-
jidToOpen = storedJid;
|
|
28
|
-
await AsyncStorage.removeItem(PENDING_NOTIFICATION_JID_KEY);
|
|
29
|
-
}
|
|
30
|
-
} catch (error) {
|
|
31
|
-
console.error('Error reading from AsyncStorage:', error);
|
|
32
|
-
}
|
|
24
|
+
jidToOpen = await readPendingJid();
|
|
33
25
|
}
|
|
34
26
|
|
|
35
27
|
if (jidToOpen) {
|
|
36
28
|
const room = rooms[jidToOpen];
|
|
37
29
|
if (room) {
|
|
38
|
-
|
|
30
|
+
dispatch(clearPendingNotificationJid());
|
|
31
|
+
AsyncStorage.removeItem(PENDING_NOTIFICATION_JID_KEY).catch(() => undefined);
|
|
32
|
+
dispatch(setCurrentRoom({ roomJID: jidToOpen }));
|
|
39
33
|
}
|
|
40
34
|
}
|
|
41
35
|
};
|