@ethora/chat-component-rn 26.8.5 → 26.8.7
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 +26 -0
- package/README.md +95 -0
- package/lib/commonjs/assets/emojiData.js +40 -0
- package/lib/commonjs/assets/emojiData.js.map +1 -0
- package/lib/commonjs/assets/icons.js +5 -3
- package/lib/commonjs/assets/icons.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatHeader.js +35 -15
- package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatRoom.js +33 -24
- package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatWrapper.js +22 -16
- package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/EncryptedSendNotice.js +47 -0
- package/lib/commonjs/components/MainComponents/EncryptedSendNotice.js.map +1 -0
- package/lib/commonjs/components/MainComponents/EncryptionCard.js +286 -0
- package/lib/commonjs/components/MainComponents/EncryptionCard.js.map +1 -0
- package/lib/commonjs/components/MainComponents/MediaMessage.js +7 -0
- package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
- 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/ReduxWrapper.js +5 -0
- package/lib/commonjs/components/MainComponents/ReduxWrapper.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 +133 -65
- package/lib/commonjs/components/MainComponents/RoomStack.js.map +1 -1
- package/lib/commonjs/components/MainComponents/SealedAttachment.js +231 -0
- package/lib/commonjs/components/MainComponents/SealedAttachment.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 +18 -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 +264 -136
- package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js +215 -13
- 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 +7 -4
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +159 -16
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js +4 -0
- package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
- package/lib/commonjs/components/Modals/Modal/SwipeBackLayer.js +76 -44
- package/lib/commonjs/components/Modals/Modal/SwipeBackLayer.js.map +1 -1
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +29 -6
- package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js +5 -1
- package/lib/commonjs/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/ChatRoomItem.js +37 -13
- package/lib/commonjs/components/RoomComponents/ChatRoomItem.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/LastMessageItem.js +6 -0
- package/lib/commonjs/components/RoomComponents/LastMessageItem.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/styled/LastAudioMessage.js +2 -2
- package/lib/commonjs/components/RoomComponents/styled/LastAudioMessage.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/RoomComponents/styled/LastMessageFile.js +4 -6
- package/lib/commonjs/components/RoomComponents/styled/LastMessageFile.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/styled/LastMessagePhoto.js +2 -2
- package/lib/commonjs/components/RoomComponents/styled/LastMessagePhoto.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/styled/LastMessageSealed.js +41 -0
- package/lib/commonjs/components/RoomComponents/styled/LastMessageSealed.js.map +1 -0
- package/lib/commonjs/components/RoomComponents/styled/LastMessageVideo.js +2 -2
- package/lib/commonjs/components/RoomComponents/styled/LastMessageVideo.js.map +1 -1
- package/lib/commonjs/components/Thread/ThreadWrapper.js +273 -152
- package/lib/commonjs/components/Thread/ThreadWrapper.js.map +1 -1
- package/lib/commonjs/components/UsersList/UsersList.js +2 -1
- package/lib/commonjs/components/UsersList/UsersList.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/components/styled/SendInput.js +4 -2
- package/lib/commonjs/components/styled/SendInput.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/e2ee/crypto.js +207 -0
- package/lib/commonjs/e2ee/crypto.js.map +1 -0
- package/lib/commonjs/e2ee/deviceStore.js +84 -0
- package/lib/commonjs/e2ee/deviceStore.js.map +1 -0
- package/lib/commonjs/e2ee/fileCipher.js +95 -0
- package/lib/commonjs/e2ee/fileCipher.js.map +1 -0
- package/lib/commonjs/e2ee/fileEnvelope.js +79 -0
- package/lib/commonjs/e2ee/fileEnvelope.js.map +1 -0
- package/lib/commonjs/e2ee/index.js +210 -0
- package/lib/commonjs/e2ee/index.js.map +1 -0
- package/lib/commonjs/e2ee/limits.js +9 -0
- package/lib/commonjs/e2ee/limits.js.map +1 -0
- package/lib/commonjs/e2ee/ns.js +8 -0
- package/lib/commonjs/e2ee/ns.js.map +1 -0
- package/lib/commonjs/e2ee/omemo.js +622 -0
- package/lib/commonjs/e2ee/omemo.js.map +1 -0
- package/lib/commonjs/e2ee/protobuf.js +149 -0
- package/lib/commonjs/e2ee/protobuf.js.map +1 -0
- package/lib/commonjs/e2ee/ratchet.js +238 -0
- package/lib/commonjs/e2ee/ratchet.js.map +1 -0
- package/lib/commonjs/e2ee/sealedBody.js +23 -0
- package/lib/commonjs/e2ee/sealedBody.js.map +1 -0
- package/lib/commonjs/e2ee/sealedFiles.js +174 -0
- package/lib/commonjs/e2ee/sealedFiles.js.map +1 -0
- package/lib/commonjs/e2ee/send.js +54 -0
- package/lib/commonjs/e2ee/send.js.map +1 -0
- package/lib/commonjs/e2ee/stanza.js +114 -0
- package/lib/commonjs/e2ee/stanza.js.map +1 -0
- package/lib/commonjs/e2ee/store.js +43 -0
- package/lib/commonjs/e2ee/store.js.map +1 -0
- package/lib/commonjs/helpers/accountName.js +23 -0
- package/lib/commonjs/helpers/accountName.js.map +1 -0
- package/lib/commonjs/helpers/createMessageFromXml.js +19 -4
- package/lib/commonjs/helpers/createMessageFromXml.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/createUserNameFromSetUser.js +2 -1
- package/lib/commonjs/helpers/createUserNameFromSetUser.js.map +1 -1
- package/lib/commonjs/helpers/displayName.js +16 -0
- package/lib/commonjs/helpers/displayName.js.map +1 -0
- 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/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/persistCrypto.js +5 -0
- package/lib/commonjs/helpers/persistCrypto.js.map +1 -1
- package/lib/commonjs/helpers/reactionsConfig.js +17 -0
- package/lib/commonjs/helpers/reactionsConfig.js.map +1 -0
- package/lib/commonjs/helpers/secureKeyValue.js +20 -0
- package/lib/commonjs/helpers/secureKeyValue.js.map +1 -1
- package/lib/commonjs/helpers/updateMessagesTillLast.js +17 -2
- package/lib/commonjs/helpers/updateMessagesTillLast.js.map +1 -1
- package/lib/commonjs/helpers/videoCache.js +136 -0
- package/lib/commonjs/helpers/videoCache.js.map +1 -0
- package/lib/commonjs/hooks/useHeapSender.js +3 -1
- package/lib/commonjs/hooks/useHeapSender.js.map +1 -1
- package/lib/commonjs/hooks/useLogout.js +8 -0
- package/lib/commonjs/hooks/useLogout.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 +85 -15
- 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/i18n/strings.js +180 -0
- package/lib/commonjs/i18n/strings.js.map +1 -1
- package/lib/commonjs/main.js +13 -0
- package/lib/commonjs/main.js.map +1 -1
- package/lib/commonjs/networking/api-requests/auth.api.js +4 -1
- package/lib/commonjs/networking/api-requests/auth.api.js.map +1 -1
- package/lib/commonjs/networking/api-requests/rooms.api.js +111 -17
- package/lib/commonjs/networking/api-requests/rooms.api.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 +44 -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/xmpp/sendMediaMessage.xmpp.js +16 -3
- package/lib/commonjs/networking/xmpp/sendMediaMessage.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js +13 -6
- package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +14 -6
- package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmppClient.js +104 -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 +93 -0
- package/lib/commonjs/roomStore/persistBackend.js.map +1 -0
- package/lib/commonjs/roomStore/persistence.js +253 -51
- 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 +4 -2
- package/lib/module/assets/icons.js.map +1 -1
- package/lib/module/components/MainComponents/ChatHeader.js +37 -17
- package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/module/components/MainComponents/ChatRoom.js +34 -25
- package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/module/components/MainComponents/ChatWrapper.js +23 -17
- package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/EncryptedSendNotice.js +42 -0
- package/lib/module/components/MainComponents/EncryptedSendNotice.js.map +1 -0
- package/lib/module/components/MainComponents/EncryptionCard.js +281 -0
- package/lib/module/components/MainComponents/EncryptionCard.js.map +1 -0
- package/lib/module/components/MainComponents/MediaMessage.js +7 -0
- package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
- 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/ReduxWrapper.js +5 -0
- package/lib/module/components/MainComponents/ReduxWrapper.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 +131 -63
- package/lib/module/components/MainComponents/RoomStack.js.map +1 -1
- package/lib/module/components/MainComponents/SealedAttachment.js +224 -0
- package/lib/module/components/MainComponents/SealedAttachment.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 +19 -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 +269 -140
- package/lib/module/components/MessageBubble/Message.js.map +1 -1
- package/lib/module/components/MessageBubble/MessageInteractions.js +217 -15
- 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 +7 -4
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +161 -18
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/module/components/Modals/FilePreviewModal/PdfView.js +4 -0
- package/lib/module/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
- package/lib/module/components/Modals/Modal/SwipeBackLayer.js +76 -44
- package/lib/module/components/Modals/Modal/SwipeBackLayer.js.map +1 -1
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +32 -8
- package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
- package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js +4 -0
- package/lib/module/components/Modals/UserSettingsModal/UserSettingsModal.js.map +1 -1
- package/lib/module/components/RoomComponents/ChatRoomItem.js +37 -13
- package/lib/module/components/RoomComponents/ChatRoomItem.js.map +1 -1
- package/lib/module/components/RoomComponents/LastMessageItem.js +6 -0
- package/lib/module/components/RoomComponents/LastMessageItem.js.map +1 -1
- package/lib/module/components/RoomComponents/styled/LastAudioMessage.js +2 -2
- package/lib/module/components/RoomComponents/styled/LastAudioMessage.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/RoomComponents/styled/LastMessageFile.js +4 -6
- package/lib/module/components/RoomComponents/styled/LastMessageFile.js.map +1 -1
- package/lib/module/components/RoomComponents/styled/LastMessagePhoto.js +2 -2
- package/lib/module/components/RoomComponents/styled/LastMessagePhoto.js.map +1 -1
- package/lib/module/components/RoomComponents/styled/LastMessageSealed.js +36 -0
- package/lib/module/components/RoomComponents/styled/LastMessageSealed.js.map +1 -0
- package/lib/module/components/RoomComponents/styled/LastMessageVideo.js +2 -2
- package/lib/module/components/RoomComponents/styled/LastMessageVideo.js.map +1 -1
- package/lib/module/components/Thread/ThreadWrapper.js +273 -153
- package/lib/module/components/Thread/ThreadWrapper.js.map +1 -1
- package/lib/module/components/UsersList/UsersList.js +2 -1
- package/lib/module/components/UsersList/UsersList.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/components/styled/SendInput.js +4 -2
- package/lib/module/components/styled/SendInput.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/e2ee/crypto.js +170 -0
- package/lib/module/e2ee/crypto.js.map +1 -0
- package/lib/module/e2ee/deviceStore.js +77 -0
- package/lib/module/e2ee/deviceStore.js.map +1 -0
- package/lib/module/e2ee/fileCipher.js +90 -0
- package/lib/module/e2ee/fileCipher.js.map +1 -0
- package/lib/module/e2ee/fileEnvelope.js +66 -0
- package/lib/module/e2ee/fileEnvelope.js.map +1 -0
- package/lib/module/e2ee/index.js +185 -0
- package/lib/module/e2ee/index.js.map +1 -0
- package/lib/module/e2ee/limits.js +5 -0
- package/lib/module/e2ee/limits.js.map +1 -0
- package/lib/module/e2ee/ns.js +4 -0
- package/lib/module/e2ee/ns.js.map +1 -0
- package/lib/module/e2ee/omemo.js +610 -0
- package/lib/module/e2ee/omemo.js.map +1 -0
- package/lib/module/e2ee/protobuf.js +140 -0
- package/lib/module/e2ee/protobuf.js.map +1 -0
- package/lib/module/e2ee/ratchet.js +228 -0
- package/lib/module/e2ee/ratchet.js.map +1 -0
- package/lib/module/e2ee/sealedBody.js +19 -0
- package/lib/module/e2ee/sealedBody.js.map +1 -0
- package/lib/module/e2ee/sealedFiles.js +154 -0
- package/lib/module/e2ee/sealedFiles.js.map +1 -0
- package/lib/module/e2ee/send.js +48 -0
- package/lib/module/e2ee/send.js.map +1 -0
- package/lib/module/e2ee/stanza.js +107 -0
- package/lib/module/e2ee/stanza.js.map +1 -0
- package/lib/module/e2ee/store.js +35 -0
- package/lib/module/e2ee/store.js.map +1 -0
- package/lib/module/helpers/accountName.js +18 -0
- package/lib/module/helpers/accountName.js.map +1 -0
- package/lib/module/helpers/createMessageFromXml.js +19 -4
- package/lib/module/helpers/createMessageFromXml.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/createUserNameFromSetUser.js +3 -1
- package/lib/module/helpers/createUserNameFromSetUser.js.map +1 -1
- package/lib/module/helpers/displayName.js +11 -0
- package/lib/module/helpers/displayName.js.map +1 -0
- 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/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/persistCrypto.js +4 -0
- package/lib/module/helpers/persistCrypto.js.map +1 -1
- package/lib/module/helpers/reactionsConfig.js +10 -0
- package/lib/module/helpers/reactionsConfig.js.map +1 -0
- package/lib/module/helpers/secureKeyValue.js +19 -0
- package/lib/module/helpers/secureKeyValue.js.map +1 -1
- package/lib/module/helpers/updateMessagesTillLast.js +17 -2
- package/lib/module/helpers/updateMessagesTillLast.js.map +1 -1
- package/lib/module/helpers/videoCache.js +125 -0
- package/lib/module/helpers/videoCache.js.map +1 -0
- package/lib/module/hooks/useHeapSender.js +3 -1
- package/lib/module/hooks/useHeapSender.js.map +1 -1
- package/lib/module/hooks/useLogout.js +8 -0
- package/lib/module/hooks/useLogout.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 +85 -15
- 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/i18n/strings.js +180 -0
- package/lib/module/i18n/strings.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 +4 -1
- package/lib/module/networking/api-requests/auth.api.js.map +1 -1
- package/lib/module/networking/api-requests/rooms.api.js +109 -18
- package/lib/module/networking/api-requests/rooms.api.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 +42 -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/xmpp/sendMediaMessage.xmpp.js +16 -3
- package/lib/module/networking/xmpp/sendMediaMessage.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/sendTextMessage.xmpp.js +13 -6
- package/lib/module/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +14 -6
- package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
- package/lib/module/networking/xmppClient.js +105 -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 +86 -0
- package/lib/module/roomStore/persistBackend.js.map +1 -0
- package/lib/module/roomStore/persistence.js +253 -49
- 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/assets/icons.d.ts +8 -0
- package/lib/typescript/assets/icons.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/EncryptedSendNotice.d.ts +4 -0
- package/lib/typescript/components/MainComponents/EncryptedSendNotice.d.ts.map +1 -0
- package/lib/typescript/components/MainComponents/EncryptionCard.d.ts +10 -0
- package/lib/typescript/components/MainComponents/EncryptionCard.d.ts.map +1 -0
- package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
- 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/ReduxWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/RoomStack.d.ts +7 -2
- package/lib/typescript/components/MainComponents/RoomStack.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/SealedAttachment.d.ts +13 -0
- package/lib/typescript/components/MainComponents/SealedAttachment.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/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/SwipeBackLayer.d.ts +2 -1
- package/lib/typescript/components/Modals/Modal/SwipeBackLayer.d.ts.map +1 -1
- package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/UserSettingsModal/UserSettingsModal.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/LastMessageItem.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/styled/LastAudioMessage.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/RoomComponents/styled/LastMessageSealed.d.ts +7 -0
- package/lib/typescript/components/RoomComponents/styled/LastMessageSealed.d.ts.map +1 -0
- 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/UsersList/UsersList.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/components/styled/SendInput.d.ts +1 -0
- package/lib/typescript/components/styled/SendInput.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/e2ee/crypto.d.ts +28 -0
- package/lib/typescript/e2ee/crypto.d.ts.map +1 -0
- package/lib/typescript/e2ee/deviceStore.d.ts +4 -0
- package/lib/typescript/e2ee/deviceStore.d.ts.map +1 -0
- package/lib/typescript/e2ee/fileCipher.d.ts +7 -0
- package/lib/typescript/e2ee/fileCipher.d.ts.map +1 -0
- package/lib/typescript/e2ee/fileEnvelope.d.ts +27 -0
- package/lib/typescript/e2ee/fileEnvelope.d.ts.map +1 -0
- package/lib/typescript/e2ee/index.d.ts +23 -0
- package/lib/typescript/e2ee/index.d.ts.map +1 -0
- package/lib/typescript/e2ee/limits.d.ts +3 -0
- package/lib/typescript/e2ee/limits.d.ts.map +1 -0
- package/lib/typescript/e2ee/ns.d.ts +2 -0
- package/lib/typescript/e2ee/ns.d.ts.map +1 -0
- package/lib/typescript/e2ee/omemo.d.ts +64 -0
- package/lib/typescript/e2ee/omemo.d.ts.map +1 -0
- package/lib/typescript/e2ee/protobuf.d.ts +25 -0
- package/lib/typescript/e2ee/protobuf.d.ts.map +1 -0
- package/lib/typescript/e2ee/ratchet.d.ts +39 -0
- package/lib/typescript/e2ee/ratchet.d.ts.map +1 -0
- package/lib/typescript/e2ee/sealedBody.d.ts +2 -0
- package/lib/typescript/e2ee/sealedBody.d.ts.map +1 -0
- package/lib/typescript/e2ee/sealedFiles.d.ts +31 -0
- package/lib/typescript/e2ee/sealedFiles.d.ts.map +1 -0
- package/lib/typescript/e2ee/send.d.ts +6 -0
- package/lib/typescript/e2ee/send.d.ts.map +1 -0
- package/lib/typescript/e2ee/stanza.d.ts +8 -0
- package/lib/typescript/e2ee/stanza.d.ts.map +1 -0
- package/lib/typescript/e2ee/store.d.ts +16 -0
- package/lib/typescript/e2ee/store.d.ts.map +1 -0
- package/lib/typescript/helpers/accountName.d.ts +7 -0
- package/lib/typescript/helpers/accountName.d.ts.map +1 -0
- package/lib/typescript/helpers/createMessageFromXml.d.ts.map +1 -1
- package/lib/typescript/helpers/createRoomFromApi.d.ts.map +1 -1
- package/lib/typescript/helpers/createUserNameFromSetUser.d.ts.map +1 -1
- package/lib/typescript/helpers/displayName.d.ts +2 -0
- package/lib/typescript/helpers/displayName.d.ts.map +1 -0
- 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/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/persistCrypto.d.ts +1 -0
- package/lib/typescript/helpers/persistCrypto.d.ts.map +1 -1
- package/lib/typescript/helpers/reactionsConfig.d.ts +5 -0
- package/lib/typescript/helpers/reactionsConfig.d.ts.map +1 -0
- package/lib/typescript/helpers/secureKeyValue.d.ts +4 -0
- package/lib/typescript/helpers/secureKeyValue.d.ts.map +1 -1
- package/lib/typescript/helpers/updateMessagesTillLast.d.ts.map +1 -1
- package/lib/typescript/helpers/videoCache.d.ts +19 -0
- package/lib/typescript/helpers/videoCache.d.ts.map +1 -0
- package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
- package/lib/typescript/hooks/useLogout.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/i18n/strings.d.ts.map +1 -1
- package/lib/typescript/main.d.ts +2 -0
- package/lib/typescript/main.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/auth.api.d.ts +4 -1
- package/lib/typescript/networking/api-requests/auth.api.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/rooms.api.d.ts +22 -1
- package/lib/typescript/networking/api-requests/rooms.api.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 +1 -0
- 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/xmpp/sendMediaMessage.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/sendTextMessageWithTranslateTag.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 +9 -0
- package/lib/typescript/types/models/message.model.d.ts.map +1 -1
- package/lib/typescript/types/models/room.model.d.ts +21 -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 +19 -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 +14 -1
- package/src/assets/emojiData.ts +2146 -0
- package/src/assets/icons.tsx +32 -5
- package/src/components/MainComponents/ChatHeader.tsx +46 -16
- package/src/components/MainComponents/ChatRoom.tsx +46 -30
- package/src/components/MainComponents/ChatWrapper.tsx +28 -10
- package/src/components/MainComponents/EncryptedSendNotice.tsx +35 -0
- package/src/components/MainComponents/EncryptionCard.tsx +287 -0
- package/src/components/MainComponents/MediaMessage.tsx +5 -0
- package/src/components/MainComponents/MessageContainer.tsx +7 -15
- package/src/components/MainComponents/MessageList.tsx +96 -43
- package/src/components/MainComponents/ReduxWrapper.tsx +5 -0
- package/src/components/MainComponents/RoomList.tsx +28 -29
- package/src/components/MainComponents/RoomStack.tsx +156 -83
- package/src/components/MainComponents/SealedAttachment.tsx +251 -0
- package/src/components/MainComponents/SystemMessage.tsx +6 -2
- package/src/components/MessageBubble/Avatar.tsx +7 -1
- package/src/components/MessageBubble/BottomReplyContainer.tsx +20 -21
- package/src/components/MessageBubble/EmojiPickerSheet.tsx +468 -0
- package/src/components/MessageBubble/Message.tsx +242 -93
- package/src/components/MessageBubble/MessageInteractions.tsx +215 -15
- package/src/components/MessageBubble/MessageReaction.tsx +120 -96
- package/src/components/MessageBubble/MessageReply.tsx +65 -32
- package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +7 -4
- package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +181 -35
- package/src/components/Modals/FilePreviewModal/PdfView.tsx +4 -0
- package/src/components/Modals/Modal/SwipeBackLayer.tsx +114 -63
- package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +53 -8
- package/src/components/Modals/UserSettingsModal/UserSettingsModal.tsx +5 -0
- package/src/components/RoomComponents/ChatRoomItem.tsx +34 -15
- package/src/components/RoomComponents/LastMessageItem.tsx +5 -0
- package/src/components/RoomComponents/styled/LastAudioMessage.tsx +3 -1
- package/src/components/RoomComponents/styled/LastMessageEmoji.tsx +7 -8
- package/src/components/RoomComponents/styled/LastMessageFile.tsx +2 -2
- package/src/components/RoomComponents/styled/LastMessagePhoto.tsx +1 -1
- package/src/components/RoomComponents/styled/LastMessageSealed.tsx +31 -0
- package/src/components/RoomComponents/styled/LastMessageVideo.tsx +1 -1
- package/src/components/Thread/ThreadWrapper.tsx +287 -198
- package/src/components/UsersList/UsersList.tsx +2 -1
- package/src/components/styled/DateLabel.tsx +7 -3
- package/src/components/styled/SendInput.tsx +5 -2
- package/src/context/MessageNotificationContext.tsx +205 -7
- package/src/context/xmppProvider.tsx +29 -9
- package/src/e2ee/crypto.ts +194 -0
- package/src/e2ee/deviceStore.ts +80 -0
- package/src/e2ee/fileCipher.ts +86 -0
- package/src/e2ee/fileEnvelope.ts +115 -0
- package/src/e2ee/index.ts +192 -0
- package/src/e2ee/limits.ts +2 -0
- package/src/e2ee/ns.ts +1 -0
- package/src/e2ee/omemo.ts +802 -0
- package/src/e2ee/protobuf.ts +188 -0
- package/src/e2ee/ratchet.ts +271 -0
- package/src/e2ee/sealedBody.ts +17 -0
- package/src/e2ee/sealedFiles.ts +181 -0
- package/src/e2ee/send.ts +70 -0
- package/src/e2ee/stanza.ts +133 -0
- package/src/e2ee/store.ts +54 -0
- package/src/helpers/accountName.ts +15 -0
- package/src/helpers/createMessageFromXml.ts +31 -6
- package/src/helpers/createRoomFromApi.tsx +37 -1
- package/src/helpers/createUserNameFromSetUser.ts +2 -1
- package/src/helpers/displayName.ts +9 -0
- 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/mamReactions.ts +59 -0
- package/src/helpers/parseMessageReference.ts +38 -0
- package/src/helpers/persistCrypto.ts +5 -0
- package/src/helpers/reactionsConfig.ts +13 -0
- package/src/helpers/secureKeyValue.ts +15 -0
- package/src/helpers/updateMessagesTillLast.tsx +14 -2
- package/src/helpers/videoCache.ts +138 -0
- package/src/hooks/useHeapSender.tsx +3 -2
- package/src/hooks/useLogout.tsx +9 -0
- package/src/hooks/useMessageHeapState.tsx +6 -2
- package/src/hooks/useRoomInitialization.tsx +32 -15
- package/src/hooks/useSendMessage.tsx +89 -16
- package/src/hooks/useUnreadMessagesCounter.ts +1 -1
- package/src/i18n/strings.ts +180 -0
- package/src/main.ts +2 -0
- package/src/networking/api-requests/auth.api.ts +9 -1
- package/src/networking/api-requests/rooms.api.ts +121 -18
- package/src/networking/stanzaHandlers.ts +116 -60
- package/src/networking/xmpp/getHistory.xmpp.ts +44 -106
- package/src/networking/xmpp/handleStanzas.xmpp.ts +51 -0
- package/src/networking/xmpp/mamRouter.ts +176 -0
- package/src/networking/xmpp/presenceInRoom.xmpp.ts +46 -3
- package/src/networking/xmpp/sendMediaMessage.xmpp.ts +19 -1
- package/src/networking/xmpp/sendTextMessage.xmpp.ts +17 -10
- package/src/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.ts +23 -10
- package/src/networking/xmppClient.ts +111 -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 +93 -0
- package/src/roomStore/persistence.ts +295 -73
- package/src/roomStore/roomsSlice.ts +304 -155
- package/src/theme/theme.ts +10 -1
- package/src/types/models/message.model.ts +9 -0
- package/src/types/models/room.model.ts +22 -0
- package/src/types/models/xmpp.model.ts +4 -2
- package/src/types/types.ts +19 -3
- package/src/utils/devLogger.ts +16 -0
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,12 +7,38 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this pr
|
|
|
7
7
|
|
|
8
8
|
### Added
|
|
9
9
|
|
|
10
|
+
- **Devices, fingerprints and trust; no corrections in clear; a repeatable interop check (E2EE phase 6).** `EncryptionCard` lists an account's OMEMO devices with their labels and identity-key fingerprints: this account's in Settings (tap copies a fingerprint), another person's on their profile, each with its trust mark - *Not verified* (trusted on first sight), *Verified*, *Not trusted* - and a tap to change it. Once one of a person's devices is verified, a device nobody verified is no longer encrypted for (`Omemo.setTrust`, as on the web; `DeviceInfo` gained `label`). Both cards appear only with `config.e2ee.enabled`. **Editing is not offered for a message that went out encrypted** (`canEditMessage`, menu and send path): a correction travels in clear, so it would publish what the encryption withheld; edits made on other clients are still shown. The struck-through padlock explains itself on a tap. `npm run e2ee:interop` runs this SDK's OMEMO code against the web SDK's in one process - sessions in both directions, rooms of mixed clients where everyone writes and everyone reads, one account on a web and a mobile device, attachments sealed by one and opened by the other - and skips with a note when the web SDK is not checked out next to this one. Fourteen strings in every locale. Tests in `e2eeDevices.test.tsx`.
|
|
11
|
+
|
|
12
|
+
- **Sealed attachments in encrypted rooms (E2EE phase 5).** With `config.e2ee.enabled`, a file, photo, video or voice message sent to an `e2ee` room is sealed on the device before upload: the web SDK's `ETHOFILE` envelope (real name, type and size inside) under the OMEMO payload construction, uploaded as opaque `application/octet-stream` bytes under a random name with `clientEncrypted` (`uploadFileV2(…, { clientEncrypted })`), its key sent as the OMEMO-encrypted `<body>` (`{v:1,keys:[…]}`) with `clientEncrypted="true"` on `<data>`. There is no clear-text fallback for an attachment: if it cannot be encrypted nothing is sent and the message fails. On the receiving side the "Encrypted file" card downloads and opens the attachment on a tap, with progress; from then on it is shown by the same components as an ordinary attachment of its kind (image bubble, video, voice player, file card), fed the decrypted copy, so an opened attachment looks no different from any other; before that it is the ordinary file card with a padlock. It opens in the preview from the decrypted copy, which is kept in the cache (`ethora-sealed/`), found again after a restart, and removed on logout. The sender's own bubble uses the file it already has. A web message with several attachments gets one card per attachment. The cipher is pure JS and runs in 32 KB slices with a yield between them (`src/e2ee/fileCipher.ts`), byte-compatible with `encryptPayload`: about 1.4 s per megabyte on Hermes in a dev build, the UI staying responsive - so sealing is capped at 20 MB (`MAX_SEAL_BYTES`; the composer says so at pick time) and opening at 50 MB. The preview modal saves and shares a file that is already on the device without downloading it, and never hands one to a remote viewer. Checked against the web implementation in both directions and on a device's file system; see `docs/e2ee-port.md`. Tests in `e2eeFiles.test.ts`, `e2eeSealedFiles.test.tsx`, `e2eeFlow.test.ts`.
|
|
13
|
+
|
|
14
|
+
- **"Encrypted message" on a user's profile.** Next to "Message", when `config.e2ee.enabled` and `newArch` are on: opens - or creates - the encrypted room of the pair through `POST /v1/chats/private { e2ee: true }` (`postPrivateRoom(username, true)`; the field is left out of the ordinary request, which stays byte-identical for backends that predate it). The encrypted room is a room of its own: it does not convert the plaintext chat, whose history stays where it was written. Not offered while this app would not encrypt in it. `action.encryptedMessage` in every locale. Tests in `userProfileScreen.test.tsx`, `e2eeFlow.test.ts`.
|
|
15
|
+
|
|
16
|
+
- **Encrypted text, both ways (E2EE phases 3-4) — `config.e2ee.enabled`.** With the flag on, rooms the backend marks `e2ee` now work: incoming OMEMO messages are decrypted in place at the top of `handleStanza` (`decryptStanzaInPlace`, `src/e2ee/stanza.ts`) - live, mucsub and MAM alike - and text sent from `sendTextMessage` / `sendTextMessageWithTranslateTag` goes out inside an OMEMO payload with `<data>` beside it in the clear (`src/e2ee/send.ts`), without the `<translate>` tag. While a message is being decrypted the stanzas behind it wait their turn, so an archive page's closing `<iq>` cannot overtake the page (it would be applied without its messages) nor an edit its message; with nothing to decrypt dispatch is as synchronous as before. The device is usable as soon as its keys are loaded (`Omemo.open`) and publishes behind that, retrying on the next connect - messages are not held up by the IQs, and a failed publish no longer costs the ability to read. No recipient device → the message goes out in clear and is marked, as on the web; not knowing who is in the room is not answered with plaintext - the members are fetched (`resolveRecipients`), and failing that nothing is sent and the message fails like any other. `/chats/my` rooms now carry `e2ee` and, for encrypted rooms, their members into the store (`dispatchRoomsFromRestItems` built the room by hand and dropped both, so a real encrypted room got no padlock at all). The composer follows the flag: a notice when it is off, text only when it is on - attachments wait for phase 5. A closed payload says why (`e2eeError`: `'unsupported' | 'other-device' | 'failed'`); sealed-attachment keys are lifted out of the decrypted body (`e2eeKeys`). Two more strings in every locale. **Checked against the web classes and a fake server; not yet against a live web client - this account has no encrypted room.** Tests in `e2eeFlow.test.ts`, `e2eeStanzaQueue.test.ts`.
|
|
17
|
+
|
|
18
|
+
- **This device's OMEMO identity: key store, `Omemo` class, start-up (E2EE phase 2) — behind `config.e2ee.enabled`, off by default.** With the flag on the SDK creates the device's keys after connecting (identity, signed prekey, 100 one-time prekeys - generated five at a time so the UI keeps running), publishes the bundle and adds the device to the account's list on PEP, labelled `iOS` / `Android`. `src/e2ee/omemo.ts` is the web SDK's class, statement for statement, including the MUC encrypt/decrypt it will need next; `useClient` re-points it at the new underlying client this SDK builds on every reconnect. Keys live in `src/e2ee/deviceStore.ts`: an encrypted MMKV instance of their own (`ethora-omemo`, keyed from the Keychain/Keystore), or AsyncStorage sealed with the history cipher key when MMKV is absent - apart from the chat cache, so logout does not wipe them and the same account resumes as the same device. A store whose key is not provably kept is refused, and no device is created: an identity lost on restart would be minted again on every launch. With the flag off none of this is loaded - `./omemo` and the crypto are required on first start, not at import. **Reading and writing encrypted messages is not wired in yet (phases 3-4): do not enable the flag in production.** `omemo()`, `isE2eeEnabled`, `DeviceInfo`, `Trust` are exported. Checked against the web class in mixed rooms in both directions (one-off, see `docs/e2ee-port.md`) and against the QA server. Tests in `e2eeOmemo.test.ts`.
|
|
19
|
+
|
|
20
|
+
- **OMEMO 2 crypto core (E2EE phase 1) — present, not wired in.** `src/e2ee/crypto.ts`, `protobuf.ts` and `ratchet.ts` are the web SDK's modules (X25519 / Ed25519, HKDF, HMAC-SHA-256, AES-256-CBC, X3DH, Double Ratchet, the message payload, the three protobuf messages), on the same pure-JS `@noble/ciphers|curves|hashes` ^2.4 — now dependencies of this package. Two runtime-forced differences: `cloneSession` replaces `structuredClone`, and base64 does not go through `btoa`/`atob`. Nothing imports them yet, so bundles and behaviour are unchanged. Checked against published vectors, against a transcript the web implementation produced (`__tests__/fixtures/omemoWebTranscript.json`), and — as a one-off — against the web code itself in every initiator/responder pairing; self-tested and timed on Hermes. Status, measurements and what they mean for the next phases: `docs/e2ee-port.md`. Jest now transforms `@noble/*` (ESM-only). Tests in `e2eeCrypto.test.ts`.
|
|
21
|
+
|
|
22
|
+
- **End-to-end encrypted rooms are presented as such (E2EE phase 0).** The SDK still cannot encrypt or decrypt, but a room the backend marks `e2ee` no longer misreads what a web client with OMEMO sends into it: the fallback body "Encrypted message" was shown as typed text, a sealed attachment (`application/octet-stream`) as a dead audio player, and the app itself posted plaintext into the room unannounced. Now `rewriteEncryptedStanza` (`src/e2ee/stanza.ts`, the seam at the top of `handleStanza`, covering live, mucsub and MAM) swaps the fallback body for a localized placeholder and stamps `omemoEncrypted` / `undecryptable` on `<data>`, dropping payload-less session messages; `createMessageFromXml` marks anything else in such a room `unencrypted`; the bubble draws a padlock line / a struck-through padlock; `MediaMessage` and `LastMessageItem` check `clientEncrypted` before mimetype (`SealedAttachment`, `LastMessageSealed`); the room list and chat header carry a padlock; and the composer gives way to `EncryptedSendNotice` while `sendMessage` / `sendMedia` refuse the room (`canSendToRoom`, the one place to lift once the OMEMO send path lands). New `IRoom.e2ee`, `IMessage.unencrypted` / `undecryptable` / `clientEncrypted` (persisted), `LockIcon` / `LockOffIcon`, six strings in every locale. Tests in `e2eeGuard.test.tsx`.
|
|
23
|
+
|
|
10
24
|
- **Settings: Appearance (Light / Dark / System) and a Push notifications switch.** Two new cards on the Settings screen, in the same card style as Manage Data / Visibility. The appearance pick is persisted per device (`@ethora/preferences`, `helpers/preferencesStorage.ts`), folded into `config.dark` by the store (`setThemePreference`; a later `setConfig` from the host keeps the user's choice) so every consumer sees it, and reported to the host through `eventHandlers.onThemeChange(preference, isDark)`. `config.dark` accepts `'system'`, resolved against the OS scheme (`resolveTheme(config, systemDark)` / `isDarkTheme`, falling back to `Appearance.getColorScheme()` for callers without a hook). The push switch (`setPushEnabled`) is wired into the SDK's own token registration: off releases every device-token registration on the backend and keeps the tokens, on registers them again, `registerPushToken` resolves `'disabled'` meanwhile; the host is told through `eventHandlers.onPushNotificationsToggle(enabled)`. `settings.hideAppearance` / `settings.hidePushToggle` hide either card. `ThemePreference`, `setThemePreference`, `setPushEnabled` are exported. Tests in `userSettingsScreen.test.tsx`, `theme.test.ts`, `pushRegistration.test.ts`.
|
|
11
25
|
|
|
12
26
|
- **`registerPushToken` / `unregisterPushToken` / `getRegisteredPushToken` — the host hands the SDK its push token; the SDK does the rest.** Until now the only code that filed a device token was `usePushNotifications`, a Firebase-bound hook that was never mounted and not exported, so a host had no way to register a token through the SDK at all (`instructions.md` claimed otherwise). `registerPushToken(token, { tokenType? })` (`src/services/pushRegistration.ts`) files the token under the signed-in user via `POST /v1/push/subscription/{appId}` — the endpoint the web SDK and the Ethora RN app already use — waits for a session when called before sign-in (`'deferred'`), dedupes the same token + account, honours `pushNotifications.enabled: false` (`'disabled'`), and rejects with `PushRegistrationError` (`status`, `body`) when the backend refuses. On logout `logoutService` releases the registration (`DELETE`, before the access token is cleared) and keeps the token, so the next login of any account is registered again without another call. `unregisterPushToken()` deletes and forgets (`'unregistered' | 'forgotten'`). `detectPushTokenType` tells `expo` / `apns` / `fcm` tokens apart by shape; a backend that predates `tokenType` still gets `apns` / `fcm` tokens through the legacy payload, while `expo` and `apns-voip` are never downgraded into something it could not deliver to. `pushNotifications.apiUrl` keeps the standalone push gateway (`ethora-node-push`) reachable as an explicit legacy mode with its own strict schema (`projectName`, not `projectId`, which the SDK used to send). A device holds up to two tokens — the chat token (`expo` / `fcm` / `apns`) and an optional PushKit `apns-voip` token — registered, released and re-registered together; a rotated token releases the one it replaces. `config.pushNotifications.getPushTokens` is the declarative alternative (called once per login, retried after a back-off on failure), so a host can hand over tokens without wiring `registerPushToken` itself; both can be combined. `PushTokenType`, `PushTokenRegistration`, `PushDeviceType`, `PushSubscriptionPayload`, `RegisterPushTokenOptions/Outcome`, `UnregisterPushTokenOptions/Outcome`, `RegisteredPushToken`, `getRegisteredPushTokens` and `isPushRegistrationError` are exported. The two-slot model and the declarative hook follow `feat/push-token-providers`; the transport differs (main API instead of the gateway, see Fixed). Tests in `pushRegistration.test.ts`.
|
|
13
27
|
|
|
14
28
|
### Fixed
|
|
15
29
|
|
|
30
|
+
- **User avatars never showed - every sender was their initials.** A bubble takes the sender's picture from `usersSet`, and `usersSet` is built from the `members` of `/chats/my` - but that mapping copied the name and the ids and left `profileImage` out, so there was never a picture to find. The fallback did not work either: the parser keeps the `<data photo>` a sender stamps on a message as `user.photoURL`, and the bubble read `user.profileImage`. Members now keep `profileImage` (and `description`) in `usersSet` and in `room.roomMembers`, with the backend's `''` / `"none"` treated as no picture; the bubble also reads `user.photoURL`, adds the file token for a picture on the membership-gated host, and falls back to the initials when the image fails to load. The member list of a chat profile shows the pictures too, and a profile opened from it carries the picture. The two endpoints do not describe a member alike - `/chats/my/{name}`, the full roster loaded when a room is opened, sends no `profileImage` - so a field a response does not carry no longer overwrites what is known: the roster adds names for everybody and leaves the pictures the list supplied in place. (A member beyond the 30 that `/chats/my` previews therefore has a picture only if their messages carry one.) Tests in `senderNames.test.tsx`.
|
|
31
|
+
|
|
32
|
+
- **Sender names showed as raw ids, and big rooms as "30 users", after `/chats/my` started previewing members.** The backend now lists at most 30 members per room there (`usersCnt` carries the real count; `/chats/my/{name}` still returns everybody). `usersSet` - the identity cache every sender name and avatar resolves through - is built from those lists, so in a room of hundreds most senders were no longer in it and the name fell back to what the message carries. That exposed two older faults: a message from the web SDK's translate-tagged send path spells the name `firstName` / `lastName`, which `createMessageFromXml` did not read (only `senderFirstName` / `senderLastName` / `fullName`), and the id it fell back to was the ROOM's - the localpart of an occupant JID `room@conference/nick` - not the sender's. Now: both spellings are read; the fallback id is the nick; `loadRoomMembers` fetches a room's whole roster when the room is opened (once per five minutes, only when the list is short of `usersCnt`) and feeds `usersSet` and `room.roomMembers`, and a later list refresh does not cut the roster back to the preview; `usersCnt` comes from the API's field, so the header and the member list no longer stop at 30; an encrypted room's recipients are the whole room, not the preview (`resolveRecipients`). Where a sender still cannot be named the room row shows no name instead of 50 characters of hex, the previews no longer leave a lone ":", and a profile opened from a bubble shows what is known about the sender now rather than the snapshot on the message. The cached roster stays preview-sized. Tests in `senderNames.test.tsx`.
|
|
33
|
+
|
|
34
|
+
- **An account registered by email showed its address twice.** The backend gives such an account the email as both first and last name; `composeName` shows that pair once (bubble, room row, reply pill, member lists, profile). Other identical pairs are left alone.
|
|
35
|
+
|
|
36
|
+
- **The MMKV chat cache was unreadable after every restart (since 26.8.6).** Its encryption key was kept in the secure store under `@ethora/persist:mmkvKey`; expo-secure-store only accepts `[A-Za-z0-9._-]` and throws on anything else, `secureSet` swallowed that, and each launch therefore opened the instance with a new random key - the cache written by the previous launch decoded to nothing, so every cold start painted from the network instead of from disk. The key is now `ethora_persist_mmkv_key`, written through `secureGetOrCreate`, which reads a new secret back before anyone encrypts with it; an instance opened with a fresh key is cleared, and when no key can be kept the backend falls back to sealed AsyncStorage rather than be a cache that never restores. Installs upgrading from 26.8.6 lose nothing they could read. The Jest mock of expo-secure-store now enforces the same key rule as the real module, and the MMKV mock models a file opened with another key - which is what let this through. Tests in `persistence.mmkv.test.ts`.
|
|
37
|
+
|
|
38
|
+
- **iOS: a video opened to a struck-through play button.** AVPlayer asks for the file by byte range and refuses a server that answers `200` instead of `206` (`AVFoundationErrorDomain -11850`, "server is not correctly configured") — which is what the secure-files host does. The full-screen preview still streams where it can; when the stream errors it downloads the clip into the cache (`helpers/videoCache.ts`, with progress), plays the local copy, and remembers the host so the next video skips the doomed attempt. A reopened video plays from the cache at once. A clip that cannot be played at all now says so instead of showing the system glyph. Tests in `videoCache.test.ts`.
|
|
39
|
+
|
|
40
|
+
- **Room list: a file preview drew its icon at 46 px over the row.** `LastMessageFile` sized `FileIcon` through `style`, which the icon ignores.
|
|
41
|
+
|
|
16
42
|
- **Android crashed on launch with `NoClassDefFoundError: expo.modules.kotlin.types.AnyTypeProvider` (expo-secure-store).** `expo-secure-store` was pinned to the SDK 54 line (`~15.0.7`, resolved 15.0.8) while the app runs Expo 57. Expo 57 consumes modules as prebuilt AARs, and that AAR was compiled against an `expo-modules-core` where `AnyTypeProvider` still existed, so the crash surfaced at native module registration, not at build time. Bumped to `~57.0.4` (`npx expo install --check` lists the rest of the drift).
|
|
17
43
|
|
|
18
44
|
- **Push registration pointed at a dead endpoint with the wrong payload.** The SDK's only registration path posted `projectId` to `{pushNotifications.apiUrl}/subscriptions` — the standalone gateway, whose Joi schema requires `projectName` and rejects unknown keys, and which the hosted clusters no longer expose at all (`nginx 405`). Every attempt failed and was logged as a success. Registration now goes through the main API by default (see Added); the gateway contract is fixed and kept behind `apiUrl` for self-hosted setups.
|
package/README.md
CHANGED
|
@@ -18,6 +18,8 @@ React Native chat UI + chat core for iOS and Android, powered by the Ethora plat
|
|
|
18
18
|
- [Unread tracking in tab-based hosts](#unread-tracking-in-tab-based-hosts)
|
|
19
19
|
- [Logging out](#logging-out)
|
|
20
20
|
- [Customization flags worth knowing](#customization-flags-worth-knowing)
|
|
21
|
+
- [Message reactions](#message-reactions)
|
|
22
|
+
- [Replies & threads](#replies--threads)
|
|
21
23
|
- [Keyboard handling](#keyboard-handling)
|
|
22
24
|
- [Header height & font sizing](#header-height--font-sizing)
|
|
23
25
|
- [Dark theme](#dark-theme)
|
|
@@ -78,6 +80,8 @@ npx expo install \
|
|
|
78
80
|
|
|
79
81
|
> `expo-blur` is only used to frost the chat picture as the chat-profile header collapses. Skip it and that layer falls back to a plain dim — everything else is unaffected.
|
|
80
82
|
|
|
83
|
+
> Two more optional peers: `expo-haptics` (a short haptic tap when the message menu opens on long-press; without it the gesture is silent) and `react-native-mmkv` (the chat cache is stored in MMKV with native encryption; without it the SDK falls back to AsyncStorage with AES on the JS thread — noticeably slower with many rooms). Both need a native rebuild after installing.
|
|
84
|
+
|
|
81
85
|
> Video playback uses **`expo-video`** (`useVideoPlayer` / `VideoView`) and audio uses **`expo-audio`** (`createAudioPlayer` / `useAudioRecorder`). Install both. The discontinued `expo-av` is no longer used anywhere in the SDK, so consumers on Expo SDK 57 / RN 0.86 with the New Architecture can drop it.
|
|
82
86
|
|
|
83
87
|
> No `metro.config.js` shim is required. As of `26.5.5` the SDK no longer statically imports any legacy `react-native-*` native modules; the bundled `withEthoraShims` helper is preserved as a no-op for backward compat with older setups.
|
|
@@ -316,6 +320,95 @@ Why awaitable: the persistence layer debounces writes by 200 ms, and the chat sl
|
|
|
316
320
|
| `disableConnectionErrorOverlay` | Replaces the full-screen "Connection error" overlay with a small, non-blocking `ConnectionBanner`. Set this when a transient reconnect shouldn't take over the whole screen. |
|
|
317
321
|
| `eventHandlers.onMessageRetry` | `(event) => void` fired when the user taps the "Failed — tap to retry" indicator on a stuck send. Use for telemetry / surfacing a retry banner. |
|
|
318
322
|
|
|
323
|
+
## Message reactions
|
|
324
|
+
|
|
325
|
+
Emoji reactions on messages, WhatsApp-style. **On by default**, shared with the web SDK: a reaction set from either client shows up on the other.
|
|
326
|
+
|
|
327
|
+
- **Long-press a message** → a row of quick reactions appears above the bubble (👍 ❤️ 😂 😮 😢 🙏 by default) together with the Copy / Edit / Delete menu. Tapping an emoji sets it; tapping the same one again removes it.
|
|
328
|
+
- **"+"** at the end of the row opens a bottom sheet with the full emoji set: search, "Frequently used" (remembered on the device), categories, and a category bar at the bottom.
|
|
329
|
+
- **Under the bubble** every emoji used on the message shows as a chip with its count; the current user's own ones are tinted. Tap a chip to toggle your own reaction; long-press it to see who reacted.
|
|
330
|
+
- **In the room list** the preview shows the latest reaction (`Ann: 👍`) when it is the newest event in the room.
|
|
331
|
+
|
|
332
|
+
```tsx
|
|
333
|
+
<Chat
|
|
334
|
+
config={{
|
|
335
|
+
reactions: {
|
|
336
|
+
enabled: true, // false → no row, no chips, no picker
|
|
337
|
+
quickReactions: ['+1', 'heart', 'joy', 'open_mouth', 'cry', 'pray'], // up to 8
|
|
338
|
+
picker: true, // false → hides the "+" (quick row only)
|
|
339
|
+
},
|
|
340
|
+
}}
|
|
341
|
+
/>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
| Option | Default | What it does |
|
|
345
|
+
| --- | --- | --- |
|
|
346
|
+
| `reactions.enabled` | `true` | Turns the feature on/off. When off, reactions other users send are still received and stored, just not shown — switching it back on shows them. |
|
|
347
|
+
| `reactions.quickReactions` | `['+1','heart','joy','open_mouth','cry','pray']` | Ids shown in the row above the menu, in order (max 8). |
|
|
348
|
+
| `reactions.picker` | `true` | Whether the "+" that opens the full emoji picker is shown. |
|
|
349
|
+
| `disableReactions` | `false` | Legacy alias of `reactions.enabled: false`. |
|
|
350
|
+
| `disableInteractions` | `false` | Disables the whole long-press menu, the reaction row included; existing chips are still shown but no longer toggle. |
|
|
351
|
+
|
|
352
|
+
**Ids, not glyphs.** Reactions travel on the wire and are stored as emoji *short names* — `+1`, `heart`, `joy`, `fire`, `pray`, … — the same ids the web SDK uses, so both platforms read each other's reactions. The SDK ships its own id→glyph table (~1850 emoji, up to Emoji 14 so every supported OS renders them) and resolves ids when rendering; no emoji library is needed. In `message.reaction` the data is keyed by the reactor's XMPP local part: `{ alice: { emoji: ['joy', '+1'], data: { senderFirstName, senderLastName } } }`.
|
|
353
|
+
|
|
354
|
+
**Protocol.** One `<message type="groupchat" id="message-reaction:…">` with `<reactions xmlns="urn:xmpp:reactions:0" id="<target stanza id>" from="<reactor jid>">` and one `<reaction>` child per id — always the reactor's **full current list** (an empty `<reactions/>` clears them). Reactions are archived with the room's history and restored with it on every history fetch.
|
|
355
|
+
|
|
356
|
+
## Replies & threads
|
|
357
|
+
|
|
358
|
+
Same model as the web SDK, so threads are shared across platforms.
|
|
359
|
+
|
|
360
|
+
- **Reply** in the long-press menu opens the message's **thread**: the parent on top, its replies below, its own input. It slides in over the room and closes with the back arrow, Android back, or a swipe from the left edge.
|
|
361
|
+
- **"Also send to <room>"** under the thread input posts the reply in the channel too. There it shows a **quote** of the parent (author + two lines); tapping the quote opens the parent's thread.
|
|
362
|
+
- A message with replies gets a **"N replies" pill** under the bubble with the repliers' avatars; tapping it opens the thread.
|
|
363
|
+
- On the wire a reply is a normal message with `isReply="true"`, `showInChannel="true|false"` and `mainMessage` (JSON of the parent: `id`, `text`, `userName`, `roomJid`, …) in its `<data>`. Replies live in the room's history; nothing extra is fetched.
|
|
364
|
+
|
|
365
|
+
| Option | Default | What it does |
|
|
366
|
+
| --- | --- | --- |
|
|
367
|
+
| `disableReplies` | `false` | Hides "Reply" in the long-press menu. Existing pills and quotes still open threads. |
|
|
368
|
+
| `disableInteractions` | `false` | Hides the whole long-press menu, Reply included. |
|
|
369
|
+
|
|
370
|
+
## End-to-end encrypted rooms
|
|
371
|
+
|
|
372
|
+
OMEMO 2 in rooms the backend marks `e2ee` (`room.e2ee` from `GET /v1/chats/my`), wire-compatible with the web SDK. Status, measurements and limits are tracked in [`docs/e2ee-port.md`](docs/e2ee-port.md).
|
|
373
|
+
|
|
374
|
+
Off by default. The host turns it on or off through the config it passes to the chat:
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
// On: this device publishes its keys; text and attachments in `e2ee` rooms are encrypted.
|
|
378
|
+
config = { e2ee: { enabled: true } };
|
|
379
|
+
|
|
380
|
+
// Off (the default): leave the block out, or set `enabled: false`. Nothing is
|
|
381
|
+
// generated or published, and encrypted rooms are shown as such but cannot be
|
|
382
|
+
// written to from this app.
|
|
383
|
+
config = { e2ee: { enabled: false } };
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
The switch can be flipped at any time; it takes effect on the next mount of the chat. Keys made while it was on stay on the device and are reused when it is on again.
|
|
387
|
+
|
|
388
|
+
**With it on**, after connecting the SDK creates this device's keys (once per account per install; they survive logout), publishes them, and in encrypted rooms:
|
|
389
|
+
|
|
390
|
+
- encrypts the text of outgoing messages for every device of every member, and decrypts incoming ones — live, from mucsub and from history alike;
|
|
391
|
+
- sends in clear when no member has a device to encrypt for (nobody else has opened the room with encryption on yet), exactly as the web SDK does — and marks that message, like any other that arrived in clear, with a struck-through padlock;
|
|
392
|
+
- seals attachments and voice messages before upload, so the server stores opaque bytes under a random name and never sees the file, its name or its type; the receiver's "Encrypted file" card downloads and opens one on a tap, and then shows it as what it is. The cipher is pure JS: about 1.4 s per megabyte, capped at 20 MB per file. An attachment is never sent in clear - if it cannot be encrypted, it is not sent.
|
|
393
|
+
|
|
394
|
+
An encrypted chat is started from a user's profile: **Encrypted message**, next to **Message** (needs `newArch`). It opens the encrypted room of the pair, a room of its own beside their ordinary chat.
|
|
395
|
+
|
|
396
|
+
What is protected is the message text and the attachments. The sender, the room, the time and the quoted text of a reply stay readable to the server — it builds push notifications from them — and deletions and reactions travel in clear. An edit would too, so a message that went out encrypted cannot be edited from this SDK. Details and the open points are in `docs/e2ee-port.md`.
|
|
397
|
+
|
|
398
|
+
**Devices and trust.** Settings lists this account's devices with their fingerprints; a person's profile lists theirs, each marked *Not verified*, *Verified* or *Not trusted*, changed with a tap. A device is trusted on first sight until one of that person's devices has been verified; after that an unverified one is no longer encrypted for.
|
|
399
|
+
|
|
400
|
+
**With it off** nothing is generated, published or loaded, and an encrypted room is presented honestly rather than misread: the composer is replaced by a notice (`sendMessage` / `sendMedia` refuse the room), and what other clients encrypted shows as a padlock line instead of the sender's fallback body.
|
|
401
|
+
|
|
402
|
+
**Either way**, a room marked `e2ee` carries a padlock next to its name in the list and the header; a message that could not be opened says why ("Encrypted for another device", "Could not decrypt this message", or that this app does not read encrypted messages); a sealed attachment shows as an "Encrypted file" card rather than a voice message; none of these is offered for translation.
|
|
403
|
+
|
|
404
|
+
Message flags a custom message component can read: `unencrypted`, `undecryptable` (`'true'` when the body is a placeholder) with `e2eeError` (`'unsupported' | 'other-device' | 'failed'`), `clientEncrypted` (`'true'` for a sealed attachment) and `e2eeKeys`. The captions are the `e2ee.*` and `media.sealed*` keys of `config.i18n.strings`. `omemo()` returns the live device (`devices(jid)`, `setTrust`, `fingerprint`) for a host that wants to show them.
|
|
405
|
+
|
|
406
|
+
Requires an XMPP server that lets members read each other's OMEMO PEP nodes (`access_model: open`).
|
|
407
|
+
|
|
408
|
+
## Session loss
|
|
409
|
+
|
|
410
|
+
When the server rejects the XMPP password (SASL `not-authorized`) the SDK refreshes credentials and reconnects. If that cannot produce a working password — the refresh request fails, returns no new password, or the new one is rejected too — twice in a row, the session is ended exactly like **Sign out** (`performLogout`, then `logout.onAfterLogout`), so the host can route to its login screen. A network outage never triggers this: without a reachable server there is no rejection, and the client keeps reconnecting with backoff.
|
|
411
|
+
|
|
319
412
|
## Keyboard handling
|
|
320
413
|
|
|
321
414
|
| Flag | What it does |
|
|
@@ -548,6 +641,8 @@ npm test -- --watch # watch mode
|
|
|
548
641
|
npm test -- some.test.ts # single file
|
|
549
642
|
```
|
|
550
643
|
|
|
644
|
+
`npm run e2ee:interop` checks the end-to-end encryption against the web SDK's (sessions, mixed rooms, attachments). It needs `ethora-chat-component` checked out next to this repository, or `WEB_SDK=/path`; without it, it skips.
|
|
645
|
+
|
|
551
646
|
### E2E (Maestro)
|
|
552
647
|
|
|
553
648
|
`e2e/auth-and-send.yaml` drives the full Setup → Email auth → Chat
|