@ethora/chat-component-rn 26.8.6 → 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 +40 -0
- package/lib/commonjs/assets/icons.js +4 -2
- package/lib/commonjs/assets/icons.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatHeader.js +28 -6
- package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatRoom.js +9 -1
- package/lib/commonjs/components/MainComponents/ChatRoom.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/ReduxWrapper.js +5 -0
- package/lib/commonjs/components/MainComponents/ReduxWrapper.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/MessageBubble/BottomReplyContainer.js +2 -1
- package/lib/commonjs/components/MessageBubble/BottomReplyContainer.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/Message.js +66 -6
- package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js +2 -1
- package/lib/commonjs/components/MessageBubble/MessageInteractions.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/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 +32 -9
- 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/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 +53 -45
- 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/SendInput.js +4 -2
- package/lib/commonjs/components/styled/SendInput.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/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/persistCrypto.js +5 -0
- package/lib/commonjs/helpers/persistCrypto.js.map +1 -1
- package/lib/commonjs/helpers/secureKeyValue.js +20 -0
- package/lib/commonjs/helpers/secureKeyValue.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/useLogout.js +8 -0
- package/lib/commonjs/hooks/useLogout.js.map +1 -1
- package/lib/commonjs/hooks/useSendMessage.js +71 -7
- package/lib/commonjs/hooks/useSendMessage.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/xmpp/handleStanzas.xmpp.js +40 -0
- package/lib/commonjs/networking/xmpp/handleStanzas.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 +6 -0
- package/lib/commonjs/networking/xmppClient.js.map +1 -1
- package/lib/commonjs/roomStore/persistBackend.js +9 -12
- package/lib/commonjs/roomStore/persistBackend.js.map +1 -1
- package/lib/commonjs/roomStore/persistence.js +8 -1
- package/lib/commonjs/roomStore/persistence.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/module/assets/icons.js +3 -1
- package/lib/module/assets/icons.js.map +1 -1
- package/lib/module/components/MainComponents/ChatHeader.js +29 -7
- package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/module/components/MainComponents/ChatRoom.js +9 -1
- package/lib/module/components/MainComponents/ChatRoom.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/ReduxWrapper.js +5 -0
- package/lib/module/components/MainComponents/ReduxWrapper.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/MessageBubble/BottomReplyContainer.js +2 -1
- package/lib/module/components/MessageBubble/BottomReplyContainer.js.map +1 -1
- package/lib/module/components/MessageBubble/Message.js +69 -9
- package/lib/module/components/MessageBubble/Message.js.map +1 -1
- package/lib/module/components/MessageBubble/MessageInteractions.js +2 -1
- package/lib/module/components/MessageBubble/MessageInteractions.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/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 +32 -9
- 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/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 +54 -46
- 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/SendInput.js +4 -2
- package/lib/module/components/styled/SendInput.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/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/persistCrypto.js +4 -0
- package/lib/module/helpers/persistCrypto.js.map +1 -1
- package/lib/module/helpers/secureKeyValue.js +19 -0
- package/lib/module/helpers/secureKeyValue.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/useLogout.js +8 -0
- package/lib/module/hooks/useLogout.js.map +1 -1
- package/lib/module/hooks/useSendMessage.js +71 -7
- package/lib/module/hooks/useSendMessage.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/xmpp/handleStanzas.xmpp.js +38 -0
- package/lib/module/networking/xmpp/handleStanzas.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 +6 -0
- package/lib/module/networking/xmppClient.js.map +1 -1
- package/lib/module/roomStore/persistBackend.js +10 -13
- package/lib/module/roomStore/persistBackend.js.map +1 -1
- package/lib/module/roomStore/persistence.js +8 -1
- package/lib/module/roomStore/persistence.js.map +1 -1
- package/lib/module/version.js +1 -1
- 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/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/ReduxWrapper.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/MessageBubble/BottomReplyContainer.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/MessageInteractions.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/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.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/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.map +1 -1
- package/lib/typescript/components/UsersList/UsersList.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/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/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/persistCrypto.d.ts +1 -0
- package/lib/typescript/helpers/persistCrypto.d.ts.map +1 -1
- package/lib/typescript/helpers/secureKeyValue.d.ts +4 -0
- package/lib/typescript/helpers/secureKeyValue.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/useLogout.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/xmpp/handleStanzas.xmpp.d.ts +1 -0
- package/lib/typescript/networking/xmpp/handleStanzas.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.map +1 -1
- package/lib/typescript/roomStore/persistBackend.d.ts.map +1 -1
- package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
- package/lib/typescript/types/models/message.model.d.ts +5 -0
- package/lib/typescript/types/models/message.model.d.ts.map +1 -1
- package/lib/typescript/types/models/room.model.d.ts +5 -0
- package/lib/typescript/types/models/room.model.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +4 -0
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/lib/typescript/version.d.ts +1 -1
- package/package.json +8 -4
- package/src/assets/icons.tsx +27 -0
- package/src/components/MainComponents/ChatHeader.tsx +30 -9
- package/src/components/MainComponents/ChatRoom.tsx +11 -1
- 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/ReduxWrapper.tsx +5 -0
- package/src/components/MainComponents/SealedAttachment.tsx +251 -0
- package/src/components/MessageBubble/BottomReplyContainer.tsx +2 -1
- package/src/components/MessageBubble/Message.tsx +96 -6
- package/src/components/MessageBubble/MessageInteractions.tsx +2 -3
- 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/UserProfileModal/UserProfileModal.tsx +53 -8
- package/src/components/Modals/UserSettingsModal/UserSettingsModal.tsx +5 -0
- package/src/components/RoomComponents/ChatRoomItem.tsx +23 -11
- package/src/components/RoomComponents/LastMessageItem.tsx +5 -0
- package/src/components/RoomComponents/styled/LastAudioMessage.tsx +3 -1
- 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 +13 -0
- package/src/components/UsersList/UsersList.tsx +2 -1
- package/src/components/styled/SendInput.tsx +5 -2
- 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/createUserNameFromSetUser.ts +2 -1
- package/src/helpers/displayName.ts +9 -0
- package/src/helpers/persistCrypto.ts +5 -0
- package/src/helpers/secureKeyValue.ts +15 -0
- package/src/helpers/videoCache.ts +138 -0
- package/src/hooks/useLogout.tsx +9 -0
- package/src/hooks/useSendMessage.tsx +71 -5
- 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/xmpp/handleStanzas.xmpp.ts +49 -0
- 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 +6 -0
- package/src/roomStore/persistBackend.ts +8 -11
- package/src/roomStore/persistence.ts +15 -0
- package/src/types/models/message.model.ts +5 -0
- package/src/types/models/room.model.ts +5 -0
- package/src/types/types.ts +4 -0
- package/src/version.ts +1 -1
|
@@ -15,6 +15,9 @@ import { RootState, store } from '../roomStore';
|
|
|
15
15
|
import { getGlobalXmppClient } from '../utils/clientRegistry';
|
|
16
16
|
import { useEventHandlers } from './useEventHandlers';
|
|
17
17
|
import type { IConfig, IMessage } from '../types/types';
|
|
18
|
+
import { canEditMessage, canSendMediaToRoom, canSendToRoom } from '../e2ee';
|
|
19
|
+
import { shouldEncrypt } from '../e2ee/send';
|
|
20
|
+
import type { SealedUpload } from '../e2ee/sealedFiles';
|
|
18
21
|
|
|
19
22
|
// Watchdog: if a message stays "pending" (no server echo) for this
|
|
20
23
|
// long after the optimistic dispatch, mark it failed so the bubble
|
|
@@ -103,6 +106,16 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
103
106
|
existingId?: string
|
|
104
107
|
) => {
|
|
105
108
|
if (editAction?.isEdit) {
|
|
109
|
+
const edited = reduxStore
|
|
110
|
+
.getState()
|
|
111
|
+
.rooms?.rooms?.[editAction.roomJid!]?.messages?.find(
|
|
112
|
+
(m: IMessage) => m.id === editAction.messageId
|
|
113
|
+
);
|
|
114
|
+
if (edited && !canEditMessage(edited)) {
|
|
115
|
+
console.warn('edit not sent: the message was encrypted');
|
|
116
|
+
dispatch(setEditAction({ isEdit: false }));
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
106
119
|
try {
|
|
107
120
|
client?.editMessageStanza(
|
|
108
121
|
editAction.roomJid!,
|
|
@@ -127,6 +140,11 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
127
140
|
return;
|
|
128
141
|
}
|
|
129
142
|
|
|
143
|
+
if (!canSendToRoom(activeRoomJID)) {
|
|
144
|
+
console.warn('message not sent: room is end-to-end encrypted');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
130
148
|
// Critical-send hint to the QoS scheduler.
|
|
131
149
|
client?.onCriticalSend?.(activeRoomJID);
|
|
132
150
|
|
|
@@ -355,6 +373,11 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
355
373
|
mainMessage: string = '',
|
|
356
374
|
existingId?: string
|
|
357
375
|
) => {
|
|
376
|
+
if (!canSendMediaToRoom(activeRoomJID)) {
|
|
377
|
+
console.warn('media not sent: room is end-to-end encrypted');
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
|
|
358
381
|
client?.onCriticalSend?.(activeRoomJID);
|
|
359
382
|
|
|
360
383
|
// Defensive 50 MB guard on every send path (SendInput blocks it at
|
|
@@ -509,20 +532,36 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
509
532
|
name: data?.name || data?.fileName || `media_${Date.now()}`,
|
|
510
533
|
};
|
|
511
534
|
|
|
535
|
+
let sealed: SealedUpload | undefined;
|
|
536
|
+
|
|
512
537
|
const tryUpload = async () => {
|
|
538
|
+
if (shouldEncrypt(activeRoomJID) && !sealed) {
|
|
539
|
+
const { sealPickedFile } =
|
|
540
|
+
require('../e2ee/sealedFiles') as typeof import('../e2ee/sealedFiles');
|
|
541
|
+
sealed = await sealPickedFile({
|
|
542
|
+
uri: fileBlob.uri,
|
|
543
|
+
name: fileBlob.name,
|
|
544
|
+
type: fileBlob.type,
|
|
545
|
+
size: typeof data?.size === 'number' ? data.size : undefined,
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
const part = sealed
|
|
549
|
+
? { uri: sealed.uri, type: 'application/octet-stream', name: sealed.name }
|
|
550
|
+
: fileBlob;
|
|
551
|
+
const options = { clientEncrypted: !!sealed };
|
|
513
552
|
const fd = new FormData();
|
|
514
|
-
fd.append('files',
|
|
553
|
+
fd.append('files', part as any);
|
|
515
554
|
try {
|
|
516
|
-
return await uploadFileV2(fd, activeRoomJID);
|
|
555
|
+
return await uploadFileV2(fd, activeRoomJID, options);
|
|
517
556
|
} catch (err: any) {
|
|
518
557
|
if (err?.response?.status === 500) {
|
|
519
558
|
console.warn(
|
|
520
559
|
'upload "files" field returned 500 — retrying with "file" (singular)',
|
|
521
|
-
{ name:
|
|
560
|
+
{ name: part.name, type: part.type }
|
|
522
561
|
);
|
|
523
562
|
const fd2 = new FormData();
|
|
524
|
-
fd2.append('file',
|
|
525
|
-
return await uploadFileV2(fd2, activeRoomJID);
|
|
563
|
+
fd2.append('file', part as any);
|
|
564
|
+
return await uploadFileV2(fd2, activeRoomJID, options);
|
|
526
565
|
}
|
|
527
566
|
throw err;
|
|
528
567
|
}
|
|
@@ -562,7 +601,23 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
562
601
|
mainMessage,
|
|
563
602
|
isPrivate: item?.isPrivate,
|
|
564
603
|
__v: item.__v,
|
|
604
|
+
e2eeKeys: sealed ? [sealed.keyMaterial] : undefined,
|
|
565
605
|
};
|
|
606
|
+
if (sealed) {
|
|
607
|
+
try {
|
|
608
|
+
const { rememberOpened } =
|
|
609
|
+
require('../e2ee/sealedFiles') as typeof import('../e2ee/sealedFiles');
|
|
610
|
+
await rememberOpened(item.location, {
|
|
611
|
+
uri: fileBlob.uri,
|
|
612
|
+
name: fileBlob.name,
|
|
613
|
+
type: fileBlob.type,
|
|
614
|
+
size: typeof data?.size === 'number' ? data.size : undefined,
|
|
615
|
+
});
|
|
616
|
+
} catch (err) {
|
|
617
|
+
console.warn('could not keep the sent attachment', err);
|
|
618
|
+
}
|
|
619
|
+
sealed.dispose();
|
|
620
|
+
}
|
|
566
621
|
// Stanza id == placeholder id so the MUC echo's outer
|
|
567
622
|
// <message id="..."> matches xmppId on the placeholder and
|
|
568
623
|
// insertMessageWithDelimiter merges in place + flips pending.
|
|
@@ -627,6 +682,7 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
627
682
|
// Upload (or stanza send) threw an explicit error. Clear the
|
|
628
683
|
// watchdog so it doesn't double-fire `markMessageFailed`.
|
|
629
684
|
clearTimeout(mediaWatchdog);
|
|
685
|
+
sealed?.dispose();
|
|
630
686
|
// Surface the real server payload so we can see why the upload
|
|
631
687
|
// was rejected (axios collapses the message to "Request failed
|
|
632
688
|
// with status code N"; the actual reason lives in
|
|
@@ -738,6 +794,16 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
738
794
|
if (!editAction?.isEdit || !editAction.roomJid || !editAction.messageId) {
|
|
739
795
|
return;
|
|
740
796
|
}
|
|
797
|
+
const edited = reduxStore
|
|
798
|
+
.getState()
|
|
799
|
+
.rooms?.rooms?.[editAction.roomJid]?.messages?.find(
|
|
800
|
+
(m: IMessage) => m.id === editAction.messageId
|
|
801
|
+
);
|
|
802
|
+
if (edited && !canEditMessage(edited)) {
|
|
803
|
+
console.warn('edit not sent: the message was encrypted');
|
|
804
|
+
dispatch(setEditAction({ isEdit: false }));
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
741
807
|
try {
|
|
742
808
|
client?.editMessageStanza(
|
|
743
809
|
editAction.roomJid,
|
package/src/i18n/strings.ts
CHANGED
|
@@ -25,6 +25,35 @@ const en: UiStringTable = {
|
|
|
25
25
|
'date.yesterday': 'Yesterday',
|
|
26
26
|
'message.deleted': 'Message deleted',
|
|
27
27
|
'message.edited': 'edited',
|
|
28
|
+
'e2ee.roomEncrypted': 'End-to-end encrypted',
|
|
29
|
+
'e2ee.notEncrypted': 'Not encrypted',
|
|
30
|
+
'e2ee.notEncryptedHint': 'Sent without end-to-end encryption, because no recipient has published a key yet.',
|
|
31
|
+
'e2ee.devices.title': 'End-to-end encryption',
|
|
32
|
+
'e2ee.devices.thisDevice': 'This device',
|
|
33
|
+
'e2ee.devices.otherDevices': 'Other devices',
|
|
34
|
+
'e2ee.devices.none': 'Has not opened an encrypted chat yet',
|
|
35
|
+
'e2ee.devices.noneOwn': 'No other devices',
|
|
36
|
+
'e2ee.devices.unavailable': 'Encryption is not running on this device right now',
|
|
37
|
+
'e2ee.devices.loading': 'Loading devices…',
|
|
38
|
+
'e2ee.devices.hint': "Compare a fingerprint with the one shown on the other person's device. Mark it verified only if they match.",
|
|
39
|
+
'e2ee.trust.verified': 'Verified',
|
|
40
|
+
'e2ee.trust.blind': 'Not verified',
|
|
41
|
+
'e2ee.trust.untrusted': 'Not trusted',
|
|
42
|
+
'e2ee.trust.verify': 'Mark as verified',
|
|
43
|
+
'e2ee.trust.distrust': 'Stop trusting',
|
|
44
|
+
'e2ee.trust.reset': 'Clear the mark',
|
|
45
|
+
'e2ee.trust.prompt': 'Device {id}',
|
|
46
|
+
'e2ee.devices.copied': 'Fingerprint copied',
|
|
47
|
+
'e2ee.unsupportedMessage': "Encrypted message. This version of the app can't read it yet.",
|
|
48
|
+
'e2ee.otherDevice': 'Encrypted for another device',
|
|
49
|
+
'e2ee.undecryptable': 'Could not decrypt this message',
|
|
50
|
+
'e2ee.sendUnavailable': "This chat is end-to-end encrypted. Sending from the mobile app isn't available yet.",
|
|
51
|
+
'media.sealedFile': 'Encrypted file',
|
|
52
|
+
'media.sealedUnsupported': "Can't be opened in this version of the app yet",
|
|
53
|
+
'media.sealedUnavailable': 'Encrypted attachment could not be opened',
|
|
54
|
+
'media.sealedDownload': 'Download and decrypt',
|
|
55
|
+
'media.sealedDownloading': 'Decrypting…',
|
|
56
|
+
'media.sealedDownloadFailed': 'Download failed — tap to retry',
|
|
28
57
|
'message.newMessages': 'New messages',
|
|
29
58
|
'notification.senderFallback': 'New message',
|
|
30
59
|
'presence.online': 'online',
|
|
@@ -169,6 +198,7 @@ const en: UiStringTable = {
|
|
|
169
198
|
'field.referralCode': 'Your referral code',
|
|
170
199
|
'action.logOut': 'Log Out',
|
|
171
200
|
'action.message': 'Message',
|
|
201
|
+
'action.encryptedMessage': 'Encrypted message',
|
|
172
202
|
'action.videoCall': 'Video call',
|
|
173
203
|
'action.call': 'Call',
|
|
174
204
|
'action.audioCall': 'Audio call',
|
|
@@ -283,6 +313,35 @@ const fr: UiStringTable = {
|
|
|
283
313
|
'date.yesterday': 'Hier',
|
|
284
314
|
'message.deleted': 'Message supprimé',
|
|
285
315
|
'message.edited': 'modifié',
|
|
316
|
+
'e2ee.roomEncrypted': 'Chiffré de bout en bout',
|
|
317
|
+
'e2ee.notEncrypted': 'Non chiffré',
|
|
318
|
+
'e2ee.notEncryptedHint': "Envoyé sans chiffrement de bout en bout, car aucun destinataire n'a encore publié de clé.",
|
|
319
|
+
'e2ee.devices.title': 'Chiffrement de bout en bout',
|
|
320
|
+
'e2ee.devices.thisDevice': 'Cet appareil',
|
|
321
|
+
'e2ee.devices.otherDevices': 'Autres appareils',
|
|
322
|
+
'e2ee.devices.none': "N'a pas encore ouvert de discussion chiffrée",
|
|
323
|
+
'e2ee.devices.noneOwn': 'Aucun autre appareil',
|
|
324
|
+
'e2ee.devices.unavailable': "Le chiffrement n'est pas actif sur cet appareil pour le moment",
|
|
325
|
+
'e2ee.devices.loading': 'Chargement des appareils…',
|
|
326
|
+
'e2ee.devices.hint': "Comparez une empreinte avec celle affichée sur l'appareil de l'autre personne. Ne la marquez comme vérifiée que si elles correspondent.",
|
|
327
|
+
'e2ee.trust.verified': 'Vérifié',
|
|
328
|
+
'e2ee.trust.blind': 'Non vérifié',
|
|
329
|
+
'e2ee.trust.untrusted': 'Non fiable',
|
|
330
|
+
'e2ee.trust.verify': 'Marquer comme vérifié',
|
|
331
|
+
'e2ee.trust.distrust': 'Ne plus faire confiance',
|
|
332
|
+
'e2ee.trust.reset': 'Effacer la marque',
|
|
333
|
+
'e2ee.trust.prompt': 'Appareil {id}',
|
|
334
|
+
'e2ee.devices.copied': 'Empreinte copiée',
|
|
335
|
+
'e2ee.unsupportedMessage': "Message chiffré. Cette version de l'application ne peut pas encore le lire.",
|
|
336
|
+
'e2ee.otherDevice': 'Chiffré pour un autre appareil',
|
|
337
|
+
'e2ee.undecryptable': 'Impossible de déchiffrer ce message',
|
|
338
|
+
'e2ee.sendUnavailable': "Cette discussion est chiffrée de bout en bout. L'envoi depuis l'application mobile n'est pas encore disponible.",
|
|
339
|
+
'media.sealedFile': 'Fichier chiffré',
|
|
340
|
+
'media.sealedUnsupported': "Ne peut pas encore être ouvert dans cette version de l'application",
|
|
341
|
+
'media.sealedUnavailable': "La pièce jointe chiffrée n'a pas pu être ouverte",
|
|
342
|
+
'media.sealedDownload': 'Télécharger et déchiffrer',
|
|
343
|
+
'media.sealedDownloading': 'Déchiffrement…',
|
|
344
|
+
'media.sealedDownloadFailed': 'Échec du téléchargement — appuyez pour réessayer',
|
|
286
345
|
'message.newMessages': 'Nouveaux messages',
|
|
287
346
|
'notification.senderFallback': 'Nouveau message',
|
|
288
347
|
'presence.online': 'en ligne',
|
|
@@ -427,6 +486,7 @@ const fr: UiStringTable = {
|
|
|
427
486
|
'field.referralCode': 'Votre code de parrainage',
|
|
428
487
|
'action.logOut': 'Déconnexion',
|
|
429
488
|
'action.message': 'Message',
|
|
489
|
+
'action.encryptedMessage': 'Message chiffré',
|
|
430
490
|
'action.videoCall': 'Appel vidéo',
|
|
431
491
|
'action.call': 'Appeler',
|
|
432
492
|
'action.audioCall': 'Appel audio',
|
|
@@ -541,6 +601,35 @@ const es: UiStringTable = {
|
|
|
541
601
|
'date.yesterday': 'Ayer',
|
|
542
602
|
'message.deleted': 'Mensaje eliminado',
|
|
543
603
|
'message.edited': 'editado',
|
|
604
|
+
'e2ee.roomEncrypted': 'Cifrado de extremo a extremo',
|
|
605
|
+
'e2ee.notEncrypted': 'Sin cifrar',
|
|
606
|
+
'e2ee.notEncryptedHint': 'Enviado sin cifrado de extremo a extremo, porque ningún destinatario ha publicado una clave todavía.',
|
|
607
|
+
'e2ee.devices.title': 'Cifrado de extremo a extremo',
|
|
608
|
+
'e2ee.devices.thisDevice': 'Este dispositivo',
|
|
609
|
+
'e2ee.devices.otherDevices': 'Otros dispositivos',
|
|
610
|
+
'e2ee.devices.none': 'Aún no ha abierto un chat cifrado',
|
|
611
|
+
'e2ee.devices.noneOwn': 'No hay otros dispositivos',
|
|
612
|
+
'e2ee.devices.unavailable': 'El cifrado no está activo en este dispositivo en este momento',
|
|
613
|
+
'e2ee.devices.loading': 'Cargando dispositivos…',
|
|
614
|
+
'e2ee.devices.hint': 'Compara una huella con la que aparece en el dispositivo de la otra persona. Márcala como verificada solo si coinciden.',
|
|
615
|
+
'e2ee.trust.verified': 'Verificado',
|
|
616
|
+
'e2ee.trust.blind': 'Sin verificar',
|
|
617
|
+
'e2ee.trust.untrusted': 'No fiable',
|
|
618
|
+
'e2ee.trust.verify': 'Marcar como verificado',
|
|
619
|
+
'e2ee.trust.distrust': 'Dejar de confiar',
|
|
620
|
+
'e2ee.trust.reset': 'Quitar la marca',
|
|
621
|
+
'e2ee.trust.prompt': 'Dispositivo {id}',
|
|
622
|
+
'e2ee.devices.copied': 'Huella copiada',
|
|
623
|
+
'e2ee.unsupportedMessage': 'Mensaje cifrado. Esta versión de la aplicación aún no puede leerlo.',
|
|
624
|
+
'e2ee.otherDevice': 'Cifrado para otro dispositivo',
|
|
625
|
+
'e2ee.undecryptable': 'No se pudo descifrar este mensaje',
|
|
626
|
+
'e2ee.sendUnavailable': 'Este chat está cifrado de extremo a extremo. El envío desde la aplicación móvil aún no está disponible.',
|
|
627
|
+
'media.sealedFile': 'Archivo cifrado',
|
|
628
|
+
'media.sealedUnsupported': 'Aún no se puede abrir en esta versión de la aplicación',
|
|
629
|
+
'media.sealedUnavailable': 'No se pudo abrir el archivo adjunto cifrado',
|
|
630
|
+
'media.sealedDownload': 'Descargar y descifrar',
|
|
631
|
+
'media.sealedDownloading': 'Descifrando…',
|
|
632
|
+
'media.sealedDownloadFailed': 'Error de descarga: toca para reintentar',
|
|
544
633
|
'message.newMessages': 'Nuevos mensajes',
|
|
545
634
|
'notification.senderFallback': 'Nuevo mensaje',
|
|
546
635
|
'presence.online': 'en línea',
|
|
@@ -685,6 +774,7 @@ const es: UiStringTable = {
|
|
|
685
774
|
'field.referralCode': 'Tu código de referido',
|
|
686
775
|
'action.logOut': 'Cerrar sesión',
|
|
687
776
|
'action.message': 'Mensaje',
|
|
777
|
+
'action.encryptedMessage': 'Mensaje cifrado',
|
|
688
778
|
'action.videoCall': 'Videollamada',
|
|
689
779
|
'action.call': 'Llamar',
|
|
690
780
|
'action.audioCall': 'Llamada de audio',
|
|
@@ -799,6 +889,35 @@ const pt: UiStringTable = {
|
|
|
799
889
|
'date.yesterday': 'Ontem',
|
|
800
890
|
'message.deleted': 'Mensagem eliminada',
|
|
801
891
|
'message.edited': 'editado',
|
|
892
|
+
'e2ee.roomEncrypted': 'Criptografado de ponta a ponta',
|
|
893
|
+
'e2ee.notEncrypted': 'Sem criptografia',
|
|
894
|
+
'e2ee.notEncryptedHint': 'Enviado sem criptografia de ponta a ponta, porque nenhum destinatário publicou uma chave ainda.',
|
|
895
|
+
'e2ee.devices.title': 'Criptografia de ponta a ponta',
|
|
896
|
+
'e2ee.devices.thisDevice': 'Este dispositivo',
|
|
897
|
+
'e2ee.devices.otherDevices': 'Outros dispositivos',
|
|
898
|
+
'e2ee.devices.none': 'Ainda não abriu uma conversa criptografada',
|
|
899
|
+
'e2ee.devices.noneOwn': 'Nenhum outro dispositivo',
|
|
900
|
+
'e2ee.devices.unavailable': 'A criptografia não está ativa neste dispositivo no momento',
|
|
901
|
+
'e2ee.devices.loading': 'Carregando dispositivos…',
|
|
902
|
+
'e2ee.devices.hint': 'Compare uma impressão digital com a exibida no dispositivo da outra pessoa. Marque como verificada somente se coincidirem.',
|
|
903
|
+
'e2ee.trust.verified': 'Verificado',
|
|
904
|
+
'e2ee.trust.blind': 'Não verificado',
|
|
905
|
+
'e2ee.trust.untrusted': 'Não confiável',
|
|
906
|
+
'e2ee.trust.verify': 'Marcar como verificado',
|
|
907
|
+
'e2ee.trust.distrust': 'Deixar de confiar',
|
|
908
|
+
'e2ee.trust.reset': 'Remover a marca',
|
|
909
|
+
'e2ee.trust.prompt': 'Dispositivo {id}',
|
|
910
|
+
'e2ee.devices.copied': 'Impressão digital copiada',
|
|
911
|
+
'e2ee.unsupportedMessage': 'Mensagem criptografada. Esta versão do aplicativo ainda não consegue lê-la.',
|
|
912
|
+
'e2ee.otherDevice': 'Criptografado para outro dispositivo',
|
|
913
|
+
'e2ee.undecryptable': 'Não foi possível descriptografar esta mensagem',
|
|
914
|
+
'e2ee.sendUnavailable': 'Esta conversa é criptografada de ponta a ponta. O envio pelo aplicativo móvel ainda não está disponível.',
|
|
915
|
+
'media.sealedFile': 'Arquivo criptografado',
|
|
916
|
+
'media.sealedUnsupported': 'Ainda não pode ser aberto nesta versão do aplicativo',
|
|
917
|
+
'media.sealedUnavailable': 'Não foi possível abrir o anexo criptografado',
|
|
918
|
+
'media.sealedDownload': 'Baixar e descriptografar',
|
|
919
|
+
'media.sealedDownloading': 'Descriptografando…',
|
|
920
|
+
'media.sealedDownloadFailed': 'Falha no download — toque para tentar novamente',
|
|
802
921
|
'message.newMessages': 'Novas mensagens',
|
|
803
922
|
'notification.senderFallback': 'Nova mensagem',
|
|
804
923
|
'presence.online': 'online',
|
|
@@ -943,6 +1062,7 @@ const pt: UiStringTable = {
|
|
|
943
1062
|
'field.referralCode': 'O seu código de referência',
|
|
944
1063
|
'action.logOut': 'Terminar sessão',
|
|
945
1064
|
'action.message': 'Mensagem',
|
|
1065
|
+
'action.encryptedMessage': 'Mensagem criptografada',
|
|
946
1066
|
'action.videoCall': 'Videochamada',
|
|
947
1067
|
'action.call': 'Ligar',
|
|
948
1068
|
'action.audioCall': 'Chamada de áudio',
|
|
@@ -1057,6 +1177,35 @@ const ht: UiStringTable = {
|
|
|
1057
1177
|
'date.yesterday': 'Yè',
|
|
1058
1178
|
'message.deleted': 'Mesaj efase',
|
|
1059
1179
|
'message.edited': 'modifye',
|
|
1180
|
+
'e2ee.roomEncrypted': 'Chifre bout-a-bout',
|
|
1181
|
+
'e2ee.notEncrypted': 'Pa chifre',
|
|
1182
|
+
'e2ee.notEncryptedHint': 'Voye san chifraj bout-a-bout, paske okenn moun ki resevwa a poko pibliye yon kle.',
|
|
1183
|
+
'e2ee.devices.title': 'Chifraj bout-a-bout',
|
|
1184
|
+
'e2ee.devices.thisDevice': 'Aparèy sa a',
|
|
1185
|
+
'e2ee.devices.otherDevices': 'Lòt aparèy',
|
|
1186
|
+
'e2ee.devices.none': 'Poko louvri yon chat chifre',
|
|
1187
|
+
'e2ee.devices.noneOwn': 'Pa gen lòt aparèy',
|
|
1188
|
+
'e2ee.devices.unavailable': 'Chifraj la pa aktif sou aparèy sa a kounye a',
|
|
1189
|
+
'e2ee.devices.loading': 'Ap chaje aparèy yo…',
|
|
1190
|
+
'e2ee.devices.hint': 'Konpare yon anprent ak sa ki parèt sou aparèy lòt moun nan. Make li kòm verifye sèlman si yo menm.',
|
|
1191
|
+
'e2ee.trust.verified': 'Verifye',
|
|
1192
|
+
'e2ee.trust.blind': 'Pa verifye',
|
|
1193
|
+
'e2ee.trust.untrusted': 'Pa fè konfyans',
|
|
1194
|
+
'e2ee.trust.verify': 'Make kòm verifye',
|
|
1195
|
+
'e2ee.trust.distrust': 'Sispann fè konfyans',
|
|
1196
|
+
'e2ee.trust.reset': 'Retire mak la',
|
|
1197
|
+
'e2ee.trust.prompt': 'Aparèy {id}',
|
|
1198
|
+
'e2ee.devices.copied': 'Anprent kopye',
|
|
1199
|
+
'e2ee.unsupportedMessage': 'Mesaj chifre. Vèsyon aplikasyon sa a poko ka li li.',
|
|
1200
|
+
'e2ee.otherDevice': 'Chifre pou yon lòt aparèy',
|
|
1201
|
+
'e2ee.undecryptable': 'Nou pa t kapab dechifre mesaj sa a',
|
|
1202
|
+
'e2ee.sendUnavailable': 'Chat sa a chifre bout-a-bout. Voye mesaj depi aplikasyon mobil la poko disponib.',
|
|
1203
|
+
'media.sealedFile': 'Fichye chifre',
|
|
1204
|
+
'media.sealedUnsupported': 'Poko ka louvri nan vèsyon aplikasyon sa a',
|
|
1205
|
+
'media.sealedUnavailable': 'Nou pa t kapab louvri atachman chifre a',
|
|
1206
|
+
'media.sealedDownload': 'Telechaje epi dechifre',
|
|
1207
|
+
'media.sealedDownloading': 'Ap dechifre…',
|
|
1208
|
+
'media.sealedDownloadFailed': 'Telechajman echwe — peze pou reeseye',
|
|
1060
1209
|
'message.newMessages': 'Nouvo mesaj yo',
|
|
1061
1210
|
'notification.senderFallback': 'Nouvo mesaj',
|
|
1062
1211
|
'presence.online': 'an liy',
|
|
@@ -1201,6 +1350,7 @@ const ht: UiStringTable = {
|
|
|
1201
1350
|
'field.referralCode': 'Kòd referans ou',
|
|
1202
1351
|
'action.logOut': 'Dekonekte',
|
|
1203
1352
|
'action.message': 'Mesaj',
|
|
1353
|
+
'action.encryptedMessage': 'Mesaj chifre',
|
|
1204
1354
|
'action.videoCall': 'Apèl videyo',
|
|
1205
1355
|
'action.call': 'Rele',
|
|
1206
1356
|
'action.audioCall': 'Apèl odyo',
|
|
@@ -1315,6 +1465,35 @@ const zh: UiStringTable = {
|
|
|
1315
1465
|
'date.yesterday': '昨天',
|
|
1316
1466
|
'message.deleted': '消息已删除',
|
|
1317
1467
|
'message.edited': '已编辑',
|
|
1468
|
+
'e2ee.roomEncrypted': '端到端加密',
|
|
1469
|
+
'e2ee.notEncrypted': '未加密',
|
|
1470
|
+
'e2ee.notEncryptedHint': '未使用端到端加密发送,因为还没有收件人发布密钥。',
|
|
1471
|
+
'e2ee.devices.title': '端到端加密',
|
|
1472
|
+
'e2ee.devices.thisDevice': '此设备',
|
|
1473
|
+
'e2ee.devices.otherDevices': '其他设备',
|
|
1474
|
+
'e2ee.devices.none': '尚未打开过加密聊天',
|
|
1475
|
+
'e2ee.devices.noneOwn': '没有其他设备',
|
|
1476
|
+
'e2ee.devices.unavailable': '此设备上的加密当前未运行',
|
|
1477
|
+
'e2ee.devices.loading': '正在加载设备…',
|
|
1478
|
+
'e2ee.devices.hint': '将指纹与对方设备上显示的指纹进行比较。仅在两者一致时才标记为已验证。',
|
|
1479
|
+
'e2ee.trust.verified': '已验证',
|
|
1480
|
+
'e2ee.trust.blind': '未验证',
|
|
1481
|
+
'e2ee.trust.untrusted': '不受信任',
|
|
1482
|
+
'e2ee.trust.verify': '标记为已验证',
|
|
1483
|
+
'e2ee.trust.distrust': '停止信任',
|
|
1484
|
+
'e2ee.trust.reset': '清除标记',
|
|
1485
|
+
'e2ee.trust.prompt': '设备 {id}',
|
|
1486
|
+
'e2ee.devices.copied': '指纹已复制',
|
|
1487
|
+
'e2ee.unsupportedMessage': '加密消息。此版本的应用暂时无法读取。',
|
|
1488
|
+
'e2ee.otherDevice': '已为其他设备加密',
|
|
1489
|
+
'e2ee.undecryptable': '无法解密此消息',
|
|
1490
|
+
'e2ee.sendUnavailable': '此聊天已启用端到端加密,暂不支持从移动应用发送消息。',
|
|
1491
|
+
'media.sealedFile': '加密文件',
|
|
1492
|
+
'media.sealedUnsupported': '此版本的应用暂时无法打开',
|
|
1493
|
+
'media.sealedUnavailable': '无法打开加密附件',
|
|
1494
|
+
'media.sealedDownload': '下载并解密',
|
|
1495
|
+
'media.sealedDownloading': '正在解密…',
|
|
1496
|
+
'media.sealedDownloadFailed': '下载失败 — 点击重试',
|
|
1318
1497
|
'message.newMessages': '新消息',
|
|
1319
1498
|
'notification.senderFallback': '新消息',
|
|
1320
1499
|
'presence.online': '在线',
|
|
@@ -1459,6 +1638,7 @@ const zh: UiStringTable = {
|
|
|
1459
1638
|
'field.referralCode': '您的推荐码',
|
|
1460
1639
|
'action.logOut': '退出登录',
|
|
1461
1640
|
'action.message': '发消息',
|
|
1641
|
+
'action.encryptedMessage': '加密消息',
|
|
1462
1642
|
'action.videoCall': '视频通话',
|
|
1463
1643
|
'action.call': '通话',
|
|
1464
1644
|
'action.audioCall': '语音通话',
|
package/src/main.ts
CHANGED
|
@@ -123,3 +123,5 @@ export {
|
|
|
123
123
|
export type { ChatTheme, ChatThemeColors, ChatThemeOverrides } from './theme';
|
|
124
124
|
export type { ThemePreference } from './theme/theme';
|
|
125
125
|
export { setThemePreference, setPushEnabled } from './roomStore/chatSettingsSlice';
|
|
126
|
+
export { omemo, isE2eeEnabled } from './e2ee';
|
|
127
|
+
export type { DeviceInfo, Trust } from './e2ee';
|
|
@@ -266,10 +266,18 @@ const canFallBackToLegacyUpload = (error: unknown): boolean => {
|
|
|
266
266
|
|
|
267
267
|
let secureUploadUnavailable = false;
|
|
268
268
|
|
|
269
|
+
export interface UploadFileOptions {
|
|
270
|
+
clientEncrypted?: boolean;
|
|
271
|
+
}
|
|
272
|
+
|
|
269
273
|
export async function uploadFileV2(
|
|
270
274
|
formData: FormData,
|
|
271
|
-
activeRoomJID: string
|
|
275
|
+
activeRoomJID: string,
|
|
276
|
+
options: UploadFileOptions = {}
|
|
272
277
|
): Promise<{ data: any }> {
|
|
278
|
+
if (options.clientEncrypted) {
|
|
279
|
+
formData.append('clientEncrypted', 'true');
|
|
280
|
+
}
|
|
273
281
|
const chatName = (activeRoomJID || '').split('@')[0];
|
|
274
282
|
const apiRoot = getCurrentBaseURL().replace(/\/$/, '');
|
|
275
283
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ApiRoom, DeleteRoomMember, PostAddRoomMember, PostReportRoom, PostRoom, RoomMember } from '../../types/models/room.model';
|
|
2
2
|
import { store } from '../../roomStore';
|
|
3
|
-
import { addRoom, mergeUsersSet } from '../../roomStore/roomsSlice';
|
|
3
|
+
import { addRoom, mergeUsersSet, updateRoom } from '../../roomStore/roomsSlice';
|
|
4
4
|
import { IRoom } from '../../types/types';
|
|
5
5
|
import http from '../apiClient';
|
|
6
6
|
|
|
@@ -19,6 +19,11 @@ import http from '../apiClient';
|
|
|
19
19
|
* - `_id` (fallback)
|
|
20
20
|
* - `xmppUsername` (raw + localpart) when the API does return one
|
|
21
21
|
*/
|
|
22
|
+
const usableImage = (value: unknown): string => {
|
|
23
|
+
const url = typeof value === 'string' ? value.trim() : '';
|
|
24
|
+
return url && url !== 'none' ? url : '';
|
|
25
|
+
};
|
|
26
|
+
|
|
22
27
|
function dispatchUsersSetFromRestItems(items: ApiRoom[]): void {
|
|
23
28
|
if (!items?.length) {return;}
|
|
24
29
|
const ownXmpp = String(
|
|
@@ -26,16 +31,24 @@ function dispatchUsersSetFromRestItems(items: ApiRoom[]): void {
|
|
|
26
31
|
);
|
|
27
32
|
const appId = ownXmpp.includes('_') ? ownXmpp.split('_')[0] : '';
|
|
28
33
|
|
|
34
|
+
const known = (store.getState().rooms?.usersSet || {}) as Record<string, RoomMember>;
|
|
29
35
|
const members: Record<string, RoomMember> = {};
|
|
30
36
|
for (const item of items) {
|
|
31
37
|
const list = Array.isArray((item as any)?.members) ? (item as any).members : [];
|
|
32
38
|
for (const m of list) {
|
|
33
39
|
if (!m) {continue;}
|
|
40
|
+
const before: RoomMember | undefined =
|
|
41
|
+
(m._id && (members[m._id] || known[m._id])) || undefined;
|
|
34
42
|
const entry: RoomMember = {
|
|
35
|
-
firstName: m.firstName
|
|
36
|
-
lastName: m.lastName
|
|
43
|
+
firstName: m.firstName ?? before?.firstName ?? '',
|
|
44
|
+
lastName: m.lastName ?? before?.lastName ?? '',
|
|
37
45
|
xmppUsername: m.xmppUsername || (appId && m._id ? `${appId}_${m._id}` : m._id || ''),
|
|
38
46
|
_id: m._id || '',
|
|
47
|
+
profileImage:
|
|
48
|
+
m.profileImage !== undefined
|
|
49
|
+
? usableImage(m.profileImage)
|
|
50
|
+
: before?.profileImage ?? '',
|
|
51
|
+
description: m.description ?? before?.description,
|
|
39
52
|
role: m.role,
|
|
40
53
|
ban_status: m.ban_status,
|
|
41
54
|
last_active: m.last_active,
|
|
@@ -85,9 +98,53 @@ interface ApiRoomMember {
|
|
|
85
98
|
* manifested as a phantom "ethora" room stub on third-party servers,
|
|
86
99
|
* customer-reported #23)
|
|
87
100
|
*/
|
|
101
|
+
export function memberAccount(member: any, appId: string): string {
|
|
102
|
+
const explicit = String(member?.xmppUsername || '').split('@')[0];
|
|
103
|
+
if (explicit) {return explicit;}
|
|
104
|
+
return appId && member?._id ? `${appId}_${member._id}` : '';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function ownAppId(): string {
|
|
108
|
+
const ownXmpp = String(
|
|
109
|
+
store.getState().chatSettingStore?.user?.xmppUsername || ''
|
|
110
|
+
);
|
|
111
|
+
return ownXmpp.includes('_') ? ownXmpp.split('_')[0]! : '';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const toRoomMembers = (members: any[] | undefined): RoomMember[] => {
|
|
115
|
+
const known = (store.getState().rooms?.usersSet || {}) as Record<string, RoomMember>;
|
|
116
|
+
return (members || []).map((m: any) => ({
|
|
117
|
+
firstName: m.firstName,
|
|
118
|
+
lastName: m.lastName,
|
|
119
|
+
profileImage:
|
|
120
|
+
m.profileImage !== undefined
|
|
121
|
+
? usableImage(m.profileImage)
|
|
122
|
+
: known[m._id]?.profileImage ?? '',
|
|
123
|
+
xmppUsername: m._id || '',
|
|
124
|
+
role: m.role,
|
|
125
|
+
ban_status: m.ban_status,
|
|
126
|
+
last_active: m.last_active,
|
|
127
|
+
jid: m.jid || '',
|
|
128
|
+
})) as any;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const toE2eeMembers = (members: any[] | undefined, appId: string): RoomMember[] =>
|
|
132
|
+
(members || [])
|
|
133
|
+
.map((m: any) => ({
|
|
134
|
+
_id: m._id || '',
|
|
135
|
+
firstName: m.firstName || '',
|
|
136
|
+
lastName: m.lastName || '',
|
|
137
|
+
xmppUsername: memberAccount(m, appId),
|
|
138
|
+
}))
|
|
139
|
+
.filter((m) => m.xmppUsername) as RoomMember[];
|
|
140
|
+
|
|
141
|
+
const memberCount = (item: ApiRoom): number =>
|
|
142
|
+
item.usersCnt ?? item.participants ?? item.members?.length ?? 0;
|
|
143
|
+
|
|
88
144
|
function dispatchRoomsFromRestItems(items: ApiRoom[]): void {
|
|
89
145
|
if (!items?.length) return;
|
|
90
146
|
const config = store.getState().chatSettingStore?.config as any;
|
|
147
|
+
const appId = ownAppId();
|
|
91
148
|
// Best: explicit xmpp settings.
|
|
92
149
|
let host: string | undefined =
|
|
93
150
|
config?.xmppSettings?.host ||
|
|
@@ -118,12 +175,16 @@ function dispatchRoomsFromRestItems(items: ApiRoom[]): void {
|
|
|
118
175
|
jid = `${item.name}@${conference}`;
|
|
119
176
|
}
|
|
120
177
|
if (!jid.includes('@')) continue;
|
|
178
|
+
const known = store.getState().rooms.rooms?.[jid];
|
|
179
|
+
const preview = (item.members?.length ?? 0) < memberCount(item);
|
|
180
|
+
const keep = <T,>(fresh: T[], existing: T[] | undefined): T[] =>
|
|
181
|
+
preview && (existing?.length ?? 0) > fresh.length ? existing! : fresh;
|
|
121
182
|
const room: IRoom = {
|
|
122
183
|
id: item._id || jid,
|
|
123
184
|
jid,
|
|
124
185
|
name: item.name,
|
|
125
186
|
title: item.title || item.name,
|
|
126
|
-
usersCnt: item
|
|
187
|
+
usersCnt: memberCount(item),
|
|
127
188
|
messages: [],
|
|
128
189
|
isLoading: false,
|
|
129
190
|
roomBg: '',
|
|
@@ -133,18 +194,14 @@ function dispatchRoomsFromRestItems(items: ApiRoom[]): void {
|
|
|
133
194
|
muted: item.muted === true,
|
|
134
195
|
description: (item as any).description,
|
|
135
196
|
type: (item as any).type,
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
ban_status: m.ban_status,
|
|
145
|
-
last_active: m.last_active,
|
|
146
|
-
jid: m.jid || '',
|
|
147
|
-
})) as any,
|
|
197
|
+
|
|
198
|
+
...(item.e2ee === true
|
|
199
|
+
? {
|
|
200
|
+
e2ee: true,
|
|
201
|
+
members: keep(toE2eeMembers(item.members, appId), known?.members),
|
|
202
|
+
}
|
|
203
|
+
: {}),
|
|
204
|
+
roomMembers: keep(toRoomMembers(item.members), known?.roomMembers),
|
|
148
205
|
};
|
|
149
206
|
store.dispatch(addRoom({ roomData: room }));
|
|
150
207
|
}
|
|
@@ -152,6 +209,51 @@ function dispatchRoomsFromRestItems(items: ApiRoom[]): void {
|
|
|
152
209
|
dispatchUsersSetFromRestItems(items);
|
|
153
210
|
}
|
|
154
211
|
|
|
212
|
+
const ROOM_MEMBERS_TTL_MS = 5 * 60_000;
|
|
213
|
+
const roomMembersLoads = new Map<string, { at: number; done: Promise<boolean> }>();
|
|
214
|
+
|
|
215
|
+
export function loadRoomMembers(roomJid: string): Promise<boolean> {
|
|
216
|
+
const jid = String(roomJid || '').split('/')[0]!;
|
|
217
|
+
const room = store.getState().rooms.rooms?.[jid];
|
|
218
|
+
if (!room) {return Promise.resolve(false);}
|
|
219
|
+
if ((room.roomMembers?.length ?? 0) >= Number(room.usersCnt || 0)) {
|
|
220
|
+
return Promise.resolve(false);
|
|
221
|
+
}
|
|
222
|
+
const running = roomMembersLoads.get(jid);
|
|
223
|
+
if (running && Date.now() - running.at < ROOM_MEMBERS_TTL_MS) {return running.done;}
|
|
224
|
+
|
|
225
|
+
const done = (async () => {
|
|
226
|
+
try {
|
|
227
|
+
const response: any = await getRoomByName(jid.split('@')[0]!);
|
|
228
|
+
const item: ApiRoom = response?.result ?? response;
|
|
229
|
+
const members = Array.isArray(item?.members) ? item.members : [];
|
|
230
|
+
if (members.length === 0) {return false;}
|
|
231
|
+
dispatchUsersSetFromRestItems([item]);
|
|
232
|
+
const current = store.getState().rooms.rooms?.[jid];
|
|
233
|
+
if (!current) {return false;}
|
|
234
|
+
store.dispatch(
|
|
235
|
+
updateRoom({
|
|
236
|
+
jid,
|
|
237
|
+
updates: {
|
|
238
|
+
roomMembers: toRoomMembers(members),
|
|
239
|
+
usersCnt: Math.max(memberCount(item), members.length),
|
|
240
|
+
...(current.e2ee
|
|
241
|
+
? { members: toE2eeMembers(members, ownAppId()) }
|
|
242
|
+
: {}),
|
|
243
|
+
},
|
|
244
|
+
})
|
|
245
|
+
);
|
|
246
|
+
return true;
|
|
247
|
+
} catch (error) {
|
|
248
|
+
roomMembersLoads.delete(jid);
|
|
249
|
+
console.warn('[ethora-rn] rooms.api: could not load room members', jid, error);
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
})();
|
|
253
|
+
roomMembersLoads.set(jid, { at: Date.now(), done });
|
|
254
|
+
return done;
|
|
255
|
+
}
|
|
256
|
+
|
|
155
257
|
const GET_ROOMS_CACHE_MS = 60_000;
|
|
156
258
|
let getRoomsInFlight: Promise<{ items: ApiRoom[] }> | null = null;
|
|
157
259
|
let getRoomsInFlightToken = '';
|
|
@@ -235,14 +337,14 @@ export async function postRoom(data: PostRoom) {
|
|
|
235
337
|
|
|
236
338
|
export async function postPrivateRoom(
|
|
237
339
|
username: string,
|
|
238
|
-
|
|
340
|
+
e2ee: boolean = false
|
|
239
341
|
): Promise<ApiRoom> {
|
|
240
342
|
const token = store.getState().chatSettingStore.user.token || '';
|
|
241
343
|
|
|
242
344
|
try {
|
|
243
345
|
const response = await http.post(
|
|
244
346
|
'/v1/chats/private',
|
|
245
|
-
{ username },
|
|
347
|
+
e2ee === true ? { username, e2ee: true } : { username },
|
|
246
348
|
{
|
|
247
349
|
headers: {
|
|
248
350
|
Authorization: token,
|
|
@@ -391,6 +493,7 @@ export async function createChatCall(
|
|
|
391
493
|
}
|
|
392
494
|
|
|
393
495
|
export function clearRoomsRestCache() {
|
|
496
|
+
roomMembersLoads.clear();
|
|
394
497
|
lastGetRoomsResponse = null;
|
|
395
498
|
lastGetRoomsResponseAt = 0;
|
|
396
499
|
lastGetRoomsResponseToken = '';
|