@droppii-org/chat-mobile 0.2.6 → 0.2.8
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/lib/module/components/AttachmentPreview.js +250 -0
- package/lib/module/components/AttachmentPreview.js.map +1 -0
- package/lib/module/components/MediaViewer/index.js +2 -0
- package/lib/module/components/MediaViewer/index.js.map +1 -0
- package/lib/module/components/MediaViewerModal.js +57 -0
- package/lib/module/components/MediaViewerModal.js.map +1 -0
- package/lib/module/components/MergedImageGrid.js +173 -0
- package/lib/module/components/MergedImageGrid.js.map +1 -0
- package/lib/module/components/ThreadCard/AvatarSection.js +4 -4
- package/lib/module/components/ThreadCard/AvatarSection.js.map +1 -1
- package/lib/module/components/ThreadCard/NamePrefixIcon.js +13 -16
- package/lib/module/components/ThreadCard/NamePrefixIcon.js.map +1 -1
- package/lib/module/components/ThreadCard/ThreadCard.js +13 -33
- package/lib/module/components/ThreadCard/ThreadCard.js.map +1 -1
- package/lib/module/components/ThreadCard/thread-card.utils.js +80 -4
- package/lib/module/components/ThreadCard/thread-card.utils.js.map +1 -1
- package/lib/module/components/messages/fileMessage/index.js +26 -0
- package/lib/module/components/messages/fileMessage/index.js.map +1 -0
- package/lib/module/components/messages/imageMessage/index.js +118 -0
- package/lib/module/components/messages/imageMessage/index.js.map +1 -0
- package/lib/module/components/messages/linkMessage/index.js +122 -0
- package/lib/module/components/messages/linkMessage/index.js.map +1 -0
- package/lib/module/components/messages/mergedMessage/index.js +37 -0
- package/lib/module/components/messages/mergedMessage/index.js.map +1 -0
- package/lib/module/components/messages/styles.js +41 -0
- package/lib/module/components/messages/styles.js.map +1 -0
- package/lib/module/components/messages/textMessage/index.js +38 -0
- package/lib/module/components/messages/textMessage/index.js.map +1 -0
- package/lib/module/components/messages/types.js +14 -0
- package/lib/module/components/messages/types.js.map +1 -0
- package/lib/module/components/messages/videoMessage/index.js +110 -0
- package/lib/module/components/messages/videoMessage/index.js.map +1 -0
- package/lib/module/config/api-endpoints.js +66 -0
- package/lib/module/config/api-endpoints.js.map +1 -0
- package/lib/module/config/attachment-priority.js +81 -0
- package/lib/module/config/attachment-priority.js.map +1 -0
- package/lib/module/config/configuration.js +50 -0
- package/lib/module/config/configuration.js.map +1 -0
- package/lib/module/config/index.js +22 -0
- package/lib/module/config/index.js.map +1 -0
- package/lib/module/context/ChatContext.js +7 -6
- package/lib/module/context/ChatContext.js.map +1 -1
- package/lib/module/core/index.js +19 -1
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/core/useChatListener.js +0 -14
- package/lib/module/core/useChatListener.js.map +1 -1
- package/lib/module/hooks/message/useSendMessage.js +106 -0
- package/lib/module/hooks/message/useSendMessage.js.map +1 -0
- package/lib/module/hooks/useChatMessages.js +36 -121
- package/lib/module/hooks/useChatMessages.js.map +1 -1
- package/lib/module/hooks/useConversationList.js +29 -17
- package/lib/module/hooks/useConversationList.js.map +1 -1
- package/lib/module/hooks/useImageAttachment.js +263 -0
- package/lib/module/hooks/useImageAttachment.js.map +1 -0
- package/lib/module/hooks/useLinkPreview/useLinkPreview.js +3 -2
- package/lib/module/hooks/useLinkPreview/useLinkPreview.js.map +1 -1
- package/lib/module/hooks/useMediaViewer.js +24 -0
- package/lib/module/hooks/useMediaViewer.js.map +1 -0
- package/lib/module/hooks/useSendAttachment.js +182 -0
- package/lib/module/hooks/useSendAttachment.js.map +1 -0
- package/lib/module/hooks/useVideoAttachment.js +251 -0
- package/lib/module/hooks/useVideoAttachment.js.map +1 -0
- package/lib/module/index.js +13 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/screens/MediaView/VideoPlayer.js +177 -0
- package/lib/module/screens/MediaView/VideoPlayer.js.map +1 -0
- package/lib/module/screens/MediaView/index.js +264 -0
- package/lib/module/screens/MediaView/index.js.map +1 -0
- package/lib/module/screens/chat-detail/ChatComposer.js +190 -196
- package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatDetail.js +106 -71
- package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatDetailHeader.js +5 -8
- package/lib/module/screens/chat-detail/ChatDetailHeader.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatLinkPreview.js +1 -1
- package/lib/module/screens/chat-detail/ChatLinkPreview.js.map +1 -1
- package/lib/module/screens/chat-detail/ChatListLegend.js +5 -15
- package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
- package/lib/module/screens/chat-detail/components/ChatInputActions.js +51 -0
- package/lib/module/screens/chat-detail/components/ChatInputActions.js.map +1 -0
- package/lib/module/screens/chat-detail/components/ChatMessageInput.js +93 -0
- package/lib/module/screens/chat-detail/components/ChatMessageInput.js.map +1 -0
- package/lib/module/screens/chat-detail/conversationHeader.utils.js +7 -9
- package/lib/module/screens/chat-detail/conversationHeader.utils.js.map +1 -1
- package/lib/module/screens/chat-detail/hooks/useAttachmentSendHandler.js +221 -0
- package/lib/module/screens/chat-detail/hooks/useAttachmentSendHandler.js.map +1 -0
- package/lib/module/screens/chat-detail/hooks/useChatComposerAnimation.js +114 -0
- package/lib/module/screens/chat-detail/hooks/useChatComposerAnimation.js.map +1 -0
- package/lib/module/screens/chat-detail/hooks/useChatComposerState.js +26 -0
- package/lib/module/screens/chat-detail/hooks/useChatComposerState.js.map +1 -0
- package/lib/module/screens/chat-detail/index.js +0 -1
- package/lib/module/screens/chat-detail/index.js.map +1 -1
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +32 -25
- package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
- package/lib/module/screens/chat-detail/legend/messageTypes.js +15 -0
- package/lib/module/screens/chat-detail/legend/messageTypes.js.map +1 -0
- package/lib/module/screens/inbox/MessagesTab.js.map +1 -1
- package/lib/module/services/attachmentHandlers/fileAttachmentHandler.js +61 -0
- package/lib/module/services/attachmentHandlers/fileAttachmentHandler.js.map +1 -0
- package/lib/module/services/attachmentHandlers/imageAttachmentHandler.js +54 -0
- package/lib/module/services/attachmentHandlers/imageAttachmentHandler.js.map +1 -0
- package/lib/module/services/attachmentHandlers/index.js +12 -0
- package/lib/module/services/attachmentHandlers/index.js.map +1 -0
- package/lib/module/services/attachmentHandlers/videoAttachmentHandler.js +85 -0
- package/lib/module/services/attachmentHandlers/videoAttachmentHandler.js.map +1 -0
- package/lib/module/services/attachmentOrchestrator.js +225 -0
- package/lib/module/services/attachmentOrchestrator.js.map +1 -0
- package/lib/module/services/auth.js +35 -0
- package/lib/module/services/auth.js.map +1 -0
- package/lib/module/services/endpoints.js +20 -1
- package/lib/module/services/endpoints.js.map +1 -1
- package/lib/module/services/imageUpload.js +126 -0
- package/lib/module/services/imageUpload.js.map +1 -0
- package/lib/module/store/conversation.js +1 -1
- package/lib/module/store/conversation.js.map +1 -1
- package/lib/module/store/message.js +45 -0
- package/lib/module/store/message.js.map +1 -0
- package/lib/module/translation/resources/i18n.js +22 -2
- package/lib/module/translation/resources/i18n.js.map +1 -1
- package/lib/module/types/attachment.js +2 -0
- package/lib/module/types/attachment.js.map +1 -0
- package/lib/module/types/attachmentHandler.js +20 -0
- package/lib/module/types/attachmentHandler.js.map +1 -0
- package/lib/module/types/chat.js +2 -7
- package/lib/module/types/chat.js.map +1 -1
- package/lib/module/types/imageUpload.js +2 -0
- package/lib/module/types/imageUpload.js.map +1 -0
- package/lib/module/types/message.js +1 -0
- package/lib/module/types/message.js.map +1 -1
- package/lib/module/utils/chatImageDimens.js +148 -0
- package/lib/module/utils/chatImageDimens.js.map +1 -0
- package/lib/module/utils/conversation.js +34 -13
- package/lib/module/utils/conversation.js.map +1 -1
- package/lib/module/utils/device.js +65 -0
- package/lib/module/utils/device.js.map +1 -0
- package/lib/module/utils/imageUrlOptimizer.js +41 -0
- package/lib/module/utils/imageUrlOptimizer.js.map +1 -0
- package/lib/module/utils/imageUtils.js +69 -0
- package/lib/module/utils/imageUtils.js.map +1 -0
- package/lib/module/utils/legendListMessage.js +0 -3
- package/lib/module/utils/legendListMessage.js.map +1 -1
- package/lib/module/utils/message.js +5 -8
- package/lib/module/utils/message.js.map +1 -1
- package/lib/module/utils/resolveMessageType.js +3 -0
- package/lib/module/utils/resolveMessageType.js.map +1 -1
- package/lib/module/utils/ui.js +17 -0
- package/lib/module/utils/ui.js.map +1 -0
- package/lib/module/utils/url.js +3 -3
- package/lib/module/utils/url.js.map +1 -1
- package/lib/module/utils/videoThumbnail.js +62 -0
- package/lib/module/utils/videoThumbnail.js.map +1 -0
- package/lib/typescript/src/components/AttachmentPreview.d.ts +28 -0
- package/lib/typescript/src/components/AttachmentPreview.d.ts.map +1 -0
- package/lib/typescript/src/components/MediaViewer/index.d.ts +1 -0
- package/lib/typescript/src/components/MediaViewer/index.d.ts.map +1 -0
- package/lib/typescript/src/components/MediaViewerModal.d.ts +10 -0
- package/lib/typescript/src/components/MediaViewerModal.d.ts.map +1 -0
- package/lib/typescript/src/components/MergedImageGrid.d.ts +16 -0
- package/lib/typescript/src/components/MergedImageGrid.d.ts.map +1 -0
- package/lib/typescript/src/components/ThreadCard/AvatarSection.d.ts +2 -2
- package/lib/typescript/src/components/ThreadCard/AvatarSection.d.ts.map +1 -1
- package/lib/typescript/src/components/ThreadCard/NamePrefixIcon.d.ts +3 -4
- package/lib/typescript/src/components/ThreadCard/NamePrefixIcon.d.ts.map +1 -1
- package/lib/typescript/src/components/ThreadCard/ThreadCard.d.ts.map +1 -1
- package/lib/typescript/src/components/ThreadCard/thread-card.utils.d.ts.map +1 -1
- package/lib/typescript/src/components/messages/fileMessage/index.d.ts +3 -0
- package/lib/typescript/src/components/messages/fileMessage/index.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/imageMessage/index.d.ts +3 -0
- package/lib/typescript/src/components/messages/imageMessage/index.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/linkMessage/index.d.ts +9 -0
- package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/mergedMessage/index.d.ts +3 -0
- package/lib/typescript/src/components/messages/mergedMessage/index.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/styles.d.ts +36 -0
- package/lib/typescript/src/components/messages/styles.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/textMessage/index.d.ts +9 -0
- package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/types.d.ts +10 -0
- package/lib/typescript/src/components/messages/types.d.ts.map +1 -0
- package/lib/typescript/src/components/messages/videoMessage/index.d.ts +3 -0
- package/lib/typescript/src/components/messages/videoMessage/index.d.ts.map +1 -0
- package/lib/typescript/src/config/api-endpoints.d.ts +40 -0
- package/lib/typescript/src/config/api-endpoints.d.ts.map +1 -0
- package/lib/typescript/src/config/attachment-priority.d.ts +31 -0
- package/lib/typescript/src/config/attachment-priority.d.ts.map +1 -0
- package/lib/typescript/src/config/configuration.d.ts +30 -0
- package/lib/typescript/src/config/configuration.d.ts.map +1 -0
- package/lib/typescript/src/config/index.d.ts +15 -0
- package/lib/typescript/src/config/index.d.ts.map +1 -0
- package/lib/typescript/src/context/ChatContext.d.ts +1 -1
- package/lib/typescript/src/context/ChatContext.d.ts.map +1 -1
- package/lib/typescript/src/core/index.d.ts +13 -1
- package/lib/typescript/src/core/index.d.ts.map +1 -1
- package/lib/typescript/src/core/useChatListener.d.ts.map +1 -1
- package/lib/typescript/src/hooks/message/useSendMessage.d.ts +12 -0
- package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useChatMessages.d.ts +0 -1
- package/lib/typescript/src/hooks/useChatMessages.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useConversationList.d.ts +2 -1
- package/lib/typescript/src/hooks/useConversationList.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useImageAttachment.d.ts +20 -0
- package/lib/typescript/src/hooks/useImageAttachment.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useLinkPreview/useLinkPreview.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useMediaViewer.d.ts +13 -0
- package/lib/typescript/src/hooks/useMediaViewer.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useSendAttachment.d.ts +59 -0
- package/lib/typescript/src/hooks/useSendAttachment.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useVideoAttachment.d.ts +29 -0
- package/lib/typescript/src/hooks/useVideoAttachment.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +14 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/screens/MediaView/VideoPlayer.d.ts +12 -0
- package/lib/typescript/src/screens/MediaView/VideoPlayer.d.ts.map +1 -0
- package/lib/typescript/src/screens/MediaView/index.d.ts +11 -0
- package/lib/typescript/src/screens/MediaView/index.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatDetailHeader.d.ts +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatDetailHeader.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts +1 -1
- package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/components/ChatInputActions.d.ts +8 -0
- package/lib/typescript/src/screens/chat-detail/components/ChatInputActions.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts +15 -0
- package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/conversationHeader.utils.d.ts +1 -1
- package/lib/typescript/src/screens/chat-detail/conversationHeader.utils.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/hooks/useAttachmentSendHandler.d.ts +23 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useAttachmentSendHandler.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerAnimation.d.ts +15 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerAnimation.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts +13 -0
- package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/index.d.ts +0 -2
- package/lib/typescript/src/screens/chat-detail/index.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +3 -3
- package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
- package/lib/typescript/src/screens/chat-detail/legend/messageTypes.d.ts +13 -0
- package/lib/typescript/src/screens/chat-detail/legend/messageTypes.d.ts.map +1 -0
- package/lib/typescript/src/screens/chat-detail/types.d.ts +10 -8
- package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
- package/lib/typescript/src/services/attachmentHandlers/fileAttachmentHandler.d.ts +22 -0
- package/lib/typescript/src/services/attachmentHandlers/fileAttachmentHandler.d.ts.map +1 -0
- package/lib/typescript/src/services/attachmentHandlers/imageAttachmentHandler.d.ts +3 -0
- package/lib/typescript/src/services/attachmentHandlers/imageAttachmentHandler.d.ts.map +1 -0
- package/lib/typescript/src/services/attachmentHandlers/index.d.ts +5 -0
- package/lib/typescript/src/services/attachmentHandlers/index.d.ts.map +1 -0
- package/lib/typescript/src/services/attachmentHandlers/videoAttachmentHandler.d.ts +31 -0
- package/lib/typescript/src/services/attachmentHandlers/videoAttachmentHandler.d.ts.map +1 -0
- package/lib/typescript/src/services/attachmentOrchestrator.d.ts +5 -0
- package/lib/typescript/src/services/attachmentOrchestrator.d.ts.map +1 -0
- package/lib/typescript/src/services/auth.d.ts +19 -0
- package/lib/typescript/src/services/auth.d.ts.map +1 -0
- package/lib/typescript/src/services/endpoints.d.ts +11 -1
- package/lib/typescript/src/services/endpoints.d.ts.map +1 -1
- package/lib/typescript/src/services/imageUpload.d.ts +7 -0
- package/lib/typescript/src/services/imageUpload.d.ts.map +1 -0
- package/lib/typescript/src/store/message.d.ts +3 -0
- package/lib/typescript/src/store/message.d.ts.map +1 -0
- package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
- package/lib/typescript/src/types/attachment.d.ts +72 -0
- package/lib/typescript/src/types/attachment.d.ts.map +1 -0
- package/lib/typescript/src/types/attachmentHandler.d.ts +13 -0
- package/lib/typescript/src/types/attachmentHandler.d.ts.map +1 -0
- package/lib/typescript/src/types/chat.d.ts +28 -27
- package/lib/typescript/src/types/chat.d.ts.map +1 -1
- package/lib/typescript/src/types/common.d.ts +1 -0
- package/lib/typescript/src/types/common.d.ts.map +1 -1
- package/lib/typescript/src/types/imageUpload.d.ts +26 -0
- package/lib/typescript/src/types/imageUpload.d.ts.map +1 -0
- package/lib/typescript/src/types/message.d.ts +1 -0
- package/lib/typescript/src/types/message.d.ts.map +1 -1
- package/lib/typescript/src/utils/chatImageDimens.d.ts +34 -0
- package/lib/typescript/src/utils/chatImageDimens.d.ts.map +1 -0
- package/lib/typescript/src/utils/conversation.d.ts +3 -2
- package/lib/typescript/src/utils/conversation.d.ts.map +1 -1
- package/lib/typescript/src/utils/device.d.ts +7 -0
- package/lib/typescript/src/utils/device.d.ts.map +1 -0
- package/lib/typescript/src/utils/imageUrlOptimizer.d.ts +12 -0
- package/lib/typescript/src/utils/imageUrlOptimizer.d.ts.map +1 -0
- package/lib/typescript/src/utils/imageUtils.d.ts +9 -0
- package/lib/typescript/src/utils/imageUtils.d.ts.map +1 -0
- package/lib/typescript/src/utils/legendListMessage.d.ts +0 -2
- package/lib/typescript/src/utils/legendListMessage.d.ts.map +1 -1
- package/lib/typescript/src/utils/message.d.ts.map +1 -1
- package/lib/typescript/src/utils/resolveMessageType.d.ts.map +1 -1
- package/lib/typescript/src/utils/ui.d.ts +13 -0
- package/lib/typescript/src/utils/ui.d.ts.map +1 -0
- package/lib/typescript/src/utils/url.d.ts +1 -1
- package/lib/typescript/src/utils/url.d.ts.map +1 -1
- package/lib/typescript/src/utils/videoThumbnail.d.ts +16 -0
- package/lib/typescript/src/utils/videoThumbnail.d.ts.map +1 -0
- package/package.json +15 -3
- package/src/components/AttachmentPreview.tsx +304 -0
- package/src/components/MediaViewer/index.tsx +0 -0
- package/src/components/MediaViewerModal.tsx +70 -0
- package/src/components/MergedImageGrid.tsx +238 -0
- package/src/components/ThreadCard/AvatarSection.tsx +5 -8
- package/src/components/ThreadCard/NamePrefixIcon.tsx +27 -38
- package/src/components/ThreadCard/ThreadCard.tsx +16 -30
- package/src/components/ThreadCard/thread-card.utils.ts +95 -4
- package/src/components/messages/fileMessage/index.tsx +30 -0
- package/src/components/messages/imageMessage/index.tsx +137 -0
- package/src/components/messages/linkMessage/index.tsx +162 -0
- package/src/components/messages/mergedMessage/index.tsx +45 -0
- package/src/components/messages/styles.ts +39 -0
- package/src/components/messages/textMessage/index.tsx +53 -0
- package/src/components/messages/types.ts +22 -0
- package/src/components/messages/videoMessage/index.tsx +120 -0
- package/src/config/api-endpoints.ts +72 -0
- package/src/config/attachment-priority.ts +93 -0
- package/src/config/configuration.ts +50 -0
- package/src/config/index.ts +19 -0
- package/src/context/ChatContext.tsx +12 -4
- package/src/core/index.ts +25 -1
- package/src/core/useChatListener.ts +0 -21
- package/src/hooks/message/useSendMessage.ts +143 -0
- package/src/hooks/useChatMessages.ts +69 -161
- package/src/hooks/useConversationList.ts +34 -16
- package/src/hooks/useImageAttachment.ts +348 -0
- package/src/hooks/useLinkPreview/useLinkPreview.ts +3 -2
- package/src/hooks/useMediaViewer.ts +32 -0
- package/src/hooks/useSendAttachment.ts +295 -0
- package/src/hooks/useVideoAttachment.ts +334 -0
- package/src/index.tsx +13 -1
- package/src/screens/MediaView/VideoPlayer.tsx +211 -0
- package/src/screens/MediaView/index.tsx +327 -0
- package/src/screens/chat-detail/ChatComposer.tsx +206 -271
- package/src/screens/chat-detail/ChatDetail.tsx +164 -104
- package/src/screens/chat-detail/ChatDetailHeader.tsx +4 -10
- package/src/screens/chat-detail/ChatLinkPreview.tsx +1 -1
- package/src/screens/chat-detail/ChatListLegend.tsx +10 -13
- package/src/screens/chat-detail/components/ChatInputActions.tsx +71 -0
- package/src/screens/chat-detail/components/ChatMessageInput.tsx +127 -0
- package/src/screens/chat-detail/conversationHeader.utils.ts +11 -14
- package/src/screens/chat-detail/hooks/useAttachmentSendHandler.ts +291 -0
- package/src/screens/chat-detail/hooks/useChatComposerAnimation.ts +184 -0
- package/src/screens/chat-detail/hooks/useChatComposerState.ts +40 -0
- package/src/screens/chat-detail/index.ts +0 -2
- package/src/screens/chat-detail/legend/LegendChatMessage.tsx +44 -39
- package/src/screens/chat-detail/legend/messageTypes.tsx +13 -0
- package/src/screens/chat-detail/types.ts +11 -9
- package/src/screens/inbox/MessagesTab.tsx +1 -1
- package/src/services/attachmentHandlers/fileAttachmentHandler.ts +78 -0
- package/src/services/attachmentHandlers/imageAttachmentHandler.ts +54 -0
- package/src/services/attachmentHandlers/index.ts +10 -0
- package/src/services/attachmentHandlers/videoAttachmentHandler.ts +114 -0
- package/src/services/attachmentOrchestrator.ts +300 -0
- package/src/services/auth.ts +34 -0
- package/src/services/endpoints.ts +24 -1
- package/src/services/imageUpload.ts +162 -0
- package/src/store/conversation.ts +1 -1
- package/src/store/message.ts +44 -0
- package/src/translation/resources/i18n.ts +22 -2
- package/src/types/attachment.ts +85 -0
- package/src/types/attachmentHandler.ts +31 -0
- package/src/types/chat.ts +31 -30
- package/src/types/common.ts +1 -0
- package/src/types/imageUpload.ts +28 -0
- package/src/types/message.ts +1 -0
- package/src/utils/chatImageDimens.ts +178 -0
- package/src/utils/conversation.ts +44 -17
- package/src/utils/device.ts +73 -0
- package/src/utils/imageUrlOptimizer.ts +56 -0
- package/src/utils/imageUtils.ts +76 -0
- package/src/utils/legendListMessage.ts +0 -5
- package/src/utils/message.ts +10 -12
- package/src/utils/resolveMessageType.ts +2 -0
- package/src/utils/ui.ts +19 -0
- package/src/utils/url.ts +3 -3
- package/src/utils/videoThumbnail.ts +85 -0
- package/lib/module/screens/chat-detail/ChatList.js +0 -147
- package/lib/module/screens/chat-detail/ChatList.js.map +0 -1
- package/lib/module/screens/chat-detail/ChatTextBubble.js +0 -62
- package/lib/module/screens/chat-detail/ChatTextBubble.js.map +0 -1
- package/lib/module/screens/chat-detail/legend/message-types.js +0 -122
- package/lib/module/screens/chat-detail/legend/message-types.js.map +0 -1
- package/lib/module/screens/chat-detail/messages/ChatMessageBubble.js +0 -24
- package/lib/module/screens/chat-detail/messages/ChatMessageBubble.js.map +0 -1
- package/lib/module/screens/chat-detail/messages/types.js +0 -4
- package/lib/module/screens/chat-detail/messages/types.js.map +0 -1
- package/lib/typescript/src/screens/chat-detail/ChatList.d.ts +0 -3
- package/lib/typescript/src/screens/chat-detail/ChatList.d.ts.map +0 -1
- package/lib/typescript/src/screens/chat-detail/ChatTextBubble.d.ts +0 -3
- package/lib/typescript/src/screens/chat-detail/ChatTextBubble.d.ts.map +0 -1
- package/lib/typescript/src/screens/chat-detail/legend/message-types.d.ts +0 -12
- package/lib/typescript/src/screens/chat-detail/legend/message-types.d.ts.map +0 -1
- package/lib/typescript/src/screens/chat-detail/messages/ChatMessageBubble.d.ts +0 -3
- package/lib/typescript/src/screens/chat-detail/messages/ChatMessageBubble.d.ts.map +0 -1
- package/lib/typescript/src/screens/chat-detail/messages/types.d.ts +0 -13
- package/lib/typescript/src/screens/chat-detail/messages/types.d.ts.map +0 -1
- package/src/screens/chat-detail/ChatList.tsx +0 -190
- package/src/screens/chat-detail/ChatTextBubble.tsx +0 -73
- package/src/screens/chat-detail/legend/message-types.tsx +0 -149
- package/src/screens/chat-detail/messages/ChatMessageBubble.tsx +0 -23
- package/src/screens/chat-detail/messages/types.ts +0 -14
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { PixelRatio } from 'react-native';
|
|
2
|
+
import { isTablet } from 'react-native-device-info';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Chat-specific image dimensions for optimal display and memory usage
|
|
6
|
+
* Responsive to device type (tablet/mobile) and pixel ratio
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export enum CHAT_IMAGE_VIEW_SOURCE {
|
|
10
|
+
MessageListThumbnail = 'MessageListThumbnail',
|
|
11
|
+
MessageDetailBubble = 'MessageDetailBubble',
|
|
12
|
+
ImagePreviewSmall = 'ImagePreviewSmall',
|
|
13
|
+
ImagePreviewMedium = 'ImagePreviewMedium',
|
|
14
|
+
ImagePreviewLarge = 'ImagePreviewLarge',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ImageDimension {
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const getSizeReduction = (originalSize: number, factor: number = 1) => {
|
|
23
|
+
const PIXEL_RATIO = PixelRatio.get();
|
|
24
|
+
return Math.round(originalSize * factor * PIXEL_RATIO);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const CHAT_IMAGE_DIMENSIONS_PLATFORM = {
|
|
28
|
+
TABLET: {
|
|
29
|
+
[CHAT_IMAGE_VIEW_SOURCE.MessageListThumbnail]: {
|
|
30
|
+
width: 240,
|
|
31
|
+
height: 240,
|
|
32
|
+
},
|
|
33
|
+
[CHAT_IMAGE_VIEW_SOURCE.MessageDetailBubble]: {
|
|
34
|
+
width: 400,
|
|
35
|
+
height: 400,
|
|
36
|
+
},
|
|
37
|
+
[CHAT_IMAGE_VIEW_SOURCE.ImagePreviewSmall]: {
|
|
38
|
+
width: 200,
|
|
39
|
+
height: 200,
|
|
40
|
+
},
|
|
41
|
+
[CHAT_IMAGE_VIEW_SOURCE.ImagePreviewMedium]: {
|
|
42
|
+
width: 300,
|
|
43
|
+
height: 300,
|
|
44
|
+
},
|
|
45
|
+
[CHAT_IMAGE_VIEW_SOURCE.ImagePreviewLarge]: {
|
|
46
|
+
width: 500,
|
|
47
|
+
height: 500,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
MOBILE: {
|
|
51
|
+
[CHAT_IMAGE_VIEW_SOURCE.MessageListThumbnail]: {
|
|
52
|
+
width: 180,
|
|
53
|
+
height: 180,
|
|
54
|
+
},
|
|
55
|
+
[CHAT_IMAGE_VIEW_SOURCE.MessageDetailBubble]: {
|
|
56
|
+
width: 250,
|
|
57
|
+
height: 250,
|
|
58
|
+
},
|
|
59
|
+
[CHAT_IMAGE_VIEW_SOURCE.ImagePreviewSmall]: {
|
|
60
|
+
width: 120,
|
|
61
|
+
height: 120,
|
|
62
|
+
},
|
|
63
|
+
[CHAT_IMAGE_VIEW_SOURCE.ImagePreviewMedium]: {
|
|
64
|
+
width: 200,
|
|
65
|
+
height: 200,
|
|
66
|
+
},
|
|
67
|
+
[CHAT_IMAGE_VIEW_SOURCE.ImagePreviewLarge]: {
|
|
68
|
+
width: 320,
|
|
69
|
+
height: 320,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
class ChatImageDimens {
|
|
75
|
+
private static instance: ChatImageDimens;
|
|
76
|
+
private static factor: number = 1;
|
|
77
|
+
private static regexCDN = /^.*(cdn)(stg|dev|beta)?(.droppii)/;
|
|
78
|
+
private static dimens = isTablet()
|
|
79
|
+
? { ...CHAT_IMAGE_DIMENSIONS_PLATFORM.TABLET }
|
|
80
|
+
: { ...CHAT_IMAGE_DIMENSIONS_PLATFORM.MOBILE };
|
|
81
|
+
|
|
82
|
+
constructor(factor: number) {
|
|
83
|
+
ChatImageDimens.factor = factor;
|
|
84
|
+
this.calculateDimensions();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private calculateDimensions() {
|
|
88
|
+
const baseDimens = isTablet()
|
|
89
|
+
? CHAT_IMAGE_DIMENSIONS_PLATFORM.TABLET
|
|
90
|
+
: CHAT_IMAGE_DIMENSIONS_PLATFORM.MOBILE;
|
|
91
|
+
|
|
92
|
+
for (const key in baseDimens) {
|
|
93
|
+
const source = key as CHAT_IMAGE_VIEW_SOURCE;
|
|
94
|
+
const baseDimen = baseDimens[source];
|
|
95
|
+
ChatImageDimens.dimens[source] = {
|
|
96
|
+
width: getSizeReduction(baseDimen.width, ChatImageDimens.factor),
|
|
97
|
+
height: getSizeReduction(baseDimen.height, ChatImageDimens.factor),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public static getInstance() {
|
|
103
|
+
if (!ChatImageDimens.instance) {
|
|
104
|
+
ChatImageDimens.instance = new ChatImageDimens(1);
|
|
105
|
+
}
|
|
106
|
+
return ChatImageDimens.instance;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public static updateFactor(factor: number) {
|
|
110
|
+
if (factor !== ChatImageDimens.factor) {
|
|
111
|
+
ChatImageDimens.factor = factor;
|
|
112
|
+
ChatImageDimens.getInstance().calculateDimensions();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public static getDimensions(source: CHAT_IMAGE_VIEW_SOURCE): ImageDimension {
|
|
117
|
+
const dimen =
|
|
118
|
+
ChatImageDimens.dimens[source] ||
|
|
119
|
+
ChatImageDimens.dimens[CHAT_IMAGE_VIEW_SOURCE.MessageListThumbnail];
|
|
120
|
+
return { ...dimen };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public static getOptimizedImageUrl(
|
|
124
|
+
url: string | undefined,
|
|
125
|
+
source: CHAT_IMAGE_VIEW_SOURCE
|
|
126
|
+
): string {
|
|
127
|
+
if (!url) {
|
|
128
|
+
return '';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const dimen = ChatImageDimens.getDimensions(source);
|
|
132
|
+
return ChatImageDimens.getOptimizedImageUrlWithDimensions(
|
|
133
|
+
url,
|
|
134
|
+
dimen.width,
|
|
135
|
+
dimen.height
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Get optimized image URL with custom dimensions (generic approach)
|
|
141
|
+
* Useful for dynamic sizing based on actual content
|
|
142
|
+
*/
|
|
143
|
+
public static getOptimizedImageUrlWithDimensions(
|
|
144
|
+
url: string | undefined,
|
|
145
|
+
width: number,
|
|
146
|
+
height: number
|
|
147
|
+
): string {
|
|
148
|
+
if (!url) {
|
|
149
|
+
return '';
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Ignore non-CDN or private URLs
|
|
153
|
+
if (!url.startsWith('http') || !url.match(ChatImageDimens.regexCDN)) {
|
|
154
|
+
return url;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const domainRegex = /^(https?:\/\/[^/]+)/;
|
|
158
|
+
const domainMatches = url.match(domainRegex);
|
|
159
|
+
|
|
160
|
+
if (!domainMatches || domainMatches.length < 2) {
|
|
161
|
+
return url;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const domain = domainMatches[1];
|
|
165
|
+
const restOfUrl = url.replace(domain as string, '');
|
|
166
|
+
|
|
167
|
+
// Build optimized URL: domain/cache/WIDTHxHEIGHT/path.webp
|
|
168
|
+
let optimizedUrl = `${domain}/cache/${width}x${height}${restOfUrl}`;
|
|
169
|
+
|
|
170
|
+
if (!restOfUrl.endsWith('.webp')) {
|
|
171
|
+
optimizedUrl += '.webp';
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return optimizedUrl;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export default ChatImageDimens;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
+
MessageType,
|
|
2
3
|
SessionType,
|
|
3
4
|
type ConversationItem,
|
|
4
5
|
} from '@droppii/openim-rn-client-sdk';
|
|
5
6
|
import { type DConversationItem, type DMessageItem } from '../types/chat';
|
|
7
|
+
import { trans } from '../translation';
|
|
6
8
|
|
|
7
9
|
export const conversationCompare = (
|
|
8
10
|
a: ConversationItem,
|
|
@@ -26,38 +28,37 @@ export const dConversationCompare = (
|
|
|
26
28
|
a: DConversationItem,
|
|
27
29
|
b: DConversationItem
|
|
28
30
|
) => {
|
|
29
|
-
|
|
30
|
-
const bIsPinned = b.pinnedAt != null;
|
|
31
|
-
|
|
32
|
-
if (aIsPinned !== bIsPinned) return aIsPinned ? -1 : 1;
|
|
31
|
+
if (a.isPinned !== b.isPinned) return a.isPinned ? -1 : 1;
|
|
33
32
|
|
|
34
|
-
const
|
|
35
|
-
|
|
33
|
+
const aTime =
|
|
34
|
+
a.draftTextTime > a.latestMsgSendTime
|
|
35
|
+
? a.draftTextTime
|
|
36
|
+
: a.latestMsgSendTime;
|
|
37
|
+
const bTime =
|
|
38
|
+
b.draftTextTime > b.latestMsgSendTime
|
|
39
|
+
? b.draftTextTime
|
|
40
|
+
: b.latestMsgSendTime;
|
|
36
41
|
|
|
37
|
-
return
|
|
42
|
+
return bTime - aTime;
|
|
38
43
|
};
|
|
39
44
|
|
|
40
45
|
export const mergeOpenIMIntoConversation = (
|
|
41
|
-
|
|
46
|
+
existing: DConversationItem,
|
|
42
47
|
openim: ConversationItem
|
|
43
48
|
): DConversationItem => {
|
|
44
|
-
|
|
45
|
-
const { latestMsg, conversationID, ...openimRest } = openim;
|
|
49
|
+
const { latestMsg, ...openimRest } = openim;
|
|
46
50
|
|
|
47
|
-
let lastMessage: DMessageItem | undefined =
|
|
51
|
+
let lastMessage: DMessageItem | undefined = existing.lastMessage;
|
|
48
52
|
if (latestMsg) {
|
|
49
53
|
try {
|
|
50
54
|
lastMessage = JSON.parse(latestMsg) as DMessageItem;
|
|
51
55
|
} catch {
|
|
52
|
-
// keep
|
|
56
|
+
// keep existing lastMessage if parse fails
|
|
53
57
|
}
|
|
54
58
|
}
|
|
55
59
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
...openimRest,
|
|
59
|
-
lastMessage,
|
|
60
|
-
};
|
|
60
|
+
// Spread existing first so peerType (not in ConversationItem) is preserved
|
|
61
|
+
return { ...existing, ...openimRest, lastMessage };
|
|
61
62
|
};
|
|
62
63
|
|
|
63
64
|
export const getConversationID = (
|
|
@@ -81,3 +82,29 @@ export const sortConversation = (map: Record<string, DConversationItem>) => {
|
|
|
81
82
|
);
|
|
82
83
|
return { map, list };
|
|
83
84
|
};
|
|
85
|
+
|
|
86
|
+
export const generateContentBasedOnMessageType = (
|
|
87
|
+
contentType: MessageType,
|
|
88
|
+
plainText?: string
|
|
89
|
+
) => {
|
|
90
|
+
switch (contentType) {
|
|
91
|
+
case MessageType.TextMessage:
|
|
92
|
+
case MessageType.QuoteMessage:
|
|
93
|
+
case MessageType.LogTextMessage:
|
|
94
|
+
return plainText || '';
|
|
95
|
+
case MessageType.PictureMessage:
|
|
96
|
+
return trans('msg_type_image');
|
|
97
|
+
case MessageType.VoiceMessage:
|
|
98
|
+
return trans('msg_type_voice');
|
|
99
|
+
case MessageType.VideoMessage:
|
|
100
|
+
return trans('msg_type_video');
|
|
101
|
+
case MessageType.FileMessage:
|
|
102
|
+
return trans('msg_type_file');
|
|
103
|
+
case MessageType.UrlTextMessage:
|
|
104
|
+
return trans('msg_type_link');
|
|
105
|
+
case MessageType.RevokeMessage:
|
|
106
|
+
return trans('revoked');
|
|
107
|
+
default:
|
|
108
|
+
return '';
|
|
109
|
+
}
|
|
110
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import ImagePicker from 'react-native-image-crop-picker';
|
|
2
|
+
|
|
3
|
+
const DeviceUtils = {
|
|
4
|
+
openImagePicker: async (multiple: boolean = false) => {
|
|
5
|
+
try {
|
|
6
|
+
const result = await ImagePicker.openPicker({
|
|
7
|
+
// cropping: true,
|
|
8
|
+
mediaType: 'any',
|
|
9
|
+
compressImageQuality: 0.8,
|
|
10
|
+
multiple,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const images = Array.isArray(result) ? result : [result];
|
|
14
|
+
console.log('[Image Picker] Selected:', {
|
|
15
|
+
count: images.length,
|
|
16
|
+
images: images.map((img) => ({
|
|
17
|
+
filename: img.filename,
|
|
18
|
+
size: img.size,
|
|
19
|
+
width: img.width,
|
|
20
|
+
height: img.height,
|
|
21
|
+
})),
|
|
22
|
+
});
|
|
23
|
+
return images;
|
|
24
|
+
} catch (error: any) {
|
|
25
|
+
// User cancelled or permission denied - don't log as error
|
|
26
|
+
if (
|
|
27
|
+
error.code === 'E_PICKER_CANCELLED' ||
|
|
28
|
+
error.code === 'E_NO_LIBRARY_PERMISSION'
|
|
29
|
+
) {
|
|
30
|
+
console.log('[Image Picker] Cancelled or permission denied');
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
console.error('[Image Picker] Error:', error);
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
openVideoPicker: async (multiple: boolean = false) => {
|
|
39
|
+
try {
|
|
40
|
+
const result = await ImagePicker.openPicker({
|
|
41
|
+
mediaType: 'video',
|
|
42
|
+
multiple,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const videos = Array.isArray(result) ? result : [result];
|
|
46
|
+
console.log('[Video Picker] Selected:', {
|
|
47
|
+
count: videos.length,
|
|
48
|
+
videos: videos.map((vid) => ({
|
|
49
|
+
filename: vid.filename,
|
|
50
|
+
size: vid.size,
|
|
51
|
+
width: vid.width,
|
|
52
|
+
height: vid.height,
|
|
53
|
+
duration: vid.duration,
|
|
54
|
+
})),
|
|
55
|
+
});
|
|
56
|
+
return videos;
|
|
57
|
+
} catch (error: any) {
|
|
58
|
+
// User cancelled or permission denied - don't log as error
|
|
59
|
+
if (
|
|
60
|
+
error.code === 'E_PICKER_CANCELLED' ||
|
|
61
|
+
error.code === 'E_NO_LIBRARY_PERMISSION'
|
|
62
|
+
) {
|
|
63
|
+
console.log('[Video Picker] Cancelled or permission denied');
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
console.error('[Video Picker] Error:', error);
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default DeviceUtils;
|
|
73
|
+
export { DeviceUtils };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optimize image URLs for chat by resizing and converting to WebP
|
|
3
|
+
* Reduces memory usage and improves loading performance
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
interface OptimizeImageUrlOptions {
|
|
7
|
+
width?: number;
|
|
8
|
+
height?: number;
|
|
9
|
+
convertToWebp?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const DEFAULT_CHAT_IMAGE_WIDTH = 180;
|
|
13
|
+
const DEFAULT_CHAT_IMAGE_HEIGHT = 180;
|
|
14
|
+
|
|
15
|
+
const CDN_REGEX = /^.*(cdn)(stg|dev|beta)?(.droppii)/;
|
|
16
|
+
|
|
17
|
+
export const optimizeImageUrl = (
|
|
18
|
+
url: string | undefined,
|
|
19
|
+
options: OptimizeImageUrlOptions = {}
|
|
20
|
+
): string => {
|
|
21
|
+
if (!url) {
|
|
22
|
+
return '';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Don't optimize if not a CDN URL
|
|
26
|
+
if (!url.startsWith('http') || !url.match(CDN_REGEX)) {
|
|
27
|
+
return url;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const {
|
|
31
|
+
width = DEFAULT_CHAT_IMAGE_WIDTH,
|
|
32
|
+
height = DEFAULT_CHAT_IMAGE_HEIGHT,
|
|
33
|
+
convertToWebp = true,
|
|
34
|
+
} = options;
|
|
35
|
+
|
|
36
|
+
const domainRegex = /^(https?:\/\/[^/]+)/;
|
|
37
|
+
const domainMatches = url.match(domainRegex);
|
|
38
|
+
|
|
39
|
+
if (!domainMatches || domainMatches.length < 2) {
|
|
40
|
+
return url;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const domain = domainMatches[1];
|
|
44
|
+
const restOfUrl = url.replace(domain as string, '');
|
|
45
|
+
|
|
46
|
+
// Build optimized URL: domain/cache/WIDTHxHEIGHT/path.webp
|
|
47
|
+
let optimizedUrl = `${domain}/cache/${Math.round(width)}x${Math.round(height)}${restOfUrl}`;
|
|
48
|
+
|
|
49
|
+
if (convertToWebp && !restOfUrl.endsWith('.webp')) {
|
|
50
|
+
optimizedUrl += '.webp';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return optimizedUrl;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default optimizeImageUrl;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ImageFile } from '../types/imageUpload';
|
|
2
|
+
|
|
3
|
+
export const generateUUID = (): string => {
|
|
4
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const isVideoFile = (filename: string | undefined): boolean => {
|
|
8
|
+
if (!filename) return false;
|
|
9
|
+
const mimeType = getMimeType(filename);
|
|
10
|
+
return mimeType.startsWith('video/');
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// Best detection: check MIME type from picker response
|
|
14
|
+
export const isVideoFromPicker = (pickedItem: any): boolean => {
|
|
15
|
+
const mime = pickedItem?.mime;
|
|
16
|
+
if (!mime) return false;
|
|
17
|
+
return mime.startsWith('video/');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const getMimeType = (fileName: string): string => {
|
|
21
|
+
const ext = fileName.split('.').pop()?.toLowerCase();
|
|
22
|
+
const mimeMap: Record<string, string> = {
|
|
23
|
+
jpg: 'image/jpeg',
|
|
24
|
+
jpeg: 'image/jpeg',
|
|
25
|
+
png: 'image/png',
|
|
26
|
+
webp: 'image/webp',
|
|
27
|
+
mp4: 'video/mp4',
|
|
28
|
+
mov: 'video/quicktime',
|
|
29
|
+
avi: 'video/x-msvideo',
|
|
30
|
+
mkv: 'video/x-matroska',
|
|
31
|
+
webm: 'video/webm',
|
|
32
|
+
m4v: 'video/mp4',
|
|
33
|
+
flv: 'video/x-flv',
|
|
34
|
+
wmv: 'video/x-ms-wmv',
|
|
35
|
+
mp3: 'audio/mpeg',
|
|
36
|
+
wav: 'audio/wav',
|
|
37
|
+
m4a: 'audio/mp4',
|
|
38
|
+
aac: 'audio/aac',
|
|
39
|
+
flac: 'audio/flac',
|
|
40
|
+
ogg: 'audio/ogg',
|
|
41
|
+
pdf: 'application/pdf',
|
|
42
|
+
doc: 'application/msword',
|
|
43
|
+
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
44
|
+
xls: 'application/vnd.ms-excel',
|
|
45
|
+
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
46
|
+
zip: 'application/zip',
|
|
47
|
+
};
|
|
48
|
+
return mimeMap[ext || ''] || 'application/octet-stream';
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const formatFileSize = (bytes: number): string => {
|
|
52
|
+
if (bytes === 0) return '0 Bytes';
|
|
53
|
+
const k = 1024;
|
|
54
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
55
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
56
|
+
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const validateImageFile = (file: ImageFile): string | null => {
|
|
60
|
+
const MAX_SIZE = 5 * 1024 * 1024;
|
|
61
|
+
|
|
62
|
+
if (file.size > MAX_SIZE) {
|
|
63
|
+
return `Image too large. Max ${formatFileSize(MAX_SIZE)}`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const validMimes = ['image/jpeg', 'image/png', 'image/webp'];
|
|
67
|
+
if (!validMimes.includes(file.mime)) {
|
|
68
|
+
return 'Unsupported format. Only JPEG, PNG, WebP';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return null;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const getImageUploadEndpoint = (baseUrl: string): string => {
|
|
75
|
+
return `${baseUrl}?isPublic=true&path=livechat`;
|
|
76
|
+
};
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { MessageType } from '@droppii/openim-rn-client-sdk';
|
|
2
2
|
import type { DMessageItem } from '../types/chat';
|
|
3
|
-
import { resolveChatMessageType } from './resolveMessageType';
|
|
4
|
-
import type { DChatMessageType } from '../types/message';
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
5
|
* Extract message text based on content type
|
|
@@ -41,7 +39,6 @@ export const getMessageText = (message: DMessageItem): string => {
|
|
|
41
39
|
export interface PrecomputedMessageData {
|
|
42
40
|
messageId: string;
|
|
43
41
|
dayStart: boolean;
|
|
44
|
-
messageType: DChatMessageType;
|
|
45
42
|
createdAt: number;
|
|
46
43
|
}
|
|
47
44
|
|
|
@@ -66,12 +63,10 @@ export const precomputeLegendListData = (
|
|
|
66
63
|
|
|
67
64
|
const createdAt = message.sendTime || message.createTime;
|
|
68
65
|
const day = new Date(createdAt).getDate();
|
|
69
|
-
const messageType = resolveChatMessageType(message);
|
|
70
66
|
|
|
71
67
|
dataMap.set(messageId, {
|
|
72
68
|
messageId,
|
|
73
69
|
dayStart: lastDay !== day,
|
|
74
|
-
messageType,
|
|
75
70
|
createdAt,
|
|
76
71
|
});
|
|
77
72
|
|
package/src/utils/message.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { SessionType, type MessageItem } from '@droppii/openim-rn-client-sdk';
|
|
2
1
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type
|
|
6
|
-
} from '
|
|
2
|
+
PeerType,
|
|
3
|
+
SessionType,
|
|
4
|
+
type MessageItem,
|
|
5
|
+
} from '@droppii/openim-rn-client-sdk';
|
|
6
|
+
import { type DConversationItem, type DMessageItem } from '../types/chat';
|
|
7
7
|
import { getConversationID } from './conversation';
|
|
8
8
|
|
|
9
9
|
const getMessageTime = (message: DMessageItem) =>
|
|
@@ -129,14 +129,12 @@ export const belongsToConversation = (
|
|
|
129
129
|
export const getReceiverId = (conversation?: DConversationItem) => {
|
|
130
130
|
if (conversation == null) return { groupID: '', recvID: '' };
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
? conversation.conversationId?.slice(3) // Remove sg_
|
|
137
|
-
: conversation.groupID;
|
|
132
|
+
if (conversation.peerType === PeerType.Group) {
|
|
133
|
+
// Group conversation: groupID is embedded after the "sg_" prefix
|
|
134
|
+
const groupID =
|
|
135
|
+
conversation.groupID || conversation.conversationID.slice(3);
|
|
138
136
|
return { groupID: groupID ?? '', recvID: '' };
|
|
139
137
|
}
|
|
140
138
|
|
|
141
|
-
return { groupID: '', recvID: conversation.
|
|
139
|
+
return { groupID: '', recvID: conversation.userID ?? '' };
|
|
142
140
|
};
|
|
@@ -30,6 +30,8 @@ export const resolveChatMessageType = (
|
|
|
30
30
|
return DChatMessageType.Video;
|
|
31
31
|
case MessageType.FileMessage:
|
|
32
32
|
return DChatMessageType.File;
|
|
33
|
+
case 107: // MergerMessage (merged/grouped messages)
|
|
34
|
+
return DChatMessageType.Merged;
|
|
33
35
|
case MessageType.CustomMessage: {
|
|
34
36
|
const customType = parseCustomDataType(message);
|
|
35
37
|
|
package/src/utils/ui.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Alert } from 'react-native';
|
|
2
|
+
|
|
3
|
+
interface ToastConfig {
|
|
4
|
+
title?: string;
|
|
5
|
+
message?: string;
|
|
6
|
+
theme?: 'success' | 'danger' | 'warning' | 'info';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const UIUtils = {
|
|
10
|
+
toast: {
|
|
11
|
+
open: (config: ToastConfig) => {
|
|
12
|
+
const { title = 'Message', message = '' } = config;
|
|
13
|
+
Alert.alert(title, message);
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default UIUtils;
|
|
19
|
+
export { UIUtils };
|
package/src/utils/url.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const URL_REGEX =
|
|
1
|
+
const URL_REGEX = /\bhttps?:\/\/[^\s<>"']*[^\s<>"',.!?()[\]{}]/g;
|
|
2
2
|
|
|
3
|
-
export function
|
|
4
|
-
return text.match(URL_REGEX)
|
|
3
|
+
export function extractUrls(text: string): string[] {
|
|
4
|
+
return text.match(URL_REGEX) ?? [];
|
|
5
5
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import RNFS from 'react-native-fs';
|
|
2
|
+
import { createThumbnail } from 'react-native-create-thumbnail';
|
|
3
|
+
|
|
4
|
+
interface ThumbnailOptions {
|
|
5
|
+
time?: number; // timestamp in milliseconds (default: 0)
|
|
6
|
+
quality?: number; // 0-100 (default: 100)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface ThumbnailResult {
|
|
10
|
+
path: string;
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const VideoThumbnailUtil = {
|
|
16
|
+
generateThumbnail: async (
|
|
17
|
+
videoPath: string,
|
|
18
|
+
options: ThumbnailOptions = {}
|
|
19
|
+
): Promise<ThumbnailResult | null> => {
|
|
20
|
+
const { time = 1000, quality = 80 } = options; // time in milliseconds
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
console.log('[VideoThumbnail] Generating thumbnail', {
|
|
24
|
+
videoPath,
|
|
25
|
+
timeMs: time,
|
|
26
|
+
quality,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const result = await createThumbnail({
|
|
30
|
+
url: videoPath,
|
|
31
|
+
timeStamp: time,
|
|
32
|
+
format: 'jpeg',
|
|
33
|
+
dirSize: 100,
|
|
34
|
+
cacheName: 'video-thumbnails',
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
console.log('✅ [VideoThumbnail] THUMBNAIL PATH:', result.path);
|
|
38
|
+
console.log('[VideoThumbnail] Thumbnail generated', {
|
|
39
|
+
path: result.path,
|
|
40
|
+
width: result.width || 0,
|
|
41
|
+
height: result.height || 0,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
path: result.path,
|
|
46
|
+
width: result.width || 0,
|
|
47
|
+
height: result.height || 0,
|
|
48
|
+
};
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error('[VideoThumbnail] Failed to generate thumbnail', error);
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
cleanupThumbnail: async (thumbnailPath: string): Promise<void> => {
|
|
56
|
+
try {
|
|
57
|
+
if (!thumbnailPath) return;
|
|
58
|
+
await RNFS.unlink(thumbnailPath);
|
|
59
|
+
console.log('[VideoThumbnail] Cleaned up:', thumbnailPath);
|
|
60
|
+
} catch (err) {
|
|
61
|
+
console.warn('[VideoThumbnail] Cleanup failed:', err);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
batchGenerateThumbnails: async (
|
|
66
|
+
videoPaths: string[],
|
|
67
|
+
options: ThumbnailOptions = {}
|
|
68
|
+
): Promise<ThumbnailResult[]> => {
|
|
69
|
+
const results: ThumbnailResult[] = [];
|
|
70
|
+
|
|
71
|
+
for (const videoPath of videoPaths) {
|
|
72
|
+
const thumbnail = await VideoThumbnailUtil.generateThumbnail(
|
|
73
|
+
videoPath,
|
|
74
|
+
options
|
|
75
|
+
);
|
|
76
|
+
if (thumbnail) {
|
|
77
|
+
results.push(thumbnail);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return results;
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export default VideoThumbnailUtil;
|