@ethora/chat-component-rn 26.10.4 → 26.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +15 -0
- package/app.plugin.js +2 -0
- package/lib/commonjs/assets/icons.js +2 -2
- package/lib/commonjs/assets/icons.js.map +1 -1
- package/lib/commonjs/components/MainComponents/AlbumGrid.js +152 -0
- package/lib/commonjs/components/MainComponents/AlbumGrid.js.map +1 -0
- package/lib/commonjs/components/MainComponents/ChatRoom.js +2 -2
- package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MediaMessage.js +199 -123
- package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MediaUploadOverlay.js +109 -0
- package/lib/commonjs/components/MainComponents/MediaUploadOverlay.js.map +1 -0
- package/lib/commonjs/components/MessageBubble/MediaCaption.js +51 -0
- package/lib/commonjs/components/MessageBubble/MediaCaption.js.map +1 -0
- package/lib/commonjs/components/MessageBubble/Message.js +40 -1
- 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/FilePreviewModal/FilePreviewModal.js +75 -0
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/LastMessageItem.js +20 -4
- package/lib/commonjs/components/RoomComponents/LastMessageItem.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/styled/LastAudioMessage.js +3 -2
- package/lib/commonjs/components/RoomComponents/styled/LastAudioMessage.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/styled/LastMessageFile.js +3 -2
- package/lib/commonjs/components/RoomComponents/styled/LastMessageFile.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/styled/LastMessagePhoto.js +3 -2
- package/lib/commonjs/components/RoomComponents/styled/LastMessagePhoto.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/styled/LastMessageVideo.js +3 -2
- package/lib/commonjs/components/RoomComponents/styled/LastMessageVideo.js.map +1 -1
- package/lib/commonjs/components/Thread/ThreadWrapper.js +3 -2
- package/lib/commonjs/components/Thread/ThreadWrapper.js.map +1 -1
- package/lib/commonjs/components/VideoCalls/ActiveCallBar.js +61 -16
- package/lib/commonjs/components/VideoCalls/ActiveCallBar.js.map +1 -1
- package/lib/commonjs/components/VideoCalls/CallIcons.js +41 -16
- package/lib/commonjs/components/VideoCalls/CallIcons.js.map +1 -1
- package/lib/commonjs/components/VideoCalls/VideoCallOverlay.js +183 -9
- package/lib/commonjs/components/VideoCalls/VideoCallOverlay.js.map +1 -1
- package/lib/commonjs/components/VideoCalls/VideoCallSession.js +40 -15
- package/lib/commonjs/components/VideoCalls/VideoCallSession.js.map +1 -1
- package/lib/commonjs/components/VideoCalls/callSessionController.js +49 -26
- package/lib/commonjs/components/VideoCalls/callSessionController.js.map +1 -1
- package/lib/commonjs/components/VideoCalls/callUiStore.js +33 -4
- package/lib/commonjs/components/VideoCalls/callUiStore.js.map +1 -1
- package/lib/commonjs/components/VideoCalls/livekitRuntime.js +9 -1
- package/lib/commonjs/components/VideoCalls/livekitRuntime.js.map +1 -1
- package/lib/commonjs/components/VideoCalls/useCallKeep.js +197 -28
- package/lib/commonjs/components/VideoCalls/useCallKeep.js.map +1 -1
- package/lib/commonjs/components/VideoCalls/useOngoingCallNotification.js +88 -0
- package/lib/commonjs/components/VideoCalls/useOngoingCallNotification.js.map +1 -0
- package/lib/commonjs/components/VideoCalls/usePipTile.js +232 -0
- package/lib/commonjs/components/VideoCalls/usePipTile.js.map +1 -0
- package/lib/commonjs/components/styled/MediaFilePreview.js +60 -47
- package/lib/commonjs/components/styled/MediaFilePreview.js.map +1 -1
- package/lib/commonjs/components/styled/MessageImage.js +16 -6
- package/lib/commonjs/components/styled/MessageImage.js.map +1 -1
- package/lib/commonjs/components/styled/SendInput.js +99 -68
- package/lib/commonjs/components/styled/SendInput.js.map +1 -1
- package/lib/commonjs/components/styled/VideoMessage.js +24 -10
- package/lib/commonjs/components/styled/VideoMessage.js.map +1 -1
- package/lib/commonjs/context/xmppProvider.js +46 -0
- package/lib/commonjs/context/xmppProvider.js.map +1 -1
- package/lib/commonjs/e2ee/fileEnvelope.js +6 -0
- package/lib/commonjs/e2ee/fileEnvelope.js.map +1 -1
- package/lib/commonjs/e2ee/sealedBody.js +32 -2
- package/lib/commonjs/e2ee/sealedBody.js.map +1 -1
- package/lib/commonjs/helpers/albumLayout.js +150 -0
- package/lib/commonjs/helpers/albumLayout.js.map +1 -0
- package/lib/commonjs/helpers/attachments.js +255 -0
- package/lib/commonjs/helpers/attachments.js.map +1 -0
- package/lib/commonjs/helpers/caption.js +214 -0
- package/lib/commonjs/helpers/caption.js.map +1 -0
- package/lib/commonjs/helpers/createMainMessageForThread.js +5 -1
- package/lib/commonjs/helpers/createMainMessageForThread.js.map +1 -1
- package/lib/commonjs/helpers/createMessageFromXml.js +19 -5
- package/lib/commonjs/helpers/createMessageFromXml.js.map +1 -1
- package/lib/commonjs/helpers/fileKind.js +40 -0
- package/lib/commonjs/helpers/fileKind.js.map +1 -0
- package/lib/commonjs/helpers/getDataFromXml.js +6 -1
- package/lib/commonjs/helpers/getDataFromXml.js.map +1 -1
- package/lib/commonjs/helpers/mapWithConcurrency.js +41 -0
- package/lib/commonjs/helpers/mapWithConcurrency.js.map +1 -0
- package/lib/commonjs/helpers/mediaLimits.js +33 -0
- package/lib/commonjs/helpers/mediaLimits.js.map +1 -0
- package/lib/commonjs/helpers/mediaSendRetry.js +64 -0
- package/lib/commonjs/helpers/mediaSendRetry.js.map +1 -0
- package/lib/commonjs/helpers/mediaWireData.js +62 -0
- package/lib/commonjs/helpers/mediaWireData.js.map +1 -0
- package/lib/commonjs/helpers/mentionSpans.js +19 -0
- package/lib/commonjs/helpers/mentionSpans.js.map +1 -0
- package/lib/commonjs/helpers/mimeToExtension.js +45 -0
- package/lib/commonjs/helpers/mimeToExtension.js.map +1 -1
- package/lib/commonjs/helpers/readReceipts.js +173 -0
- package/lib/commonjs/helpers/readReceipts.js.map +1 -0
- package/lib/commonjs/helpers/repairFilenameEncoding.js +79 -0
- package/lib/commonjs/helpers/repairFilenameEncoding.js.map +1 -0
- package/lib/commonjs/helpers/safeJson.js +18 -0
- package/lib/commonjs/helpers/safeJson.js.map +1 -0
- package/lib/commonjs/helpers/updateMessagesTillLast.js +3 -1
- package/lib/commonjs/helpers/updateMessagesTillLast.js.map +1 -1
- package/lib/commonjs/hooks/useSendMessage.js +384 -193
- package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
- package/lib/commonjs/i18n/strings.js +144 -0
- package/lib/commonjs/i18n/strings.js.map +1 -1
- package/lib/commonjs/main.js.map +1 -1
- package/lib/commonjs/networking/api-requests/auth.api.js +62 -3
- package/lib/commonjs/networking/api-requests/auth.api.js.map +1 -1
- package/lib/commonjs/networking/stanzaHandlers.js +100 -3
- package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
- package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js +4 -2
- package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/sendDisplayedMarker.xmpp.js +28 -0
- package/lib/commonjs/networking/xmpp/sendDisplayedMarker.xmpp.js.map +1 -0
- package/lib/commonjs/networking/xmpp/sendMediaMessage.xmpp.js +53 -2
- package/lib/commonjs/networking/xmpp/sendMediaMessage.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/sendReceivedReceipt.xmpp.js +28 -0
- package/lib/commonjs/networking/xmpp/sendReceivedReceipt.xmpp.js.map +1 -0
- package/lib/commonjs/networking/xmppClient.js +64 -0
- package/lib/commonjs/networking/xmppClient.js.map +1 -1
- package/lib/commonjs/roomStore/persistence.js +78 -5
- package/lib/commonjs/roomStore/persistence.js.map +1 -1
- package/lib/commonjs/roomStore/roomHeapSlice.js +4 -0
- package/lib/commonjs/roomStore/roomHeapSlice.js.map +1 -1
- package/lib/commonjs/roomStore/roomsSlice.js +114 -1
- package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
- package/lib/commonjs/types/models/attachment.model.js +2 -0
- package/lib/commonjs/types/models/attachment.model.js.map +1 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/module/assets/icons.js +1 -1
- package/lib/module/assets/icons.js.map +1 -1
- package/lib/module/components/MainComponents/AlbumGrid.js +146 -0
- package/lib/module/components/MainComponents/AlbumGrid.js.map +1 -0
- package/lib/module/components/MainComponents/ChatRoom.js +2 -2
- package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/module/components/MainComponents/MediaMessage.js +200 -124
- package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
- package/lib/module/components/MainComponents/MediaUploadOverlay.js +104 -0
- package/lib/module/components/MainComponents/MediaUploadOverlay.js.map +1 -0
- package/lib/module/components/MessageBubble/MediaCaption.js +46 -0
- package/lib/module/components/MessageBubble/MediaCaption.js.map +1 -0
- package/lib/module/components/MessageBubble/Message.js +44 -5
- 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/FilePreviewModal/FilePreviewModal.js +75 -0
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
- package/lib/module/components/RoomComponents/LastMessageItem.js +20 -4
- package/lib/module/components/RoomComponents/LastMessageItem.js.map +1 -1
- package/lib/module/components/RoomComponents/styled/LastAudioMessage.js +3 -2
- package/lib/module/components/RoomComponents/styled/LastAudioMessage.js.map +1 -1
- package/lib/module/components/RoomComponents/styled/LastMessageFile.js +3 -2
- package/lib/module/components/RoomComponents/styled/LastMessageFile.js.map +1 -1
- package/lib/module/components/RoomComponents/styled/LastMessagePhoto.js +3 -2
- package/lib/module/components/RoomComponents/styled/LastMessagePhoto.js.map +1 -1
- package/lib/module/components/RoomComponents/styled/LastMessageVideo.js +3 -2
- package/lib/module/components/RoomComponents/styled/LastMessageVideo.js.map +1 -1
- package/lib/module/components/Thread/ThreadWrapper.js +3 -2
- package/lib/module/components/Thread/ThreadWrapper.js.map +1 -1
- package/lib/module/components/VideoCalls/ActiveCallBar.js +63 -18
- package/lib/module/components/VideoCalls/ActiveCallBar.js.map +1 -1
- package/lib/module/components/VideoCalls/CallIcons.js +38 -15
- package/lib/module/components/VideoCalls/CallIcons.js.map +1 -1
- package/lib/module/components/VideoCalls/VideoCallOverlay.js +185 -11
- package/lib/module/components/VideoCalls/VideoCallOverlay.js.map +1 -1
- package/lib/module/components/VideoCalls/VideoCallSession.js +41 -16
- package/lib/module/components/VideoCalls/VideoCallSession.js.map +1 -1
- package/lib/module/components/VideoCalls/callSessionController.js +46 -24
- package/lib/module/components/VideoCalls/callSessionController.js.map +1 -1
- package/lib/module/components/VideoCalls/callUiStore.js +30 -3
- package/lib/module/components/VideoCalls/callUiStore.js.map +1 -1
- package/lib/module/components/VideoCalls/livekitRuntime.js +9 -1
- package/lib/module/components/VideoCalls/livekitRuntime.js.map +1 -1
- package/lib/module/components/VideoCalls/useCallKeep.js +198 -29
- package/lib/module/components/VideoCalls/useCallKeep.js.map +1 -1
- package/lib/module/components/VideoCalls/useOngoingCallNotification.js +84 -0
- package/lib/module/components/VideoCalls/useOngoingCallNotification.js.map +1 -0
- package/lib/module/components/VideoCalls/usePipTile.js +228 -0
- package/lib/module/components/VideoCalls/usePipTile.js.map +1 -0
- package/lib/module/components/styled/MediaFilePreview.js +61 -48
- package/lib/module/components/styled/MediaFilePreview.js.map +1 -1
- package/lib/module/components/styled/MessageImage.js +16 -6
- package/lib/module/components/styled/MessageImage.js.map +1 -1
- package/lib/module/components/styled/SendInput.js +99 -68
- package/lib/module/components/styled/SendInput.js.map +1 -1
- package/lib/module/components/styled/VideoMessage.js +24 -10
- package/lib/module/components/styled/VideoMessage.js.map +1 -1
- package/lib/module/context/xmppProvider.js +46 -0
- package/lib/module/context/xmppProvider.js.map +1 -1
- package/lib/module/e2ee/fileEnvelope.js +1 -1
- package/lib/module/e2ee/fileEnvelope.js.map +1 -1
- package/lib/module/e2ee/sealedBody.js +32 -2
- package/lib/module/e2ee/sealedBody.js.map +1 -1
- package/lib/module/helpers/albumLayout.js +143 -0
- package/lib/module/helpers/albumLayout.js.map +1 -0
- package/lib/module/helpers/attachments.js +245 -0
- package/lib/module/helpers/attachments.js.map +1 -0
- package/lib/module/helpers/caption.js +207 -0
- package/lib/module/helpers/caption.js.map +1 -0
- package/lib/module/helpers/createMainMessageForThread.js +5 -1
- package/lib/module/helpers/createMainMessageForThread.js.map +1 -1
- package/lib/module/helpers/createMessageFromXml.js +20 -6
- package/lib/module/helpers/createMessageFromXml.js.map +1 -1
- package/lib/module/helpers/fileKind.js +34 -0
- package/lib/module/helpers/fileKind.js.map +1 -0
- package/lib/module/helpers/getDataFromXml.js +6 -1
- package/lib/module/helpers/getDataFromXml.js.map +1 -1
- package/lib/module/helpers/mapWithConcurrency.js +37 -0
- package/lib/module/helpers/mapWithConcurrency.js.map +1 -0
- package/lib/module/helpers/mediaLimits.js +27 -0
- package/lib/module/helpers/mediaLimits.js.map +1 -0
- package/lib/module/helpers/mediaSendRetry.js +55 -0
- package/lib/module/helpers/mediaSendRetry.js.map +1 -0
- package/lib/module/helpers/mediaWireData.js +58 -0
- package/lib/module/helpers/mediaWireData.js.map +1 -0
- package/lib/module/helpers/mentionSpans.js +14 -0
- package/lib/module/helpers/mentionSpans.js.map +1 -0
- package/lib/module/helpers/mimeToExtension.js +43 -0
- package/lib/module/helpers/mimeToExtension.js.map +1 -1
- package/lib/module/helpers/readReceipts.js +160 -0
- package/lib/module/helpers/readReceipts.js.map +1 -0
- package/lib/module/helpers/repairFilenameEncoding.js +74 -0
- package/lib/module/helpers/repairFilenameEncoding.js.map +1 -0
- package/lib/module/helpers/safeJson.js +13 -0
- package/lib/module/helpers/safeJson.js.map +1 -0
- package/lib/module/helpers/updateMessagesTillLast.js +3 -1
- package/lib/module/helpers/updateMessagesTillLast.js.map +1 -1
- package/lib/module/hooks/useSendMessage.js +387 -195
- package/lib/module/hooks/useSendMessage.js.map +1 -1
- package/lib/module/i18n/strings.js +144 -0
- package/lib/module/i18n/strings.js.map +1 -1
- package/lib/module/main.js.map +1 -1
- package/lib/module/networking/api-requests/auth.api.js +62 -3
- package/lib/module/networking/api-requests/auth.api.js.map +1 -1
- package/lib/module/networking/stanzaHandlers.js +97 -4
- package/lib/module/networking/stanzaHandlers.js.map +1 -1
- package/lib/module/networking/xmpp/handleStanzas.xmpp.js +5 -3
- package/lib/module/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/sendDisplayedMarker.xmpp.js +25 -0
- package/lib/module/networking/xmpp/sendDisplayedMarker.xmpp.js.map +1 -0
- package/lib/module/networking/xmpp/sendMediaMessage.xmpp.js +53 -2
- package/lib/module/networking/xmpp/sendMediaMessage.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/sendReceivedReceipt.xmpp.js +25 -0
- package/lib/module/networking/xmpp/sendReceivedReceipt.xmpp.js.map +1 -0
- package/lib/module/networking/xmppClient.js +64 -0
- package/lib/module/networking/xmppClient.js.map +1 -1
- package/lib/module/roomStore/persistence.js +78 -5
- package/lib/module/roomStore/persistence.js.map +1 -1
- package/lib/module/roomStore/roomHeapSlice.js +4 -0
- package/lib/module/roomStore/roomHeapSlice.js.map +1 -1
- package/lib/module/roomStore/roomsSlice.js +109 -0
- package/lib/module/roomStore/roomsSlice.js.map +1 -1
- package/lib/module/types/models/attachment.model.js +2 -0
- package/lib/module/types/models/attachment.model.js.map +1 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/assets/icons.d.ts +6 -1
- package/lib/typescript/assets/icons.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/AlbumGrid.d.ts +21 -0
- package/lib/typescript/components/MainComponents/AlbumGrid.d.ts.map +1 -0
- package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/MediaUploadOverlay.d.ts +17 -0
- package/lib/typescript/components/MainComponents/MediaUploadOverlay.d.ts.map +1 -0
- package/lib/typescript/components/MessageBubble/MediaCaption.d.ts +12 -0
- package/lib/typescript/components/MessageBubble/MediaCaption.d.ts.map +1 -0
- 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/FilePreviewModal/FilePreviewModal.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 +2 -0
- package/lib/typescript/components/RoomComponents/styled/LastAudioMessage.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/styled/LastMessageFile.d.ts +2 -0
- package/lib/typescript/components/RoomComponents/styled/LastMessageFile.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/styled/LastMessagePhoto.d.ts +2 -0
- package/lib/typescript/components/RoomComponents/styled/LastMessagePhoto.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/styled/LastMessageVideo.d.ts +2 -0
- package/lib/typescript/components/RoomComponents/styled/LastMessageVideo.d.ts.map +1 -1
- package/lib/typescript/components/Thread/ThreadWrapper.d.ts.map +1 -1
- package/lib/typescript/components/VideoCalls/ActiveCallBar.d.ts +9 -3
- package/lib/typescript/components/VideoCalls/ActiveCallBar.d.ts.map +1 -1
- package/lib/typescript/components/VideoCalls/CallIcons.d.ts +9 -0
- package/lib/typescript/components/VideoCalls/CallIcons.d.ts.map +1 -1
- package/lib/typescript/components/VideoCalls/VideoCallOverlay.d.ts.map +1 -1
- package/lib/typescript/components/VideoCalls/VideoCallSession.d.ts.map +1 -1
- package/lib/typescript/components/VideoCalls/callSessionController.d.ts +7 -0
- package/lib/typescript/components/VideoCalls/callSessionController.d.ts.map +1 -1
- package/lib/typescript/components/VideoCalls/callUiStore.d.ts +13 -0
- package/lib/typescript/components/VideoCalls/callUiStore.d.ts.map +1 -1
- package/lib/typescript/components/VideoCalls/livekitRuntime.d.ts +5 -0
- package/lib/typescript/components/VideoCalls/livekitRuntime.d.ts.map +1 -1
- package/lib/typescript/components/VideoCalls/useCallKeep.d.ts +12 -0
- package/lib/typescript/components/VideoCalls/useCallKeep.d.ts.map +1 -1
- package/lib/typescript/components/VideoCalls/useOngoingCallNotification.d.ts +10 -0
- package/lib/typescript/components/VideoCalls/useOngoingCallNotification.d.ts.map +1 -0
- package/lib/typescript/components/VideoCalls/usePipTile.d.ts +46 -0
- package/lib/typescript/components/VideoCalls/usePipTile.d.ts.map +1 -0
- package/lib/typescript/components/styled/MediaFilePreview.d.ts.map +1 -1
- package/lib/typescript/components/styled/MessageImage.d.ts +10 -0
- package/lib/typescript/components/styled/MessageImage.d.ts.map +1 -1
- package/lib/typescript/components/styled/SendInput.d.ts +7 -1
- package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
- package/lib/typescript/components/styled/VideoMessage.d.ts +7 -0
- package/lib/typescript/components/styled/VideoMessage.d.ts.map +1 -1
- package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
- package/lib/typescript/e2ee/fileEnvelope.d.ts +1 -1
- package/lib/typescript/e2ee/fileEnvelope.d.ts.map +1 -1
- package/lib/typescript/e2ee/sealedBody.d.ts +16 -0
- package/lib/typescript/e2ee/sealedBody.d.ts.map +1 -1
- package/lib/typescript/helpers/albumLayout.d.ts +66 -0
- package/lib/typescript/helpers/albumLayout.d.ts.map +1 -0
- package/lib/typescript/helpers/attachments.d.ts +55 -0
- package/lib/typescript/helpers/attachments.d.ts.map +1 -0
- package/lib/typescript/helpers/caption.d.ts +64 -0
- package/lib/typescript/helpers/caption.d.ts.map +1 -0
- package/lib/typescript/helpers/createMainMessageForThread.d.ts.map +1 -1
- package/lib/typescript/helpers/createMessageFromXml.d.ts.map +1 -1
- package/lib/typescript/helpers/fileKind.d.ts +20 -0
- package/lib/typescript/helpers/fileKind.d.ts.map +1 -0
- package/lib/typescript/helpers/getDataFromXml.d.ts.map +1 -1
- package/lib/typescript/helpers/mapWithConcurrency.d.ts +9 -0
- package/lib/typescript/helpers/mapWithConcurrency.d.ts.map +1 -0
- package/lib/typescript/helpers/mediaLimits.d.ts +13 -0
- package/lib/typescript/helpers/mediaLimits.d.ts.map +1 -0
- package/lib/typescript/helpers/mediaSendRetry.d.ts +26 -0
- package/lib/typescript/helpers/mediaSendRetry.d.ts.map +1 -0
- package/lib/typescript/helpers/mediaWireData.d.ts +16 -0
- package/lib/typescript/helpers/mediaWireData.d.ts.map +1 -0
- package/lib/typescript/helpers/mentionSpans.d.ts +8 -0
- package/lib/typescript/helpers/mentionSpans.d.ts.map +1 -0
- package/lib/typescript/helpers/mimeToExtension.d.ts +7 -0
- package/lib/typescript/helpers/mimeToExtension.d.ts.map +1 -1
- package/lib/typescript/helpers/readReceipts.d.ts +82 -0
- package/lib/typescript/helpers/readReceipts.d.ts.map +1 -0
- package/lib/typescript/helpers/repairFilenameEncoding.d.ts +12 -0
- package/lib/typescript/helpers/repairFilenameEncoding.d.ts.map +1 -0
- package/lib/typescript/helpers/safeJson.d.ts +2 -0
- package/lib/typescript/helpers/safeJson.d.ts.map +1 -0
- package/lib/typescript/helpers/updateMessagesTillLast.d.ts.map +1 -1
- package/lib/typescript/hooks/useSendMessage.d.ts +2 -1
- package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/i18n/strings.d.ts.map +1 -1
- package/lib/typescript/main.d.ts +1 -1
- package/lib/typescript/main.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/auth.api.d.ts +2 -0
- package/lib/typescript/networking/api-requests/auth.api.d.ts.map +1 -1
- package/lib/typescript/networking/stanzaHandlers.d.ts +7 -3
- package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/sendDisplayedMarker.xmpp.d.ts +3 -0
- package/lib/typescript/networking/xmpp/sendDisplayedMarker.xmpp.d.ts.map +1 -0
- package/lib/typescript/networking/xmpp/sendMediaMessage.xmpp.d.ts +12 -0
- package/lib/typescript/networking/xmpp/sendMediaMessage.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/sendReceivedReceipt.xmpp.d.ts +3 -0
- package/lib/typescript/networking/xmpp/sendReceivedReceipt.xmpp.d.ts.map +1 -0
- package/lib/typescript/networking/xmppClient.d.ts +15 -0
- package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
- package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
- package/lib/typescript/roomStore/roomHeapSlice.d.ts +22 -1
- package/lib/typescript/roomStore/roomHeapSlice.d.ts.map +1 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts +67 -3
- package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
- package/lib/typescript/types/models/attachment.model.d.ts +52 -0
- package/lib/typescript/types/models/attachment.model.d.ts.map +1 -0
- package/lib/typescript/types/models/message.model.d.ts +26 -0
- package/lib/typescript/types/models/message.model.d.ts.map +1 -1
- package/lib/typescript/types/models/modal.model.d.ts +7 -0
- package/lib/typescript/types/models/modal.model.d.ts.map +1 -1
- package/lib/typescript/types/models/room.model.d.ts +2 -0
- package/lib/typescript/types/models/room.model.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +69 -1
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/lib/typescript/version.d.ts +1 -1
- package/package.json +4 -1
- package/plugins/notification-service/Info.plist +31 -0
- package/plugins/notification-service/NotificationService.swift +82 -0
- package/plugins/withNotificationServiceExtension.js +137 -0
- package/src/assets/icons.tsx +20 -2
- package/src/components/MainComponents/AlbumGrid.tsx +183 -0
- package/src/components/MainComponents/ChatRoom.tsx +4 -2
- package/src/components/MainComponents/MediaMessage.tsx +246 -130
- package/src/components/MainComponents/MediaUploadOverlay.tsx +102 -0
- package/src/components/MessageBubble/MediaCaption.tsx +45 -0
- package/src/components/MessageBubble/Message.tsx +71 -3
- package/src/components/MessageBubble/MessageInteractions.tsx +2 -1
- package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +64 -0
- package/src/components/RoomComponents/LastMessageItem.tsx +15 -4
- package/src/components/RoomComponents/styled/LastAudioMessage.tsx +6 -3
- package/src/components/RoomComponents/styled/LastMessageFile.tsx +6 -2
- package/src/components/RoomComponents/styled/LastMessagePhoto.tsx +6 -2
- package/src/components/RoomComponents/styled/LastMessageVideo.tsx +6 -2
- package/src/components/Thread/ThreadWrapper.tsx +5 -9
- package/src/components/VideoCalls/ActiveCallBar.tsx +56 -10
- package/src/components/VideoCalls/CallIcons.tsx +36 -12
- package/src/components/VideoCalls/VideoCallOverlay.tsx +205 -8
- package/src/components/VideoCalls/VideoCallSession.tsx +45 -13
- package/src/components/VideoCalls/callSessionController.ts +51 -20
- package/src/components/VideoCalls/callUiStore.ts +33 -3
- package/src/components/VideoCalls/livekitRuntime.ts +13 -0
- package/src/components/VideoCalls/useCallKeep.ts +204 -33
- package/src/components/VideoCalls/useOngoingCallNotification.ts +113 -0
- package/src/components/VideoCalls/usePipTile.ts +214 -0
- package/src/components/styled/MediaFilePreview.tsx +49 -34
- package/src/components/styled/MessageImage.tsx +21 -5
- package/src/components/styled/SendInput.tsx +101 -87
- package/src/components/styled/VideoMessage.tsx +34 -9
- package/src/context/xmppProvider.tsx +32 -0
- package/src/e2ee/fileEnvelope.ts +1 -1
- package/src/e2ee/sealedBody.ts +44 -5
- package/src/helpers/albumLayout.ts +207 -0
- package/src/helpers/attachments.ts +316 -0
- package/src/helpers/caption.ts +283 -0
- package/src/helpers/createMainMessageForThread.ts +6 -1
- package/src/helpers/createMessageFromXml.ts +21 -5
- package/src/helpers/fileKind.ts +38 -0
- package/src/helpers/getDataFromXml.ts +5 -1
- package/src/helpers/mapWithConcurrency.ts +32 -0
- package/src/helpers/mediaLimits.ts +27 -0
- package/src/helpers/mediaSendRetry.ts +59 -0
- package/src/helpers/mediaWireData.ts +57 -0
- package/src/helpers/mentionSpans.ts +17 -0
- package/src/helpers/mimeToExtension.ts +51 -0
- package/src/helpers/readReceipts.ts +219 -0
- package/src/helpers/repairFilenameEncoding.ts +82 -0
- package/src/helpers/safeJson.ts +11 -0
- package/src/helpers/updateMessagesTillLast.tsx +2 -1
- package/src/hooks/useSendMessage.tsx +448 -249
- package/src/i18n/strings.ts +144 -0
- package/src/main.ts +3 -0
- package/src/networking/api-requests/auth.api.ts +60 -3
- package/src/networking/stanzaHandlers.ts +91 -2
- package/src/networking/xmpp/handleStanzas.xmpp.ts +6 -2
- package/src/networking/xmpp/sendDisplayedMarker.xmpp.ts +31 -0
- package/src/networking/xmpp/sendMediaMessage.xmpp.ts +60 -3
- package/src/networking/xmpp/sendReceivedReceipt.xmpp.ts +31 -0
- package/src/networking/xmppClient.ts +48 -0
- package/src/roomStore/persistence.ts +94 -3
- package/src/roomStore/roomHeapSlice.ts +23 -1
- package/src/roomStore/roomsSlice.ts +112 -1
- package/src/types/models/attachment.model.ts +51 -0
- package/src/types/models/message.model.ts +29 -0
- package/src/types/models/modal.model.ts +7 -0
- package/src/types/models/room.model.ts +2 -0
- package/src/types/types.ts +83 -1
- package/src/version.ts +1 -1
- package/lib/commonjs/components/VideoCalls/useDraggable.js +0 -59
- package/lib/commonjs/components/VideoCalls/useDraggable.js.map +0 -1
- package/lib/module/components/VideoCalls/useDraggable.js +0 -55
- package/lib/module/components/VideoCalls/useDraggable.js.map +0 -1
- package/lib/typescript/components/VideoCalls/useDraggable.d.ts +0 -19
- package/lib/typescript/components/VideoCalls/useDraggable.d.ts.map +0 -1
- package/src/components/VideoCalls/useDraggable.ts +0 -46
package/src/assets/icons.tsx
CHANGED
|
@@ -720,7 +720,25 @@ export const ArowDownIcon = ({
|
|
|
720
720
|
</Svg>
|
|
721
721
|
);
|
|
722
722
|
|
|
723
|
-
export const
|
|
723
|
+
export const SingleTick = ({ stroke = '#16A34A', ...props }) => (
|
|
724
|
+
<Svg
|
|
725
|
+
width="16"
|
|
726
|
+
height="16"
|
|
727
|
+
viewBox="0 0 16 16"
|
|
728
|
+
fill="none"
|
|
729
|
+
{...props}
|
|
730
|
+
>
|
|
731
|
+
<Path
|
|
732
|
+
d="M4 8.5L7 11.5L12 5.5"
|
|
733
|
+
stroke={stroke}
|
|
734
|
+
strokeWidth="1.5"
|
|
735
|
+
strokeLinecap="round"
|
|
736
|
+
strokeLinejoin="round"
|
|
737
|
+
/>
|
|
738
|
+
</Svg>
|
|
739
|
+
);
|
|
740
|
+
|
|
741
|
+
export const DoubleTick = ({ fill = '#fff', color = '#0052CD', stroke = '#16A34A', ...props }) => (
|
|
724
742
|
<Svg
|
|
725
743
|
width="16"
|
|
726
744
|
height="16"
|
|
@@ -730,7 +748,7 @@ export const DoubleTick = ({ fill = '#fff', color = '#0052CD', ...props }) => (
|
|
|
730
748
|
>
|
|
731
749
|
<Path
|
|
732
750
|
d="M1.75 9.75L4.25 12.25M7.75 8.25L10.25 5.75M5.75 9.75L8.25 12.25L14.25 5.75"
|
|
733
|
-
stroke=
|
|
751
|
+
stroke={stroke}
|
|
734
752
|
strokeWidth="1.5"
|
|
735
753
|
strokeLinecap="round"
|
|
736
754
|
strokeLinejoin="round"
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import React, { useCallback, useMemo } from 'react';
|
|
2
|
+
import { Pressable, StyleSheet, Text, View } from 'react-native';
|
|
3
|
+
import { useDispatch } from 'react-redux';
|
|
4
|
+
import { IAttachment, ModalFile } from '../../types/types';
|
|
5
|
+
import CustomMessageImage from '../styled/MessageImage';
|
|
6
|
+
import CustomMessageVideo from '../styled/VideoMessage';
|
|
7
|
+
import { getAttachmentName } from '../../helpers/attachments';
|
|
8
|
+
import { getFileKind } from '../../helpers/fileKind';
|
|
9
|
+
import { getAlbumFrame, getAlbumLayout } from '../../helpers/albumLayout';
|
|
10
|
+
import { MEDIA_MAX_W } from '../../helpers/mediaDimensions';
|
|
11
|
+
import { appendFileToken } from '../../helpers/secureFileUrl';
|
|
12
|
+
import { useFileToken } from '../../hooks/useFileToken';
|
|
13
|
+
import { useT } from '../../i18n/useT';
|
|
14
|
+
import {
|
|
15
|
+
setActiveFile,
|
|
16
|
+
setActiveModal,
|
|
17
|
+
} from '../../roomStore/chatSettingsSlice';
|
|
18
|
+
import { MODAL_TYPES } from '../../helpers/constants/MODAL_TYPES';
|
|
19
|
+
import MediaUploadOverlay from './MediaUploadOverlay';
|
|
20
|
+
|
|
21
|
+
interface AlbumGridProps {
|
|
22
|
+
/** The pictures and videos of one message, in order. */
|
|
23
|
+
attachments: IAttachment[];
|
|
24
|
+
/** Width of the whole grid; the bubble's media width by default. */
|
|
25
|
+
width?: number;
|
|
26
|
+
/** Re-runs the upload of the tile at this position (a failed outgoing file). */
|
|
27
|
+
onRetryTile?: (position: number) => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Photo and video album of a message with several media files. The geometry
|
|
32
|
+
* comes from getAlbumLayout / getAlbumFrame; every tile is the ordinary
|
|
33
|
+
* picture or video component sized to its cell. A tap opens the viewer on
|
|
34
|
+
* that file with the whole album as its siblings, so the viewer can page
|
|
35
|
+
* through files the grid does not show. The last tile of a long album carries
|
|
36
|
+
* a "+N" overlay for the files folded behind it.
|
|
37
|
+
*/
|
|
38
|
+
const AlbumGrid: React.FC<AlbumGridProps> = ({
|
|
39
|
+
attachments,
|
|
40
|
+
width = MEDIA_MAX_W,
|
|
41
|
+
onRetryTile,
|
|
42
|
+
}) => {
|
|
43
|
+
const t = useT();
|
|
44
|
+
const dispatch = useDispatch();
|
|
45
|
+
const fileToken = useFileToken();
|
|
46
|
+
|
|
47
|
+
const layout = useMemo(
|
|
48
|
+
() => getAlbumLayout(attachments.length),
|
|
49
|
+
[attachments.length]
|
|
50
|
+
);
|
|
51
|
+
const frame = useMemo(() => getAlbumFrame(layout, width), [layout, width]);
|
|
52
|
+
|
|
53
|
+
const siblings: ModalFile[] = useMemo(
|
|
54
|
+
() =>
|
|
55
|
+
attachments.map((attachment) => ({
|
|
56
|
+
fileName: getAttachmentName(attachment),
|
|
57
|
+
originalName: attachment.originalName,
|
|
58
|
+
fileURL: appendFileToken(attachment.location, fileToken) || '',
|
|
59
|
+
mimetype: attachment.mimetype || '',
|
|
60
|
+
duration: attachment.duration,
|
|
61
|
+
})),
|
|
62
|
+
[attachments, fileToken]
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const openAt = useCallback(
|
|
66
|
+
(index: number) => {
|
|
67
|
+
const target = siblings[index];
|
|
68
|
+
// A file still on its way up has no server copy to open yet.
|
|
69
|
+
if (!target || !target.fileURL || attachments[index]?.uploadStatus) {return;}
|
|
70
|
+
dispatch(setActiveFile({ ...target, siblings, index }));
|
|
71
|
+
dispatch(setActiveModal(MODAL_TYPES.FILE_PREVIEW));
|
|
72
|
+
},
|
|
73
|
+
[attachments, dispatch, siblings]
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<View
|
|
78
|
+
testID="album-grid"
|
|
79
|
+
style={[styles.grid, { width: frame.width, height: frame.height }]}
|
|
80
|
+
>
|
|
81
|
+
{attachments.slice(0, layout.visible).map((attachment, position) => {
|
|
82
|
+
const style = frame.tiles[position]!;
|
|
83
|
+
const tile = {
|
|
84
|
+
width: Number(style.width),
|
|
85
|
+
height: Number(style.height),
|
|
86
|
+
};
|
|
87
|
+
const fileName = getAttachmentName(attachment);
|
|
88
|
+
const kind = getFileKind({
|
|
89
|
+
mimetype: attachment.mimetype,
|
|
90
|
+
name: fileName,
|
|
91
|
+
url: attachment.location,
|
|
92
|
+
duration: attachment.duration,
|
|
93
|
+
});
|
|
94
|
+
// An outgoing tile shows the file on this device until its upload
|
|
95
|
+
// has given it a server copy.
|
|
96
|
+
const outgoing = Boolean(attachment.uploadStatus);
|
|
97
|
+
const fileURL = outgoing
|
|
98
|
+
? attachment.localUrl || ''
|
|
99
|
+
: appendFileToken(attachment.location, fileToken) || '';
|
|
100
|
+
const preview = outgoing
|
|
101
|
+
? attachment.localUrl || undefined
|
|
102
|
+
: appendFileToken(attachment.locationPreview, fileToken);
|
|
103
|
+
const showMore = position === layout.visible - 1 && layout.hidden > 0;
|
|
104
|
+
const open = () => openAt(position);
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<View
|
|
108
|
+
key={attachment.attachmentId || `${position}-${fileName}`}
|
|
109
|
+
testID={`album-tile-${position}`}
|
|
110
|
+
style={style}
|
|
111
|
+
>
|
|
112
|
+
{kind === 'video' ? (
|
|
113
|
+
<CustomMessageVideo
|
|
114
|
+
fileName={fileName}
|
|
115
|
+
originalName={attachment.originalName}
|
|
116
|
+
fileURL={fileURL}
|
|
117
|
+
previewURL={preview}
|
|
118
|
+
mimetype={attachment.mimetype || ''}
|
|
119
|
+
tile={tile}
|
|
120
|
+
onOpen={outgoing ? undefined : open}
|
|
121
|
+
/>
|
|
122
|
+
) : (
|
|
123
|
+
<CustomMessageImage
|
|
124
|
+
fileName={fileName}
|
|
125
|
+
originalName={attachment.originalName}
|
|
126
|
+
fileURL={fileURL}
|
|
127
|
+
locationPreview={preview}
|
|
128
|
+
mimetype={attachment.mimetype || ''}
|
|
129
|
+
tile={tile}
|
|
130
|
+
onOpen={outgoing ? undefined : open}
|
|
131
|
+
/>
|
|
132
|
+
)}
|
|
133
|
+
{outgoing && attachment.uploadStatus && (
|
|
134
|
+
<MediaUploadOverlay
|
|
135
|
+
status={attachment.uploadStatus}
|
|
136
|
+
progress={attachment.uploadProgress}
|
|
137
|
+
onRetry={onRetryTile ? () => onRetryTile(position) : undefined}
|
|
138
|
+
/>
|
|
139
|
+
)}
|
|
140
|
+
{showMore && (
|
|
141
|
+
<Pressable
|
|
142
|
+
testID="album-more"
|
|
143
|
+
accessibilityRole="button"
|
|
144
|
+
accessibilityLabel={t('attachment.moreLabel', {
|
|
145
|
+
count: layout.hidden,
|
|
146
|
+
})}
|
|
147
|
+
onPress={open}
|
|
148
|
+
style={styles.more}
|
|
149
|
+
>
|
|
150
|
+
<Text style={styles.moreText}>
|
|
151
|
+
{t('attachment.moreCount', { count: layout.hidden })}
|
|
152
|
+
</Text>
|
|
153
|
+
</Pressable>
|
|
154
|
+
)}
|
|
155
|
+
</View>
|
|
156
|
+
);
|
|
157
|
+
})}
|
|
158
|
+
</View>
|
|
159
|
+
);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export default AlbumGrid;
|
|
163
|
+
|
|
164
|
+
const styles = StyleSheet.create({
|
|
165
|
+
grid: {
|
|
166
|
+
position: 'relative',
|
|
167
|
+
overflow: 'hidden',
|
|
168
|
+
borderRadius: 10,
|
|
169
|
+
},
|
|
170
|
+
more: {
|
|
171
|
+
...StyleSheet.absoluteFill,
|
|
172
|
+
alignItems: 'center',
|
|
173
|
+
justifyContent: 'center',
|
|
174
|
+
// Sits on the photo itself, so it stays hard-coded: it must read on the
|
|
175
|
+
// picture, not on the theme.
|
|
176
|
+
backgroundColor: 'rgba(8, 12, 24, 0.5)',
|
|
177
|
+
},
|
|
178
|
+
moreText: {
|
|
179
|
+
color: '#FFFFFF',
|
|
180
|
+
fontSize: 28,
|
|
181
|
+
fontWeight: '600',
|
|
182
|
+
},
|
|
183
|
+
});
|
|
@@ -201,14 +201,16 @@ const ChatRoom: React.FC<ChatRoomProps> = React.memo(
|
|
|
201
201
|
);
|
|
202
202
|
|
|
203
203
|
const sendMedia = useCallback(
|
|
204
|
-
(data: any, type: string) => {
|
|
204
|
+
(data: any, type: string, caption?: { text: string }) => {
|
|
205
205
|
// Return the promise so callers can sequence the follow-up
|
|
206
206
|
// text send AFTER the upload finishes (consumer expectation:
|
|
207
207
|
// media first, text second — never interleaved).
|
|
208
208
|
if (store.getState().rooms.jumpWindow) {
|
|
209
209
|
dispatch(clearJumpWindow());
|
|
210
210
|
}
|
|
211
|
-
return
|
|
211
|
+
return caption
|
|
212
|
+
? sendMessageMedia(data, type, activeRoomJID || '', false, false, '', undefined, caption)
|
|
213
|
+
: sendMessageMedia(data, type, activeRoomJID || '');
|
|
212
214
|
},
|
|
213
215
|
[activeRoomJID, dispatch],
|
|
214
216
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
|
-
import { IMessage } from '../../types/types';
|
|
2
|
+
import { IAttachment, IMessage } from '../../types/types';
|
|
3
3
|
import FileDownload from '../styled/UnsupportedType';
|
|
4
4
|
import CustomMessageImage from '../styled/MessageImage';
|
|
5
5
|
import CustomMessageVideo from '../styled/VideoMessage';
|
|
@@ -11,7 +11,9 @@ import {
|
|
|
11
11
|
Text,
|
|
12
12
|
View,
|
|
13
13
|
} from 'react-native';
|
|
14
|
-
import {
|
|
14
|
+
import { getAttachmentName, getMessageAttachments } from '../../helpers/attachments';
|
|
15
|
+
import { getMessageCaption } from '../../helpers/caption';
|
|
16
|
+
import { getFileKind, isAlbumKind } from '../../helpers/fileKind';
|
|
15
17
|
import { getDisplayFileName } from '../../helpers/getDisplayFileName';
|
|
16
18
|
import { FileIcon, PlayIcon } from '../../assets/icons';
|
|
17
19
|
import { defaultMediaDims } from '../../helpers/mediaDimensions';
|
|
@@ -19,6 +21,10 @@ import { useFileToken } from '../../hooks/useFileToken';
|
|
|
19
21
|
import { appendFileToken } from '../../helpers/secureFileUrl';
|
|
20
22
|
import { useTheme } from '../../hooks/useTheme';
|
|
21
23
|
import SealedAttachment from './SealedAttachment';
|
|
24
|
+
import AlbumGrid from './AlbumGrid';
|
|
25
|
+
import MediaCaption from '../MessageBubble/MediaCaption';
|
|
26
|
+
import MediaUploadOverlay from './MediaUploadOverlay';
|
|
27
|
+
import { requestMediaRetry } from '../../helpers/mediaSendRetry';
|
|
22
28
|
|
|
23
29
|
interface MediaMessageProps {
|
|
24
30
|
mimeType?: string;
|
|
@@ -156,160 +162,270 @@ const PendingMediaMessage: React.FC<{
|
|
|
156
162
|
);
|
|
157
163
|
};
|
|
158
164
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
165
|
+
interface AttachmentCardProps {
|
|
166
|
+
attachment: IAttachment;
|
|
167
|
+
/** Position in the message; the voice waveform belongs to #0 only. */
|
|
168
|
+
index: number;
|
|
169
|
+
message?: IMessage;
|
|
170
|
+
isUser: boolean;
|
|
171
|
+
fileToken?: string | null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** One file of a message: the picture, video, player or file card it gets. */
|
|
175
|
+
const AttachmentCard: React.FC<AttachmentCardProps> = ({
|
|
176
|
+
attachment,
|
|
177
|
+
index,
|
|
163
178
|
message,
|
|
164
179
|
isUser,
|
|
180
|
+
fileToken,
|
|
165
181
|
}) => {
|
|
166
|
-
const
|
|
167
|
-
const
|
|
182
|
+
const mimeType = attachment.mimetype || '';
|
|
183
|
+
const rawLocation = attachment.location;
|
|
184
|
+
const rawPreview = attachment.locationPreview;
|
|
168
185
|
const location = appendFileToken(rawLocation, fileToken);
|
|
169
|
-
const
|
|
186
|
+
const previewText = appendFileToken(rawPreview, fileToken);
|
|
187
|
+
const originalName = attachment.originalName;
|
|
188
|
+
const duration = attachment.duration ?? (message as any)?.duration;
|
|
189
|
+
const waveForm = index === 0 ? (message as any)?.waveForm : undefined;
|
|
170
190
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
191
|
+
const displayName = getDisplayFileName({
|
|
192
|
+
originalName,
|
|
193
|
+
fileName: attachment.fileName,
|
|
194
|
+
location: rawLocation || rawPreview,
|
|
195
|
+
mimetype: mimeType,
|
|
196
|
+
});
|
|
197
|
+
const kind = getFileKind({
|
|
198
|
+
mimetype: mimeType,
|
|
199
|
+
name: displayName,
|
|
200
|
+
url: rawLocation,
|
|
201
|
+
duration,
|
|
202
|
+
waveForm,
|
|
203
|
+
originalName,
|
|
204
|
+
});
|
|
174
205
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
waveForm: (message as any)?.waveForm,
|
|
189
|
-
originalName: (message as any)?.originalName,
|
|
190
|
-
}
|
|
206
|
+
// The sender's own voice note plays from its local file while it
|
|
207
|
+
// uploads, waveform and all - no placeholder card in between.
|
|
208
|
+
const localPreview = attachment.localUrl;
|
|
209
|
+
if (message?.pending && kind === 'audio' && (localPreview || previewText || location)) {
|
|
210
|
+
return (
|
|
211
|
+
<AudioMessage
|
|
212
|
+
src={localPreview || previewText || location || ''}
|
|
213
|
+
mimeType={mimeType}
|
|
214
|
+
fileName={displayName}
|
|
215
|
+
duration={duration}
|
|
216
|
+
waveForm={waveForm}
|
|
217
|
+
isUser={isUser}
|
|
218
|
+
/>
|
|
191
219
|
);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
220
|
+
}
|
|
221
|
+
if (message?.pending) {
|
|
222
|
+
return (
|
|
223
|
+
<PendingMediaMessage
|
|
224
|
+
fileName={displayName}
|
|
225
|
+
mimeType={mimeType}
|
|
226
|
+
previewUri={localPreview || previewText || location || ''}
|
|
227
|
+
isUser={isUser}
|
|
228
|
+
size={index === 0 ? message?.size : attachment.size}
|
|
229
|
+
/>
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
switch (kind) {
|
|
234
|
+
case 'image':
|
|
235
|
+
return (
|
|
236
|
+
<CustomMessageImage
|
|
237
|
+
fileName={displayName}
|
|
238
|
+
originalName={originalName}
|
|
239
|
+
// Full-size original: opened by the preview modal.
|
|
240
|
+
fileURL={location || previewText || ''}
|
|
241
|
+
// ...and the thumbnail the bubble actually renders, which is
|
|
242
|
+
// what the web client shows too.
|
|
243
|
+
locationPreview={previewText}
|
|
244
|
+
mimetype={mimeType}
|
|
245
|
+
/>
|
|
246
|
+
);
|
|
247
|
+
case 'video':
|
|
248
|
+
return (
|
|
249
|
+
<CustomMessageVideo
|
|
250
|
+
fileName={displayName}
|
|
251
|
+
originalName={originalName}
|
|
252
|
+
fileURL={location || ''}
|
|
253
|
+
// The message's locationPreview is the poster frame the backend
|
|
254
|
+
// generated for this video. Handing it over lets the bubble render
|
|
255
|
+
// as a still + play badge instead of mounting a video surface per
|
|
256
|
+
// row (see VideoMessage).
|
|
257
|
+
previewURL={previewText}
|
|
258
|
+
mimetype={mimeType}
|
|
259
|
+
/>
|
|
260
|
+
);
|
|
261
|
+
case 'audio':
|
|
262
|
+
// Covers audio/*, octet-stream voice notes and the voice-message
|
|
263
|
+
// heuristics of isLikelyAudio (customer-reported #9 voicemail fix):
|
|
264
|
+
// a voicemail shipped as octet-stream with no audio extension still
|
|
265
|
+
// gets the player instead of a broken `.bin` file card.
|
|
195
266
|
return (
|
|
196
267
|
<AudioMessage
|
|
197
|
-
src={
|
|
268
|
+
src={location || ''}
|
|
198
269
|
mimeType={mimeType}
|
|
199
270
|
fileName={displayName}
|
|
200
|
-
|
|
201
|
-
|
|
271
|
+
originalName={originalName}
|
|
272
|
+
duration={duration}
|
|
273
|
+
waveForm={waveForm}
|
|
202
274
|
isUser={isUser}
|
|
203
275
|
/>
|
|
204
276
|
);
|
|
205
|
-
|
|
206
|
-
if (message?.pending) {
|
|
277
|
+
default:
|
|
207
278
|
return (
|
|
208
|
-
<
|
|
279
|
+
<FileDownload
|
|
280
|
+
fileURL={location ? location : ''}
|
|
209
281
|
fileName={displayName}
|
|
210
|
-
|
|
211
|
-
previewUri={messageText || location || ''}
|
|
282
|
+
mimetype={mimeType}
|
|
212
283
|
isUser={isUser}
|
|
213
|
-
|
|
284
|
+
originalName={originalName}
|
|
285
|
+
duration={duration}
|
|
286
|
+
waveForm={waveForm}
|
|
214
287
|
/>
|
|
215
288
|
);
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
// frame the backend generated for this video. Handing it over
|
|
239
|
-
// lets the bubble render as a still + play badge instead of
|
|
240
|
-
// mounting a video surface per row (see VideoMessage).
|
|
241
|
-
previewURL={messageText}
|
|
242
|
-
mimetype={mimeType}
|
|
243
|
-
/>
|
|
244
|
-
);
|
|
245
|
-
case mimeType.startsWith('audio/'): {
|
|
246
|
-
return (
|
|
247
|
-
<AudioMessage
|
|
248
|
-
src={location || ''}
|
|
249
|
-
mimeType={mimeType}
|
|
250
|
-
fileName={displayName}
|
|
251
|
-
originalName={(message as any)?.originalName}
|
|
252
|
-
duration={(message as any)?.duration}
|
|
253
|
-
waveForm={(message as any)?.waveForm}
|
|
254
|
-
isUser={isUser}
|
|
255
|
-
/>
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
case mimeType.includes('application/octet-stream'): {
|
|
259
|
-
return (
|
|
260
|
-
<AudioMessage
|
|
261
|
-
src={location || ''}
|
|
262
|
-
mimeType={mimeType}
|
|
263
|
-
fileName={displayName}
|
|
264
|
-
originalName={(message as any)?.originalName}
|
|
265
|
-
duration={(message as any)?.duration}
|
|
266
|
-
waveForm={(message as any)?.waveForm}
|
|
267
|
-
isUser={isUser}
|
|
268
|
-
/>
|
|
269
|
-
);
|
|
270
|
-
}
|
|
271
|
-
default: {
|
|
272
|
-
// Some senders (notably the web app's voice-message uploader)
|
|
273
|
-
// ship audio as `application/octet-stream` with no audio file
|
|
274
|
-
// extension. `isLikelyAudio` recognises those via the URL path,
|
|
275
|
-
// filename, or voice-message naming hints (voicemail-,
|
|
276
|
-
// voice-note-, recording-, …) so we still render the AudioMessage
|
|
277
|
-
// player instead of falling through to the generic FileDownload
|
|
278
|
-
// card (where the voicemail rendered as a broken `.bin`
|
|
279
|
-
// attachment). Customer-reported #9 voicemail fix.
|
|
280
|
-
if (isAudioPayload) {
|
|
281
|
-
return (
|
|
282
|
-
<AudioMessage
|
|
283
|
-
src={location || ''}
|
|
284
|
-
mimeType={mimeType}
|
|
285
|
-
fileName={displayName}
|
|
286
|
-
originalName={(message as any)?.originalName}
|
|
287
|
-
duration={(message as any)?.duration}
|
|
288
|
-
waveForm={(message as any)?.waveForm}
|
|
289
|
-
isUser={isUser}
|
|
290
|
-
/>
|
|
291
|
-
);
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const MediaMessage: React.FC<MediaMessageProps> = ({
|
|
293
|
+
mimeType,
|
|
294
|
+
location: rawLocation,
|
|
295
|
+
messageText: rawMessageText,
|
|
296
|
+
message,
|
|
297
|
+
isUser,
|
|
298
|
+
}) => {
|
|
299
|
+
const fileToken = useFileToken();
|
|
300
|
+
const theme = useTheme();
|
|
301
|
+
|
|
302
|
+
// Order of truth: the message's own attachments, else its flat fields, else
|
|
303
|
+
// the props the bubble was handed (a bare file with no message around it).
|
|
304
|
+
const attachments = useMemo(
|
|
305
|
+
() =>
|
|
306
|
+
getMessageAttachments(
|
|
307
|
+
message ?? {
|
|
308
|
+
location: rawLocation,
|
|
309
|
+
locationPreview: rawMessageText,
|
|
310
|
+
mimetype: mimeType,
|
|
292
311
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
312
|
+
),
|
|
313
|
+
[message, rawLocation, rawMessageText, mimeType]
|
|
314
|
+
);
|
|
315
|
+
const caption = message ? getMessageCaption(message) : undefined;
|
|
316
|
+
|
|
317
|
+
if (message?.clientEncrypted === 'true') {
|
|
318
|
+
// A sealed file has nothing to show until it is opened, so each one is a
|
|
319
|
+
// card of its own (SealedAttachment); the caption came out of the
|
|
320
|
+
// encrypted body.
|
|
321
|
+
return (
|
|
322
|
+
<>
|
|
323
|
+
<SealedAttachment message={message} isUser={isUser} />
|
|
324
|
+
<MediaCaption text={caption} isUser={isUser} />
|
|
325
|
+
</>
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (attachments.length === 0) {
|
|
330
|
+
return <Text style={{ color: theme.text }}>Unsupported media type</Text>;
|
|
306
331
|
}
|
|
307
|
-
|
|
332
|
+
|
|
333
|
+
// A file of an outgoing multi-file message carries its upload state. It is
|
|
334
|
+
// "reachable" through its local copy, not a server one, until the send lands.
|
|
335
|
+
const isOutgoingFile = (attachment: IAttachment) =>
|
|
336
|
+
Boolean(message?.pending) &&
|
|
337
|
+
Boolean(attachment.uploadStatus || attachment.localUrl);
|
|
338
|
+
|
|
339
|
+
const card = (attachment: IAttachment, index: number) => {
|
|
340
|
+
const body = (
|
|
341
|
+
<AttachmentCard
|
|
342
|
+
key={attachment.attachmentId || `${index}-${attachment.location}`}
|
|
343
|
+
attachment={attachment}
|
|
344
|
+
index={index}
|
|
345
|
+
message={message}
|
|
346
|
+
isUser={isUser}
|
|
347
|
+
fileToken={fileToken}
|
|
348
|
+
/>
|
|
349
|
+
);
|
|
350
|
+
// In a multi-file message each file gets its own progress and Retry.
|
|
351
|
+
if (!attachment.uploadStatus || attachments.length < 2) {return body;}
|
|
352
|
+
return (
|
|
353
|
+
<View
|
|
354
|
+
key={`tile-${attachment.attachmentId || index}`}
|
|
355
|
+
style={styles.uploadTile}
|
|
356
|
+
testID={`media-upload-tile-${index}`}
|
|
357
|
+
>
|
|
358
|
+
{body}
|
|
359
|
+
<MediaUploadOverlay
|
|
360
|
+
status={attachment.uploadStatus}
|
|
361
|
+
progress={attachment.uploadProgress}
|
|
362
|
+
onRetry={message?.id ? () => requestMediaRetry(message.id, index) : undefined}
|
|
363
|
+
/>
|
|
364
|
+
</View>
|
|
365
|
+
);
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
// Pictures and videos share one album when there are two or more of them;
|
|
369
|
+
// documents and voice notes follow as one card each. A lone picture is the
|
|
370
|
+
// ordinary bubble picture, exactly as a single-file message always was.
|
|
371
|
+
const album = attachments.filter(
|
|
372
|
+
(attachment) =>
|
|
373
|
+
(Boolean(attachment.location) || isOutgoingFile(attachment)) &&
|
|
374
|
+
isAlbumKind(
|
|
375
|
+
getFileKind({
|
|
376
|
+
mimetype: attachment.mimetype,
|
|
377
|
+
name: getAttachmentName(attachment),
|
|
378
|
+
url: attachment.location,
|
|
379
|
+
duration: attachment.duration,
|
|
380
|
+
})
|
|
381
|
+
)
|
|
382
|
+
);
|
|
383
|
+
const useAlbum = album.length >= 2;
|
|
384
|
+
const rest = useAlbum
|
|
385
|
+
? attachments.filter((attachment) => !album.includes(attachment))
|
|
386
|
+
: attachments;
|
|
387
|
+
|
|
388
|
+
// One file and no text: the card alone, no wrapper around it.
|
|
389
|
+
if (!useAlbum && attachments.length === 1 && !caption) {
|
|
390
|
+
return card(attachments[0]!, 0);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return (
|
|
394
|
+
<View style={styles.stack}>
|
|
395
|
+
{useAlbum && (
|
|
396
|
+
<AlbumGrid
|
|
397
|
+
attachments={album}
|
|
398
|
+
onRetryTile={
|
|
399
|
+
message?.id
|
|
400
|
+
? (position) =>
|
|
401
|
+
requestMediaRetry(
|
|
402
|
+
message.id,
|
|
403
|
+
attachments.indexOf(album[position]!)
|
|
404
|
+
)
|
|
405
|
+
: undefined
|
|
406
|
+
}
|
|
407
|
+
/>
|
|
408
|
+
)}
|
|
409
|
+
{rest.map((attachment) => card(attachment, attachments.indexOf(attachment)))}
|
|
410
|
+
<MediaCaption text={caption} isUser={isUser} />
|
|
411
|
+
</View>
|
|
412
|
+
);
|
|
308
413
|
};
|
|
309
414
|
|
|
310
415
|
export default MediaMessage;
|
|
311
416
|
|
|
312
417
|
const styles = StyleSheet.create({
|
|
418
|
+
stack: {
|
|
419
|
+
alignItems: 'flex-start',
|
|
420
|
+
gap: 4,
|
|
421
|
+
},
|
|
422
|
+
// Frames one file of a multi-file message so its upload overlay covers it.
|
|
423
|
+
uploadTile: {
|
|
424
|
+
position: 'relative',
|
|
425
|
+
alignSelf: 'stretch',
|
|
426
|
+
borderRadius: 10,
|
|
427
|
+
overflow: 'hidden',
|
|
428
|
+
},
|
|
313
429
|
pendingImageWrapper: {
|
|
314
430
|
width: pendingImageDims.width,
|
|
315
431
|
height: pendingImageDims.height,
|