@ethora/chat-component-rn 26.5.7 → 26.5.11
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 +191 -0
- package/README.md +95 -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 +31 -16
- package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatRoom.js +78 -38
- package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatWrapper.js +74 -27
- package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MediaMessage.js +16 -11
- 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 +165 -28
- 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/InteractionsOverlay.js +119 -0
- package/lib/commonjs/components/MessageBubble/InteractionsOverlay.js.map +1 -0
- package/lib/commonjs/components/MessageBubble/Message.js +122 -41
- package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js +132 -44
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
- package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js +155 -52
- package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js +20 -5
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.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 +144 -24
- 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/ModalHeaderComponent.js +10 -0
- package/lib/commonjs/components/Modals/ModalHeaderComponent.js.map +1 -1
- package/lib/commonjs/components/Modals/ModalWrapper/ModalWrapper.js +77 -47
- 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 +17 -13
- package/lib/commonjs/components/Modals/styledModalComponents.js.map +1 -1
- package/lib/commonjs/components/styled/MediaFilePreview.js +47 -28
- package/lib/commonjs/components/styled/MediaFilePreview.js.map +1 -1
- package/lib/commonjs/components/styled/MessageImage.js +49 -9
- 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 +49 -27
- package/lib/commonjs/components/styled/SendInput.js.map +1 -1
- package/lib/commonjs/components/styled/StyledComponents.js +6 -3
- package/lib/commonjs/components/styled/StyledComponents.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 +81 -16
- 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 +244 -32
- 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 +56 -0
- package/lib/commonjs/helpers/mimeToExtension.js.map +1 -1
- package/lib/commonjs/helpers/normalizeRoomJid.js +20 -0
- package/lib/commonjs/helpers/normalizeRoomJid.js.map +1 -0
- package/lib/commonjs/hooks/useChatRoomFocus.js +87 -0
- package/lib/commonjs/hooks/useChatRoomFocus.js.map +1 -0
- package/lib/commonjs/hooks/useHeapSender.js +1 -1
- package/lib/commonjs/hooks/useHeapSender.js.map +1 -1
- package/lib/commonjs/hooks/useLogout.js +36 -11
- package/lib/commonjs/hooks/useLogout.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 +201 -10
- 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 +67 -0
- package/lib/commonjs/networking/api-requests/auth.api.js.map +1 -1
- package/lib/commonjs/networking/api-requests/rooms.api.js +29 -4
- package/lib/commonjs/networking/api-requests/rooms.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 +294 -35
- 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/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 +31 -16
- package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/module/components/MainComponents/ChatRoom.js +80 -40
- package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/module/components/MainComponents/ChatWrapper.js +74 -27
- package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/MediaMessage.js +17 -12
- 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 +166 -29
- 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/InteractionsOverlay.js +112 -0
- package/lib/module/components/MessageBubble/InteractionsOverlay.js.map +1 -0
- package/lib/module/components/MessageBubble/Message.js +123 -42
- package/lib/module/components/MessageBubble/Message.js.map +1 -1
- package/lib/module/components/MessageBubble/MessageInteractions.js +134 -46
- package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
- package/lib/module/components/Modals/AttachSheet/AttachSheet.js +155 -52
- package/lib/module/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js +20 -5
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.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 +148 -26
- 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/ModalHeaderComponent.js +10 -0
- package/lib/module/components/Modals/ModalHeaderComponent.js.map +1 -1
- package/lib/module/components/Modals/ModalWrapper/ModalWrapper.js +79 -49
- 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 +17 -13
- package/lib/module/components/Modals/styledModalComponents.js.map +1 -1
- package/lib/module/components/styled/MediaFilePreview.js +47 -28
- package/lib/module/components/styled/MediaFilePreview.js.map +1 -1
- package/lib/module/components/styled/MessageImage.js +51 -11
- 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 +50 -28
- package/lib/module/components/styled/SendInput.js.map +1 -1
- package/lib/module/components/styled/StyledComponents.js +6 -3
- package/lib/module/components/styled/StyledComponents.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 +82 -17
- 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 +246 -34
- 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 +55 -0
- package/lib/module/helpers/mimeToExtension.js.map +1 -1
- package/lib/module/helpers/normalizeRoomJid.js +15 -0
- package/lib/module/helpers/normalizeRoomJid.js.map +1 -0
- package/lib/module/hooks/useChatRoomFocus.js +82 -0
- package/lib/module/hooks/useChatRoomFocus.js.map +1 -0
- package/lib/module/hooks/useHeapSender.js +1 -1
- package/lib/module/hooks/useHeapSender.js.map +1 -1
- package/lib/module/hooks/useLogout.js +36 -11
- package/lib/module/hooks/useLogout.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 +203 -12
- 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 +67 -1
- package/lib/module/networking/api-requests/auth.api.js.map +1 -1
- package/lib/module/networking/api-requests/rooms.api.js +29 -4
- package/lib/module/networking/api-requests/rooms.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 +294 -35
- 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/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/InteractionsOverlay.d.ts +13 -0
- package/lib/typescript/components/MessageBubble/InteractionsOverlay.d.ts.map +1 -0
- 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/ChatProfileModal/ChatProfileModal.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/ModalHeaderComponent.d.ts.map +1 -1
- 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/StyledComponents.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 +8 -0
- package/lib/typescript/helpers/mimeToExtension.d.ts.map +1 -1
- package/lib/typescript/helpers/normalizeRoomJid.d.ts +2 -0
- package/lib/typescript/helpers/normalizeRoomJid.d.ts.map +1 -0
- package/lib/typescript/hooks/useChatRoomFocus.d.ts +42 -0
- package/lib/typescript/hooks/useChatRoomFocus.d.ts.map +1 -0
- package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
- package/lib/typescript/hooks/useLogout.d.ts +23 -1
- package/lib/typescript/hooks/useLogout.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.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/api-requests/rooms.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 +33 -4
- 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/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 +20 -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 +23 -4
- package/src/assets/icons.tsx +23 -14
- package/src/components/ContextMenu/ContextMenuComponents.tsx +10 -5
- package/src/components/MainComponents/ChatHeader.tsx +46 -15
- package/src/components/MainComponents/ChatRoom.tsx +95 -66
- package/src/components/MainComponents/ChatWrapper.tsx +127 -42
- package/src/components/MainComponents/MediaMessage.tsx +14 -8
- package/src/components/MainComponents/MessageContainer.tsx +4 -2
- package/src/components/MainComponents/MessageList.tsx +175 -28
- package/src/components/MainComponents/ReduxWrapper.tsx +19 -9
- package/src/components/MainComponents/SystemMessage.tsx +38 -26
- package/src/components/MessageBubble/InteractionsOverlay.tsx +121 -0
- package/src/components/MessageBubble/Message.tsx +133 -63
- package/src/components/MessageBubble/MessageInteractions.tsx +146 -58
- package/src/components/Modals/AttachSheet/AttachSheet.tsx +146 -39
- package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +25 -3
- package/src/components/Modals/FilePreviewModal/DocumentViewer.tsx +93 -0
- package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +161 -26
- package/src/components/Modals/FilePreviewModal/PdfView.tsx +32 -4
- package/src/components/Modals/Modal/Modal.tsx +4 -1
- package/src/components/Modals/ModalHeaderComponent.tsx +8 -1
- package/src/components/Modals/ModalWrapper/ModalWrapper.tsx +70 -58
- package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +19 -15
- package/src/components/Modals/styledModalComponents.tsx +17 -13
- package/src/components/styled/MediaFilePreview.tsx +46 -26
- package/src/components/styled/MessageImage.tsx +58 -13
- package/src/components/styled/NewMessageLabel.tsx +8 -5
- package/src/components/styled/SendInput.tsx +64 -29
- package/src/components/styled/StyledComponents.ts +6 -3
- 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 +76 -12
- package/src/context/MessageNotificationContext.tsx +8 -8
- package/src/context/xmppProvider.tsx +247 -30
- 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 +64 -0
- package/src/helpers/normalizeRoomJid.ts +6 -0
- package/src/hooks/useChatRoomFocus.ts +95 -0
- package/src/hooks/useHeapSender.tsx +2 -1
- package/src/hooks/useLogout.tsx +36 -13
- package/src/hooks/usePushNotifications.ts +21 -8
- package/src/hooks/useRoomState.tsx +4 -0
- package/src/hooks/useSendMessage.tsx +258 -13
- package/src/hooks/useUnreadMessagesCounter.ts +13 -16
- package/src/main.ts +1 -0
- package/src/networking/api-requests/auth.api.ts +55 -1
- package/src/networking/api-requests/rooms.api.ts +31 -7
- 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 +317 -43
- package/src/roomStore/Middleware/unreadMidlleware.tsx +23 -5
- 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 +31 -0
- package/src/utils/installPromiseRejectionTracker.ts +91 -0
- package/src/utils/resendMessage.ts +2 -1
|
@@ -9,6 +9,7 @@ import React, {
|
|
|
9
9
|
} from 'react';
|
|
10
10
|
import {
|
|
11
11
|
View,
|
|
12
|
+
Text,
|
|
12
13
|
StyleSheet,
|
|
13
14
|
FlatList,
|
|
14
15
|
Image,
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
ImageSourcePropType,
|
|
19
20
|
} from 'react-native';
|
|
20
21
|
import { IMessage, User, IConfig, IRoom } from '../../types/types';
|
|
22
|
+
import { msgSortableMs } from '../../roomStore/roomsSlice';
|
|
21
23
|
import Composing from '../styled/StyledInputComponents/Composing';
|
|
22
24
|
import TreadLabel from '../styled/TreadLabel';
|
|
23
25
|
import { MessageContainer } from './MessageContainer';
|
|
@@ -68,10 +70,24 @@ const MessageList = <TMessage extends IMessage>({
|
|
|
68
70
|
.room! as IRoom;
|
|
69
71
|
const [isUserAtBottom, setIsUserAtBottom] = useState(true);
|
|
70
72
|
const [showNewMessageIndicator, setShowNewMessageIndicator] = useState(false);
|
|
71
|
-
const [isContentOffset, setIsContentOffset] = useState(false);
|
|
72
73
|
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
73
74
|
const [isScrollBlocked, setIsScrollBlocked] = useState(false);
|
|
74
|
-
|
|
75
|
+
// Count of messages that arrived while the user was scrolled up.
|
|
76
|
+
// Renders as a badge on the scroll-to-bottom arrow so they know how
|
|
77
|
+
// much they're missing without having to scroll to find out.
|
|
78
|
+
const [unreadWhileScrolledUp, setUnreadWhileScrolledUp] = useState(0);
|
|
79
|
+
// Newest message timestamp at the moment the user scrolled away from
|
|
80
|
+
// the bottom. The badge counts only messages NEWER than this, so
|
|
81
|
+
// back-pagination (loading OLDER history while scrolled up) never
|
|
82
|
+
// inflates the count. Was previously a message-COUNT snapshot, which
|
|
83
|
+
// wrongly counted back-paginated old messages as "new" (Android repro).
|
|
84
|
+
const newestSeenTsRef = useRef<number | null>(null);
|
|
85
|
+
// Refs mirror the viewport state synchronously. The auto-follow logic
|
|
86
|
+
// runs from FlatList callbacks where setState hasn't necessarily
|
|
87
|
+
// committed yet; relying on stale React state is what caused the chat
|
|
88
|
+
// to jump back to the bottom when a new message landed mid-scroll.
|
|
89
|
+
const isUserAtBottomRef = useRef(true);
|
|
90
|
+
const hasUserScrolledRef = useRef(false);
|
|
75
91
|
|
|
76
92
|
const flatListRef = useRef<FlatList<IMessage>>(null);
|
|
77
93
|
|
|
@@ -176,16 +192,72 @@ const MessageList = <TMessage extends IMessage>({
|
|
|
176
192
|
]);
|
|
177
193
|
|
|
178
194
|
const dataMessages = useMemo(() => {
|
|
179
|
-
|
|
180
|
-
|
|
195
|
+
const base = memoizedMessages.slice().reverse();
|
|
196
|
+
const boundaryTs = newestSeenTsRef.current;
|
|
197
|
+
if (
|
|
198
|
+
isUserAtBottomRef.current ||
|
|
199
|
+
boundaryTs === null ||
|
|
200
|
+
unreadWhileScrolledUp === 0
|
|
201
|
+
) {
|
|
202
|
+
return base;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
let lastNewIndex = -1;
|
|
206
|
+
for (let i = 0; i < base.length; i++) {
|
|
207
|
+
if (msgSortableMs(base[i]) > boundaryTs) {
|
|
208
|
+
lastNewIndex = i;
|
|
209
|
+
} else {
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (lastNewIndex === -1) {return base;}
|
|
215
|
+
|
|
216
|
+
const withDivider = base.slice();
|
|
217
|
+
withDivider.splice(lastNewIndex + 1, 0, {
|
|
218
|
+
id: 'delimiter-new-local',
|
|
219
|
+
user: {
|
|
220
|
+
id: 'system',
|
|
221
|
+
name: undefined,
|
|
222
|
+
token: '',
|
|
223
|
+
refreshToken: '',
|
|
224
|
+
} as any,
|
|
225
|
+
date: new Date(boundaryTs).toISOString(),
|
|
226
|
+
body: 'New Messages',
|
|
227
|
+
roomJid: roomJID,
|
|
228
|
+
} as IMessage);
|
|
229
|
+
return withDivider;
|
|
230
|
+
}, [memoizedMessages, isUserAtBottom, roomJID, unreadWhileScrolledUp]);
|
|
181
231
|
|
|
182
232
|
const renderMessage = useCallback(
|
|
183
233
|
({ item, index }: { item: IMessage; index: number }) => {
|
|
234
|
+
if (String(item.id).startsWith('delimiter-new')) {
|
|
235
|
+
return (
|
|
236
|
+
<MessageContainer
|
|
237
|
+
CustomMessage={CustomMessage}
|
|
238
|
+
CustomDaySeparator={CustomDaySeparator}
|
|
239
|
+
CustomNewMessageLabel={CustomNewMessageLabel}
|
|
240
|
+
message={item}
|
|
241
|
+
activeMessage={activeMessage}
|
|
242
|
+
config={config}
|
|
243
|
+
walletAddress={user.xmppUsername || user.walletAddress}
|
|
244
|
+
isReply={isReply}
|
|
245
|
+
showDateLabel={false}
|
|
246
|
+
/>
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
184
250
|
const messageDate = new Date(item.date).toDateString();
|
|
185
251
|
let showDateLabel = false;
|
|
186
252
|
|
|
187
|
-
|
|
188
|
-
|
|
253
|
+
let nextMessage = null;
|
|
254
|
+
for (let i = index + 1; i < dataMessages.length; i++) {
|
|
255
|
+
const candidate = dataMessages[i];
|
|
256
|
+
if (!String(candidate.id).startsWith('delimiter-new')) {
|
|
257
|
+
nextMessage = candidate;
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
189
261
|
const nextMessageDate = nextMessage
|
|
190
262
|
? new Date(nextMessage.date).toDateString()
|
|
191
263
|
: null;
|
|
@@ -211,10 +283,13 @@ const MessageList = <TMessage extends IMessage>({
|
|
|
211
283
|
[
|
|
212
284
|
activeMessage,
|
|
213
285
|
config,
|
|
286
|
+
CustomDaySeparator,
|
|
287
|
+
CustomMessage,
|
|
288
|
+
CustomNewMessageLabel,
|
|
289
|
+
dataMessages,
|
|
290
|
+
isReply,
|
|
214
291
|
user.xmppUsername,
|
|
215
292
|
user.walletAddress,
|
|
216
|
-
isReply,
|
|
217
|
-
memoizedMessages.length,
|
|
218
293
|
]
|
|
219
294
|
);
|
|
220
295
|
|
|
@@ -228,16 +303,12 @@ const MessageList = <TMessage extends IMessage>({
|
|
|
228
303
|
}, [flatListRef]);
|
|
229
304
|
|
|
230
305
|
const handleContentSizeChange = useCallback(() => {
|
|
231
|
-
if (
|
|
232
|
-
scrollToBottom();
|
|
233
|
-
setIsContentOffset(false);
|
|
234
|
-
}
|
|
235
|
-
if (!isLoadingMore && flatListRef.current && isUserAtBottom) {
|
|
306
|
+
if (!isLoadingMore && flatListRef.current && isUserAtBottomRef.current) {
|
|
236
307
|
scrollToBottom();
|
|
237
|
-
} else if (!isLoadingMore &&
|
|
308
|
+
} else if (!isLoadingMore && hasUserScrolledRef.current) {
|
|
238
309
|
setShowNewMessageIndicator(true);
|
|
239
310
|
}
|
|
240
|
-
}, [
|
|
311
|
+
}, [scrollToBottom, isLoadingMore]);
|
|
241
312
|
|
|
242
313
|
const handleScroll = useCallback(
|
|
243
314
|
(event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
@@ -248,40 +319,78 @@ const MessageList = <TMessage extends IMessage>({
|
|
|
248
319
|
// to a long thread feel broken. Drag-to-dismiss still works via
|
|
249
320
|
// FlatList's keyboardDismissMode="interactive" below.
|
|
250
321
|
|
|
251
|
-
if (contentOffset > 150 && !
|
|
252
|
-
|
|
322
|
+
if (contentOffset > 150 && !hasUserScrolledRef.current) {
|
|
323
|
+
hasUserScrolledRef.current = true;
|
|
253
324
|
}
|
|
254
325
|
|
|
255
326
|
if (contentOffset < 150) {
|
|
256
|
-
|
|
327
|
+
isUserAtBottomRef.current = true;
|
|
257
328
|
setShowNewMessageIndicator(false);
|
|
258
329
|
setIsUserAtBottom(true);
|
|
330
|
+
// Back at the bottom — clear the unread-while-scrolled-up
|
|
331
|
+
// counter so the badge disappears with the arrow.
|
|
332
|
+
setUnreadWhileScrolledUp(0);
|
|
333
|
+
newestSeenTsRef.current = null;
|
|
259
334
|
} else {
|
|
260
|
-
|
|
261
|
-
if (
|
|
335
|
+
isUserAtBottomRef.current = false;
|
|
336
|
+
if (hasUserScrolledRef.current) {
|
|
262
337
|
setShowNewMessageIndicator(true);
|
|
263
338
|
}
|
|
339
|
+
if (newestSeenTsRef.current === null) {
|
|
340
|
+
// Snapshot the NEWEST message's timestamp the moment the user
|
|
341
|
+
// first leaves the bottom. Anything newer than this that
|
|
342
|
+
// arrives later is genuinely "new"; older history loaded by
|
|
343
|
+
// back-pagination is < this and never counts.
|
|
344
|
+
newestSeenTsRef.current = memoizedMessages.reduce(
|
|
345
|
+
(mx: number, m: IMessage) => {
|
|
346
|
+
const t = msgSortableMs(m);
|
|
347
|
+
return t > mx ? t : mx;
|
|
348
|
+
},
|
|
349
|
+
0
|
|
350
|
+
);
|
|
351
|
+
}
|
|
264
352
|
setIsUserAtBottom(false);
|
|
265
353
|
}
|
|
266
354
|
},
|
|
267
|
-
[
|
|
355
|
+
[memoizedMessages]
|
|
268
356
|
);
|
|
269
357
|
|
|
358
|
+
// Keep the badge in sync with messages that arrive while the user is
|
|
359
|
+
// scrolled up. Count ONLY messages newer than the newest-seen snapshot
|
|
360
|
+
// — so loading older history (back-pagination) doesn't inflate it.
|
|
361
|
+
useEffect(() => {
|
|
362
|
+
if (isUserAtBottomRef.current) {return;}
|
|
363
|
+
if (newestSeenTsRef.current === null) {return;}
|
|
364
|
+
const since = newestSeenTsRef.current;
|
|
365
|
+
const count = memoizedMessages.reduce(
|
|
366
|
+
(n: number, m: IMessage) => (msgSortableMs(m) > since ? n + 1 : n),
|
|
367
|
+
0
|
|
368
|
+
);
|
|
369
|
+
setUnreadWhileScrolledUp(count);
|
|
370
|
+
}, [memoizedMessages, isUserAtBottom]);
|
|
371
|
+
|
|
270
372
|
const handleLayout = () => {
|
|
271
|
-
|
|
373
|
+
isUserAtBottomRef.current = true;
|
|
374
|
+
hasUserScrolledRef.current = false;
|
|
272
375
|
setIsUserAtBottom(true);
|
|
273
376
|
};
|
|
274
377
|
|
|
275
378
|
const handleNewMessageIndicatorPress = () => {
|
|
379
|
+
isUserAtBottomRef.current = true;
|
|
276
380
|
setShowNewMessageIndicator(false);
|
|
277
381
|
setIsUserAtBottom(true);
|
|
382
|
+
setUnreadWhileScrolledUp(0);
|
|
383
|
+
newestSeenTsRef.current = null;
|
|
278
384
|
scrollToBottom();
|
|
279
385
|
};
|
|
280
386
|
|
|
281
387
|
useEffect(() => {
|
|
282
|
-
|
|
388
|
+
hasUserScrolledRef.current = false;
|
|
389
|
+
isUserAtBottomRef.current = true;
|
|
283
390
|
setShowNewMessageIndicator(false);
|
|
284
391
|
setIsUserAtBottom(true);
|
|
392
|
+
setUnreadWhileScrolledUp(0);
|
|
393
|
+
newestSeenTsRef.current = null;
|
|
285
394
|
}, [roomJID]);
|
|
286
395
|
|
|
287
396
|
const BackgroundImage = useMemo(() => {
|
|
@@ -321,7 +430,7 @@ const MessageList = <TMessage extends IMessage>({
|
|
|
321
430
|
)}
|
|
322
431
|
<FlatList
|
|
323
432
|
ref={flatListRef}
|
|
324
|
-
data={
|
|
433
|
+
data={dataMessages}
|
|
325
434
|
renderItem={renderMessage}
|
|
326
435
|
keyExtractor={(item) => item.id.toString()}
|
|
327
436
|
onEndReached={handleLoadMore}
|
|
@@ -344,11 +453,21 @@ const MessageList = <TMessage extends IMessage>({
|
|
|
344
453
|
<TouchableOpacity
|
|
345
454
|
style={[
|
|
346
455
|
styles.newMessageIndicator,
|
|
347
|
-
{ backgroundColor: config?.colors?.
|
|
456
|
+
{ backgroundColor: config?.colors?.primary || '#0052CD' },
|
|
348
457
|
]}
|
|
349
458
|
onPress={handleNewMessageIndicatorPress}
|
|
350
459
|
>
|
|
351
|
-
|
|
460
|
+
{/* White chevron on the saturated FAB. The icon's default
|
|
461
|
+
color is white, which was invisible against the previous
|
|
462
|
+
light `secondary` background — hence "no icon". */}
|
|
463
|
+
<ArowDownIcon color="#FFFFFF" width={22} height={22} />
|
|
464
|
+
{unreadWhileScrolledUp > 0 && (
|
|
465
|
+
<View style={styles.newMessageBadge}>
|
|
466
|
+
<Text style={styles.newMessageBadgeText}>
|
|
467
|
+
{unreadWhileScrolledUp > 99 ? '99+' : unreadWhileScrolledUp}
|
|
468
|
+
</Text>
|
|
469
|
+
</View>
|
|
470
|
+
)}
|
|
352
471
|
</TouchableOpacity>
|
|
353
472
|
)}
|
|
354
473
|
{config?.customTypingIndicator?.enabled && composing && (
|
|
@@ -407,12 +526,40 @@ const styles = StyleSheet.create({
|
|
|
407
526
|
height: 40,
|
|
408
527
|
bottom: 20,
|
|
409
528
|
right: 20,
|
|
410
|
-
backgroundColor: '#
|
|
411
|
-
padding: 10,
|
|
529
|
+
backgroundColor: '#0052CD',
|
|
412
530
|
borderRadius: 20,
|
|
531
|
+
justifyContent: 'center',
|
|
532
|
+
alignItems: 'center',
|
|
533
|
+
// Lift the FAB off the chat background so it reads as a button.
|
|
534
|
+
shadowColor: '#000',
|
|
535
|
+
shadowOffset: { width: 0, height: 2 },
|
|
536
|
+
shadowOpacity: 0.2,
|
|
537
|
+
shadowRadius: 3,
|
|
538
|
+
elevation: 4,
|
|
413
539
|
},
|
|
414
540
|
newMessageText: {
|
|
415
541
|
color: '#fff',
|
|
416
542
|
fontWeight: 'bold',
|
|
417
543
|
},
|
|
544
|
+
newMessageBadge: {
|
|
545
|
+
position: 'absolute',
|
|
546
|
+
top: -6,
|
|
547
|
+
right: -6,
|
|
548
|
+
minWidth: 20,
|
|
549
|
+
height: 20,
|
|
550
|
+
paddingHorizontal: 6,
|
|
551
|
+
borderRadius: 10,
|
|
552
|
+
justifyContent: 'center',
|
|
553
|
+
alignItems: 'center',
|
|
554
|
+
// Fixed red so it stays distinct from the (primary-coloured) FAB,
|
|
555
|
+
// with a white ring to separate the two.
|
|
556
|
+
backgroundColor: '#E53935',
|
|
557
|
+
borderWidth: 2,
|
|
558
|
+
borderColor: '#fff',
|
|
559
|
+
},
|
|
560
|
+
newMessageBadgeText: {
|
|
561
|
+
color: '#fff',
|
|
562
|
+
fontWeight: 'bold',
|
|
563
|
+
fontSize: 11,
|
|
564
|
+
},
|
|
418
565
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, {useMemo} from 'react';
|
|
2
2
|
import {Provider} from 'react-redux';
|
|
3
3
|
import {KeyboardProvider} from 'react-native-keyboard-controller';
|
|
4
|
+
import {SafeAreaProvider} from 'react-native-safe-area-context';
|
|
4
5
|
import {store} from '../../roomStore';
|
|
5
6
|
import {ConfigUser, IConfig, MessageProps} from '../../types/types';
|
|
6
7
|
import {XmppProvider} from '../../context/xmppProvider';
|
|
@@ -8,6 +9,12 @@ import {MessageNotificationProvider} from '../../context/MessageNotificationCont
|
|
|
8
9
|
import {ToastProvider} from '../../context/ToastContext';
|
|
9
10
|
import LoginWrapper from './LoginWrapper';
|
|
10
11
|
import '../../helpers/storeConsole';
|
|
12
|
+
import {installPromiseRejectionTracker} from '../../utils/installPromiseRejectionTracker';
|
|
13
|
+
|
|
14
|
+
// Mount-time, dev-only — wire a global unhandled-promise-rejection
|
|
15
|
+
// tracker so any future leak surfaces with a real stack trace in Metro
|
|
16
|
+
// logs (bug #4 follow-up). No-op in production.
|
|
17
|
+
installPromiseRejectionTracker();
|
|
11
18
|
|
|
12
19
|
interface ChatWrapperProps {
|
|
13
20
|
token?: string;
|
|
@@ -17,6 +24,7 @@ interface ChatWrapperProps {
|
|
|
17
24
|
MainComponentStyles?: React.CSSProperties;
|
|
18
25
|
CustomMessageComponent?: React.ComponentType<MessageProps>;
|
|
19
26
|
config?: IConfig;
|
|
27
|
+
isVisible?: boolean;
|
|
20
28
|
}
|
|
21
29
|
|
|
22
30
|
export const ReduxWrapper: React.FC<ChatWrapperProps> = React.memo(
|
|
@@ -27,15 +35,17 @@ export const ReduxWrapper: React.FC<ChatWrapperProps> = React.memo(
|
|
|
27
35
|
|
|
28
36
|
return (
|
|
29
37
|
<Provider store={store}>
|
|
30
|
-
<
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
<
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
<SafeAreaProvider>
|
|
39
|
+
<KeyboardProvider>
|
|
40
|
+
<XmppProvider config={memoizedConfig} isVisible={props.isVisible}>
|
|
41
|
+
<ToastProvider>
|
|
42
|
+
<MessageNotificationProvider config={memoizedConfig}>
|
|
43
|
+
<LoginWrapper config={memoizedConfig} {...props} />
|
|
44
|
+
</MessageNotificationProvider>
|
|
45
|
+
</ToastProvider>
|
|
46
|
+
</XmppProvider>
|
|
47
|
+
</KeyboardProvider>
|
|
48
|
+
</SafeAreaProvider>
|
|
39
49
|
</Provider>
|
|
40
50
|
);
|
|
41
51
|
},
|
|
@@ -1,42 +1,54 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import styled from 'styled-components/native';
|
|
2
|
+
import { View, Text, StyleSheet } from 'react-native';
|
|
4
3
|
|
|
5
4
|
interface SystemMessageProps {
|
|
6
5
|
messageText?: string;
|
|
7
6
|
colors?: { primary?: string; secondary?: string };
|
|
8
7
|
}
|
|
9
8
|
|
|
10
|
-
export const CustomSystemMessageText = styled.Text<{
|
|
11
|
-
primary?: string;
|
|
12
|
-
secondary?: string;
|
|
13
|
-
}>`
|
|
14
|
-
margin: 0;
|
|
15
|
-
color: ${(props) => props.primary || '#0052cd'};
|
|
16
|
-
border-radius: 118px;
|
|
17
|
-
padding: 5px 8px;
|
|
18
|
-
display: flex;
|
|
19
|
-
align-items: center;
|
|
20
|
-
justify-content: center;
|
|
21
|
-
font-size: 12px;
|
|
22
|
-
line-height: 14px;
|
|
23
|
-
font-weight: 600;
|
|
24
|
-
background-color: ${(props) => props.secondary || '#e7edf9'};
|
|
25
|
-
height: 24px;
|
|
26
|
-
white-space: nowrap;
|
|
27
|
-
`;
|
|
28
|
-
|
|
29
9
|
const SystemMessage: React.FC<SystemMessageProps> = ({
|
|
30
10
|
messageText,
|
|
31
11
|
colors,
|
|
32
12
|
}) => {
|
|
33
13
|
return (
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
14
|
+
<View style={styles.container}>
|
|
15
|
+
{/* maxWidth lives on this View (not the Text) so the Text reliably
|
|
16
|
+
wraps to multiple lines instead of staying on one line and
|
|
17
|
+
getting clipped — a styled.Text with a percentage max-width
|
|
18
|
+
doesn't bound its own line box the way a View does. */}
|
|
19
|
+
<View
|
|
20
|
+
style={[
|
|
21
|
+
styles.bubble,
|
|
22
|
+
{ backgroundColor: colors?.secondary || '#e7edf9' },
|
|
23
|
+
]}
|
|
24
|
+
>
|
|
25
|
+
<Text style={[styles.text, { color: colors?.primary || '#0052cd' }]}>
|
|
26
|
+
{messageText}
|
|
27
|
+
</Text>
|
|
28
|
+
</View>
|
|
29
|
+
</View>
|
|
39
30
|
);
|
|
40
31
|
};
|
|
41
32
|
|
|
42
33
|
export default SystemMessage;
|
|
34
|
+
|
|
35
|
+
const styles = StyleSheet.create({
|
|
36
|
+
container: {
|
|
37
|
+
width: '100%',
|
|
38
|
+
alignItems: 'center',
|
|
39
|
+
paddingVertical: 8,
|
|
40
|
+
paddingHorizontal: 16,
|
|
41
|
+
},
|
|
42
|
+
bubble: {
|
|
43
|
+
maxWidth: '85%',
|
|
44
|
+
borderRadius: 12,
|
|
45
|
+
paddingVertical: 6,
|
|
46
|
+
paddingHorizontal: 12,
|
|
47
|
+
},
|
|
48
|
+
text: {
|
|
49
|
+
fontSize: 12,
|
|
50
|
+
lineHeight: 16,
|
|
51
|
+
fontWeight: '600',
|
|
52
|
+
textAlign: 'center',
|
|
53
|
+
},
|
|
54
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
createContext,
|
|
3
|
+
useCallback,
|
|
4
|
+
useContext,
|
|
5
|
+
useMemo,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
} from 'react';
|
|
9
|
+
import { StyleSheet, View } from 'react-native';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* In-tree overlay host for the message context menu (MessageInteractions).
|
|
13
|
+
*
|
|
14
|
+
* Why this exists: MessageInteractions used to render inside a React Native
|
|
15
|
+
* `<Modal>`. On Android a Modal opens its own window, which steals focus
|
|
16
|
+
* from the chat input — so opening the menu dismissed the keyboard. Hosting
|
|
17
|
+
* the menu in the SAME view tree (no extra window) keeps the keyboard up.
|
|
18
|
+
*
|
|
19
|
+
* Coordinate note: the menu is positioned from `UIManager.measure` WINDOW
|
|
20
|
+
* coordinates (pageX/pageY), but this host sits below the status bar / any
|
|
21
|
+
* safe-area + header insets, so its own origin is offset from the window.
|
|
22
|
+
* The host measures that offset (`measureInWindow`) and exposes it so the
|
|
23
|
+
* menu can convert window coords → host-local coords. The host is mounted
|
|
24
|
+
* ABOVE ChatRoom's KeyboardAvoidingView, so its origin doesn't move when the
|
|
25
|
+
* keyboard opens (only the measured bubble's pageY does).
|
|
26
|
+
*/
|
|
27
|
+
interface OverlayEntry {
|
|
28
|
+
id: string;
|
|
29
|
+
node: React.ReactNode;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface InteractionsOverlayCtx {
|
|
33
|
+
present: (id: string, node: React.ReactNode) => void;
|
|
34
|
+
dismiss: (id: string) => void;
|
|
35
|
+
originX: number;
|
|
36
|
+
originY: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const Ctx = createContext<InteractionsOverlayCtx>({
|
|
40
|
+
present: () => {},
|
|
41
|
+
dismiss: () => {},
|
|
42
|
+
originX: 0,
|
|
43
|
+
originY: 0,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const useInteractionsOverlay = () => useContext(Ctx);
|
|
47
|
+
|
|
48
|
+
export const InteractionsOverlayProvider: React.FC<{
|
|
49
|
+
children: React.ReactNode;
|
|
50
|
+
}> = ({ children }) => {
|
|
51
|
+
const [entries, setEntries] = useState<OverlayEntry[]>([]);
|
|
52
|
+
const [origin, setOrigin] = useState({ x: 0, y: 0 });
|
|
53
|
+
const hostRef = useRef<View>(null);
|
|
54
|
+
|
|
55
|
+
const measure = useCallback(() => {
|
|
56
|
+
hostRef.current?.measureInWindow?.((x, y) => {
|
|
57
|
+
if (typeof x !== 'number' || typeof y !== 'number') {return;}
|
|
58
|
+
setOrigin((prev) => (prev.x === x && prev.y === y ? prev : { x, y }));
|
|
59
|
+
});
|
|
60
|
+
}, []);
|
|
61
|
+
|
|
62
|
+
const present = useCallback(
|
|
63
|
+
(id: string, node: React.ReactNode) => {
|
|
64
|
+
// Re-measure on present: the keyboard / layout may have shifted us
|
|
65
|
+
// since the last onLayout.
|
|
66
|
+
measure();
|
|
67
|
+
setEntries((prev) => {
|
|
68
|
+
const next = prev.filter((e) => e.id !== id);
|
|
69
|
+
next.push({ id, node });
|
|
70
|
+
return next;
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
[measure]
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
const dismiss = useCallback((id: string) => {
|
|
77
|
+
setEntries((prev) =>
|
|
78
|
+
prev.some((e) => e.id === id) ? prev.filter((e) => e.id !== id) : prev
|
|
79
|
+
);
|
|
80
|
+
}, []);
|
|
81
|
+
|
|
82
|
+
// MUST be memoized. Otherwise every host re-render (e.g. from present()'s
|
|
83
|
+
// setEntries) creates a new context value → all consumers re-render →
|
|
84
|
+
// MessageInteractions' present-effect fires again → setEntries → … →
|
|
85
|
+
// "Maximum update depth exceeded". present/dismiss are stable (useCallback)
|
|
86
|
+
// and origin rarely changes, so this value is stable across entry changes.
|
|
87
|
+
const ctxValue = useMemo(
|
|
88
|
+
() => ({ present, dismiss, originX: origin.x, originY: origin.y }),
|
|
89
|
+
[present, dismiss, origin.x, origin.y]
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
// `children` is a stable element from the caller, so re-rendering this
|
|
94
|
+
// host (present/dismiss/origin state) does NOT re-render the chat
|
|
95
|
+
// subtree — React reconciliation skips the unchanged children element.
|
|
96
|
+
<View
|
|
97
|
+
ref={hostRef}
|
|
98
|
+
style={styles.host}
|
|
99
|
+
onLayout={measure}
|
|
100
|
+
collapsable={false}
|
|
101
|
+
>
|
|
102
|
+
<Ctx.Provider value={ctxValue}>
|
|
103
|
+
{children}
|
|
104
|
+
{entries.length > 0 && (
|
|
105
|
+
<View style={styles.overlay} pointerEvents="box-none">
|
|
106
|
+
{entries.map((e) => (
|
|
107
|
+
<React.Fragment key={e.id}>{e.node}</React.Fragment>
|
|
108
|
+
))}
|
|
109
|
+
</View>
|
|
110
|
+
)}
|
|
111
|
+
</Ctx.Provider>
|
|
112
|
+
</View>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const styles = StyleSheet.create({
|
|
117
|
+
host: { flex: 1 },
|
|
118
|
+
overlay: { ...StyleSheet.absoluteFillObject, zIndex: 9999, elevation: 9999 },
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
export default InteractionsOverlayProvider;
|