@ethora/chat-component-rn 26.5.5 → 26.5.10
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 +177 -0
- package/README.md +67 -10
- package/index.js +24 -0
- package/lib/commonjs/assets/icons.js +5 -1
- package/lib/commonjs/assets/icons.js.map +1 -1
- package/lib/commonjs/components/ContextMenu/ContextMenuComponents.js +11 -5
- package/lib/commonjs/components/ContextMenu/ContextMenuComponents.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatHeader.js +7 -1
- package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatRoom.js +66 -34
- package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatWrapper.js +59 -14
- package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MediaMessage.js +15 -7
- package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MessageContainer.js +2 -2
- package/lib/commonjs/components/MainComponents/MessageContainer.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MessageList.js +175 -30
- package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ReduxWrapper.js +17 -8
- package/lib/commonjs/components/MainComponents/ReduxWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/SystemMessage.js +34 -22
- package/lib/commonjs/components/MainComponents/SystemMessage.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/Message.js +117 -19
- package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js +82 -22
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
- package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js +16 -4
- package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
- package/lib/commonjs/components/Modals/FilePreviewModal/DocumentViewer.js +104 -0
- package/lib/commonjs/components/Modals/FilePreviewModal/DocumentViewer.js.map +1 -0
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +175 -40
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js +29 -1
- package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
- package/lib/commonjs/components/Modals/Modal/Modal.js +5 -1
- package/lib/commonjs/components/Modals/Modal/Modal.js.map +1 -1
- package/lib/commonjs/components/Modals/ModalWrapper/ModalWrapper.js +78 -39
- package/lib/commonjs/components/Modals/ModalWrapper/ModalWrapper.js.map +1 -1
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +3 -3
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/commonjs/components/Modals/styledModalComponents.js +4 -9
- package/lib/commonjs/components/Modals/styledModalComponents.js.map +1 -1
- package/lib/commonjs/components/styled/MediaFilePreview.js +115 -5
- package/lib/commonjs/components/styled/MediaFilePreview.js.map +1 -1
- package/lib/commonjs/components/styled/MessageImage.js +49 -10
- package/lib/commonjs/components/styled/MessageImage.js.map +1 -1
- package/lib/commonjs/components/styled/NewMessageLabel.js +8 -6
- package/lib/commonjs/components/styled/NewMessageLabel.js.map +1 -1
- package/lib/commonjs/components/styled/SendInput.js +53 -29
- package/lib/commonjs/components/styled/SendInput.js.map +1 -1
- package/lib/commonjs/components/styled/StyledInputComponents/MediaComponents.js +14 -4
- package/lib/commonjs/components/styled/StyledInputComponents/MediaComponents.js.map +1 -1
- package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js +7 -2
- package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
- package/lib/commonjs/components/styled/UnsupportedType.js +5 -1
- package/lib/commonjs/components/styled/UnsupportedType.js.map +1 -1
- package/lib/commonjs/components/styled/VideoMessage.js +60 -22
- package/lib/commonjs/components/styled/VideoMessage.js.map +1 -1
- package/lib/commonjs/context/MessageNotificationContext.js +7 -7
- package/lib/commonjs/context/MessageNotificationContext.js.map +1 -1
- package/lib/commonjs/context/xmppProvider.js +315 -34
- package/lib/commonjs/context/xmppProvider.js.map +1 -1
- package/lib/commonjs/helpers/chatAutoEnterer.js +2 -7
- package/lib/commonjs/helpers/chatAutoEnterer.js.map +1 -1
- package/lib/commonjs/helpers/historyPreloadScheduler.js +4 -1
- package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/commonjs/helpers/insertMessageWithDelimiter.js +15 -5
- package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
- package/lib/commonjs/helpers/keyboardLayout.js +18 -0
- package/lib/commonjs/helpers/keyboardLayout.js.map +1 -0
- package/lib/commonjs/helpers/mediaDimensions.js +51 -0
- package/lib/commonjs/helpers/mediaDimensions.js.map +1 -0
- package/lib/commonjs/helpers/mimeToExtension.js +131 -0
- package/lib/commonjs/helpers/mimeToExtension.js.map +1 -0
- package/lib/commonjs/helpers/normalizeRoomJid.js +20 -0
- package/lib/commonjs/helpers/normalizeRoomJid.js.map +1 -0
- package/lib/commonjs/helpers/resolveInitBeforeLoadUser.js +73 -1
- package/lib/commonjs/helpers/resolveInitBeforeLoadUser.js.map +1 -1
- package/lib/commonjs/hooks/useChatRoomFocus.js +87 -0
- package/lib/commonjs/hooks/useChatRoomFocus.js.map +1 -0
- package/lib/commonjs/hooks/useChatWrapperInit.js +22 -10
- package/lib/commonjs/hooks/useChatWrapperInit.js.map +1 -1
- package/lib/commonjs/hooks/useEventHandlers.js +9 -1
- package/lib/commonjs/hooks/useEventHandlers.js.map +1 -1
- package/lib/commonjs/hooks/useHeapSender.js +1 -1
- package/lib/commonjs/hooks/useHeapSender.js.map +1 -1
- package/lib/commonjs/hooks/useLogout.js +3 -3
- package/lib/commonjs/hooks/useLogout.js.map +1 -1
- package/lib/commonjs/hooks/useMessageHeapState.js +6 -2
- package/lib/commonjs/hooks/useMessageHeapState.js.map +1 -1
- package/lib/commonjs/hooks/usePushNotifications.js +6 -2
- package/lib/commonjs/hooks/usePushNotifications.js.map +1 -1
- package/lib/commonjs/hooks/useRoomState.js +2 -0
- package/lib/commonjs/hooks/useRoomState.js.map +1 -1
- package/lib/commonjs/hooks/useSendMessage.js +249 -14
- package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
- package/lib/commonjs/hooks/useUnreadMessagesCounter.js +12 -14
- package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
- package/lib/commonjs/main.js +7 -0
- package/lib/commonjs/main.js.map +1 -1
- package/lib/commonjs/networking/api-requests/auth.api.js +74 -1
- package/lib/commonjs/networking/api-requests/auth.api.js.map +1 -1
- package/lib/commonjs/networking/apiClient.js +2 -1
- package/lib/commonjs/networking/apiClient.js.map +1 -1
- package/lib/commonjs/networking/outboundQueue.js +92 -0
- package/lib/commonjs/networking/outboundQueue.js.map +1 -0
- package/lib/commonjs/networking/xmpp/createTimeoutPromise.xmpp.js +4 -1
- package/lib/commonjs/networking/xmpp/createTimeoutPromise.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js +7 -8
- package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
- package/lib/commonjs/networking/xmpp/getRoomsPaged.xmpp.js +26 -3
- package/lib/commonjs/networking/xmpp/getRoomsPaged.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js +26 -8
- package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js +2 -1
- package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmppClient.js +371 -26
- package/lib/commonjs/networking/xmppClient.js.map +1 -1
- package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js +22 -6
- package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js.map +1 -1
- package/lib/commonjs/roomStore/roomHeapSlice.js +26 -8
- package/lib/commonjs/roomStore/roomHeapSlice.js.map +1 -1
- package/lib/commonjs/roomStore/roomsSlice.js +157 -23
- package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
- package/lib/commonjs/utils/installPromiseRejectionTracker.js +83 -0
- package/lib/commonjs/utils/installPromiseRejectionTracker.js.map +1 -0
- package/lib/commonjs/utils/resendMessage.js +1 -1
- package/lib/commonjs/utils/resendMessage.js.map +1 -1
- package/lib/module/assets/icons.js +5 -1
- package/lib/module/assets/icons.js.map +1 -1
- package/lib/module/components/ContextMenu/ContextMenuComponents.js +11 -5
- package/lib/module/components/ContextMenu/ContextMenuComponents.js.map +1 -1
- package/lib/module/components/MainComponents/ChatHeader.js +7 -1
- package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/module/components/MainComponents/ChatRoom.js +67 -35
- package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/module/components/MainComponents/ChatWrapper.js +59 -14
- package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/MediaMessage.js +15 -7
- package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
- package/lib/module/components/MainComponents/MessageContainer.js +2 -2
- package/lib/module/components/MainComponents/MessageContainer.js.map +1 -1
- package/lib/module/components/MainComponents/MessageList.js +176 -31
- package/lib/module/components/MainComponents/MessageList.js.map +1 -1
- package/lib/module/components/MainComponents/ReduxWrapper.js +18 -8
- package/lib/module/components/MainComponents/ReduxWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/SystemMessage.js +33 -21
- package/lib/module/components/MainComponents/SystemMessage.js.map +1 -1
- package/lib/module/components/MessageBubble/Message.js +118 -20
- package/lib/module/components/MessageBubble/Message.js.map +1 -1
- package/lib/module/components/MessageBubble/MessageInteractions.js +84 -24
- package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
- package/lib/module/components/Modals/AttachSheet/AttachSheet.js +15 -3
- package/lib/module/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
- package/lib/module/components/Modals/FilePreviewModal/DocumentViewer.js +99 -0
- package/lib/module/components/Modals/FilePreviewModal/DocumentViewer.js.map +1 -0
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +179 -42
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/module/components/Modals/FilePreviewModal/PdfView.js +31 -3
- package/lib/module/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
- package/lib/module/components/Modals/Modal/Modal.js +5 -1
- package/lib/module/components/Modals/Modal/Modal.js.map +1 -1
- package/lib/module/components/Modals/ModalWrapper/ModalWrapper.js +80 -41
- package/lib/module/components/Modals/ModalWrapper/ModalWrapper.js.map +1 -1
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +3 -3
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/module/components/Modals/styledModalComponents.js +4 -9
- package/lib/module/components/Modals/styledModalComponents.js.map +1 -1
- package/lib/module/components/styled/MediaFilePreview.js +116 -6
- package/lib/module/components/styled/MediaFilePreview.js.map +1 -1
- package/lib/module/components/styled/MessageImage.js +51 -12
- package/lib/module/components/styled/MessageImage.js.map +1 -1
- package/lib/module/components/styled/NewMessageLabel.js +8 -6
- package/lib/module/components/styled/NewMessageLabel.js.map +1 -1
- package/lib/module/components/styled/SendInput.js +54 -30
- package/lib/module/components/styled/SendInput.js.map +1 -1
- package/lib/module/components/styled/StyledInputComponents/MediaComponents.js +14 -4
- package/lib/module/components/styled/StyledInputComponents/MediaComponents.js.map +1 -1
- package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js +7 -2
- package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
- package/lib/module/components/styled/UnsupportedType.js +5 -1
- package/lib/module/components/styled/UnsupportedType.js.map +1 -1
- package/lib/module/components/styled/VideoMessage.js +61 -23
- package/lib/module/components/styled/VideoMessage.js.map +1 -1
- package/lib/module/context/MessageNotificationContext.js +7 -7
- package/lib/module/context/MessageNotificationContext.js.map +1 -1
- package/lib/module/context/xmppProvider.js +319 -37
- package/lib/module/context/xmppProvider.js.map +1 -1
- package/lib/module/helpers/chatAutoEnterer.js +2 -7
- package/lib/module/helpers/chatAutoEnterer.js.map +1 -1
- package/lib/module/helpers/historyPreloadScheduler.js +4 -1
- package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/module/helpers/insertMessageWithDelimiter.js +15 -5
- package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
- package/lib/module/helpers/keyboardLayout.js +12 -0
- package/lib/module/helpers/keyboardLayout.js.map +1 -0
- package/lib/module/helpers/mediaDimensions.js +46 -0
- package/lib/module/helpers/mediaDimensions.js.map +1 -0
- package/lib/module/helpers/mimeToExtension.js +124 -0
- package/lib/module/helpers/mimeToExtension.js.map +1 -0
- package/lib/module/helpers/normalizeRoomJid.js +15 -0
- package/lib/module/helpers/normalizeRoomJid.js.map +1 -0
- package/lib/module/helpers/resolveInitBeforeLoadUser.js +71 -0
- package/lib/module/helpers/resolveInitBeforeLoadUser.js.map +1 -1
- package/lib/module/hooks/useChatRoomFocus.js +82 -0
- package/lib/module/hooks/useChatRoomFocus.js.map +1 -0
- package/lib/module/hooks/useChatWrapperInit.js +22 -10
- package/lib/module/hooks/useChatWrapperInit.js.map +1 -1
- package/lib/module/hooks/useEventHandlers.js +9 -1
- package/lib/module/hooks/useEventHandlers.js.map +1 -1
- package/lib/module/hooks/useHeapSender.js +1 -1
- package/lib/module/hooks/useHeapSender.js.map +1 -1
- package/lib/module/hooks/useLogout.js +3 -3
- package/lib/module/hooks/useLogout.js.map +1 -1
- package/lib/module/hooks/useMessageHeapState.js +6 -2
- package/lib/module/hooks/useMessageHeapState.js.map +1 -1
- package/lib/module/hooks/usePushNotifications.js +6 -2
- package/lib/module/hooks/usePushNotifications.js.map +1 -1
- package/lib/module/hooks/useRoomState.js +2 -0
- package/lib/module/hooks/useRoomState.js.map +1 -1
- package/lib/module/hooks/useSendMessage.js +252 -17
- package/lib/module/hooks/useSendMessage.js.map +1 -1
- package/lib/module/hooks/useUnreadMessagesCounter.js +12 -14
- package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
- package/lib/module/main.js +1 -0
- package/lib/module/main.js.map +1 -1
- package/lib/module/networking/api-requests/auth.api.js +74 -2
- package/lib/module/networking/api-requests/auth.api.js.map +1 -1
- package/lib/module/networking/apiClient.js +2 -1
- package/lib/module/networking/apiClient.js.map +1 -1
- package/lib/module/networking/outboundQueue.js +84 -0
- package/lib/module/networking/outboundQueue.js.map +1 -0
- package/lib/module/networking/xmpp/createTimeoutPromise.xmpp.js +4 -1
- package/lib/module/networking/xmpp/createTimeoutPromise.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js +7 -8
- package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
- package/lib/module/networking/xmpp/getRoomsPaged.xmpp.js +26 -3
- package/lib/module/networking/xmpp/getRoomsPaged.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/presenceInRoom.xmpp.js +26 -8
- package/lib/module/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/sendTextMessage.xmpp.js +2 -1
- package/lib/module/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
- package/lib/module/networking/xmppClient.js +371 -26
- package/lib/module/networking/xmppClient.js.map +1 -1
- package/lib/module/roomStore/Middleware/unreadMidlleware.js +22 -6
- package/lib/module/roomStore/Middleware/unreadMidlleware.js.map +1 -1
- package/lib/module/roomStore/roomHeapSlice.js +24 -7
- package/lib/module/roomStore/roomHeapSlice.js.map +1 -1
- package/lib/module/roomStore/roomsSlice.js +154 -22
- package/lib/module/roomStore/roomsSlice.js.map +1 -1
- package/lib/module/utils/installPromiseRejectionTracker.js +78 -0
- package/lib/module/utils/installPromiseRejectionTracker.js.map +1 -0
- package/lib/module/utils/resendMessage.js +1 -1
- package/lib/module/utils/resendMessage.js.map +1 -1
- package/lib/typescript/assets/icons.d.ts +8 -4
- package/lib/typescript/assets/icons.d.ts.map +1 -1
- package/lib/typescript/components/ContextMenu/ContextMenuComponents.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/MediaMessage.d.ts +1 -0
- 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.map +1 -1
- package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts +1 -0
- package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/SystemMessage.d.ts +0 -7
- package/lib/typescript/components/MainComponents/SystemMessage.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts +4 -2
- package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
- package/lib/typescript/components/Modals/AttachSheet/AttachSheet.d.ts.map +1 -1
- package/lib/typescript/components/Modals/FilePreviewModal/DocumentViewer.d.ts +29 -0
- package/lib/typescript/components/Modals/FilePreviewModal/DocumentViewer.d.ts.map +1 -0
- package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts +0 -1
- 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/ModalWrapper/ModalWrapper.d.ts +6 -0
- package/lib/typescript/components/Modals/ModalWrapper/ModalWrapper.d.ts.map +1 -1
- package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/styledModalComponents.d.ts.map +1 -1
- package/lib/typescript/components/styled/MediaFilePreview.d.ts.map +1 -1
- package/lib/typescript/components/styled/MessageImage.d.ts.map +1 -1
- package/lib/typescript/components/styled/NewMessageLabel.d.ts +1 -5
- package/lib/typescript/components/styled/NewMessageLabel.d.ts.map +1 -1
- package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
- package/lib/typescript/components/styled/StyledInputComponents/MediaComponents.d.ts +9 -1
- package/lib/typescript/components/styled/StyledInputComponents/MediaComponents.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 +1 -0
- package/lib/typescript/components/styled/UnsupportedType.d.ts.map +1 -1
- package/lib/typescript/components/styled/VideoMessage.d.ts.map +1 -1
- package/lib/typescript/context/xmppProvider.d.ts +1 -0
- package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
- package/lib/typescript/helpers/chatAutoEnterer.d.ts.map +1 -1
- package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
- package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
- package/lib/typescript/helpers/keyboardLayout.d.ts +9 -0
- package/lib/typescript/helpers/keyboardLayout.d.ts.map +1 -0
- package/lib/typescript/helpers/mediaDimensions.d.ts +9 -0
- package/lib/typescript/helpers/mediaDimensions.d.ts.map +1 -0
- package/lib/typescript/helpers/mimeToExtension.d.ts +37 -0
- package/lib/typescript/helpers/mimeToExtension.d.ts.map +1 -0
- package/lib/typescript/helpers/normalizeRoomJid.d.ts +2 -0
- package/lib/typescript/helpers/normalizeRoomJid.d.ts.map +1 -0
- package/lib/typescript/helpers/resolveInitBeforeLoadUser.d.ts +18 -0
- package/lib/typescript/helpers/resolveInitBeforeLoadUser.d.ts.map +1 -1
- package/lib/typescript/hooks/useChatRoomFocus.d.ts +42 -0
- package/lib/typescript/hooks/useChatRoomFocus.d.ts.map +1 -0
- package/lib/typescript/hooks/useChatWrapperInit.d.ts.map +1 -1
- package/lib/typescript/hooks/useEventHandlers.d.ts +6 -0
- package/lib/typescript/hooks/useEventHandlers.d.ts.map +1 -1
- package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
- package/lib/typescript/hooks/useMessageHeapState.d.ts +2 -0
- package/lib/typescript/hooks/useMessageHeapState.d.ts.map +1 -1
- package/lib/typescript/hooks/usePushNotifications.d.ts.map +1 -1
- package/lib/typescript/hooks/useRoomState.d.ts +1 -0
- package/lib/typescript/hooks/useRoomState.d.ts.map +1 -1
- package/lib/typescript/hooks/useSendMessage.d.ts +2 -1
- package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/hooks/useUnreadMessagesCounter.d.ts.map +1 -1
- package/lib/typescript/main.d.ts +1 -0
- package/lib/typescript/main.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/auth.api.d.ts +3 -0
- package/lib/typescript/networking/api-requests/auth.api.d.ts.map +1 -1
- package/lib/typescript/networking/apiClient.d.ts.map +1 -1
- package/lib/typescript/networking/outboundQueue.d.ts +57 -0
- package/lib/typescript/networking/outboundQueue.d.ts.map +1 -0
- package/lib/typescript/networking/xmpp/createTimeoutPromise.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts +1 -1
- package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/getRoomsPaged.xmpp.d.ts +1 -1
- package/lib/typescript/networking/xmpp/getRoomsPaged.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmppClient.d.ts +58 -5
- package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
- package/lib/typescript/roomStore/Middleware/unreadMidlleware.d.ts.map +1 -1
- package/lib/typescript/roomStore/roomHeapSlice.d.ts +22 -1
- package/lib/typescript/roomStore/roomHeapSlice.d.ts.map +1 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts +8 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
- package/lib/typescript/types/models/media.model.d.ts +1 -0
- package/lib/typescript/types/models/media.model.d.ts.map +1 -1
- package/lib/typescript/types/models/xmpp.model.d.ts +1 -1
- package/lib/typescript/types/models/xmpp.model.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +10 -0
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/lib/typescript/utils/installPromiseRejectionTracker.d.ts +20 -0
- package/lib/typescript/utils/installPromiseRejectionTracker.d.ts.map +1 -0
- package/lib/typescript/utils/resendMessage.d.ts.map +1 -1
- package/package.json +18 -2
- package/src/assets/icons.tsx +23 -14
- package/src/components/ContextMenu/ContextMenuComponents.tsx +10 -5
- package/src/components/MainComponents/ChatHeader.tsx +5 -1
- package/src/components/MainComponents/ChatRoom.tsx +81 -61
- package/src/components/MainComponents/ChatWrapper.tsx +100 -21
- package/src/components/MainComponents/MediaMessage.tsx +18 -8
- package/src/components/MainComponents/MessageContainer.tsx +4 -2
- package/src/components/MainComponents/MessageList.tsx +185 -31
- package/src/components/MainComponents/ReduxWrapper.tsx +19 -9
- package/src/components/MainComponents/SystemMessage.tsx +38 -26
- package/src/components/MessageBubble/Message.tsx +110 -27
- package/src/components/MessageBubble/MessageInteractions.tsx +98 -29
- package/src/components/Modals/AttachSheet/AttachSheet.tsx +17 -3
- package/src/components/Modals/FilePreviewModal/DocumentViewer.tsx +93 -0
- package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +182 -37
- package/src/components/Modals/FilePreviewModal/PdfView.tsx +32 -4
- package/src/components/Modals/Modal/Modal.tsx +4 -1
- package/src/components/Modals/ModalWrapper/ModalWrapper.tsx +77 -44
- package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +19 -15
- package/src/components/Modals/styledModalComponents.tsx +4 -9
- package/src/components/styled/MediaFilePreview.tsx +111 -5
- package/src/components/styled/MessageImage.tsx +58 -14
- package/src/components/styled/NewMessageLabel.tsx +8 -5
- package/src/components/styled/SendInput.tsx +67 -29
- package/src/components/styled/StyledInputComponents/MediaComponents.tsx +15 -5
- package/src/components/styled/StyledInputComponents/StyledInputComponents.tsx +7 -2
- package/src/components/styled/UnsupportedType.tsx +7 -1
- package/src/components/styled/VideoMessage.tsx +59 -18
- package/src/context/MessageNotificationContext.tsx +8 -8
- package/src/context/xmppProvider.tsx +337 -32
- package/src/helpers/chatAutoEnterer.ts +2 -8
- package/src/helpers/historyPreloadScheduler.ts +4 -1
- package/src/helpers/insertMessageWithDelimiter.ts +22 -15
- package/src/helpers/keyboardLayout.ts +18 -0
- package/src/helpers/mediaDimensions.ts +47 -0
- package/src/helpers/mimeToExtension.ts +135 -0
- package/src/helpers/normalizeRoomJid.ts +6 -0
- package/src/helpers/resolveInitBeforeLoadUser.ts +79 -0
- package/src/hooks/useChatRoomFocus.ts +95 -0
- package/src/hooks/useChatWrapperInit.ts +51 -46
- package/src/hooks/useEventHandlers.tsx +24 -1
- package/src/hooks/useHeapSender.tsx +2 -1
- package/src/hooks/useLogout.tsx +3 -3
- package/src/hooks/useMessageHeapState.tsx +6 -2
- package/src/hooks/usePushNotifications.ts +21 -8
- package/src/hooks/useRoomState.tsx +4 -0
- package/src/hooks/useSendMessage.tsx +333 -17
- package/src/hooks/useUnreadMessagesCounter.ts +13 -16
- package/src/main.ts +1 -0
- package/src/networking/api-requests/auth.api.ts +60 -2
- package/src/networking/apiClient.ts +2 -1
- package/src/networking/outboundQueue.ts +98 -0
- package/src/networking/xmpp/createTimeoutPromise.xmpp.ts +5 -1
- package/src/networking/xmpp/flushLastViewedToPrivateStore.ts +11 -13
- package/src/networking/xmpp/getRoomsPaged.xmpp.ts +27 -3
- package/src/networking/xmpp/presenceInRoom.xmpp.ts +24 -9
- package/src/networking/xmpp/sendTextMessage.xmpp.ts +2 -1
- package/src/networking/xmppClient.ts +399 -31
- package/src/roomStore/Middleware/unreadMidlleware.tsx +23 -5
- package/src/roomStore/roomHeapSlice.ts +47 -4
- package/src/roomStore/roomsSlice.ts +177 -27
- package/src/types/models/media.model.ts +3 -0
- package/src/types/models/xmpp.model.ts +2 -1
- package/src/types/types.ts +25 -0
- package/src/utils/installPromiseRejectionTracker.ts +91 -0
- package/src/utils/resendMessage.ts +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["xml","_sendTextSeq","toServiceXmlns","devServer","client","clientService","options","service","test","ds","trim","includes","replace","sendTextMessage","roomJID","firstName","lastName","photo","walletAddress","userMessage","notDisplayedValue","isReply","showInChannel","mainMessage","customId","id","Date","now","message","to","type","xmlns","senderFirstName","senderLastName","fullName","photoURL","senderJID","jid","toString","senderWalletAddress","roomJid","isSystemMessage","tokenAmount","quickReplies","push","sendResult","send","then","console","log","catch","err","error","name","stack"],"sourceRoot":"../../../../src","sources":["networking/xmpp/sendTextMessage.xmpp.ts"],"mappings":";;AAAA,SAAiBA,GAAG,QAAQ,cAAc;;AAE1C;AACA,IAAIC,YAAY,GAAG,CAAC;;AAEpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,cAAc,GAAGA,CAACC,SAA6B,EAAEC,MAAc,KAAa;EAChF;EACA;EACA,MAAMC,aAAa,GAAID,MAAM,EAAUE,OAAO,EAAEC,OAA6B;EAC7E,IAAIF,aAAa,IAAI,YAAY,CAACG,IAAI,CAACH,aAAa,CAAC,EAAE;IAAC,OAAOA,aAAa;EAAC;EAC7E,MAAMI,EAAE,GAAG,CAACN,SAAS,IAAI,EAAE,EAAEO,IAAI,CAAC,CAAC;EACnC,IAAI,CAACD,EAAE,EAAE;IAAC,OAAO,6BAA6B;EAAC;EAC/C,IAAI,YAAY,CAACD,IAAI,CAACC,EAAE,CAAC,EAAE;IAAC,OAAOA,EAAE;EAAC;EACtC,IAAIA,EAAE,CAACE,QAAQ,CAAC,KAAK,CAAC,EAAE;IAAC,OAAOF,EAAE;EAAC;EACnC;EACA,OAAO,SAASA,EAAE,CAACG,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,KAAK;AACnD,CAAC;AAED,OAAO,MAAMC,eAAe,GAAGA,CAC7BT,MAAc,EACdU,OAAe,EACfC,SAAiB,EACjBC,QAAgB,EAChBC,KAAa,EACbC,aAAqB,EACrBC,WAAmB,EACnBC,iBAA0B,EAC1BC,OAAiB,EACjBC,aAAuB,EACvBC,WAAoB,EACpBpB,SAAkB,EAClBqB,QAAiB,KACd;EACH;EACA;EACA;EACA,IAAI,CAACvB,YAAY,EAAE,CAAC;EACpB,MAAMwB,EAAE,GAAGD,QAAQ,GACfA,QAAQ,GACRH,OAAO,GACL,sBAAsBK,IAAI,CAACC,GAAG,CAAC,CAAC,IAAK1B,YAAY,GAAIA,YAAY,GAAG,CAAC,KAAM,CAAC,EAAG,GAC/E,qBAAqByB,IAAI,CAACC,GAAG,CAAC,CAAC,IAAK1B,YAAY,GAAIA,YAAY,GAAG,CAAC,KAAM,CAAC,EAAG;EAEpF,IAAI;IACF,MAAM2B,OAAO,
|
|
1
|
+
{"version":3,"names":["xml","_sendTextSeq","toServiceXmlns","devServer","client","clientService","options","service","test","ds","trim","includes","replace","sendTextMessage","roomJID","firstName","lastName","photo","walletAddress","userMessage","notDisplayedValue","isReply","showInChannel","mainMessage","customId","id","Date","now","dataXmlns","message","to","type","xmlns","senderFirstName","senderLastName","fullName","photoURL","senderJID","jid","toString","senderWalletAddress","roomJid","isSystemMessage","tokenAmount","quickReplies","push","sendResult","send","then","console","log","catch","err","error","name","stack"],"sourceRoot":"../../../../src","sources":["networking/xmpp/sendTextMessage.xmpp.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -22,9 +22,27 @@ import { inviteRoomRequest } from './xmpp/inviteRoomRequest.xmpp';
|
|
|
22
22
|
import { getRooms } from './xmpp/getRooms.xmpp';
|
|
23
23
|
import { handleStanza } from './xmpp/handleStanzas.xmpp';
|
|
24
24
|
import { pushLog as devPushLog } from '../utils/devLogger';
|
|
25
|
+
import { normalizeRoomJid } from '../helpers/normalizeRoomJid';
|
|
26
|
+
import { clearOutboundSends, enqueueOutboundSend, flushOutboundSends } from './outboundQueue';
|
|
25
27
|
|
|
26
28
|
// Canonical production XMPP WSS endpoint (standard wss/443, no port suffix).
|
|
27
29
|
const DEFAULT_DEV_SERVER = 'xmpp.chat.ethora.com';
|
|
30
|
+
|
|
31
|
+
// @xmpp/client surfaces SASL/stream errors in a few shapes depending on
|
|
32
|
+
// where it fails — XMPPError on stream:error, SASLError on SASL bind, or
|
|
33
|
+
// a generic Error whose message contains "not-authorized". Match all of
|
|
34
|
+
// them so we trigger the credentials refresh path consistently.
|
|
35
|
+
function isNotAuthorizedError(err) {
|
|
36
|
+
if (!err) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
const condition = err?.condition || err?.name || err?.type || err?.error?.condition || '';
|
|
40
|
+
if (typeof condition === 'string' && condition.includes('not-authorized')) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
const message = (err?.message || err?.text || '').toString();
|
|
44
|
+
return /not-authorized|SASLError/i.test(message);
|
|
45
|
+
}
|
|
28
46
|
export class XmppClient {
|
|
29
47
|
host = '';
|
|
30
48
|
service = '';
|
|
@@ -34,7 +52,35 @@ export class XmppClient {
|
|
|
34
52
|
reconnectAttempts = 0;
|
|
35
53
|
maxReconnectAttempts = 5;
|
|
36
54
|
reconnectDelay = 2000;
|
|
55
|
+
// Upper bound on the backoff delay. The old hard stop at
|
|
56
|
+
// maxReconnectAttempts gave up entirely after ~62s; now we keep retrying
|
|
57
|
+
// at a steady cadence on a long outage and just clamp the delay here.
|
|
58
|
+
maxReconnectDelay = 30000;
|
|
59
|
+
// Timestamp of the last forced reconnect so bursty external triggers
|
|
60
|
+
// (NetInfo + AppState + the provider watchdog firing together) can't
|
|
61
|
+
// spawn a reconnect storm.
|
|
62
|
+
lastReconnectAt = 0;
|
|
37
63
|
suppressReconnect = false;
|
|
64
|
+
// Tracked so close()/disconnect() can cancel a pending reconnect —
|
|
65
|
+
// otherwise a scheduleReconnect() timer fires after logout and (until
|
|
66
|
+
// suppressReconnect short-circuits it) keeps the dead instance alive.
|
|
67
|
+
reconnectTimer = null;
|
|
68
|
+
// Single-flight guard for reconnect(). Multiple triggers can fire near-
|
|
69
|
+
// simultaneously (AppState 'active' + NetInfo restore + a scheduled
|
|
70
|
+
// timer). Without this, two overlapping reconnect()s each spawn a fresh
|
|
71
|
+
// underlying client and one is leaked with its `stanza` handler still
|
|
72
|
+
// bound → duplicate stanza dispatch into redux.
|
|
73
|
+
reconnecting = false;
|
|
74
|
+
|
|
75
|
+
// Set when SASL fails with `not-authorized` (typically a stale JWT-
|
|
76
|
+
// derived XMPP password after idle). Triggers the credentialsProvider
|
|
77
|
+
// refresh path in reconnect().
|
|
78
|
+
lastAuthError = null;
|
|
79
|
+
credentialsProvider = null;
|
|
80
|
+
credentialsRefreshInFlight = null;
|
|
81
|
+
// Fired by the provider on every 'online' so it can re-join MUC rooms
|
|
82
|
+
// after a reconnect (bug #21 — reconnected but not in the room).
|
|
83
|
+
onOnlineCallback = null;
|
|
38
84
|
|
|
39
85
|
// ---- QoS state (mirrors web XmppClient) ----------------------------
|
|
40
86
|
presencesReady = false;
|
|
@@ -53,6 +99,29 @@ export class XmppClient {
|
|
|
53
99
|
checkOnline() {
|
|
54
100
|
return this.client && this.client.status === 'online';
|
|
55
101
|
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Inject (or replace) the callback used by reconnect() to fetch fresh
|
|
105
|
+
* XMPP credentials after a `not-authorized` SASL failure. The provider
|
|
106
|
+
* is responsible for refreshing whatever upstream token is needed
|
|
107
|
+
* (REST JWT, /users/client, etc.) and returning the resulting
|
|
108
|
+
* username + password.
|
|
109
|
+
*/
|
|
110
|
+
setCredentialsProvider(provider) {
|
|
111
|
+
this.credentialsProvider = provider;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Install a callback invoked on every successful 'online'. The provider
|
|
115
|
+
* uses it to re-join MUC rooms after a reconnect. */
|
|
116
|
+
setOnOnline(cb) {
|
|
117
|
+
this.onOnlineCallback = cb;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Swap in fresh credentials before the next reconnect. */
|
|
121
|
+
updateCredentials(username, password) {
|
|
122
|
+
this.username = username;
|
|
123
|
+
this.password = password;
|
|
124
|
+
}
|
|
56
125
|
constructor(username, password, xmppSettings) {
|
|
57
126
|
// Back-compat: third arg used to be a bare devServer string.
|
|
58
127
|
if (typeof xmppSettings === 'string') {
|
|
@@ -206,11 +275,22 @@ export class XmppClient {
|
|
|
206
275
|
this.host = this.xmppSettings?.host || url.match(/wss:\/\/([^:/]+)/)?.[1] || '';
|
|
207
276
|
this.conference = this.xmppSettings?.conference || `conference.${this.host}`;
|
|
208
277
|
this.status = 'connecting';
|
|
278
|
+
|
|
279
|
+
// Defensive: if a previous underlying client is still referenced
|
|
280
|
+
// (initializeClient reached from a path other than reconnect()),
|
|
281
|
+
// detach its handlers before we overwrite the ref so the orphaned
|
|
282
|
+
// client can't keep dispatching stanzas into redux.
|
|
283
|
+
try {
|
|
284
|
+
this.detachEventListeners();
|
|
285
|
+
} catch {}
|
|
209
286
|
this.client = xmpp.client({
|
|
210
287
|
service: url,
|
|
211
288
|
username: walletToUsername(this.username),
|
|
212
289
|
password: this.password
|
|
213
290
|
});
|
|
291
|
+
try {
|
|
292
|
+
this.client?.reconnect?.stop?.();
|
|
293
|
+
} catch {}
|
|
214
294
|
|
|
215
295
|
// Concurrent room preloads each register their own short-lived
|
|
216
296
|
// 'stanza' handler (getHistory, getRooms, getChatsPrivateStore,
|
|
@@ -238,7 +318,18 @@ export class XmppClient {
|
|
|
238
318
|
const to = stanza?.attrs?.to || '';
|
|
239
319
|
devPushLog('xmpp', `→ ${tag}${id ? ` id=${id}` : ''}${to ? ` to=${to.split('/')[0]}` : ''}`, stanza?.toString ? stanza.toString() : undefined);
|
|
240
320
|
} catch {}
|
|
241
|
-
|
|
321
|
+
const result = origSend(stanza);
|
|
322
|
+
// Most stanza helpers fire-and-forget `client.send(...)`
|
|
323
|
+
// without awaiting/catching. On @xmpp/client builds where
|
|
324
|
+
// send() returns a Promise, a transient send failure (e.g.
|
|
325
|
+
// mid-reconnect) then surfaces as a red-screen "Uncaught (in
|
|
326
|
+
// promise, id: N)" (#4). Attach a no-op catch so the
|
|
327
|
+
// rejection is considered handled — callers that DO await/
|
|
328
|
+
// catch still get it, because we return the SAME promise.
|
|
329
|
+
if (result && typeof result.catch === 'function') {
|
|
330
|
+
result.catch(() => {});
|
|
331
|
+
}
|
|
332
|
+
return result;
|
|
242
333
|
};
|
|
243
334
|
// Property may be non-writable on some builds; defineProperty
|
|
244
335
|
// gives us a clearer error than a plain assignment.
|
|
@@ -254,15 +345,39 @@ export class XmppClient {
|
|
|
254
345
|
this.attachEventListeners();
|
|
255
346
|
this.client.start().catch(error => {
|
|
256
347
|
console.error('Error starting xmpp client:', error);
|
|
348
|
+
if (isNotAuthorizedError(error)) {
|
|
349
|
+
this.lastAuthError = 'not-authorized';
|
|
350
|
+
}
|
|
257
351
|
this.status = 'error';
|
|
352
|
+
// A connect-time failure lands in 'error', which — unlike a
|
|
353
|
+
// 'disconnect' after being online — has no other retry path
|
|
354
|
+
// (onError doesn't reschedule; the provider only reacts to
|
|
355
|
+
// 'offline'). Schedule a backoff retry so a failed initial or
|
|
356
|
+
// reconnect attempt recovers on its own. reconnect() refreshes
|
|
357
|
+
// creds first when the failure was a SASL not-authorized.
|
|
358
|
+
if (!this.suppressReconnect) {
|
|
359
|
+
try {
|
|
360
|
+
this.scheduleReconnect();
|
|
361
|
+
} catch {}
|
|
362
|
+
}
|
|
258
363
|
});
|
|
259
364
|
} catch (error) {
|
|
260
365
|
console.error('Error initializing client:', error);
|
|
261
366
|
this.status = 'error';
|
|
262
367
|
}
|
|
263
368
|
}
|
|
369
|
+
|
|
370
|
+
// Stored so detachEventListeners() can remove exactly the handlers we
|
|
371
|
+
// added (not xmpp.js's internal ones). Without this a re-login left the
|
|
372
|
+
// previous instance's `stanza` handler bound, double-dispatching every
|
|
373
|
+
// incoming stanza into the (new session's) redux store.
|
|
374
|
+
|
|
264
375
|
attachEventListeners() {
|
|
265
|
-
|
|
376
|
+
// Idempotent: drop any previously-attached handlers first so a
|
|
377
|
+
// reconnect that re-runs initializeClient on a fresh underlying
|
|
378
|
+
// client doesn't stack duplicates.
|
|
379
|
+
this.detachEventListeners();
|
|
380
|
+
this.onDisconnect = () => {
|
|
266
381
|
console.log('XMPP disconnected.');
|
|
267
382
|
this.status = 'offline';
|
|
268
383
|
try {
|
|
@@ -270,8 +385,19 @@ export class XmppClient {
|
|
|
270
385
|
// that don't reference it; tree-shaken via dead-code elim.
|
|
271
386
|
devPushLog('xmpp', 'disconnect');
|
|
272
387
|
} catch {}
|
|
273
|
-
|
|
274
|
-
|
|
388
|
+
// Self-heal at the socket level. The provider's reconnect effect
|
|
389
|
+
// keys on `client.status`, but that's a mutated class field React
|
|
390
|
+
// does NOT track — so a silent socket drop (e.g. JS paused by the
|
|
391
|
+
// debugger, iOS WebSocket suspend) never re-runs the effect and the
|
|
392
|
+
// client sits 'offline' forever (sends then queue and time out).
|
|
393
|
+
// Driving reconnect here makes recovery independent of React.
|
|
394
|
+
if (!this.suppressReconnect) {
|
|
395
|
+
try {
|
|
396
|
+
this.scheduleReconnect();
|
|
397
|
+
} catch {}
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
this.onOnline = () => {
|
|
275
401
|
console.log('XMPP online.', new Date());
|
|
276
402
|
this.status = 'online';
|
|
277
403
|
this.presencesReady = true;
|
|
@@ -279,14 +405,39 @@ export class XmppClient {
|
|
|
279
405
|
try {
|
|
280
406
|
devPushLog('xmpp', 'online', this.username);
|
|
281
407
|
} catch {}
|
|
282
|
-
|
|
283
|
-
|
|
408
|
+
// Notify the provider that the session is live again. On a RECONNECT
|
|
409
|
+
// (new stream) the client is no longer joined to any MUC, so the
|
|
410
|
+
// provider must re-send room presences — otherwise messages get a
|
|
411
|
+
// local double-tick but never reach the room (bug #21). Harmless on
|
|
412
|
+
// the first connect (room list not loaded yet → joins nothing; the
|
|
413
|
+
// bootstrap's own allRoomPresences handles that pass).
|
|
414
|
+
try {
|
|
415
|
+
this.onOnlineCallback?.();
|
|
416
|
+
} catch (err) {
|
|
417
|
+
console.warn('onOnline callback failed', err);
|
|
418
|
+
}
|
|
419
|
+
// Drain any sends that were buffered while the stream was down. The
|
|
420
|
+
// presence stanzas from onOnlineCallback above were written to the
|
|
421
|
+
// socket synchronously (allRoomPresences → presenceInRoom send the
|
|
422
|
+
// <presence> before yielding), so flushing here puts the message
|
|
423
|
+
// stanzas AFTER the joins on the same stream — XMPP's in-order
|
|
424
|
+
// per-stream processing guarantees the MUC join lands first.
|
|
425
|
+
try {
|
|
426
|
+
this.flushPendingSends();
|
|
427
|
+
} catch (err) {
|
|
428
|
+
console.warn('flushPendingSends failed', err);
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
this.onError = error => {
|
|
284
432
|
console.error('XMPP client error:', error);
|
|
433
|
+
if (isNotAuthorizedError(error)) {
|
|
434
|
+
this.lastAuthError = 'not-authorized';
|
|
435
|
+
}
|
|
285
436
|
try {
|
|
286
437
|
devPushLog('xmpp', 'error', error && error.message || error);
|
|
287
438
|
} catch {}
|
|
288
|
-
}
|
|
289
|
-
this.
|
|
439
|
+
};
|
|
440
|
+
this.onStanza = stanza => {
|
|
290
441
|
try {
|
|
291
442
|
const tag = stanza?.name || 'stanza';
|
|
292
443
|
const id = stanza?.attrs?.id || '';
|
|
@@ -295,7 +446,35 @@ export class XmppClient {
|
|
|
295
446
|
devPushLog('xmpp', `← ${tag}${id ? ` id=${id}` : ''}${type ? ` type=${type}` : ''}${from ? ` from=${from.split('/')[0]}` : ''}`, stanza?.toString ? stanza.toString() : undefined);
|
|
296
447
|
} catch {}
|
|
297
448
|
handleStanza.bind(this, stanza, this)();
|
|
298
|
-
}
|
|
449
|
+
};
|
|
450
|
+
this.client.on('disconnect', this.onDisconnect);
|
|
451
|
+
this.client.on('online', this.onOnline);
|
|
452
|
+
this.client.on('error', this.onError);
|
|
453
|
+
this.client.on('stanza', this.onStanza);
|
|
454
|
+
}
|
|
455
|
+
detachEventListeners() {
|
|
456
|
+
const c = this.client;
|
|
457
|
+
if (!c?.removeListener) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
try {
|
|
461
|
+
if (this.onDisconnect) {
|
|
462
|
+
c.removeListener('disconnect', this.onDisconnect);
|
|
463
|
+
}
|
|
464
|
+
if (this.onOnline) {
|
|
465
|
+
c.removeListener('online', this.onOnline);
|
|
466
|
+
}
|
|
467
|
+
if (this.onError) {
|
|
468
|
+
c.removeListener('error', this.onError);
|
|
469
|
+
}
|
|
470
|
+
if (this.onStanza) {
|
|
471
|
+
c.removeListener('stanza', this.onStanza);
|
|
472
|
+
}
|
|
473
|
+
} catch {}
|
|
474
|
+
this.onDisconnect = undefined;
|
|
475
|
+
this.onOnline = undefined;
|
|
476
|
+
this.onError = undefined;
|
|
477
|
+
this.onStanza = undefined;
|
|
299
478
|
}
|
|
300
479
|
|
|
301
480
|
/**
|
|
@@ -332,28 +511,133 @@ export class XmppClient {
|
|
|
332
511
|
if (this.suppressReconnect) {
|
|
333
512
|
return;
|
|
334
513
|
}
|
|
335
|
-
if (this.
|
|
336
|
-
console.error('Max reconnect attempts reached.');
|
|
514
|
+
if (this.reconnecting || this.reconnectTimer) {
|
|
337
515
|
return;
|
|
338
516
|
}
|
|
339
517
|
this.reconnectAttempts++;
|
|
340
|
-
const
|
|
518
|
+
const exp = Math.min(this.reconnectAttempts - 1, Math.max(0, this.maxReconnectAttempts));
|
|
519
|
+
const delay = Math.min(this.maxReconnectDelay, this.reconnectDelay * Math.pow(2, exp));
|
|
341
520
|
console.log(`Reconnecting attempt ${this.reconnectAttempts} in ${delay}ms`);
|
|
342
|
-
|
|
521
|
+
// No clearTimeout needed — the guard above guarantees no pending timer.
|
|
522
|
+
this.reconnectTimer = setTimeout(() => {
|
|
523
|
+
this.reconnectTimer = null;
|
|
524
|
+
// The connection may have recovered on its own (xmpp.js auto-
|
|
525
|
+
// reconnect) between scheduling and firing — don't tear down a
|
|
526
|
+
// healthy stream. forceReconnect() bypasses this by calling
|
|
527
|
+
// reconnect() directly.
|
|
528
|
+
if (this.status === 'online') {
|
|
529
|
+
this.reconnectAttempts = 0;
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
this.reconnect();
|
|
533
|
+
}, delay);
|
|
343
534
|
}
|
|
344
|
-
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Force an immediate reconnect, resetting the backoff counter. Called
|
|
538
|
+
* by the provider when NetInfo reports the network came back or the app
|
|
539
|
+
* returned to the foreground — we don't want to wait out the existing
|
|
540
|
+
* exponential delay (or a maxed-out attempt count) in those cases.
|
|
541
|
+
*/
|
|
542
|
+
forceReconnect() {
|
|
543
|
+
if (this.suppressReconnect) {
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
// Debounce bursts: NetInfo restore + AppState 'active' + the provider
|
|
547
|
+
// watchdog can fire within the same instant. reconnect() dedups
|
|
548
|
+
// CONCURRENT calls, but sequential ones (one finishes, the next
|
|
549
|
+
// arrives) would still each tear down + re-create the client. Ignore
|
|
550
|
+
// forces within 2s of the last one.
|
|
551
|
+
const now = Date.now();
|
|
552
|
+
if (now - this.lastReconnectAt < 2000) {
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
this.lastReconnectAt = now;
|
|
556
|
+
if (this.reconnectTimer) {
|
|
557
|
+
clearTimeout(this.reconnectTimer);
|
|
558
|
+
this.reconnectTimer = null;
|
|
559
|
+
}
|
|
560
|
+
this.reconnectAttempts = 0;
|
|
561
|
+
this.reconnect();
|
|
562
|
+
}
|
|
563
|
+
async reconnect() {
|
|
345
564
|
if (this.suppressReconnect) {
|
|
346
565
|
return;
|
|
347
566
|
}
|
|
567
|
+
// Single-flight: ignore overlapping triggers (AppState + NetInfo +
|
|
568
|
+
// scheduled timer) so we never spawn two underlying clients and leak
|
|
569
|
+
// one with live listeners (duplicate stanza dispatch).
|
|
570
|
+
if (this.reconnecting) {
|
|
571
|
+
console.log('reconnect already in progress — skip');
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
this.reconnecting = true;
|
|
348
575
|
console.log('Attempting to reconnect xmpp client...');
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
576
|
+
try {
|
|
577
|
+
// If the last failure was a SASL `not-authorized` (typically a stale
|
|
578
|
+
// JWT-derived XMPP password after idle), try to fetch fresh creds
|
|
579
|
+
// before retrying. Without this, reconnect retries with the same
|
|
580
|
+
// stale password forever and the user has to kill the app.
|
|
581
|
+
if (this.lastAuthError === 'not-authorized' && this.credentialsProvider) {
|
|
582
|
+
try {
|
|
583
|
+
await this.refreshCredentialsOnce();
|
|
584
|
+
} catch (err) {
|
|
585
|
+
console.warn('XMPP credential refresh failed; reconnecting with cached creds', err);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// Tear the OLD underlying client down FULLY before spinning up a new
|
|
590
|
+
// one: detach our handlers (so its `stanza` handler can't keep
|
|
591
|
+
// dispatching) and stop it. detachEventListeners() must run while
|
|
592
|
+
// `this.client` still points at the old client — i.e. before
|
|
593
|
+
// initializeClient() reassigns it.
|
|
594
|
+
const old = this.client;
|
|
595
|
+
if (old) {
|
|
596
|
+
this.detachEventListeners();
|
|
597
|
+
try {
|
|
598
|
+
await old.stop();
|
|
599
|
+
} catch {}
|
|
600
|
+
}
|
|
354
601
|
this.initializeClient();
|
|
602
|
+
} finally {
|
|
603
|
+
this.reconnecting = false;
|
|
355
604
|
}
|
|
356
605
|
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Single-flight wrapper around credentialsProvider. Multiple concurrent
|
|
609
|
+
* reconnect() calls (e.g. from the provider's reconnect effect firing
|
|
610
|
+
* twice quickly) share one in-flight request and update `this.password`
|
|
611
|
+
* exactly once.
|
|
612
|
+
*/
|
|
613
|
+
refreshCredentialsOnce() {
|
|
614
|
+
if (this.credentialsRefreshInFlight) {
|
|
615
|
+
return this.credentialsRefreshInFlight;
|
|
616
|
+
}
|
|
617
|
+
if (!this.credentialsProvider) {
|
|
618
|
+
return Promise.resolve();
|
|
619
|
+
}
|
|
620
|
+
const provider = this.credentialsProvider;
|
|
621
|
+
this.credentialsRefreshInFlight = (async () => {
|
|
622
|
+
try {
|
|
623
|
+
const fresh = await provider();
|
|
624
|
+
if (fresh?.username && fresh?.password) {
|
|
625
|
+
// Apply whatever the provider returns and retry. We do NOT try to
|
|
626
|
+
// detect "auth expired" by comparing passwords — a stable
|
|
627
|
+
// xmppPassword (e.g. deterministic from the JWT/wallet) is the
|
|
628
|
+
// NORMAL case for a transient blip, and treating it as expiry
|
|
629
|
+
// falsely bricked recoverable sessions (sending stopped). If the
|
|
630
|
+
// creds really are stale we simply get not-authorized again and
|
|
631
|
+
// retry, which is the confirmed-good 26.5.7 behaviour.
|
|
632
|
+
this.updateCredentials(fresh.username, fresh.password);
|
|
633
|
+
this.lastAuthError = null;
|
|
634
|
+
}
|
|
635
|
+
} finally {
|
|
636
|
+
this.credentialsRefreshInFlight = null;
|
|
637
|
+
}
|
|
638
|
+
})();
|
|
639
|
+
return this.credentialsRefreshInFlight;
|
|
640
|
+
}
|
|
357
641
|
async disconnect(options) {
|
|
358
642
|
if (options?.suppressReconnect) {
|
|
359
643
|
this.suppressReconnect = true;
|
|
@@ -361,7 +645,17 @@ export class XmppClient {
|
|
|
361
645
|
return this.close();
|
|
362
646
|
}
|
|
363
647
|
async close() {
|
|
648
|
+
// Cancel any pending reconnect so a stale timer can't resurrect this
|
|
649
|
+
// instance after teardown/logout.
|
|
650
|
+
if (this.reconnectTimer) {
|
|
651
|
+
clearTimeout(this.reconnectTimer);
|
|
652
|
+
this.reconnectTimer = null;
|
|
653
|
+
}
|
|
364
654
|
if (this.client) {
|
|
655
|
+
// Detach OUR handlers first so a late stanza during the close
|
|
656
|
+
// handshake can't re-enter handleStanza and dispatch into a store
|
|
657
|
+
// that's being wiped (or, on re-login, the new session's store).
|
|
658
|
+
this.detachEventListeners();
|
|
365
659
|
try {
|
|
366
660
|
await this.client.stop();
|
|
367
661
|
console.log('XMPP client connection closed.');
|
|
@@ -370,6 +664,11 @@ export class XmppClient {
|
|
|
370
664
|
}
|
|
371
665
|
}
|
|
372
666
|
this.status = 'offline';
|
|
667
|
+
this.presencesReady = false;
|
|
668
|
+
// Permanent teardown (logout / unmount) — drop buffered sends so they
|
|
669
|
+
// don't replay into the next session. Reconnect uses old.stop(), NOT
|
|
670
|
+
// close(), so the queue still survives a transient drop+reconnect.
|
|
671
|
+
clearOutboundSends();
|
|
373
672
|
}
|
|
374
673
|
getRoomsStanza = async () => {
|
|
375
674
|
await getRooms(this.client);
|
|
@@ -384,10 +683,10 @@ export class XmppClient {
|
|
|
384
683
|
await inviteRoomRequest(this.client, to, roomJid);
|
|
385
684
|
}
|
|
386
685
|
leaveTheRoomStanza = roomJID => {
|
|
387
|
-
leaveTheRoom(roomJID, this.client);
|
|
686
|
+
leaveTheRoom(normalizeRoomJid(roomJID, this.conference), this.client);
|
|
388
687
|
};
|
|
389
688
|
presenceInRoomStanza = roomJID => {
|
|
390
|
-
presenceInRoom(this.client, roomJID);
|
|
689
|
+
presenceInRoom(this.client, normalizeRoomJid(roomJID, this.conference));
|
|
391
690
|
};
|
|
392
691
|
getHistoryStanza = async (chatJID, max, before, id, options) => {
|
|
393
692
|
if (options?.coalesceRoom) {
|
|
@@ -402,21 +701,49 @@ export class XmppClient {
|
|
|
402
701
|
return await getHistory(this.client, chatJID, max, before, id);
|
|
403
702
|
};
|
|
404
703
|
getLastMessageArchiveStanza(roomJID) {
|
|
405
|
-
getLastMessage(this.client, roomJID);
|
|
704
|
+
getLastMessage(this.client, normalizeRoomJid(roomJID, this.conference));
|
|
406
705
|
}
|
|
407
706
|
setRoomImageStanza = (roomJid, roomThumbnail, type, roomBackground) => {
|
|
408
707
|
setRoomImage(roomJid, roomThumbnail, type, this.client, roomBackground);
|
|
409
708
|
};
|
|
410
709
|
getRoomInfoStanza = roomJID => {
|
|
411
|
-
getRoomInfo(roomJID, this.client);
|
|
710
|
+
getRoomInfo(normalizeRoomJid(roomJID, this.conference), this.client);
|
|
412
711
|
};
|
|
413
712
|
getRoomMembersStanza = roomJID => {
|
|
414
|
-
getRoomMembers(roomJID, this.client);
|
|
713
|
+
getRoomMembers(normalizeRoomJid(roomJID, this.conference), this.client);
|
|
415
714
|
};
|
|
416
715
|
|
|
716
|
+
/**
|
|
717
|
+
* True when the underlying stream is live enough to actually put a
|
|
718
|
+
* stanza on the wire. Used to gate sends: when false we buffer instead
|
|
719
|
+
* of firing a fire-and-forget stanza into a dead/half-open socket
|
|
720
|
+
* (which is silently dropped and only caught by the 30s watchdog).
|
|
721
|
+
*/
|
|
722
|
+
isStreamReady() {
|
|
723
|
+
return !!this.client && this.status === 'online' && !this.reconnecting;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/** Replay buffered sends against this (now-online) client, in order. */
|
|
727
|
+
flushPendingSends() {
|
|
728
|
+
flushOutboundSends(this, Date.now());
|
|
729
|
+
}
|
|
730
|
+
|
|
417
731
|
//messages
|
|
418
732
|
sendMessage = (roomJID, firstName, lastName, photo, walletAddress, userMessage, notDisplayedValue, isReply, showInChannel, mainMessage, customId) => {
|
|
733
|
+
// Stream down (start race / reconnect window): buffer and replay on
|
|
734
|
+
// the next 'online' instead of losing the stanza. Returns false so
|
|
735
|
+
// callers know the send was deferred, not delivered.
|
|
736
|
+
if (!this.isStreamReady()) {
|
|
737
|
+
enqueueOutboundSend({
|
|
738
|
+
optimisticId: customId || `send-text-message-${Date.now()}`,
|
|
739
|
+
roomJID,
|
|
740
|
+
enqueuedAt: Date.now(),
|
|
741
|
+
send: c => c.sendMessage(roomJID, firstName, lastName, photo, walletAddress, userMessage, notDisplayedValue, isReply, showInChannel, mainMessage, customId)
|
|
742
|
+
});
|
|
743
|
+
return false;
|
|
744
|
+
}
|
|
419
745
|
sendTextMessage(this.client, roomJID, firstName, lastName, photo, walletAddress, userMessage, notDisplayedValue, isReply, showInChannel, mainMessage, this.devServer || DEFAULT_DEV_SERVER, customId);
|
|
746
|
+
return true;
|
|
420
747
|
};
|
|
421
748
|
deleteMessageStanza(room, msgId) {
|
|
422
749
|
deleteMessage(this.client, room, msgId);
|
|
@@ -461,6 +788,19 @@ export class XmppClient {
|
|
|
461
788
|
}
|
|
462
789
|
}
|
|
463
790
|
sendMediaMessageStanza(roomJID, data, customId) {
|
|
791
|
+
// Media: the file is already uploaded by the time we get here; only the
|
|
792
|
+
// stanza needs the stream. Buffer + replay on reconnect if it's down so
|
|
793
|
+
// the upload isn't wasted (otherwise the stanza is lost and the media
|
|
794
|
+
// bubble sits pending until the 30s watchdog fails it).
|
|
795
|
+
if (!this.isStreamReady()) {
|
|
796
|
+
enqueueOutboundSend({
|
|
797
|
+
optimisticId: customId || `send-media-message-${Date.now()}`,
|
|
798
|
+
roomJID,
|
|
799
|
+
enqueuedAt: Date.now(),
|
|
800
|
+
send: c => c.sendMediaMessageStanza(roomJID, data, customId)
|
|
801
|
+
});
|
|
802
|
+
return undefined;
|
|
803
|
+
}
|
|
464
804
|
return sendMediaMessage(this.client, roomJID, data, customId, this.devServer || DEFAULT_DEV_SERVER);
|
|
465
805
|
}
|
|
466
806
|
|
|
@@ -482,9 +822,14 @@ export class XmppClient {
|
|
|
482
822
|
sendMessageReactionStanza(_messageId, _roomJid, _reactionsList, _reactionSymbol) {
|
|
483
823
|
console.warn('sendMessageReactionStanza: not implemented in RN xmpp client');
|
|
484
824
|
}
|
|
485
|
-
sendTextMessageWithTranslateTagStanza(roomJID, firstName, lastName, photo, walletAddress, userMessage, notDisplayedValue, isReply, showInChannel, mainMessage, _langSource) {
|
|
825
|
+
sendTextMessageWithTranslateTagStanza(roomJID, firstName, lastName, photo, walletAddress, userMessage, notDisplayedValue, isReply, showInChannel, mainMessage, _langSource, customId) {
|
|
486
826
|
// No translate tag support yet — fall back to a regular text send.
|
|
487
|
-
|
|
827
|
+
// Forward the caller's customId so the optimistic message (heap/redux)
|
|
828
|
+
// reconciles with the server echo. Without it, translated sends went
|
|
829
|
+
// out with no client id → the echo carried a server-assigned id and
|
|
830
|
+
// surfaced as a stuck-pending message PLUS a duplicate (affected both
|
|
831
|
+
// the live translated-send path and resend).
|
|
832
|
+
this.sendMessage(roomJID, firstName, lastName, photo, walletAddress, userMessage, notDisplayedValue, isReply, showInChannel, mainMessage, customId);
|
|
488
833
|
}
|
|
489
834
|
}
|
|
490
835
|
export default XmppClient;
|