@ethora/chat-component-rn 26.8.4 → 26.8.6
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/README.md +55 -0
- package/lib/commonjs/assets/emojiData.js +40 -0
- package/lib/commonjs/assets/emojiData.js.map +1 -0
- package/lib/commonjs/assets/icons.js +1 -1
- package/lib/commonjs/assets/icons.js.map +1 -1
- package/lib/commonjs/components/Header/HeaderRoomList.js +12 -7
- package/lib/commonjs/components/Header/HeaderRoomList.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatHeader.js +7 -9
- package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatRoom.js +47 -26
- package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatWrapper.js +58 -21
- package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/KeyboardInputDock.js +40 -0
- package/lib/commonjs/components/MainComponents/KeyboardInputDock.js.map +1 -0
- package/lib/commonjs/components/MainComponents/MessageContainer.js +4 -12
- package/lib/commonjs/components/MainComponents/MessageContainer.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MessageList.js +110 -35
- package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
- package/lib/commonjs/components/MainComponents/RoomList.js +32 -29
- package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
- package/lib/commonjs/components/MainComponents/RoomStack.js +270 -0
- package/lib/commonjs/components/MainComponents/RoomStack.js.map +1 -0
- package/lib/commonjs/components/MainComponents/SystemMessage.js +6 -2
- package/lib/commonjs/components/MainComponents/SystemMessage.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/Avatar.js +5 -1
- package/lib/commonjs/components/MessageBubble/Avatar.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/BottomReplyContainer.js +17 -21
- package/lib/commonjs/components/MessageBubble/BottomReplyContainer.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/EmojiPickerSheet.js +447 -0
- package/lib/commonjs/components/MessageBubble/EmojiPickerSheet.js.map +1 -0
- package/lib/commonjs/components/MessageBubble/Message.js +200 -132
- package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js +213 -12
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/MessageReaction.js +113 -94
- package/lib/commonjs/components/MessageBubble/MessageReaction.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/MessageReply.js +66 -24
- package/lib/commonjs/components/MessageBubble/MessageReply.js.map +1 -1
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js +6 -1
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/commonjs/components/Modals/Modal/Modal.js +24 -0
- package/lib/commonjs/components/Modals/Modal/Modal.js.map +1 -1
- package/lib/commonjs/components/Modals/Modal/SwipeBackLayer.js +178 -0
- package/lib/commonjs/components/Modals/Modal/SwipeBackLayer.js.map +1 -0
- package/lib/commonjs/components/Modals/ProfileHeader/ProfileHeader.js +28 -10
- package/lib/commonjs/components/Modals/ProfileHeader/ProfileHeader.js.map +1 -1
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +9 -3
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/ChatRoomItem.js +5 -4
- package/lib/commonjs/components/RoomComponents/ChatRoomItem.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/styled/LastMessageEmoji.js +8 -9
- package/lib/commonjs/components/RoomComponents/styled/LastMessageEmoji.js.map +1 -1
- package/lib/commonjs/components/Thread/ThreadWrapper.js +265 -152
- package/lib/commonjs/components/Thread/ThreadWrapper.js.map +1 -1
- package/lib/commonjs/components/styled/DateLabel.js +6 -3
- package/lib/commonjs/components/styled/DateLabel.js.map +1 -1
- package/lib/commonjs/context/MessageNotificationContext.js +188 -9
- package/lib/commonjs/context/MessageNotificationContext.js.map +1 -1
- package/lib/commonjs/context/xmppProvider.js +22 -7
- package/lib/commonjs/context/xmppProvider.js.map +1 -1
- package/lib/commonjs/helpers/createRoomFromApi.js +36 -2
- package/lib/commonjs/helpers/createRoomFromApi.js.map +1 -1
- package/lib/commonjs/helpers/emoji.js +51 -0
- package/lib/commonjs/helpers/emoji.js.map +1 -0
- package/lib/commonjs/helpers/haptics.js +29 -0
- package/lib/commonjs/helpers/haptics.js.map +1 -0
- package/lib/commonjs/helpers/historyPreloadScheduler.js +32 -66
- package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/commonjs/helpers/insertMessageWithDelimiter.js +21 -12
- package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
- package/lib/commonjs/helpers/keyboardLayout.js +23 -1
- package/lib/commonjs/helpers/keyboardLayout.js.map +1 -1
- package/lib/commonjs/helpers/mamReactions.js +57 -0
- package/lib/commonjs/helpers/mamReactions.js.map +1 -0
- package/lib/commonjs/helpers/parseMessageReference.js +42 -0
- package/lib/commonjs/helpers/parseMessageReference.js.map +1 -0
- package/lib/commonjs/helpers/reactionsConfig.js +17 -0
- package/lib/commonjs/helpers/reactionsConfig.js.map +1 -0
- package/lib/commonjs/helpers/updateMessagesTillLast.js +17 -2
- package/lib/commonjs/helpers/updateMessagesTillLast.js.map +1 -1
- package/lib/commonjs/hooks/useHeapSender.js +3 -1
- package/lib/commonjs/hooks/useHeapSender.js.map +1 -1
- package/lib/commonjs/hooks/useMessageHeapState.js +3 -2
- package/lib/commonjs/hooks/useMessageHeapState.js.map +1 -1
- package/lib/commonjs/hooks/useRoomInitialization.js +16 -7
- package/lib/commonjs/hooks/useRoomInitialization.js.map +1 -1
- package/lib/commonjs/hooks/useSendMessage.js +14 -8
- package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
- package/lib/commonjs/hooks/useUnreadMessagesCounter.js +1 -1
- package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
- package/lib/commonjs/networking/stanzaHandlers.js +106 -50
- package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
- package/lib/commonjs/networking/xmpp/getHistory.xmpp.js +29 -74
- package/lib/commonjs/networking/xmpp/getHistory.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js +4 -0
- package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/mamRouter.js +186 -0
- package/lib/commonjs/networking/xmpp/mamRouter.js.map +1 -0
- package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js +41 -4
- package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmppClient.js +98 -23
- package/lib/commonjs/networking/xmppClient.js.map +1 -1
- package/lib/commonjs/roomStore/Middleware/newMessageMidlleware.js +29 -34
- package/lib/commonjs/roomStore/Middleware/newMessageMidlleware.js.map +1 -1
- package/lib/commonjs/roomStore/Middleware/perfMiddleware.js +51 -0
- package/lib/commonjs/roomStore/Middleware/perfMiddleware.js.map +1 -0
- package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js +66 -43
- package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
- package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js +88 -68
- package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js.map +1 -1
- package/lib/commonjs/roomStore/index.js +18 -14
- package/lib/commonjs/roomStore/index.js.map +1 -1
- package/lib/commonjs/roomStore/persistBackend.js +96 -0
- package/lib/commonjs/roomStore/persistBackend.js.map +1 -0
- package/lib/commonjs/roomStore/persistence.js +245 -50
- package/lib/commonjs/roomStore/persistence.js.map +1 -1
- package/lib/commonjs/roomStore/roomsSlice.js +282 -136
- package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
- package/lib/commonjs/theme/theme.js +3 -0
- package/lib/commonjs/theme/theme.js.map +1 -1
- package/lib/commonjs/utils/devLogger.js +14 -0
- package/lib/commonjs/utils/devLogger.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/module/assets/emojiData.js +36 -0
- package/lib/module/assets/emojiData.js.map +1 -0
- package/lib/module/assets/icons.js +1 -1
- package/lib/module/assets/icons.js.map +1 -1
- package/lib/module/components/Header/HeaderRoomList.js +12 -7
- package/lib/module/components/Header/HeaderRoomList.js.map +1 -1
- package/lib/module/components/MainComponents/ChatHeader.js +8 -10
- package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/module/components/MainComponents/ChatRoom.js +49 -28
- package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/module/components/MainComponents/ChatWrapper.js +60 -23
- package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/KeyboardInputDock.js +33 -0
- package/lib/module/components/MainComponents/KeyboardInputDock.js.map +1 -0
- package/lib/module/components/MainComponents/MessageContainer.js +7 -14
- package/lib/module/components/MainComponents/MessageContainer.js.map +1 -1
- package/lib/module/components/MainComponents/MessageList.js +110 -35
- package/lib/module/components/MainComponents/MessageList.js.map +1 -1
- package/lib/module/components/MainComponents/RoomList.js +32 -29
- package/lib/module/components/MainComponents/RoomList.js.map +1 -1
- package/lib/module/components/MainComponents/RoomStack.js +266 -0
- package/lib/module/components/MainComponents/RoomStack.js.map +1 -0
- package/lib/module/components/MainComponents/SystemMessage.js +6 -2
- package/lib/module/components/MainComponents/SystemMessage.js.map +1 -1
- package/lib/module/components/MessageBubble/Avatar.js +5 -1
- package/lib/module/components/MessageBubble/Avatar.js.map +1 -1
- package/lib/module/components/MessageBubble/BottomReplyContainer.js +18 -22
- package/lib/module/components/MessageBubble/BottomReplyContainer.js.map +1 -1
- package/lib/module/components/MessageBubble/EmojiPickerSheet.js +438 -0
- package/lib/module/components/MessageBubble/EmojiPickerSheet.js.map +1 -0
- package/lib/module/components/MessageBubble/Message.js +203 -134
- package/lib/module/components/MessageBubble/Message.js.map +1 -1
- package/lib/module/components/MessageBubble/MessageInteractions.js +215 -14
- package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
- package/lib/module/components/MessageBubble/MessageReaction.js +115 -94
- package/lib/module/components/MessageBubble/MessageReaction.js.map +1 -1
- package/lib/module/components/MessageBubble/MessageReply.js +65 -24
- package/lib/module/components/MessageBubble/MessageReply.js.map +1 -1
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js +6 -1
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/module/components/Modals/Modal/Modal.js +25 -1
- package/lib/module/components/Modals/Modal/Modal.js.map +1 -1
- package/lib/module/components/Modals/Modal/SwipeBackLayer.js +172 -0
- package/lib/module/components/Modals/Modal/SwipeBackLayer.js.map +1 -0
- package/lib/module/components/Modals/ProfileHeader/ProfileHeader.js +29 -11
- package/lib/module/components/Modals/ProfileHeader/ProfileHeader.js.map +1 -1
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +10 -4
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/module/components/RoomComponents/ChatRoomItem.js +5 -4
- package/lib/module/components/RoomComponents/ChatRoomItem.js.map +1 -1
- package/lib/module/components/RoomComponents/styled/LastMessageEmoji.js +8 -9
- package/lib/module/components/RoomComponents/styled/LastMessageEmoji.js.map +1 -1
- package/lib/module/components/Thread/ThreadWrapper.js +264 -152
- package/lib/module/components/Thread/ThreadWrapper.js.map +1 -1
- package/lib/module/components/styled/DateLabel.js +6 -3
- package/lib/module/components/styled/DateLabel.js.map +1 -1
- package/lib/module/context/MessageNotificationContext.js +190 -11
- package/lib/module/context/MessageNotificationContext.js.map +1 -1
- package/lib/module/context/xmppProvider.js +22 -7
- package/lib/module/context/xmppProvider.js.map +1 -1
- package/lib/module/helpers/createRoomFromApi.js +36 -2
- package/lib/module/helpers/createRoomFromApi.js.map +1 -1
- package/lib/module/helpers/emoji.js +44 -0
- package/lib/module/helpers/emoji.js.map +1 -0
- package/lib/module/helpers/haptics.js +24 -0
- package/lib/module/helpers/haptics.js.map +1 -0
- package/lib/module/helpers/historyPreloadScheduler.js +32 -66
- package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/module/helpers/insertMessageWithDelimiter.js +21 -12
- package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
- package/lib/module/helpers/keyboardLayout.js +20 -0
- package/lib/module/helpers/keyboardLayout.js.map +1 -1
- package/lib/module/helpers/mamReactions.js +51 -0
- package/lib/module/helpers/mamReactions.js.map +1 -0
- package/lib/module/helpers/parseMessageReference.js +37 -0
- package/lib/module/helpers/parseMessageReference.js.map +1 -0
- package/lib/module/helpers/reactionsConfig.js +10 -0
- package/lib/module/helpers/reactionsConfig.js.map +1 -0
- package/lib/module/helpers/updateMessagesTillLast.js +17 -2
- package/lib/module/helpers/updateMessagesTillLast.js.map +1 -1
- package/lib/module/hooks/useHeapSender.js +3 -1
- package/lib/module/hooks/useHeapSender.js.map +1 -1
- package/lib/module/hooks/useMessageHeapState.js +3 -2
- package/lib/module/hooks/useMessageHeapState.js.map +1 -1
- package/lib/module/hooks/useRoomInitialization.js +17 -8
- package/lib/module/hooks/useRoomInitialization.js.map +1 -1
- package/lib/module/hooks/useSendMessage.js +14 -8
- package/lib/module/hooks/useSendMessage.js.map +1 -1
- package/lib/module/hooks/useUnreadMessagesCounter.js +1 -1
- package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
- package/lib/module/networking/stanzaHandlers.js +107 -51
- package/lib/module/networking/stanzaHandlers.js.map +1 -1
- package/lib/module/networking/xmpp/getHistory.xmpp.js +29 -74
- package/lib/module/networking/xmpp/getHistory.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/handleStanzas.xmpp.js +4 -0
- package/lib/module/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/mamRouter.js +175 -0
- package/lib/module/networking/xmpp/mamRouter.js.map +1 -0
- package/lib/module/networking/xmpp/presenceInRoom.xmpp.js +38 -2
- package/lib/module/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
- package/lib/module/networking/xmppClient.js +99 -24
- package/lib/module/networking/xmppClient.js.map +1 -1
- package/lib/module/roomStore/Middleware/newMessageMidlleware.js +29 -34
- package/lib/module/roomStore/Middleware/newMessageMidlleware.js.map +1 -1
- package/lib/module/roomStore/Middleware/perfMiddleware.js +45 -0
- package/lib/module/roomStore/Middleware/perfMiddleware.js.map +1 -0
- package/lib/module/roomStore/Middleware/reactionsMiddleware.js +66 -43
- package/lib/module/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
- package/lib/module/roomStore/Middleware/unreadMidlleware.js +89 -69
- package/lib/module/roomStore/Middleware/unreadMidlleware.js.map +1 -1
- package/lib/module/roomStore/index.js +19 -15
- package/lib/module/roomStore/index.js.map +1 -1
- package/lib/module/roomStore/persistBackend.js +89 -0
- package/lib/module/roomStore/persistBackend.js.map +1 -0
- package/lib/module/roomStore/persistence.js +245 -48
- package/lib/module/roomStore/persistence.js.map +1 -1
- package/lib/module/roomStore/roomsSlice.js +275 -134
- package/lib/module/roomStore/roomsSlice.js.map +1 -1
- package/lib/module/theme/theme.js +3 -0
- package/lib/module/theme/theme.js.map +1 -1
- package/lib/module/utils/devLogger.js +13 -0
- package/lib/module/utils/devLogger.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/typescript/assets/emojiData.d.ts +8 -0
- package/lib/typescript/assets/emojiData.d.ts.map +1 -0
- package/lib/typescript/components/Header/HeaderRoomList.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/KeyboardInputDock.d.ts +16 -0
- package/lib/typescript/components/MainComponents/KeyboardInputDock.d.ts.map +1 -0
- package/lib/typescript/components/MainComponents/MessageContainer.d.ts +2 -2
- 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/RoomList.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/RoomStack.d.ts +42 -0
- package/lib/typescript/components/MainComponents/RoomStack.d.ts.map +1 -0
- package/lib/typescript/components/MainComponents/SystemMessage.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/Avatar.d.ts +2 -0
- package/lib/typescript/components/MessageBubble/Avatar.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/BottomReplyContainer.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/EmojiPickerSheet.d.ts +11 -0
- package/lib/typescript/components/MessageBubble/EmojiPickerSheet.d.ts.map +1 -0
- package/lib/typescript/components/MessageBubble/Message.d.ts +2 -2
- package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts +2 -0
- package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/MessageReaction.d.ts +1 -0
- package/lib/typescript/components/MessageBubble/MessageReaction.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/MessageReply.d.ts +7 -7
- package/lib/typescript/components/MessageBubble/MessageReply.d.ts.map +1 -1
- package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/Modal/Modal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/Modal/SwipeBackLayer.d.ts +16 -0
- package/lib/typescript/components/Modals/Modal/SwipeBackLayer.d.ts.map +1 -0
- package/lib/typescript/components/Modals/ProfileHeader/ProfileHeader.d.ts.map +1 -1
- package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts +2 -2
- package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/styled/LastMessageEmoji.d.ts +3 -6
- package/lib/typescript/components/RoomComponents/styled/LastMessageEmoji.d.ts.map +1 -1
- package/lib/typescript/components/Thread/ThreadWrapper.d.ts +7 -1
- package/lib/typescript/components/Thread/ThreadWrapper.d.ts.map +1 -1
- package/lib/typescript/components/styled/DateLabel.d.ts +1 -0
- package/lib/typescript/components/styled/DateLabel.d.ts.map +1 -1
- package/lib/typescript/context/MessageNotificationContext.d.ts.map +1 -1
- package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
- package/lib/typescript/helpers/createRoomFromApi.d.ts.map +1 -1
- package/lib/typescript/helpers/emoji.d.ts +6 -0
- package/lib/typescript/helpers/emoji.d.ts.map +1 -0
- package/lib/typescript/helpers/haptics.d.ts +3 -0
- package/lib/typescript/helpers/haptics.d.ts.map +1 -0
- package/lib/typescript/helpers/historyPreloadScheduler.d.ts +1 -0
- 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 +6 -0
- package/lib/typescript/helpers/keyboardLayout.d.ts.map +1 -1
- package/lib/typescript/helpers/mamReactions.d.ts +13 -0
- package/lib/typescript/helpers/mamReactions.d.ts.map +1 -0
- package/lib/typescript/helpers/parseMessageReference.d.ts +16 -0
- package/lib/typescript/helpers/parseMessageReference.d.ts.map +1 -0
- package/lib/typescript/helpers/reactionsConfig.d.ts +5 -0
- package/lib/typescript/helpers/reactionsConfig.d.ts.map +1 -0
- package/lib/typescript/helpers/updateMessagesTillLast.d.ts.map +1 -1
- package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
- package/lib/typescript/hooks/useMessageHeapState.d.ts.map +1 -1
- package/lib/typescript/hooks/useRoomInitialization.d.ts +2 -2
- package/lib/typescript/hooks/useRoomInitialization.d.ts.map +1 -1
- package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/networking/stanzaHandlers.d.ts +4 -2
- package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts +3 -1
- package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/mamRouter.d.ts +23 -0
- package/lib/typescript/networking/xmpp/mamRouter.d.ts.map +1 -0
- package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts +1 -0
- package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmppClient.d.ts +22 -1
- package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
- package/lib/typescript/roomStore/Middleware/newMessageMidlleware.d.ts.map +1 -1
- package/lib/typescript/roomStore/Middleware/perfMiddleware.d.ts +4 -0
- package/lib/typescript/roomStore/Middleware/perfMiddleware.d.ts.map +1 -0
- package/lib/typescript/roomStore/Middleware/reactionsMiddleware.d.ts +9 -0
- package/lib/typescript/roomStore/Middleware/reactionsMiddleware.d.ts.map +1 -1
- package/lib/typescript/roomStore/Middleware/unreadMidlleware.d.ts.map +1 -1
- package/lib/typescript/roomStore/index.d.ts.map +1 -1
- package/lib/typescript/roomStore/persistBackend.d.ts +11 -0
- package/lib/typescript/roomStore/persistBackend.d.ts.map +1 -0
- package/lib/typescript/roomStore/persistence.d.ts +5 -6
- package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts +41 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
- package/lib/typescript/theme/theme.d.ts +4 -1
- package/lib/typescript/theme/theme.d.ts.map +1 -1
- package/lib/typescript/types/models/message.model.d.ts +4 -0
- package/lib/typescript/types/models/message.model.d.ts.map +1 -1
- package/lib/typescript/types/models/room.model.d.ts +16 -0
- package/lib/typescript/types/models/room.model.d.ts.map +1 -1
- package/lib/typescript/types/models/xmpp.model.d.ts +6 -1
- package/lib/typescript/types/models/xmpp.model.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +15 -3
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/lib/typescript/utils/devLogger.d.ts +8 -0
- package/lib/typescript/utils/devLogger.d.ts.map +1 -1
- package/lib/typescript/version.d.ts +1 -1
- package/package.json +10 -1
- package/src/assets/emojiData.ts +2146 -0
- package/src/assets/icons.tsx +5 -5
- package/src/components/Header/HeaderRoomList.tsx +7 -5
- package/src/components/MainComponents/ChatHeader.tsx +16 -7
- package/src/components/MainComponents/ChatRoom.tsx +64 -32
- package/src/components/MainComponents/ChatWrapper.tsx +73 -21
- package/src/components/MainComponents/KeyboardInputDock.tsx +47 -0
- package/src/components/MainComponents/MessageContainer.tsx +7 -15
- package/src/components/MainComponents/MessageList.tsx +96 -43
- package/src/components/MainComponents/RoomList.tsx +28 -29
- package/src/components/MainComponents/RoomStack.tsx +309 -0
- package/src/components/MainComponents/SystemMessage.tsx +6 -2
- package/src/components/MessageBubble/Avatar.tsx +7 -1
- package/src/components/MessageBubble/BottomReplyContainer.tsx +19 -21
- package/src/components/MessageBubble/EmojiPickerSheet.tsx +468 -0
- package/src/components/MessageBubble/Message.tsx +146 -87
- package/src/components/MessageBubble/MessageInteractions.tsx +213 -12
- package/src/components/MessageBubble/MessageReaction.tsx +120 -96
- package/src/components/MessageBubble/MessageReply.tsx +65 -32
- package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +4 -0
- package/src/components/Modals/Modal/Modal.tsx +32 -1
- package/src/components/Modals/Modal/SwipeBackLayer.tsx +221 -0
- package/src/components/Modals/ProfileHeader/ProfileHeader.tsx +29 -8
- package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +6 -3
- package/src/components/RoomComponents/ChatRoomItem.tsx +11 -4
- package/src/components/RoomComponents/styled/LastMessageEmoji.tsx +7 -8
- package/src/components/Thread/ThreadWrapper.tsx +274 -198
- package/src/components/styled/DateLabel.tsx +7 -3
- package/src/context/MessageNotificationContext.tsx +205 -7
- package/src/context/xmppProvider.tsx +29 -9
- package/src/helpers/createRoomFromApi.tsx +37 -1
- package/src/helpers/emoji.ts +39 -0
- package/src/helpers/haptics.ts +19 -0
- package/src/helpers/historyPreloadScheduler.ts +37 -69
- package/src/helpers/insertMessageWithDelimiter.ts +23 -16
- package/src/helpers/keyboardLayout.ts +26 -0
- package/src/helpers/mamReactions.ts +59 -0
- package/src/helpers/parseMessageReference.ts +38 -0
- package/src/helpers/reactionsConfig.ts +13 -0
- package/src/helpers/updateMessagesTillLast.tsx +14 -2
- package/src/hooks/useHeapSender.tsx +3 -2
- package/src/hooks/useMessageHeapState.tsx +6 -2
- package/src/hooks/useRoomInitialization.tsx +32 -15
- package/src/hooks/useSendMessage.tsx +18 -11
- package/src/hooks/useUnreadMessagesCounter.ts +1 -1
- package/src/networking/stanzaHandlers.ts +116 -60
- package/src/networking/xmpp/getHistory.xmpp.ts +44 -106
- package/src/networking/xmpp/handleStanzas.xmpp.ts +2 -0
- package/src/networking/xmpp/mamRouter.ts +176 -0
- package/src/networking/xmpp/presenceInRoom.xmpp.ts +46 -3
- package/src/networking/xmppClient.ts +105 -20
- package/src/roomStore/Middleware/newMessageMidlleware.tsx +35 -38
- package/src/roomStore/Middleware/perfMiddleware.ts +50 -0
- package/src/roomStore/Middleware/reactionsMiddleware.tsx +53 -52
- package/src/roomStore/Middleware/unreadMidlleware.tsx +92 -80
- package/src/roomStore/index.ts +28 -27
- package/src/roomStore/persistBackend.ts +96 -0
- package/src/roomStore/persistence.ts +280 -73
- package/src/roomStore/roomsSlice.ts +304 -155
- package/src/theme/theme.ts +10 -1
- package/src/types/models/message.model.ts +4 -0
- package/src/types/models/room.model.ts +17 -0
- package/src/types/models/xmpp.model.ts +4 -2
- package/src/types/types.ts +15 -3
- package/src/utils/devLogger.ts +16 -0
- package/src/version.ts +1 -1
|
@@ -6,10 +6,44 @@ let presenceIdCounter = 0;
|
|
|
6
6
|
const nextPresenceId = () =>
|
|
7
7
|
`presenceInRoom-${Date.now().toString(36)}-${(++presenceIdCounter).toString(36)}`;
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
const joinedByClient = new WeakMap<Client, Map<string, Promise<Element>>>();
|
|
10
|
+
|
|
11
|
+
const joinedRooms = (client: Client): Map<string, Promise<Element>> => {
|
|
12
|
+
let map = joinedByClient.get(client);
|
|
13
|
+
if (!map) {
|
|
14
|
+
map = new Map();
|
|
15
|
+
joinedByClient.set(client, map);
|
|
16
|
+
const forget = () => joinedByClient.get(client)?.clear();
|
|
17
|
+
client.on('disconnect', forget);
|
|
18
|
+
client.on('offline', forget);
|
|
19
|
+
}
|
|
20
|
+
return map;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const __forgetJoinedRooms = (client: Client) =>
|
|
24
|
+
joinedByClient.get(client)?.clear();
|
|
25
|
+
|
|
26
|
+
export const presenceInRoom = (
|
|
27
|
+
client: Client,
|
|
28
|
+
roomJID: string,
|
|
29
|
+
delay = 0
|
|
30
|
+
): Promise<Element> => {
|
|
31
|
+
const joined = joinedRooms(client);
|
|
32
|
+
const existing = joined.get(roomJID);
|
|
33
|
+
if (existing) {return existing;}
|
|
34
|
+
const join = joinRoom(client, roomJID, delay);
|
|
35
|
+
joined.set(roomJID, join);
|
|
36
|
+
// A failed join is not a join: let the next caller try again.
|
|
37
|
+
join.catch(() => {
|
|
38
|
+
if (joined.get(roomJID) === join) {joined.delete(roomJID);}
|
|
39
|
+
});
|
|
40
|
+
return join;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const joinRoom = async (
|
|
10
44
|
client: Client,
|
|
11
45
|
roomJID: string,
|
|
12
|
-
delay
|
|
46
|
+
delay: number
|
|
13
47
|
): Promise<Element> => {
|
|
14
48
|
let stanzaHandler: (stanza: Element) => void;
|
|
15
49
|
const unsubscribe = () => client.off('stanza', stanzaHandler);
|
|
@@ -27,6 +61,11 @@ export const presenceInRoom = async (
|
|
|
27
61
|
if (settled) {return;}
|
|
28
62
|
settled = true;
|
|
29
63
|
|
|
64
|
+
if (delay <= 0) {
|
|
65
|
+
unsubscribe();
|
|
66
|
+
cb(value);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
30
69
|
setTimeout(() => {
|
|
31
70
|
unsubscribe();
|
|
32
71
|
cb(value);
|
|
@@ -52,7 +91,11 @@ export const presenceInRoom = async (
|
|
|
52
91
|
to: `${roomJID}/${client.jid?.getLocal()}`,
|
|
53
92
|
id: stanzaId,
|
|
54
93
|
},
|
|
55
|
-
xml(
|
|
94
|
+
xml(
|
|
95
|
+
'x',
|
|
96
|
+
{ xmlns: 'http://jabber.org/protocol/muc' },
|
|
97
|
+
xml('history', { maxstanzas: '0' })
|
|
98
|
+
)
|
|
56
99
|
);
|
|
57
100
|
|
|
58
101
|
// Side-effects sequence: send the presence (handles its own
|
|
@@ -10,6 +10,7 @@ import { sendTypingRequest } from './xmpp/sendTypingRequest.xmpp';
|
|
|
10
10
|
import { sendPing } from './xmpp/sendPing.xmpp';
|
|
11
11
|
import { getHistory } from './xmpp/getHistory.xmpp';
|
|
12
12
|
import { sendTextMessage } from './xmpp/sendTextMessage.xmpp';
|
|
13
|
+
import { sendMessageReaction } from './xmpp/sendMessageReaction.xmpp';
|
|
13
14
|
import { sendTextMessageWithTranslateTag } from './xmpp/sendTextMessageWithTranslateTag.xmpp';
|
|
14
15
|
import { deleteMessage } from './xmpp/deleteMessage.xmpp';
|
|
15
16
|
import { presenceInRoom } from './xmpp/presenceInRoom.xmpp';
|
|
@@ -23,7 +24,7 @@ import { editMessage } from './xmpp/editMessage.xmpp';
|
|
|
23
24
|
import { inviteRoomRequest } from './xmpp/inviteRoomRequest.xmpp';
|
|
24
25
|
import { getRooms } from './xmpp/getRooms.xmpp';
|
|
25
26
|
import { handleStanza } from './xmpp/handleStanzas.xmpp';
|
|
26
|
-
import { pushLog as devPushLog } from '../utils/devLogger';
|
|
27
|
+
import { pushLog as devPushLog, isDevLogActive } from '../utils/devLogger';
|
|
27
28
|
import { normalizeRoomJid } from '../helpers/normalizeRoomJid';
|
|
28
29
|
import { store } from '../roomStore';
|
|
29
30
|
import { applyPrivateStoreMarkers } from '../roomStore/roomsSlice';
|
|
@@ -69,6 +70,11 @@ function withTimeout(promise: Promise<unknown>, ms: number): Promise<void> {
|
|
|
69
70
|
// where it fails — XMPPError on stream:error, SASLError on SASL bind, or
|
|
70
71
|
// a generic Error whose message contains "not-authorized". Match all of
|
|
71
72
|
// them so we trigger the credentials refresh path consistently.
|
|
73
|
+
// Failed XMPP-password recoveries in a row before the session is ended.
|
|
74
|
+
const AUTH_RECOVERY_MAX_FAILURES = 2;
|
|
75
|
+
// Rejections (each with a fresh password) before the password counts as lost.
|
|
76
|
+
const AUTH_REJECTIONS_LIMIT = 3;
|
|
77
|
+
|
|
72
78
|
function isNotAuthorizedError(err: any): boolean {
|
|
73
79
|
if (!err) {return false;}
|
|
74
80
|
const condition =
|
|
@@ -90,6 +96,10 @@ interface HistoryOptions {
|
|
|
90
96
|
coalesceRoom?: boolean;
|
|
91
97
|
skipIfPreloaded?: boolean;
|
|
92
98
|
source?: HistorySource;
|
|
99
|
+
/** The caller merges the returned page into the store itself (the
|
|
100
|
+
* preload scheduler and the catch-up pass do, to detect gaps); the MAM
|
|
101
|
+
* router then does not apply it. Default: applied by the router. */
|
|
102
|
+
selfApplied?: boolean;
|
|
93
103
|
}
|
|
94
104
|
|
|
95
105
|
interface MamInFlightEntry {
|
|
@@ -185,6 +195,42 @@ export class XmppClient {
|
|
|
185
195
|
* (REST JWT, /users/client, etc.) and returning the resulting
|
|
186
196
|
* username + password.
|
|
187
197
|
*/
|
|
198
|
+
/**
|
|
199
|
+
* Called once when the session's XMPP password is lost for good: the
|
|
200
|
+
* server rejected it (SASL not-authorized) and the refresh chain could
|
|
201
|
+
* not produce a working one — the refresh request failed, came back
|
|
202
|
+
* without a new password, or the new one was rejected too. Network
|
|
203
|
+
* outages never get here (no rejection without a reachable server).
|
|
204
|
+
*/
|
|
205
|
+
private authLostHandler: (() => void) | null = null;
|
|
206
|
+
private authRecoveryFailures = 0;
|
|
207
|
+
private authLostFired = false;
|
|
208
|
+
// Rejections since the stream was last online — catches a refresh that
|
|
209
|
+
// keeps returning NEW passwords the server still rejects.
|
|
210
|
+
private authRejectionsSinceOnline = 0;
|
|
211
|
+
|
|
212
|
+
setAuthLostHandler(handler: (() => void) | null) {
|
|
213
|
+
this.authLostHandler = handler;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private markAuthRecoveryFailed(reason: string) {
|
|
217
|
+
this.authRecoveryFailures += 1;
|
|
218
|
+
console.warn(
|
|
219
|
+
`[xmpp] XMPP password recovery failed (${reason}), attempt ${this.authRecoveryFailures}`
|
|
220
|
+
);
|
|
221
|
+
// One retry before giving up, so a single REST hiccup does not end the
|
|
222
|
+
// session; a second failure in a row means the password is gone.
|
|
223
|
+
if (this.authRecoveryFailures >= AUTH_RECOVERY_MAX_FAILURES && !this.authLostFired) {
|
|
224
|
+
this.authLostFired = true;
|
|
225
|
+
this.suppressReconnect = true;
|
|
226
|
+
try {
|
|
227
|
+
this.authLostHandler?.();
|
|
228
|
+
} catch (e) {
|
|
229
|
+
console.warn('[xmpp] auth-lost handler threw', e);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
188
234
|
setCredentialsProvider(provider: XmppCredentialsProvider | null) {
|
|
189
235
|
this.credentialsProvider = provider;
|
|
190
236
|
}
|
|
@@ -286,8 +332,9 @@ export class XmppClient {
|
|
|
286
332
|
before?: number;
|
|
287
333
|
id?: string;
|
|
288
334
|
source?: HistorySource;
|
|
335
|
+
selfApplied?: boolean;
|
|
289
336
|
}): Promise<any> {
|
|
290
|
-
const { chatJID, max, before, id, source = 'default' } = params;
|
|
337
|
+
const { chatJID, max, before, id, source = 'default', selfApplied } = params;
|
|
291
338
|
|
|
292
339
|
// Coalesce — if a fetch for the same room is in-flight, reuse it
|
|
293
340
|
// unless the new request is higher priority.
|
|
@@ -315,7 +362,9 @@ export class XmppClient {
|
|
|
315
362
|
const handle: { p?: Promise<any> } = {};
|
|
316
363
|
handle.p = (async () => {
|
|
317
364
|
try {
|
|
318
|
-
return await getHistory(this.client, chatJID, max, before, id
|
|
365
|
+
return await getHistory(this.client, chatJID, max, before, id, {
|
|
366
|
+
selfApplied,
|
|
367
|
+
});
|
|
319
368
|
} finally {
|
|
320
369
|
const cur = this.mamInFlightByRoom.get(chatJID);
|
|
321
370
|
if (cur && cur.promise === handle.p) {
|
|
@@ -383,7 +432,7 @@ export class XmppClient {
|
|
|
383
432
|
// Raising the cap silences the warning without masking real leaks
|
|
384
433
|
// — true leaks would still grow unboundedly past this number.
|
|
385
434
|
try {
|
|
386
|
-
(this.client as any)?.setMaxListeners?.(
|
|
435
|
+
(this.client as any)?.setMaxListeners?.(120);
|
|
387
436
|
} catch {}
|
|
388
437
|
|
|
389
438
|
// Wrap `send` so the dev logger sees outgoing stanzas too.
|
|
@@ -395,7 +444,7 @@ export class XmppClient {
|
|
|
395
444
|
const origSend = this.client.send?.bind(this.client);
|
|
396
445
|
if (origSend) {
|
|
397
446
|
const wrapped = (stanza: any) => {
|
|
398
|
-
try {
|
|
447
|
+
if (isDevLogActive()) {try {
|
|
399
448
|
const tag = stanza?.name || 'stanza';
|
|
400
449
|
const id = stanza?.attrs?.id || '';
|
|
401
450
|
const to = stanza?.attrs?.to || '';
|
|
@@ -404,7 +453,7 @@ export class XmppClient {
|
|
|
404
453
|
`→ ${tag}${id ? ` id=${id}` : ''}${to ? ` to=${to.split('/')[0]}` : ''}`,
|
|
405
454
|
stanza?.toString ? stanza.toString() : undefined
|
|
406
455
|
);
|
|
407
|
-
} catch {}
|
|
456
|
+
} catch {}}
|
|
408
457
|
const result = origSend(stanza);
|
|
409
458
|
// Most stanza helpers fire-and-forget `client.send(...)`
|
|
410
459
|
// without awaiting/catching. On @xmpp/client builds where
|
|
@@ -438,6 +487,7 @@ export class XmppClient {
|
|
|
438
487
|
console.error('Error starting xmpp client:', error);
|
|
439
488
|
if (isNotAuthorizedError(error)) {
|
|
440
489
|
this.lastAuthError = 'not-authorized';
|
|
490
|
+
this.authRejectionsSinceOnline += 1;
|
|
441
491
|
}
|
|
442
492
|
this.status = 'error';
|
|
443
493
|
// A connect-time failure lands in 'error', which — unlike a
|
|
@@ -497,6 +547,8 @@ export class XmppClient {
|
|
|
497
547
|
this.onOnline = () => {
|
|
498
548
|
console.log('XMPP online.', new Date());
|
|
499
549
|
this.status = 'online';
|
|
550
|
+
this.authRecoveryFailures = 0;
|
|
551
|
+
this.authRejectionsSinceOnline = 0;
|
|
500
552
|
this.presencesReady = true;
|
|
501
553
|
this.reconnectAttempts = 0;
|
|
502
554
|
try {
|
|
@@ -534,6 +586,7 @@ export class XmppClient {
|
|
|
534
586
|
console.error('XMPP client error:', error);
|
|
535
587
|
if (isNotAuthorizedError(error)) {
|
|
536
588
|
this.lastAuthError = 'not-authorized';
|
|
589
|
+
this.authRejectionsSinceOnline += 1;
|
|
537
590
|
}
|
|
538
591
|
try {
|
|
539
592
|
devPushLog(
|
|
@@ -545,7 +598,7 @@ export class XmppClient {
|
|
|
545
598
|
};
|
|
546
599
|
|
|
547
600
|
this.onStanza = (stanza: any) => {
|
|
548
|
-
try {
|
|
601
|
+
if (isDevLogActive()) {try {
|
|
549
602
|
const tag = stanza?.name || 'stanza';
|
|
550
603
|
const id = stanza?.attrs?.id || '';
|
|
551
604
|
const from = stanza?.attrs?.from || '';
|
|
@@ -555,7 +608,7 @@ export class XmppClient {
|
|
|
555
608
|
`← ${tag}${id ? ` id=${id}` : ''}${type ? ` type=${type}` : ''}${from ? ` from=${from.split('/')[0]}` : ''}`,
|
|
556
609
|
stanza?.toString ? stanza.toString() : undefined
|
|
557
610
|
);
|
|
558
|
-
} catch {}
|
|
611
|
+
} catch {}}
|
|
559
612
|
handleStanza.bind(this, stanza, this)();
|
|
560
613
|
};
|
|
561
614
|
|
|
@@ -739,16 +792,29 @@ export class XmppClient {
|
|
|
739
792
|
CREDENTIALS_REFRESH_MIN_INTERVAL_MS;
|
|
740
793
|
|
|
741
794
|
if (this.credentialsProvider && (authFailed || staleCreds)) {
|
|
795
|
+
const rejectedPassword = authFailed ? this.password : null;
|
|
742
796
|
try {
|
|
743
797
|
await this.refreshCredentialsOnce();
|
|
798
|
+
// The server said this password is wrong and the refresh handed
|
|
799
|
+
// back nothing new: there is no working password to connect with.
|
|
800
|
+
if (rejectedPassword !== null && (!this.password || this.password === rejectedPassword)) {
|
|
801
|
+
this.markAuthRecoveryFailed('no new XMPP password after refresh');
|
|
802
|
+
} else if (this.authRejectionsSinceOnline >= AUTH_REJECTIONS_LIMIT) {
|
|
803
|
+
this.markAuthRecoveryFailed('refreshed XMPP password rejected again');
|
|
804
|
+
}
|
|
744
805
|
} catch (err) {
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
806
|
+
if (rejectedPassword !== null) {
|
|
807
|
+
this.markAuthRecoveryFailed('refresh request failed');
|
|
808
|
+
} else {
|
|
809
|
+
// Offline is the common case here — reconnect with what we
|
|
810
|
+
// have and let the next attempt try again.
|
|
811
|
+
console.warn(
|
|
812
|
+
'XMPP credential refresh failed; reconnecting with cached creds',
|
|
813
|
+
err
|
|
814
|
+
);
|
|
815
|
+
}
|
|
751
816
|
}
|
|
817
|
+
if (this.suppressReconnect) {return;}
|
|
752
818
|
}
|
|
753
819
|
|
|
754
820
|
// Tear the OLD underlying client down FULLY before spinning up a new
|
|
@@ -903,6 +969,16 @@ export class XmppClient {
|
|
|
903
969
|
}
|
|
904
970
|
|
|
905
971
|
getRoomsStanza = async () => {
|
|
972
|
+
// Asked while the socket is down (mid-reconnect) this used to throw
|
|
973
|
+
// "Cannot read property 'write' of null". Wait for the stream instead;
|
|
974
|
+
// if it does not come back, skip — the reconnect hook re-syncs rooms.
|
|
975
|
+
if (this.status !== 'online') {
|
|
976
|
+
try {
|
|
977
|
+
await this.waitForOnline(15000);
|
|
978
|
+
} catch {
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
906
982
|
await getRooms(this.client);
|
|
907
983
|
};
|
|
908
984
|
|
|
@@ -938,9 +1014,12 @@ export class XmppClient {
|
|
|
938
1014
|
before,
|
|
939
1015
|
id,
|
|
940
1016
|
source: options?.source || 'default',
|
|
1017
|
+
selfApplied: options?.selfApplied,
|
|
941
1018
|
});
|
|
942
1019
|
}
|
|
943
|
-
return await getHistory(this.client, chatJID, max, before, id
|
|
1020
|
+
return await getHistory(this.client, chatJID, max, before, id, {
|
|
1021
|
+
selfApplied: options?.selfApplied,
|
|
1022
|
+
});
|
|
944
1023
|
};
|
|
945
1024
|
|
|
946
1025
|
getLastMessageArchiveStanza(roomJID: string) {
|
|
@@ -1194,12 +1273,18 @@ export class XmppClient {
|
|
|
1194
1273
|
}
|
|
1195
1274
|
|
|
1196
1275
|
sendMessageReactionStanza(
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1276
|
+
messageId: string,
|
|
1277
|
+
roomJid: string,
|
|
1278
|
+
reactionsList: string[],
|
|
1279
|
+
data?: { firstName?: string; lastName?: string }
|
|
1201
1280
|
) {
|
|
1202
|
-
|
|
1281
|
+
sendMessageReaction(
|
|
1282
|
+
this.client,
|
|
1283
|
+
messageId,
|
|
1284
|
+
normalizeRoomJid(roomJid, this.conference),
|
|
1285
|
+
reactionsList,
|
|
1286
|
+
data || {}
|
|
1287
|
+
);
|
|
1203
1288
|
}
|
|
1204
1289
|
|
|
1205
1290
|
// Sends a groupchat message carrying a `<translate source="xx"/>` tag so
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Middleware } from '@reduxjs/toolkit';
|
|
2
|
-
import { updateRoom } from '../roomsSlice';
|
|
3
2
|
import { clearMessageFailure } from '../roomHeapSlice';
|
|
4
3
|
import { removeOutboundSend } from '../../networking/outboundQueue';
|
|
5
|
-
import {
|
|
4
|
+
import { IMessage } from '../../types/types';
|
|
6
5
|
|
|
7
6
|
export const newMessageMidlleware: Middleware =
|
|
8
7
|
(storeAPI) => (next) => (action: any) => {
|
|
@@ -11,7 +10,9 @@ export const newMessageMidlleware: Middleware =
|
|
|
11
10
|
return next(action);
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
const isSingle = action.type === 'roomMessages/addRoomMessage';
|
|
14
|
+
const isBatch = action.type === 'roomMessages/addRoomMessages';
|
|
15
|
+
if (!isSingle && !isBatch) {
|
|
15
16
|
return next(action);
|
|
16
17
|
}
|
|
17
18
|
|
|
@@ -22,48 +23,44 @@ export const newMessageMidlleware: Middleware =
|
|
|
22
23
|
|
|
23
24
|
const result = next(action);
|
|
24
25
|
const state = storeAPI.getState();
|
|
25
|
-
const rooms: { [jid: string]: IRoom } = state.rooms.rooms;
|
|
26
|
-
|
|
27
|
-
const { roomJID, message } = action.payload;
|
|
28
|
-
|
|
29
|
-
// Un-fail on confirmed delivery. A server-confirmed copy (echo or MAM
|
|
30
|
-
// history, never `pending`) arriving for a message we'd flagged failed
|
|
31
|
-
// means the send actually went through — e.g. a slow send that completed
|
|
32
|
-
// just after the 5s watchdog window, or a queued auto-resend landing on
|
|
33
|
-
// reconnect. The failed flag is keyed by our optimistic/stanza id, which
|
|
34
|
-
// the echo carries back as `id`/`xmppId`, so clear it here and let the
|
|
35
|
-
// bubble flip to delivered instead of staying stuck on "Failed".
|
|
36
|
-
if (message && !message.pending) {
|
|
37
|
-
// The confirmed copy carries our optimistic/stanza id back as id/xmppId.
|
|
38
|
-
// Drop any still-buffered replay for it so a later reconnect flush can't
|
|
39
|
-
// re-send an already-delivered message.
|
|
40
|
-
removeOutboundSend(message.id);
|
|
41
|
-
removeOutboundSend(message.xmppId);
|
|
42
|
-
|
|
43
|
-
const failedMap = state.roomHeapSlice?.failedMessages || {};
|
|
44
|
-
const failedKey = [message.id, message.xmppId].find(
|
|
45
|
-
(k: string | undefined) => k && failedMap[k]
|
|
46
|
-
);
|
|
47
|
-
if (failedKey) {
|
|
48
|
-
storeAPI.dispatch(clearMessageFailure(failedKey as string));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
26
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
27
|
+
// `lastMessageTimestamp` is now bumped inside the reducer itself (no
|
|
28
|
+
// second `updateRoom` pass per message). What is left here are the
|
|
29
|
+
// side effects outside the rooms slice.
|
|
30
|
+
const messages: IMessage[] = isBatch
|
|
31
|
+
? action.payload.messages || []
|
|
32
|
+
: [action.payload.message];
|
|
33
|
+
const failedMap = state.roomHeapSlice?.failedMessages || {};
|
|
34
|
+
|
|
35
|
+
for (const message of messages) {
|
|
36
|
+
// Un-fail on confirmed delivery. A server-confirmed copy (echo or MAM
|
|
37
|
+
// history, never `pending`) arriving for a message we'd flagged failed
|
|
38
|
+
// means the send actually went through — e.g. a slow send that completed
|
|
39
|
+
// just after the 5s watchdog window, or a queued auto-resend landing on
|
|
40
|
+
// reconnect. The failed flag is keyed by our optimistic/stanza id, which
|
|
41
|
+
// the echo carries back as `id`/`xmppId`, so clear it here and let the
|
|
42
|
+
// bubble flip to delivered instead of staying stuck on "Failed".
|
|
43
|
+
if (message && !message.pending) {
|
|
44
|
+
// The confirmed copy carries our optimistic/stanza id back as id/xmppId.
|
|
45
|
+
// Drop any still-buffered replay for it so a later reconnect flush can't
|
|
46
|
+
// re-send an already-delivered message.
|
|
47
|
+
removeOutboundSend(message.id);
|
|
48
|
+
if (message.xmppId) {removeOutboundSend(message.xmppId);}
|
|
49
|
+
|
|
50
|
+
const failedKey = [message.id, message.xmppId].find(
|
|
51
|
+
(k: string | undefined) => k && failedMap[k]
|
|
52
|
+
);
|
|
53
|
+
if (failedKey) {
|
|
54
|
+
storeAPI.dispatch(clearMessageFailure(failedKey as string));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
59
57
|
}
|
|
60
58
|
|
|
61
59
|
return result;
|
|
62
60
|
};
|
|
63
61
|
|
|
64
62
|
// import { Middleware, PayloadAction } from '@reduxjs/toolkit';
|
|
65
|
-
// import {
|
|
66
|
-
// import { AddRoomMessageAction, IRoom } from '../../types/types';
|
|
63
|
+
// // import { AddRoomMessageAction, IRoom } from '../../types/types';
|
|
67
64
|
// import { nanoToMs } from '../../helpers/nanoToMs';
|
|
68
65
|
|
|
69
66
|
// export const newMessageMidlleware: Middleware =
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Middleware } from '@reduxjs/toolkit';
|
|
2
|
+
|
|
3
|
+
declare const __DEV__: boolean | undefined;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Dev-only store profiler: counts dispatches and the time the reducer +
|
|
7
|
+
* middleware chain spent on them, and prints a one-line summary every
|
|
8
|
+
* 10 s while there was activity. Reads as
|
|
9
|
+
* [perf] 10s: 143 actions, 212ms in store, top: roomMessages/addRoomMessages×12 (90ms) …
|
|
10
|
+
* No-op (and not even installed) in release builds.
|
|
11
|
+
*/
|
|
12
|
+
const WINDOW_MS = 10000;
|
|
13
|
+
|
|
14
|
+
let count = 0;
|
|
15
|
+
let totalMs = 0;
|
|
16
|
+
let byType: Record<string, { n: number; ms: number }> = {};
|
|
17
|
+
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
18
|
+
|
|
19
|
+
const flush = () => {
|
|
20
|
+
timer = null;
|
|
21
|
+
if (count === 0) {return;}
|
|
22
|
+
const top = Object.entries(byType)
|
|
23
|
+
.sort((a, b) => b[1].ms - a[1].ms)
|
|
24
|
+
.slice(0, 4)
|
|
25
|
+
.map(([type, v]) => `${type}×${v.n} (${v.ms.toFixed(0)}ms)`)
|
|
26
|
+
.join(', ');
|
|
27
|
+
console.log(
|
|
28
|
+
`[perf] ${WINDOW_MS / 1000}s: ${count} actions, ${totalMs.toFixed(0)}ms in store, top: ${top}`
|
|
29
|
+
);
|
|
30
|
+
count = 0;
|
|
31
|
+
totalMs = 0;
|
|
32
|
+
byType = {};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const perfMiddleware: Middleware = () => (next) => (action: any) => {
|
|
36
|
+
const start = Date.now();
|
|
37
|
+
const result = next(action);
|
|
38
|
+
const ms = Date.now() - start;
|
|
39
|
+
count += 1;
|
|
40
|
+
totalMs += ms;
|
|
41
|
+
const type = action?.type || '?';
|
|
42
|
+
const entry = byType[type] || (byType[type] = { n: 0, ms: 0 });
|
|
43
|
+
entry.n += 1;
|
|
44
|
+
entry.ms += ms;
|
|
45
|
+
if (!timer) {timer = setTimeout(flush, WINDOW_MS);}
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const isPerfProfilingEnabled = () =>
|
|
50
|
+
typeof __DEV__ !== 'undefined' && __DEV__ === true;
|
|
@@ -1,77 +1,78 @@
|
|
|
1
|
-
import { Middleware
|
|
1
|
+
import { Middleware } from '@reduxjs/toolkit';
|
|
2
2
|
import { updateRoom } from '../roomsSlice';
|
|
3
|
-
import {
|
|
4
|
-
import { nanoToMs } from '../../helpers/nanoToMs';
|
|
3
|
+
import { IMessage, IRoom } from '../../types/types';
|
|
5
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Keeps the room-list preview in step with reactions (as on web): the
|
|
7
|
+
* newest event in a room being a reaction shows "Ann: 👍"; a reactor
|
|
8
|
+
* clearing theirs puts the last real message back.
|
|
9
|
+
*
|
|
10
|
+
* Timestamps here are the server's stanza ids, the same unit as
|
|
11
|
+
* `lastMessageTimestamp` (set from message ids in the reducer), so a
|
|
12
|
+
* reaction older than the room's latest message never takes the preview.
|
|
13
|
+
*/
|
|
6
14
|
export const reactionsMiddleware: Middleware =
|
|
7
15
|
(storeAPI) => (next) => (action: any) => {
|
|
8
|
-
if (action
|
|
16
|
+
if (action?.type !== 'roomMessages/setReactions') {
|
|
9
17
|
return next(action);
|
|
10
18
|
}
|
|
11
|
-
|
|
12
19
|
if (!action.payload || typeof action.payload !== 'object') {
|
|
13
20
|
console.error('Invalid action payload for setReactions:', action);
|
|
14
21
|
return next(action);
|
|
15
22
|
}
|
|
16
|
-
|
|
17
23
|
const result = next(action);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
try {
|
|
25
|
+
const payload = action.payload || {};
|
|
26
|
+
const { roomJID, reactions, latestReactionTimestamp, data } = payload;
|
|
27
|
+
const room: IRoom | undefined = storeAPI.getState().rooms?.rooms?.[roomJID];
|
|
28
|
+
if (!room) {return result;}
|
|
22
29
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const newLastMessage =
|
|
26
|
-
rooms[roomJID].messages[rooms[roomJID].messages.length - 1];
|
|
30
|
+
const ts = Number(latestReactionTimestamp) || 0;
|
|
31
|
+
const roomTs = Number(room.lastMessageTimestamp) || 0;
|
|
27
32
|
|
|
33
|
+
if (Array.isArray(reactions) && reactions[0]) {
|
|
34
|
+
// Only the newest event in the room may become the preview.
|
|
35
|
+
if (!ts || ts < roomTs) {return result;}
|
|
36
|
+
const name = `${data?.senderFirstName || ''} ${data?.senderLastName || ''}`.trim();
|
|
28
37
|
storeAPI.dispatch(
|
|
29
38
|
updateRoom({
|
|
30
39
|
jid: roomJID,
|
|
31
40
|
updates: {
|
|
32
|
-
lastMessageTimestamp:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
lastMessageTimestamp: ts,
|
|
42
|
+
lastMessage: {
|
|
43
|
+
id: `reaction-${ts}`,
|
|
44
|
+
body: reactions[0],
|
|
45
|
+
emoji: reactions[0],
|
|
46
|
+
user: { id: `emoji-${ts}`, name },
|
|
47
|
+
date: new Date(Math.floor(ts / 1000)).toISOString(),
|
|
48
|
+
} as any,
|
|
36
49
|
},
|
|
37
50
|
})
|
|
38
51
|
);
|
|
39
|
-
|
|
40
|
-
const updates = {
|
|
41
|
-
lastMessageTimestamp: nanoToMs(latestReactionTimestamp) ?? 0,
|
|
42
|
-
lastMessage: {
|
|
43
|
-
...rest,
|
|
44
|
-
body: reactions[0],
|
|
45
|
-
emoji: reactions[0],
|
|
46
|
-
user: {
|
|
47
|
-
name: `${data.senderFirstName} ${data.senderLastName}`,
|
|
48
|
-
id: `emoji-${new Date().toString()}`,
|
|
49
|
-
},
|
|
50
|
-
date: new Date(nanoToMs(latestReactionTimestamp) ?? 0).toISOString(),
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
storeAPI.dispatch(
|
|
55
|
-
updateRoom({
|
|
56
|
-
jid: roomJID,
|
|
57
|
-
updates: updates as any,
|
|
58
|
-
})
|
|
59
|
-
);
|
|
52
|
+
return result;
|
|
60
53
|
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
if (!rooms[roomJID]) {
|
|
64
|
-
console.warn(`Room ${roomJID} not found in reactions middleware`);
|
|
65
|
-
return result;
|
|
66
|
-
}
|
|
67
54
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
55
|
+
// A reaction was cleared: if the preview was a reaction, fall back to
|
|
56
|
+
// the newest real message (the room may have none loaded yet).
|
|
57
|
+
if (!(room.lastMessage as any)?.emoji) {return result;}
|
|
58
|
+
const messages: IMessage[] = room.messages || [];
|
|
59
|
+
let last: IMessage | undefined;
|
|
60
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
61
|
+
const m = messages[i];
|
|
62
|
+
if (m && m.id !== 'delimiter-new' && !m.isDeleted) {
|
|
63
|
+
last = m;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
storeAPI.dispatch(
|
|
68
|
+
updateRoom({
|
|
69
|
+
jid: roomJID,
|
|
70
|
+
updates: { lastMessage: (last as any) ?? undefined },
|
|
71
|
+
})
|
|
72
|
+
);
|
|
73
|
+
} catch (e) {
|
|
74
|
+
// A preview update must never break the action that carried it.
|
|
75
|
+
console.warn('reactionsMiddleware: preview update failed', e);
|
|
74
76
|
}
|
|
75
|
-
|
|
76
77
|
return result;
|
|
77
78
|
};
|