@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.
Files changed (398) hide show
  1. package/lib/module/components/AttachmentPreview.js +250 -0
  2. package/lib/module/components/AttachmentPreview.js.map +1 -0
  3. package/lib/module/components/MediaViewer/index.js +2 -0
  4. package/lib/module/components/MediaViewer/index.js.map +1 -0
  5. package/lib/module/components/MediaViewerModal.js +57 -0
  6. package/lib/module/components/MediaViewerModal.js.map +1 -0
  7. package/lib/module/components/MergedImageGrid.js +173 -0
  8. package/lib/module/components/MergedImageGrid.js.map +1 -0
  9. package/lib/module/components/ThreadCard/AvatarSection.js +4 -4
  10. package/lib/module/components/ThreadCard/AvatarSection.js.map +1 -1
  11. package/lib/module/components/ThreadCard/NamePrefixIcon.js +13 -16
  12. package/lib/module/components/ThreadCard/NamePrefixIcon.js.map +1 -1
  13. package/lib/module/components/ThreadCard/ThreadCard.js +13 -33
  14. package/lib/module/components/ThreadCard/ThreadCard.js.map +1 -1
  15. package/lib/module/components/ThreadCard/thread-card.utils.js +80 -4
  16. package/lib/module/components/ThreadCard/thread-card.utils.js.map +1 -1
  17. package/lib/module/components/messages/fileMessage/index.js +26 -0
  18. package/lib/module/components/messages/fileMessage/index.js.map +1 -0
  19. package/lib/module/components/messages/imageMessage/index.js +118 -0
  20. package/lib/module/components/messages/imageMessage/index.js.map +1 -0
  21. package/lib/module/components/messages/linkMessage/index.js +122 -0
  22. package/lib/module/components/messages/linkMessage/index.js.map +1 -0
  23. package/lib/module/components/messages/mergedMessage/index.js +37 -0
  24. package/lib/module/components/messages/mergedMessage/index.js.map +1 -0
  25. package/lib/module/components/messages/styles.js +41 -0
  26. package/lib/module/components/messages/styles.js.map +1 -0
  27. package/lib/module/components/messages/textMessage/index.js +38 -0
  28. package/lib/module/components/messages/textMessage/index.js.map +1 -0
  29. package/lib/module/components/messages/types.js +14 -0
  30. package/lib/module/components/messages/types.js.map +1 -0
  31. package/lib/module/components/messages/videoMessage/index.js +110 -0
  32. package/lib/module/components/messages/videoMessage/index.js.map +1 -0
  33. package/lib/module/config/api-endpoints.js +66 -0
  34. package/lib/module/config/api-endpoints.js.map +1 -0
  35. package/lib/module/config/attachment-priority.js +81 -0
  36. package/lib/module/config/attachment-priority.js.map +1 -0
  37. package/lib/module/config/configuration.js +50 -0
  38. package/lib/module/config/configuration.js.map +1 -0
  39. package/lib/module/config/index.js +22 -0
  40. package/lib/module/config/index.js.map +1 -0
  41. package/lib/module/context/ChatContext.js +7 -6
  42. package/lib/module/context/ChatContext.js.map +1 -1
  43. package/lib/module/core/index.js +19 -1
  44. package/lib/module/core/index.js.map +1 -1
  45. package/lib/module/core/useChatListener.js +0 -14
  46. package/lib/module/core/useChatListener.js.map +1 -1
  47. package/lib/module/hooks/message/useSendMessage.js +106 -0
  48. package/lib/module/hooks/message/useSendMessage.js.map +1 -0
  49. package/lib/module/hooks/useChatMessages.js +36 -121
  50. package/lib/module/hooks/useChatMessages.js.map +1 -1
  51. package/lib/module/hooks/useConversationList.js +29 -17
  52. package/lib/module/hooks/useConversationList.js.map +1 -1
  53. package/lib/module/hooks/useImageAttachment.js +263 -0
  54. package/lib/module/hooks/useImageAttachment.js.map +1 -0
  55. package/lib/module/hooks/useLinkPreview/useLinkPreview.js +3 -2
  56. package/lib/module/hooks/useLinkPreview/useLinkPreview.js.map +1 -1
  57. package/lib/module/hooks/useMediaViewer.js +24 -0
  58. package/lib/module/hooks/useMediaViewer.js.map +1 -0
  59. package/lib/module/hooks/useSendAttachment.js +182 -0
  60. package/lib/module/hooks/useSendAttachment.js.map +1 -0
  61. package/lib/module/hooks/useVideoAttachment.js +251 -0
  62. package/lib/module/hooks/useVideoAttachment.js.map +1 -0
  63. package/lib/module/index.js +13 -1
  64. package/lib/module/index.js.map +1 -1
  65. package/lib/module/screens/MediaView/VideoPlayer.js +177 -0
  66. package/lib/module/screens/MediaView/VideoPlayer.js.map +1 -0
  67. package/lib/module/screens/MediaView/index.js +264 -0
  68. package/lib/module/screens/MediaView/index.js.map +1 -0
  69. package/lib/module/screens/chat-detail/ChatComposer.js +190 -196
  70. package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
  71. package/lib/module/screens/chat-detail/ChatDetail.js +106 -71
  72. package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
  73. package/lib/module/screens/chat-detail/ChatDetailHeader.js +5 -8
  74. package/lib/module/screens/chat-detail/ChatDetailHeader.js.map +1 -1
  75. package/lib/module/screens/chat-detail/ChatLinkPreview.js +1 -1
  76. package/lib/module/screens/chat-detail/ChatLinkPreview.js.map +1 -1
  77. package/lib/module/screens/chat-detail/ChatListLegend.js +5 -15
  78. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  79. package/lib/module/screens/chat-detail/components/ChatInputActions.js +51 -0
  80. package/lib/module/screens/chat-detail/components/ChatInputActions.js.map +1 -0
  81. package/lib/module/screens/chat-detail/components/ChatMessageInput.js +93 -0
  82. package/lib/module/screens/chat-detail/components/ChatMessageInput.js.map +1 -0
  83. package/lib/module/screens/chat-detail/conversationHeader.utils.js +7 -9
  84. package/lib/module/screens/chat-detail/conversationHeader.utils.js.map +1 -1
  85. package/lib/module/screens/chat-detail/hooks/useAttachmentSendHandler.js +221 -0
  86. package/lib/module/screens/chat-detail/hooks/useAttachmentSendHandler.js.map +1 -0
  87. package/lib/module/screens/chat-detail/hooks/useChatComposerAnimation.js +114 -0
  88. package/lib/module/screens/chat-detail/hooks/useChatComposerAnimation.js.map +1 -0
  89. package/lib/module/screens/chat-detail/hooks/useChatComposerState.js +26 -0
  90. package/lib/module/screens/chat-detail/hooks/useChatComposerState.js.map +1 -0
  91. package/lib/module/screens/chat-detail/index.js +0 -1
  92. package/lib/module/screens/chat-detail/index.js.map +1 -1
  93. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +32 -25
  94. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
  95. package/lib/module/screens/chat-detail/legend/messageTypes.js +15 -0
  96. package/lib/module/screens/chat-detail/legend/messageTypes.js.map +1 -0
  97. package/lib/module/screens/inbox/MessagesTab.js.map +1 -1
  98. package/lib/module/services/attachmentHandlers/fileAttachmentHandler.js +61 -0
  99. package/lib/module/services/attachmentHandlers/fileAttachmentHandler.js.map +1 -0
  100. package/lib/module/services/attachmentHandlers/imageAttachmentHandler.js +54 -0
  101. package/lib/module/services/attachmentHandlers/imageAttachmentHandler.js.map +1 -0
  102. package/lib/module/services/attachmentHandlers/index.js +12 -0
  103. package/lib/module/services/attachmentHandlers/index.js.map +1 -0
  104. package/lib/module/services/attachmentHandlers/videoAttachmentHandler.js +85 -0
  105. package/lib/module/services/attachmentHandlers/videoAttachmentHandler.js.map +1 -0
  106. package/lib/module/services/attachmentOrchestrator.js +225 -0
  107. package/lib/module/services/attachmentOrchestrator.js.map +1 -0
  108. package/lib/module/services/auth.js +35 -0
  109. package/lib/module/services/auth.js.map +1 -0
  110. package/lib/module/services/endpoints.js +20 -1
  111. package/lib/module/services/endpoints.js.map +1 -1
  112. package/lib/module/services/imageUpload.js +126 -0
  113. package/lib/module/services/imageUpload.js.map +1 -0
  114. package/lib/module/store/conversation.js +1 -1
  115. package/lib/module/store/conversation.js.map +1 -1
  116. package/lib/module/store/message.js +45 -0
  117. package/lib/module/store/message.js.map +1 -0
  118. package/lib/module/translation/resources/i18n.js +22 -2
  119. package/lib/module/translation/resources/i18n.js.map +1 -1
  120. package/lib/module/types/attachment.js +2 -0
  121. package/lib/module/types/attachment.js.map +1 -0
  122. package/lib/module/types/attachmentHandler.js +20 -0
  123. package/lib/module/types/attachmentHandler.js.map +1 -0
  124. package/lib/module/types/chat.js +2 -7
  125. package/lib/module/types/chat.js.map +1 -1
  126. package/lib/module/types/imageUpload.js +2 -0
  127. package/lib/module/types/imageUpload.js.map +1 -0
  128. package/lib/module/types/message.js +1 -0
  129. package/lib/module/types/message.js.map +1 -1
  130. package/lib/module/utils/chatImageDimens.js +148 -0
  131. package/lib/module/utils/chatImageDimens.js.map +1 -0
  132. package/lib/module/utils/conversation.js +34 -13
  133. package/lib/module/utils/conversation.js.map +1 -1
  134. package/lib/module/utils/device.js +65 -0
  135. package/lib/module/utils/device.js.map +1 -0
  136. package/lib/module/utils/imageUrlOptimizer.js +41 -0
  137. package/lib/module/utils/imageUrlOptimizer.js.map +1 -0
  138. package/lib/module/utils/imageUtils.js +69 -0
  139. package/lib/module/utils/imageUtils.js.map +1 -0
  140. package/lib/module/utils/legendListMessage.js +0 -3
  141. package/lib/module/utils/legendListMessage.js.map +1 -1
  142. package/lib/module/utils/message.js +5 -8
  143. package/lib/module/utils/message.js.map +1 -1
  144. package/lib/module/utils/resolveMessageType.js +3 -0
  145. package/lib/module/utils/resolveMessageType.js.map +1 -1
  146. package/lib/module/utils/ui.js +17 -0
  147. package/lib/module/utils/ui.js.map +1 -0
  148. package/lib/module/utils/url.js +3 -3
  149. package/lib/module/utils/url.js.map +1 -1
  150. package/lib/module/utils/videoThumbnail.js +62 -0
  151. package/lib/module/utils/videoThumbnail.js.map +1 -0
  152. package/lib/typescript/src/components/AttachmentPreview.d.ts +28 -0
  153. package/lib/typescript/src/components/AttachmentPreview.d.ts.map +1 -0
  154. package/lib/typescript/src/components/MediaViewer/index.d.ts +1 -0
  155. package/lib/typescript/src/components/MediaViewer/index.d.ts.map +1 -0
  156. package/lib/typescript/src/components/MediaViewerModal.d.ts +10 -0
  157. package/lib/typescript/src/components/MediaViewerModal.d.ts.map +1 -0
  158. package/lib/typescript/src/components/MergedImageGrid.d.ts +16 -0
  159. package/lib/typescript/src/components/MergedImageGrid.d.ts.map +1 -0
  160. package/lib/typescript/src/components/ThreadCard/AvatarSection.d.ts +2 -2
  161. package/lib/typescript/src/components/ThreadCard/AvatarSection.d.ts.map +1 -1
  162. package/lib/typescript/src/components/ThreadCard/NamePrefixIcon.d.ts +3 -4
  163. package/lib/typescript/src/components/ThreadCard/NamePrefixIcon.d.ts.map +1 -1
  164. package/lib/typescript/src/components/ThreadCard/ThreadCard.d.ts.map +1 -1
  165. package/lib/typescript/src/components/ThreadCard/thread-card.utils.d.ts.map +1 -1
  166. package/lib/typescript/src/components/messages/fileMessage/index.d.ts +3 -0
  167. package/lib/typescript/src/components/messages/fileMessage/index.d.ts.map +1 -0
  168. package/lib/typescript/src/components/messages/imageMessage/index.d.ts +3 -0
  169. package/lib/typescript/src/components/messages/imageMessage/index.d.ts.map +1 -0
  170. package/lib/typescript/src/components/messages/linkMessage/index.d.ts +9 -0
  171. package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -0
  172. package/lib/typescript/src/components/messages/mergedMessage/index.d.ts +3 -0
  173. package/lib/typescript/src/components/messages/mergedMessage/index.d.ts.map +1 -0
  174. package/lib/typescript/src/components/messages/styles.d.ts +36 -0
  175. package/lib/typescript/src/components/messages/styles.d.ts.map +1 -0
  176. package/lib/typescript/src/components/messages/textMessage/index.d.ts +9 -0
  177. package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -0
  178. package/lib/typescript/src/components/messages/types.d.ts +10 -0
  179. package/lib/typescript/src/components/messages/types.d.ts.map +1 -0
  180. package/lib/typescript/src/components/messages/videoMessage/index.d.ts +3 -0
  181. package/lib/typescript/src/components/messages/videoMessage/index.d.ts.map +1 -0
  182. package/lib/typescript/src/config/api-endpoints.d.ts +40 -0
  183. package/lib/typescript/src/config/api-endpoints.d.ts.map +1 -0
  184. package/lib/typescript/src/config/attachment-priority.d.ts +31 -0
  185. package/lib/typescript/src/config/attachment-priority.d.ts.map +1 -0
  186. package/lib/typescript/src/config/configuration.d.ts +30 -0
  187. package/lib/typescript/src/config/configuration.d.ts.map +1 -0
  188. package/lib/typescript/src/config/index.d.ts +15 -0
  189. package/lib/typescript/src/config/index.d.ts.map +1 -0
  190. package/lib/typescript/src/context/ChatContext.d.ts +1 -1
  191. package/lib/typescript/src/context/ChatContext.d.ts.map +1 -1
  192. package/lib/typescript/src/core/index.d.ts +13 -1
  193. package/lib/typescript/src/core/index.d.ts.map +1 -1
  194. package/lib/typescript/src/core/useChatListener.d.ts.map +1 -1
  195. package/lib/typescript/src/hooks/message/useSendMessage.d.ts +12 -0
  196. package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -0
  197. package/lib/typescript/src/hooks/useChatMessages.d.ts +0 -1
  198. package/lib/typescript/src/hooks/useChatMessages.d.ts.map +1 -1
  199. package/lib/typescript/src/hooks/useConversationList.d.ts +2 -1
  200. package/lib/typescript/src/hooks/useConversationList.d.ts.map +1 -1
  201. package/lib/typescript/src/hooks/useImageAttachment.d.ts +20 -0
  202. package/lib/typescript/src/hooks/useImageAttachment.d.ts.map +1 -0
  203. package/lib/typescript/src/hooks/useLinkPreview/useLinkPreview.d.ts.map +1 -1
  204. package/lib/typescript/src/hooks/useMediaViewer.d.ts +13 -0
  205. package/lib/typescript/src/hooks/useMediaViewer.d.ts.map +1 -0
  206. package/lib/typescript/src/hooks/useSendAttachment.d.ts +59 -0
  207. package/lib/typescript/src/hooks/useSendAttachment.d.ts.map +1 -0
  208. package/lib/typescript/src/hooks/useVideoAttachment.d.ts +29 -0
  209. package/lib/typescript/src/hooks/useVideoAttachment.d.ts.map +1 -0
  210. package/lib/typescript/src/index.d.ts +14 -1
  211. package/lib/typescript/src/index.d.ts.map +1 -1
  212. package/lib/typescript/src/screens/MediaView/VideoPlayer.d.ts +12 -0
  213. package/lib/typescript/src/screens/MediaView/VideoPlayer.d.ts.map +1 -0
  214. package/lib/typescript/src/screens/MediaView/index.d.ts +11 -0
  215. package/lib/typescript/src/screens/MediaView/index.d.ts.map +1 -0
  216. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts +1 -1
  217. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
  218. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts +1 -1
  219. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
  220. package/lib/typescript/src/screens/chat-detail/ChatDetailHeader.d.ts +1 -1
  221. package/lib/typescript/src/screens/chat-detail/ChatDetailHeader.d.ts.map +1 -1
  222. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts +1 -1
  223. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
  224. package/lib/typescript/src/screens/chat-detail/components/ChatInputActions.d.ts +8 -0
  225. package/lib/typescript/src/screens/chat-detail/components/ChatInputActions.d.ts.map +1 -0
  226. package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts +15 -0
  227. package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts.map +1 -0
  228. package/lib/typescript/src/screens/chat-detail/conversationHeader.utils.d.ts +1 -1
  229. package/lib/typescript/src/screens/chat-detail/conversationHeader.utils.d.ts.map +1 -1
  230. package/lib/typescript/src/screens/chat-detail/hooks/useAttachmentSendHandler.d.ts +23 -0
  231. package/lib/typescript/src/screens/chat-detail/hooks/useAttachmentSendHandler.d.ts.map +1 -0
  232. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerAnimation.d.ts +15 -0
  233. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerAnimation.d.ts.map +1 -0
  234. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts +13 -0
  235. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts.map +1 -0
  236. package/lib/typescript/src/screens/chat-detail/index.d.ts +0 -2
  237. package/lib/typescript/src/screens/chat-detail/index.d.ts.map +1 -1
  238. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +3 -3
  239. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
  240. package/lib/typescript/src/screens/chat-detail/legend/messageTypes.d.ts +13 -0
  241. package/lib/typescript/src/screens/chat-detail/legend/messageTypes.d.ts.map +1 -0
  242. package/lib/typescript/src/screens/chat-detail/types.d.ts +10 -8
  243. package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
  244. package/lib/typescript/src/services/attachmentHandlers/fileAttachmentHandler.d.ts +22 -0
  245. package/lib/typescript/src/services/attachmentHandlers/fileAttachmentHandler.d.ts.map +1 -0
  246. package/lib/typescript/src/services/attachmentHandlers/imageAttachmentHandler.d.ts +3 -0
  247. package/lib/typescript/src/services/attachmentHandlers/imageAttachmentHandler.d.ts.map +1 -0
  248. package/lib/typescript/src/services/attachmentHandlers/index.d.ts +5 -0
  249. package/lib/typescript/src/services/attachmentHandlers/index.d.ts.map +1 -0
  250. package/lib/typescript/src/services/attachmentHandlers/videoAttachmentHandler.d.ts +31 -0
  251. package/lib/typescript/src/services/attachmentHandlers/videoAttachmentHandler.d.ts.map +1 -0
  252. package/lib/typescript/src/services/attachmentOrchestrator.d.ts +5 -0
  253. package/lib/typescript/src/services/attachmentOrchestrator.d.ts.map +1 -0
  254. package/lib/typescript/src/services/auth.d.ts +19 -0
  255. package/lib/typescript/src/services/auth.d.ts.map +1 -0
  256. package/lib/typescript/src/services/endpoints.d.ts +11 -1
  257. package/lib/typescript/src/services/endpoints.d.ts.map +1 -1
  258. package/lib/typescript/src/services/imageUpload.d.ts +7 -0
  259. package/lib/typescript/src/services/imageUpload.d.ts.map +1 -0
  260. package/lib/typescript/src/store/message.d.ts +3 -0
  261. package/lib/typescript/src/store/message.d.ts.map +1 -0
  262. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
  263. package/lib/typescript/src/types/attachment.d.ts +72 -0
  264. package/lib/typescript/src/types/attachment.d.ts.map +1 -0
  265. package/lib/typescript/src/types/attachmentHandler.d.ts +13 -0
  266. package/lib/typescript/src/types/attachmentHandler.d.ts.map +1 -0
  267. package/lib/typescript/src/types/chat.d.ts +28 -27
  268. package/lib/typescript/src/types/chat.d.ts.map +1 -1
  269. package/lib/typescript/src/types/common.d.ts +1 -0
  270. package/lib/typescript/src/types/common.d.ts.map +1 -1
  271. package/lib/typescript/src/types/imageUpload.d.ts +26 -0
  272. package/lib/typescript/src/types/imageUpload.d.ts.map +1 -0
  273. package/lib/typescript/src/types/message.d.ts +1 -0
  274. package/lib/typescript/src/types/message.d.ts.map +1 -1
  275. package/lib/typescript/src/utils/chatImageDimens.d.ts +34 -0
  276. package/lib/typescript/src/utils/chatImageDimens.d.ts.map +1 -0
  277. package/lib/typescript/src/utils/conversation.d.ts +3 -2
  278. package/lib/typescript/src/utils/conversation.d.ts.map +1 -1
  279. package/lib/typescript/src/utils/device.d.ts +7 -0
  280. package/lib/typescript/src/utils/device.d.ts.map +1 -0
  281. package/lib/typescript/src/utils/imageUrlOptimizer.d.ts +12 -0
  282. package/lib/typescript/src/utils/imageUrlOptimizer.d.ts.map +1 -0
  283. package/lib/typescript/src/utils/imageUtils.d.ts +9 -0
  284. package/lib/typescript/src/utils/imageUtils.d.ts.map +1 -0
  285. package/lib/typescript/src/utils/legendListMessage.d.ts +0 -2
  286. package/lib/typescript/src/utils/legendListMessage.d.ts.map +1 -1
  287. package/lib/typescript/src/utils/message.d.ts.map +1 -1
  288. package/lib/typescript/src/utils/resolveMessageType.d.ts.map +1 -1
  289. package/lib/typescript/src/utils/ui.d.ts +13 -0
  290. package/lib/typescript/src/utils/ui.d.ts.map +1 -0
  291. package/lib/typescript/src/utils/url.d.ts +1 -1
  292. package/lib/typescript/src/utils/url.d.ts.map +1 -1
  293. package/lib/typescript/src/utils/videoThumbnail.d.ts +16 -0
  294. package/lib/typescript/src/utils/videoThumbnail.d.ts.map +1 -0
  295. package/package.json +15 -3
  296. package/src/components/AttachmentPreview.tsx +304 -0
  297. package/src/components/MediaViewer/index.tsx +0 -0
  298. package/src/components/MediaViewerModal.tsx +70 -0
  299. package/src/components/MergedImageGrid.tsx +238 -0
  300. package/src/components/ThreadCard/AvatarSection.tsx +5 -8
  301. package/src/components/ThreadCard/NamePrefixIcon.tsx +27 -38
  302. package/src/components/ThreadCard/ThreadCard.tsx +16 -30
  303. package/src/components/ThreadCard/thread-card.utils.ts +95 -4
  304. package/src/components/messages/fileMessage/index.tsx +30 -0
  305. package/src/components/messages/imageMessage/index.tsx +137 -0
  306. package/src/components/messages/linkMessage/index.tsx +162 -0
  307. package/src/components/messages/mergedMessage/index.tsx +45 -0
  308. package/src/components/messages/styles.ts +39 -0
  309. package/src/components/messages/textMessage/index.tsx +53 -0
  310. package/src/components/messages/types.ts +22 -0
  311. package/src/components/messages/videoMessage/index.tsx +120 -0
  312. package/src/config/api-endpoints.ts +72 -0
  313. package/src/config/attachment-priority.ts +93 -0
  314. package/src/config/configuration.ts +50 -0
  315. package/src/config/index.ts +19 -0
  316. package/src/context/ChatContext.tsx +12 -4
  317. package/src/core/index.ts +25 -1
  318. package/src/core/useChatListener.ts +0 -21
  319. package/src/hooks/message/useSendMessage.ts +143 -0
  320. package/src/hooks/useChatMessages.ts +69 -161
  321. package/src/hooks/useConversationList.ts +34 -16
  322. package/src/hooks/useImageAttachment.ts +348 -0
  323. package/src/hooks/useLinkPreview/useLinkPreview.ts +3 -2
  324. package/src/hooks/useMediaViewer.ts +32 -0
  325. package/src/hooks/useSendAttachment.ts +295 -0
  326. package/src/hooks/useVideoAttachment.ts +334 -0
  327. package/src/index.tsx +13 -1
  328. package/src/screens/MediaView/VideoPlayer.tsx +211 -0
  329. package/src/screens/MediaView/index.tsx +327 -0
  330. package/src/screens/chat-detail/ChatComposer.tsx +206 -271
  331. package/src/screens/chat-detail/ChatDetail.tsx +164 -104
  332. package/src/screens/chat-detail/ChatDetailHeader.tsx +4 -10
  333. package/src/screens/chat-detail/ChatLinkPreview.tsx +1 -1
  334. package/src/screens/chat-detail/ChatListLegend.tsx +10 -13
  335. package/src/screens/chat-detail/components/ChatInputActions.tsx +71 -0
  336. package/src/screens/chat-detail/components/ChatMessageInput.tsx +127 -0
  337. package/src/screens/chat-detail/conversationHeader.utils.ts +11 -14
  338. package/src/screens/chat-detail/hooks/useAttachmentSendHandler.ts +291 -0
  339. package/src/screens/chat-detail/hooks/useChatComposerAnimation.ts +184 -0
  340. package/src/screens/chat-detail/hooks/useChatComposerState.ts +40 -0
  341. package/src/screens/chat-detail/index.ts +0 -2
  342. package/src/screens/chat-detail/legend/LegendChatMessage.tsx +44 -39
  343. package/src/screens/chat-detail/legend/messageTypes.tsx +13 -0
  344. package/src/screens/chat-detail/types.ts +11 -9
  345. package/src/screens/inbox/MessagesTab.tsx +1 -1
  346. package/src/services/attachmentHandlers/fileAttachmentHandler.ts +78 -0
  347. package/src/services/attachmentHandlers/imageAttachmentHandler.ts +54 -0
  348. package/src/services/attachmentHandlers/index.ts +10 -0
  349. package/src/services/attachmentHandlers/videoAttachmentHandler.ts +114 -0
  350. package/src/services/attachmentOrchestrator.ts +300 -0
  351. package/src/services/auth.ts +34 -0
  352. package/src/services/endpoints.ts +24 -1
  353. package/src/services/imageUpload.ts +162 -0
  354. package/src/store/conversation.ts +1 -1
  355. package/src/store/message.ts +44 -0
  356. package/src/translation/resources/i18n.ts +22 -2
  357. package/src/types/attachment.ts +85 -0
  358. package/src/types/attachmentHandler.ts +31 -0
  359. package/src/types/chat.ts +31 -30
  360. package/src/types/common.ts +1 -0
  361. package/src/types/imageUpload.ts +28 -0
  362. package/src/types/message.ts +1 -0
  363. package/src/utils/chatImageDimens.ts +178 -0
  364. package/src/utils/conversation.ts +44 -17
  365. package/src/utils/device.ts +73 -0
  366. package/src/utils/imageUrlOptimizer.ts +56 -0
  367. package/src/utils/imageUtils.ts +76 -0
  368. package/src/utils/legendListMessage.ts +0 -5
  369. package/src/utils/message.ts +10 -12
  370. package/src/utils/resolveMessageType.ts +2 -0
  371. package/src/utils/ui.ts +19 -0
  372. package/src/utils/url.ts +3 -3
  373. package/src/utils/videoThumbnail.ts +85 -0
  374. package/lib/module/screens/chat-detail/ChatList.js +0 -147
  375. package/lib/module/screens/chat-detail/ChatList.js.map +0 -1
  376. package/lib/module/screens/chat-detail/ChatTextBubble.js +0 -62
  377. package/lib/module/screens/chat-detail/ChatTextBubble.js.map +0 -1
  378. package/lib/module/screens/chat-detail/legend/message-types.js +0 -122
  379. package/lib/module/screens/chat-detail/legend/message-types.js.map +0 -1
  380. package/lib/module/screens/chat-detail/messages/ChatMessageBubble.js +0 -24
  381. package/lib/module/screens/chat-detail/messages/ChatMessageBubble.js.map +0 -1
  382. package/lib/module/screens/chat-detail/messages/types.js +0 -4
  383. package/lib/module/screens/chat-detail/messages/types.js.map +0 -1
  384. package/lib/typescript/src/screens/chat-detail/ChatList.d.ts +0 -3
  385. package/lib/typescript/src/screens/chat-detail/ChatList.d.ts.map +0 -1
  386. package/lib/typescript/src/screens/chat-detail/ChatTextBubble.d.ts +0 -3
  387. package/lib/typescript/src/screens/chat-detail/ChatTextBubble.d.ts.map +0 -1
  388. package/lib/typescript/src/screens/chat-detail/legend/message-types.d.ts +0 -12
  389. package/lib/typescript/src/screens/chat-detail/legend/message-types.d.ts.map +0 -1
  390. package/lib/typescript/src/screens/chat-detail/messages/ChatMessageBubble.d.ts +0 -3
  391. package/lib/typescript/src/screens/chat-detail/messages/ChatMessageBubble.d.ts.map +0 -1
  392. package/lib/typescript/src/screens/chat-detail/messages/types.d.ts +0 -13
  393. package/lib/typescript/src/screens/chat-detail/messages/types.d.ts.map +0 -1
  394. package/src/screens/chat-detail/ChatList.tsx +0 -190
  395. package/src/screens/chat-detail/ChatTextBubble.tsx +0 -73
  396. package/src/screens/chat-detail/legend/message-types.tsx +0 -149
  397. package/src/screens/chat-detail/messages/ChatMessageBubble.tsx +0 -23
  398. 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
- const aIsPinned = a.pinnedAt != null;
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 aCreateTime = a.lastMessage?.createTime ?? 0;
35
- const bCreateTime = b.lastMessage?.createTime ?? 0;
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 bCreateTime - aCreateTime;
42
+ return bTime - aTime;
38
43
  };
39
44
 
40
45
  export const mergeOpenIMIntoConversation = (
41
- droppii: DConversationItem,
46
+ existing: DConversationItem,
42
47
  openim: ConversationItem
43
48
  ): DConversationItem => {
44
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
45
- const { latestMsg, conversationID, ...openimRest } = openim;
49
+ const { latestMsg, ...openimRest } = openim;
46
50
 
47
- let lastMessage: DMessageItem | undefined = droppii.lastMessage;
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 droppii lastMessage if parse fails
56
+ // keep existing lastMessage if parse fails
53
57
  }
54
58
  }
55
59
 
56
- return {
57
- ...droppii,
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
 
@@ -1,9 +1,9 @@
1
- import { SessionType, type MessageItem } from '@droppii/openim-rn-client-sdk';
2
1
  import {
3
- DChatType,
4
- type DConversationItem,
5
- type DMessageItem,
6
- } from '../types/chat';
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
- const isGroupChat = conversation.chatType === DChatType.GROUP;
133
- if (isGroupChat) {
134
- const isBot = conversation.chatCategory?.includes('BOT');
135
- const groupID = isBot
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.peer.id ?? '' };
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
 
@@ -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 = /https?:\/\/[^\s]+/i;
1
+ const URL_REGEX = /\bhttps?:\/\/[^\s<>"']*[^\s<>"',.!?()[\]{}]/g;
2
2
 
3
- export function extractFirstUrl(text: string): string | undefined {
4
- return text.match(URL_REGEX)?.[0];
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;