@droppii-org/chat-mobile 0.2.7 → 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 (323) 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/thread-card.utils.js +80 -4
  10. package/lib/module/components/ThreadCard/thread-card.utils.js.map +1 -1
  11. package/lib/module/components/messages/fileMessage/index.js +26 -0
  12. package/lib/module/components/messages/fileMessage/index.js.map +1 -0
  13. package/lib/module/components/messages/imageMessage/index.js +118 -0
  14. package/lib/module/components/messages/imageMessage/index.js.map +1 -0
  15. package/lib/module/components/messages/linkMessage/index.js +122 -0
  16. package/lib/module/components/messages/linkMessage/index.js.map +1 -0
  17. package/lib/module/components/messages/mergedMessage/index.js +37 -0
  18. package/lib/module/components/messages/mergedMessage/index.js.map +1 -0
  19. package/lib/module/components/messages/styles.js +41 -0
  20. package/lib/module/components/messages/styles.js.map +1 -0
  21. package/lib/module/components/messages/textMessage/index.js +38 -0
  22. package/lib/module/components/messages/textMessage/index.js.map +1 -0
  23. package/lib/module/components/messages/types.js +14 -0
  24. package/lib/module/components/messages/types.js.map +1 -0
  25. package/lib/module/components/messages/videoMessage/index.js +110 -0
  26. package/lib/module/components/messages/videoMessage/index.js.map +1 -0
  27. package/lib/module/config/api-endpoints.js +66 -0
  28. package/lib/module/config/api-endpoints.js.map +1 -0
  29. package/lib/module/config/attachment-priority.js +81 -0
  30. package/lib/module/config/attachment-priority.js.map +1 -0
  31. package/lib/module/config/configuration.js +50 -0
  32. package/lib/module/config/configuration.js.map +1 -0
  33. package/lib/module/config/index.js +22 -0
  34. package/lib/module/config/index.js.map +1 -0
  35. package/lib/module/core/index.js +19 -1
  36. package/lib/module/core/index.js.map +1 -1
  37. package/lib/module/core/useChatListener.js +0 -14
  38. package/lib/module/core/useChatListener.js.map +1 -1
  39. package/lib/module/hooks/message/useSendMessage.js +10 -5
  40. package/lib/module/hooks/message/useSendMessage.js.map +1 -1
  41. package/lib/module/hooks/useChatMessages.js +0 -3
  42. package/lib/module/hooks/useChatMessages.js.map +1 -1
  43. package/lib/module/hooks/useImageAttachment.js +263 -0
  44. package/lib/module/hooks/useImageAttachment.js.map +1 -0
  45. package/lib/module/hooks/useMediaViewer.js +24 -0
  46. package/lib/module/hooks/useMediaViewer.js.map +1 -0
  47. package/lib/module/hooks/useSendAttachment.js +182 -0
  48. package/lib/module/hooks/useSendAttachment.js.map +1 -0
  49. package/lib/module/hooks/useVideoAttachment.js +251 -0
  50. package/lib/module/hooks/useVideoAttachment.js.map +1 -0
  51. package/lib/module/index.js +13 -1
  52. package/lib/module/index.js.map +1 -1
  53. package/lib/module/screens/MediaView/VideoPlayer.js +177 -0
  54. package/lib/module/screens/MediaView/VideoPlayer.js.map +1 -0
  55. package/lib/module/screens/MediaView/index.js +264 -0
  56. package/lib/module/screens/MediaView/index.js.map +1 -0
  57. package/lib/module/screens/chat-detail/ChatComposer.js +190 -196
  58. package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
  59. package/lib/module/screens/chat-detail/ChatDetail.js +94 -63
  60. package/lib/module/screens/chat-detail/ChatDetail.js.map +1 -1
  61. package/lib/module/screens/chat-detail/ChatListLegend.js +5 -13
  62. package/lib/module/screens/chat-detail/ChatListLegend.js.map +1 -1
  63. package/lib/module/screens/chat-detail/components/ChatInputActions.js +51 -0
  64. package/lib/module/screens/chat-detail/components/ChatInputActions.js.map +1 -0
  65. package/lib/module/screens/chat-detail/components/ChatMessageInput.js +93 -0
  66. package/lib/module/screens/chat-detail/components/ChatMessageInput.js.map +1 -0
  67. package/lib/module/screens/chat-detail/hooks/useAttachmentSendHandler.js +221 -0
  68. package/lib/module/screens/chat-detail/hooks/useAttachmentSendHandler.js.map +1 -0
  69. package/lib/module/screens/chat-detail/hooks/useChatComposerAnimation.js +114 -0
  70. package/lib/module/screens/chat-detail/hooks/useChatComposerAnimation.js.map +1 -0
  71. package/lib/module/screens/chat-detail/hooks/useChatComposerState.js +26 -0
  72. package/lib/module/screens/chat-detail/hooks/useChatComposerState.js.map +1 -0
  73. package/lib/module/screens/chat-detail/index.js +0 -1
  74. package/lib/module/screens/chat-detail/index.js.map +1 -1
  75. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js +33 -13
  76. package/lib/module/screens/chat-detail/legend/LegendChatMessage.js.map +1 -1
  77. package/lib/module/screens/chat-detail/legend/messageTypes.js +15 -0
  78. package/lib/module/screens/chat-detail/legend/messageTypes.js.map +1 -0
  79. package/lib/module/screens/inbox/MessagesTab.js.map +1 -1
  80. package/lib/module/services/attachmentHandlers/fileAttachmentHandler.js +61 -0
  81. package/lib/module/services/attachmentHandlers/fileAttachmentHandler.js.map +1 -0
  82. package/lib/module/services/attachmentHandlers/imageAttachmentHandler.js +54 -0
  83. package/lib/module/services/attachmentHandlers/imageAttachmentHandler.js.map +1 -0
  84. package/lib/module/services/attachmentHandlers/index.js +12 -0
  85. package/lib/module/services/attachmentHandlers/index.js.map +1 -0
  86. package/lib/module/services/attachmentHandlers/videoAttachmentHandler.js +85 -0
  87. package/lib/module/services/attachmentHandlers/videoAttachmentHandler.js.map +1 -0
  88. package/lib/module/services/attachmentOrchestrator.js +225 -0
  89. package/lib/module/services/attachmentOrchestrator.js.map +1 -0
  90. package/lib/module/services/auth.js +35 -0
  91. package/lib/module/services/auth.js.map +1 -0
  92. package/lib/module/services/endpoints.js +20 -1
  93. package/lib/module/services/endpoints.js.map +1 -1
  94. package/lib/module/services/imageUpload.js +126 -0
  95. package/lib/module/services/imageUpload.js.map +1 -0
  96. package/lib/module/translation/resources/i18n.js +22 -8
  97. package/lib/module/translation/resources/i18n.js.map +1 -1
  98. package/lib/module/types/attachment.js +2 -0
  99. package/lib/module/types/attachment.js.map +1 -0
  100. package/lib/module/types/attachmentHandler.js +20 -0
  101. package/lib/module/types/attachmentHandler.js.map +1 -0
  102. package/lib/module/types/imageUpload.js +2 -0
  103. package/lib/module/types/imageUpload.js.map +1 -0
  104. package/lib/module/types/message.js +1 -0
  105. package/lib/module/types/message.js.map +1 -1
  106. package/lib/module/utils/chatImageDimens.js +148 -0
  107. package/lib/module/utils/chatImageDimens.js.map +1 -0
  108. package/lib/module/utils/device.js +65 -0
  109. package/lib/module/utils/device.js.map +1 -0
  110. package/lib/module/utils/imageUrlOptimizer.js +41 -0
  111. package/lib/module/utils/imageUrlOptimizer.js.map +1 -0
  112. package/lib/module/utils/imageUtils.js +69 -0
  113. package/lib/module/utils/imageUtils.js.map +1 -0
  114. package/lib/module/utils/resolveMessageType.js +3 -0
  115. package/lib/module/utils/resolveMessageType.js.map +1 -1
  116. package/lib/module/utils/ui.js +17 -0
  117. package/lib/module/utils/ui.js.map +1 -0
  118. package/lib/module/utils/url.js +1 -1
  119. package/lib/module/utils/url.js.map +1 -1
  120. package/lib/module/utils/videoThumbnail.js +62 -0
  121. package/lib/module/utils/videoThumbnail.js.map +1 -0
  122. package/lib/typescript/src/components/AttachmentPreview.d.ts +28 -0
  123. package/lib/typescript/src/components/AttachmentPreview.d.ts.map +1 -0
  124. package/lib/typescript/src/components/MediaViewer/index.d.ts +1 -0
  125. package/lib/typescript/src/components/MediaViewer/index.d.ts.map +1 -0
  126. package/lib/typescript/src/components/MediaViewerModal.d.ts +10 -0
  127. package/lib/typescript/src/components/MediaViewerModal.d.ts.map +1 -0
  128. package/lib/typescript/src/components/MergedImageGrid.d.ts +16 -0
  129. package/lib/typescript/src/components/MergedImageGrid.d.ts.map +1 -0
  130. package/lib/typescript/src/components/ThreadCard/thread-card.utils.d.ts.map +1 -1
  131. package/lib/typescript/src/components/messages/fileMessage/index.d.ts +3 -0
  132. package/lib/typescript/src/components/messages/fileMessage/index.d.ts.map +1 -0
  133. package/lib/typescript/src/components/messages/imageMessage/index.d.ts +3 -0
  134. package/lib/typescript/src/components/messages/imageMessage/index.d.ts.map +1 -0
  135. package/lib/typescript/src/components/messages/linkMessage/index.d.ts +9 -0
  136. package/lib/typescript/src/components/messages/linkMessage/index.d.ts.map +1 -0
  137. package/lib/typescript/src/components/messages/mergedMessage/index.d.ts +3 -0
  138. package/lib/typescript/src/components/messages/mergedMessage/index.d.ts.map +1 -0
  139. package/lib/typescript/src/components/messages/styles.d.ts +36 -0
  140. package/lib/typescript/src/components/messages/styles.d.ts.map +1 -0
  141. package/lib/typescript/src/components/messages/textMessage/index.d.ts +9 -0
  142. package/lib/typescript/src/components/messages/textMessage/index.d.ts.map +1 -0
  143. package/lib/typescript/src/components/messages/types.d.ts +10 -0
  144. package/lib/typescript/src/components/messages/types.d.ts.map +1 -0
  145. package/lib/typescript/src/components/messages/videoMessage/index.d.ts +3 -0
  146. package/lib/typescript/src/components/messages/videoMessage/index.d.ts.map +1 -0
  147. package/lib/typescript/src/config/api-endpoints.d.ts +40 -0
  148. package/lib/typescript/src/config/api-endpoints.d.ts.map +1 -0
  149. package/lib/typescript/src/config/attachment-priority.d.ts +31 -0
  150. package/lib/typescript/src/config/attachment-priority.d.ts.map +1 -0
  151. package/lib/typescript/src/config/configuration.d.ts +30 -0
  152. package/lib/typescript/src/config/configuration.d.ts.map +1 -0
  153. package/lib/typescript/src/config/index.d.ts +15 -0
  154. package/lib/typescript/src/config/index.d.ts.map +1 -0
  155. package/lib/typescript/src/core/index.d.ts +13 -1
  156. package/lib/typescript/src/core/index.d.ts.map +1 -1
  157. package/lib/typescript/src/core/useChatListener.d.ts.map +1 -1
  158. package/lib/typescript/src/hooks/message/useSendMessage.d.ts.map +1 -1
  159. package/lib/typescript/src/hooks/useChatMessages.d.ts.map +1 -1
  160. package/lib/typescript/src/hooks/useImageAttachment.d.ts +20 -0
  161. package/lib/typescript/src/hooks/useImageAttachment.d.ts.map +1 -0
  162. package/lib/typescript/src/hooks/useMediaViewer.d.ts +13 -0
  163. package/lib/typescript/src/hooks/useMediaViewer.d.ts.map +1 -0
  164. package/lib/typescript/src/hooks/useSendAttachment.d.ts +59 -0
  165. package/lib/typescript/src/hooks/useSendAttachment.d.ts.map +1 -0
  166. package/lib/typescript/src/hooks/useVideoAttachment.d.ts +29 -0
  167. package/lib/typescript/src/hooks/useVideoAttachment.d.ts.map +1 -0
  168. package/lib/typescript/src/index.d.ts +14 -1
  169. package/lib/typescript/src/index.d.ts.map +1 -1
  170. package/lib/typescript/src/screens/MediaView/VideoPlayer.d.ts +12 -0
  171. package/lib/typescript/src/screens/MediaView/VideoPlayer.d.ts.map +1 -0
  172. package/lib/typescript/src/screens/MediaView/index.d.ts +11 -0
  173. package/lib/typescript/src/screens/MediaView/index.d.ts.map +1 -0
  174. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts +1 -1
  175. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
  176. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts +1 -1
  177. package/lib/typescript/src/screens/chat-detail/ChatDetail.d.ts.map +1 -1
  178. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts +1 -1
  179. package/lib/typescript/src/screens/chat-detail/ChatListLegend.d.ts.map +1 -1
  180. package/lib/typescript/src/screens/chat-detail/components/ChatInputActions.d.ts +8 -0
  181. package/lib/typescript/src/screens/chat-detail/components/ChatInputActions.d.ts.map +1 -0
  182. package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts +15 -0
  183. package/lib/typescript/src/screens/chat-detail/components/ChatMessageInput.d.ts.map +1 -0
  184. package/lib/typescript/src/screens/chat-detail/hooks/useAttachmentSendHandler.d.ts +23 -0
  185. package/lib/typescript/src/screens/chat-detail/hooks/useAttachmentSendHandler.d.ts.map +1 -0
  186. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerAnimation.d.ts +15 -0
  187. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerAnimation.d.ts.map +1 -0
  188. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts +13 -0
  189. package/lib/typescript/src/screens/chat-detail/hooks/useChatComposerState.d.ts.map +1 -0
  190. package/lib/typescript/src/screens/chat-detail/index.d.ts +0 -2
  191. package/lib/typescript/src/screens/chat-detail/index.d.ts.map +1 -1
  192. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts +3 -1
  193. package/lib/typescript/src/screens/chat-detail/legend/LegendChatMessage.d.ts.map +1 -1
  194. package/lib/typescript/src/screens/chat-detail/legend/messageTypes.d.ts +13 -0
  195. package/lib/typescript/src/screens/chat-detail/legend/messageTypes.d.ts.map +1 -0
  196. package/lib/typescript/src/screens/chat-detail/types.d.ts +4 -1
  197. package/lib/typescript/src/screens/chat-detail/types.d.ts.map +1 -1
  198. package/lib/typescript/src/services/attachmentHandlers/fileAttachmentHandler.d.ts +22 -0
  199. package/lib/typescript/src/services/attachmentHandlers/fileAttachmentHandler.d.ts.map +1 -0
  200. package/lib/typescript/src/services/attachmentHandlers/imageAttachmentHandler.d.ts +3 -0
  201. package/lib/typescript/src/services/attachmentHandlers/imageAttachmentHandler.d.ts.map +1 -0
  202. package/lib/typescript/src/services/attachmentHandlers/index.d.ts +5 -0
  203. package/lib/typescript/src/services/attachmentHandlers/index.d.ts.map +1 -0
  204. package/lib/typescript/src/services/attachmentHandlers/videoAttachmentHandler.d.ts +31 -0
  205. package/lib/typescript/src/services/attachmentHandlers/videoAttachmentHandler.d.ts.map +1 -0
  206. package/lib/typescript/src/services/attachmentOrchestrator.d.ts +5 -0
  207. package/lib/typescript/src/services/attachmentOrchestrator.d.ts.map +1 -0
  208. package/lib/typescript/src/services/auth.d.ts +19 -0
  209. package/lib/typescript/src/services/auth.d.ts.map +1 -0
  210. package/lib/typescript/src/services/endpoints.d.ts +11 -1
  211. package/lib/typescript/src/services/endpoints.d.ts.map +1 -1
  212. package/lib/typescript/src/services/imageUpload.d.ts +7 -0
  213. package/lib/typescript/src/services/imageUpload.d.ts.map +1 -0
  214. package/lib/typescript/src/translation/resources/i18n.d.ts.map +1 -1
  215. package/lib/typescript/src/types/attachment.d.ts +72 -0
  216. package/lib/typescript/src/types/attachment.d.ts.map +1 -0
  217. package/lib/typescript/src/types/attachmentHandler.d.ts +13 -0
  218. package/lib/typescript/src/types/attachmentHandler.d.ts.map +1 -0
  219. package/lib/typescript/src/types/imageUpload.d.ts +26 -0
  220. package/lib/typescript/src/types/imageUpload.d.ts.map +1 -0
  221. package/lib/typescript/src/types/message.d.ts +1 -0
  222. package/lib/typescript/src/types/message.d.ts.map +1 -1
  223. package/lib/typescript/src/utils/chatImageDimens.d.ts +34 -0
  224. package/lib/typescript/src/utils/chatImageDimens.d.ts.map +1 -0
  225. package/lib/typescript/src/utils/device.d.ts +7 -0
  226. package/lib/typescript/src/utils/device.d.ts.map +1 -0
  227. package/lib/typescript/src/utils/imageUrlOptimizer.d.ts +12 -0
  228. package/lib/typescript/src/utils/imageUrlOptimizer.d.ts.map +1 -0
  229. package/lib/typescript/src/utils/imageUtils.d.ts +9 -0
  230. package/lib/typescript/src/utils/imageUtils.d.ts.map +1 -0
  231. package/lib/typescript/src/utils/resolveMessageType.d.ts.map +1 -1
  232. package/lib/typescript/src/utils/ui.d.ts +13 -0
  233. package/lib/typescript/src/utils/ui.d.ts.map +1 -0
  234. package/lib/typescript/src/utils/videoThumbnail.d.ts +16 -0
  235. package/lib/typescript/src/utils/videoThumbnail.d.ts.map +1 -0
  236. package/package.json +15 -3
  237. package/src/components/AttachmentPreview.tsx +304 -0
  238. package/src/components/MediaViewer/index.tsx +0 -0
  239. package/src/components/MediaViewerModal.tsx +70 -0
  240. package/src/components/MergedImageGrid.tsx +238 -0
  241. package/src/components/ThreadCard/thread-card.utils.ts +95 -4
  242. package/src/components/messages/fileMessage/index.tsx +30 -0
  243. package/src/components/messages/imageMessage/index.tsx +137 -0
  244. package/src/components/messages/linkMessage/index.tsx +162 -0
  245. package/src/components/messages/mergedMessage/index.tsx +45 -0
  246. package/src/components/messages/styles.ts +39 -0
  247. package/src/components/messages/textMessage/index.tsx +53 -0
  248. package/src/components/messages/types.ts +22 -0
  249. package/src/components/messages/videoMessage/index.tsx +120 -0
  250. package/src/config/api-endpoints.ts +72 -0
  251. package/src/config/attachment-priority.ts +93 -0
  252. package/src/config/configuration.ts +50 -0
  253. package/src/config/index.ts +19 -0
  254. package/src/core/index.ts +25 -1
  255. package/src/core/useChatListener.ts +0 -21
  256. package/src/hooks/message/useSendMessage.ts +12 -5
  257. package/src/hooks/useChatMessages.ts +0 -4
  258. package/src/hooks/useImageAttachment.ts +348 -0
  259. package/src/hooks/useMediaViewer.ts +32 -0
  260. package/src/hooks/useSendAttachment.ts +295 -0
  261. package/src/hooks/useVideoAttachment.ts +334 -0
  262. package/src/index.tsx +13 -1
  263. package/src/screens/MediaView/VideoPlayer.tsx +211 -0
  264. package/src/screens/MediaView/index.tsx +327 -0
  265. package/src/screens/chat-detail/ChatComposer.tsx +206 -271
  266. package/src/screens/chat-detail/ChatDetail.tsx +142 -89
  267. package/src/screens/chat-detail/ChatListLegend.tsx +9 -11
  268. package/src/screens/chat-detail/components/ChatInputActions.tsx +71 -0
  269. package/src/screens/chat-detail/components/ChatMessageInput.tsx +127 -0
  270. package/src/screens/chat-detail/hooks/useAttachmentSendHandler.ts +291 -0
  271. package/src/screens/chat-detail/hooks/useChatComposerAnimation.ts +184 -0
  272. package/src/screens/chat-detail/hooks/useChatComposerState.ts +40 -0
  273. package/src/screens/chat-detail/index.ts +0 -2
  274. package/src/screens/chat-detail/legend/LegendChatMessage.tsx +47 -24
  275. package/src/screens/chat-detail/legend/messageTypes.tsx +13 -0
  276. package/src/screens/chat-detail/types.ts +5 -1
  277. package/src/screens/inbox/MessagesTab.tsx +1 -1
  278. package/src/services/attachmentHandlers/fileAttachmentHandler.ts +78 -0
  279. package/src/services/attachmentHandlers/imageAttachmentHandler.ts +54 -0
  280. package/src/services/attachmentHandlers/index.ts +10 -0
  281. package/src/services/attachmentHandlers/videoAttachmentHandler.ts +114 -0
  282. package/src/services/attachmentOrchestrator.ts +300 -0
  283. package/src/services/auth.ts +34 -0
  284. package/src/services/endpoints.ts +24 -1
  285. package/src/services/imageUpload.ts +162 -0
  286. package/src/translation/resources/i18n.ts +22 -8
  287. package/src/types/attachment.ts +85 -0
  288. package/src/types/attachmentHandler.ts +31 -0
  289. package/src/types/imageUpload.ts +28 -0
  290. package/src/types/message.ts +1 -0
  291. package/src/utils/chatImageDimens.ts +178 -0
  292. package/src/utils/device.ts +73 -0
  293. package/src/utils/imageUrlOptimizer.ts +56 -0
  294. package/src/utils/imageUtils.ts +76 -0
  295. package/src/utils/resolveMessageType.ts +2 -0
  296. package/src/utils/ui.ts +19 -0
  297. package/src/utils/url.ts +1 -1
  298. package/src/utils/videoThumbnail.ts +85 -0
  299. package/lib/module/screens/chat-detail/ChatList.js +0 -147
  300. package/lib/module/screens/chat-detail/ChatList.js.map +0 -1
  301. package/lib/module/screens/chat-detail/ChatTextBubble.js +0 -62
  302. package/lib/module/screens/chat-detail/ChatTextBubble.js.map +0 -1
  303. package/lib/module/screens/chat-detail/legend/message-types.js +0 -244
  304. package/lib/module/screens/chat-detail/legend/message-types.js.map +0 -1
  305. package/lib/module/screens/chat-detail/messages/ChatMessageBubble.js +0 -24
  306. package/lib/module/screens/chat-detail/messages/ChatMessageBubble.js.map +0 -1
  307. package/lib/module/screens/chat-detail/messages/types.js +0 -4
  308. package/lib/module/screens/chat-detail/messages/types.js.map +0 -1
  309. package/lib/typescript/src/screens/chat-detail/ChatList.d.ts +0 -3
  310. package/lib/typescript/src/screens/chat-detail/ChatList.d.ts.map +0 -1
  311. package/lib/typescript/src/screens/chat-detail/ChatTextBubble.d.ts +0 -3
  312. package/lib/typescript/src/screens/chat-detail/ChatTextBubble.d.ts.map +0 -1
  313. package/lib/typescript/src/screens/chat-detail/legend/message-types.d.ts +0 -13
  314. package/lib/typescript/src/screens/chat-detail/legend/message-types.d.ts.map +0 -1
  315. package/lib/typescript/src/screens/chat-detail/messages/ChatMessageBubble.d.ts +0 -3
  316. package/lib/typescript/src/screens/chat-detail/messages/ChatMessageBubble.d.ts.map +0 -1
  317. package/lib/typescript/src/screens/chat-detail/messages/types.d.ts +0 -13
  318. package/lib/typescript/src/screens/chat-detail/messages/types.d.ts.map +0 -1
  319. package/src/screens/chat-detail/ChatList.tsx +0 -190
  320. package/src/screens/chat-detail/ChatTextBubble.tsx +0 -73
  321. package/src/screens/chat-detail/legend/message-types.tsx +0 -304
  322. package/src/screens/chat-detail/messages/ChatMessageBubble.tsx +0 -23
  323. package/src/screens/chat-detail/messages/types.ts +0 -14
@@ -0,0 +1,162 @@
1
+ import ReactNativeBlobUtil from 'react-native-blob-util';
2
+ import RNFS from 'react-native-fs';
3
+ import { getImageUploadEndpoint, getMimeType } from '../utils/imageUtils';
4
+ import { getAuthToken } from './auth';
5
+ import { getApiEndpoint } from '../config/api-endpoints';
6
+ import { getBaseUrl } from '../config/configuration';
7
+ import type {
8
+ ImageFile,
9
+ UploadedImage,
10
+ ImageUploadConfig,
11
+ } from '../types/imageUpload';
12
+
13
+ export namespace ImageUploadAPI {
14
+ export const uploadImageFile = async (
15
+ file: ImageFile,
16
+ onProgress?: (progress: number) => void
17
+ ): Promise<UploadedImage> => {
18
+ let token: string;
19
+ let uploadUrl: string;
20
+
21
+ try {
22
+ token = getAuthToken();
23
+ const relativePath = getApiEndpoint('imageUpload');
24
+ const baseUrl = getBaseUrl();
25
+
26
+ if (!baseUrl) {
27
+ throw new Error(
28
+ 'Image upload base URL not configured. Call initChatSdk() with apiBaseUrl during app initialization.'
29
+ );
30
+ }
31
+
32
+ // Construct absolute URL for ReactNativeBlobUtil.fetch()
33
+ uploadUrl = getImageUploadEndpoint(`${baseUrl}${relativePath}`);
34
+ } catch (e) {
35
+ if (__DEV__) console.error('[ImageUploadAPI] Auth error:', e);
36
+ throw e;
37
+ }
38
+
39
+ return new Promise((resolve, reject) => {
40
+ ReactNativeBlobUtil.fetch(
41
+ 'POST',
42
+ uploadUrl,
43
+ {
44
+ Authorization: `Bearer ${token}`,
45
+ },
46
+ [
47
+ {
48
+ name: 'files',
49
+ filename: file.filename,
50
+ data: ReactNativeBlobUtil.wrap(file.path),
51
+ type: getMimeType(file.filename),
52
+ },
53
+ ]
54
+ )
55
+ .uploadProgress((written, total) => {
56
+ const progress = Math.round((written / total) * 100);
57
+ onProgress?.(progress);
58
+ })
59
+ .then((response) => {
60
+ // Check for HTTP error status
61
+ const status = response.respInfo?.status;
62
+ if (status && status >= 400) {
63
+ if (__DEV__)
64
+ console.error('[ImageUploadAPI] Server error response', {
65
+ status,
66
+ data: response.data,
67
+ });
68
+ reject(new Error(`Upload failed with status ${status}`));
69
+ return;
70
+ }
71
+
72
+ if (!response.data || response.data.length === 0) {
73
+ if (__DEV__)
74
+ console.error('[ImageUploadAPI] Empty response', {
75
+ dataType: typeof response.data,
76
+ data: response.data,
77
+ });
78
+ reject(new Error('Empty response from server'));
79
+ return;
80
+ }
81
+
82
+ try {
83
+ const json = JSON.parse(response.data);
84
+ const uploaded = json.data?.[0] || json.files?.[0];
85
+ const imageUrl =
86
+ uploaded?.publicUrl || uploaded?.url || uploaded?.data;
87
+ if (imageUrl) {
88
+ resolve({
89
+ url: imageUrl,
90
+ name: uploaded?.fileName,
91
+ width: file.width,
92
+ height: file.height,
93
+ size: file.size,
94
+ });
95
+ } else {
96
+ if (__DEV__)
97
+ console.error('[ImageUploadAPI] No URL in response:', json);
98
+ reject(new Error('No URL in response'));
99
+ }
100
+ } catch (err) {
101
+ if (__DEV__) console.error('[ImageUploadAPI] Parse error:', err);
102
+ reject(new Error('Invalid response format'));
103
+ }
104
+ })
105
+ .catch((error) => {
106
+ if (__DEV__) console.error('[ImageUploadAPI] Fetch error:', error);
107
+ reject(error);
108
+ });
109
+ });
110
+ };
111
+
112
+ export const uploadImageQueue = async (
113
+ files: ImageFile[],
114
+ config: ImageUploadConfig = {},
115
+ onProgress?: (completed: number, total: number) => void
116
+ ): Promise<UploadedImage[]> => {
117
+ const { maxConcurrent = 2 } = config;
118
+ const results: UploadedImage[] = [];
119
+ const queue = [...files];
120
+ let activeCount = 0;
121
+
122
+ return new Promise((resolve, _reject) => {
123
+ const processNext = async () => {
124
+ if (queue.length === 0 && activeCount === 0) {
125
+ resolve(results);
126
+ return;
127
+ }
128
+
129
+ if (queue.length > 0 && activeCount < maxConcurrent) {
130
+ const file = queue.shift();
131
+ if (!file) return;
132
+
133
+ activeCount++;
134
+
135
+ try {
136
+ const result = await uploadImageFile(file);
137
+ results.push(result);
138
+ onProgress?.(results.length, files.length);
139
+ } catch (error) {
140
+ if (__DEV__)
141
+ console.error(`Failed to upload ${file.filename}:`, error);
142
+ } finally {
143
+ activeCount--;
144
+ processNext();
145
+ }
146
+ }
147
+ };
148
+
149
+ for (let i = 0; i < maxConcurrent && queue.length > 0; i++) {
150
+ processNext();
151
+ }
152
+ });
153
+ };
154
+
155
+ export const cleanupImageFile = async (filePath: string): Promise<void> => {
156
+ try {
157
+ await RNFS.unlink(filePath);
158
+ } catch (err) {
159
+ if (__DEV__) console.warn('Cleanup failed:', err);
160
+ }
161
+ };
162
+ }
@@ -1,12 +1,26 @@
1
1
  const i18nKey: Record<string, string> = {
2
- thread_card_bot_crm_name: 'Droppii Hỗ Trợ',
3
- thread_card_fallback_name: 'Người dùng',
4
- msg_type_image: '[Hình ảnh]',
5
- msg_type_voice: '[Tin nhắn thoại]',
6
- msg_type_video: '[Video]',
7
- msg_type_file: '[File đính kèm]',
8
- msg_type_link: '[Liên kết]',
9
- msg_type_revoke: 'Đã thu hồi tin nhắn',
2
+ 'thread_card_bot_crm_name': 'Droppii Hỗ Trợ',
3
+ 'thread_card_fallback_name': 'Người dùng',
4
+ 'chat:image_preview': 'Xem trước ảnh',
5
+ 'chat:image_too_large': 'Ảnh quá lớn. Tối đa 5MB',
6
+ 'chat:image_sent': 'Đã gửi ảnh',
7
+ 'chat:image_upload_failed': 'Lỗi tải ảnh',
8
+ 'chat:failed_to_send_message': 'Không thể gửi tin nhắn. Thử lại?',
9
+ 'chat:filename': 'Tên tệp',
10
+ 'chat:file_size': 'Kích thước',
11
+ 'chat:dimensions': 'Kích cỡ',
12
+ 'chat:send': 'Gửi',
13
+ 'chat:retry': 'Thử lại',
14
+ 'chat:retry_failed_no_data': 'Không có dữ liệu để thử lại',
15
+ 'chat:retry_failed': 'Thử lại thất bại',
16
+ 'chat:upload_in_progress': 'Đang tải ảnh lên',
17
+ 'chat:wait_or_cancel': 'Vui lòng chờ hoặc hủy bỏ',
18
+ 'msg_type_image': '[Hình ảnh]',
19
+ 'msg_type_voice': '[Tin nhắn thoại]',
20
+ 'msg_type_video': '[Video]',
21
+ 'msg_type_file': '[File đính kèm]',
22
+ 'msg_type_link': '[Liên kết]',
23
+ 'msg_type_revoke': 'Đã thu hồi tin nhắn',
10
24
  };
11
25
 
12
26
  export default {
@@ -0,0 +1,85 @@
1
+ export type AttachmentType = 'image' | 'video' | 'file' | 'audio';
2
+
3
+ export interface BaseAttachment {
4
+ id: string;
5
+ type: AttachmentType;
6
+ sourceFile: {
7
+ path: string;
8
+ filename: string;
9
+ size: number;
10
+ mimeType: string;
11
+ };
12
+ }
13
+
14
+ export interface ImageAttachment extends BaseAttachment {
15
+ type: 'image';
16
+ metadata: {
17
+ width: number;
18
+ height: number;
19
+ orientation?: 'portrait' | 'landscape' | 'square';
20
+ };
21
+ }
22
+
23
+ export interface VideoAttachment extends BaseAttachment {
24
+ type: 'video';
25
+ metadata: {
26
+ width: number;
27
+ height: number;
28
+ duration: number;
29
+ thumbnail?: {
30
+ url: string;
31
+ width: number;
32
+ height: number;
33
+ size?: number;
34
+ };
35
+ };
36
+ }
37
+
38
+ export interface FileAttachment extends BaseAttachment {
39
+ type: 'file';
40
+ metadata: {
41
+ extension: string;
42
+ category: 'document' | 'spreadsheet' | 'presentation' | 'other';
43
+ };
44
+ }
45
+
46
+ export interface AudioAttachment extends BaseAttachment {
47
+ type: 'audio';
48
+ metadata: {
49
+ duration: number;
50
+ bitrate?: number;
51
+ };
52
+ }
53
+
54
+ export type Attachment =
55
+ | ImageAttachment
56
+ | VideoAttachment
57
+ | FileAttachment
58
+ | AudioAttachment;
59
+
60
+ export interface AttachmentUploadStatus {
61
+ attachmentId: string;
62
+ state: 'pending' | 'uploading' | 'uploaded' | 'failed' | 'cancelled';
63
+ progress: number;
64
+ uploadedUrl?: string;
65
+ error?: string;
66
+ uploadedAt?: number;
67
+ }
68
+
69
+ export type BatchStrategy = 'individual' | 'merged' | 'grouped';
70
+
71
+ export interface AttachmentSendOptions {
72
+ strategy: BatchStrategy;
73
+ includeCaption?: string;
74
+ uploadConcurrency?: number;
75
+ retryFailedUploads?: boolean;
76
+ maxRetries?: number;
77
+ }
78
+
79
+ export interface AttachmentSendResult {
80
+ success: boolean;
81
+ sentAttachmentIds: string[];
82
+ failedAttachmentIds: string[];
83
+ mergedMessageId?: string;
84
+ errors: Record<string, string>;
85
+ }
@@ -0,0 +1,31 @@
1
+ import type { Attachment } from './attachment';
2
+ // Imported from handlers to provide dispatch
3
+ import { ImageAttachmentHandler } from '../services/attachmentHandlers/imageAttachmentHandler';
4
+ import VideoAttachmentHandlerDefault from '../services/attachmentHandlers/videoAttachmentHandler';
5
+ import FileAttachmentHandlerDefault from '../services/attachmentHandlers/fileAttachmentHandler';
6
+
7
+ export interface IAttachmentHandler {
8
+ validate(
9
+ attachment: Attachment
10
+ ): { valid: true } | { valid: false; reason: string };
11
+
12
+ prepare?(attachment: Attachment): Promise<Attachment>;
13
+
14
+ buildPayload(attachment: Attachment, uploadedUrl: string): Promise<unknown>;
15
+ }
16
+
17
+ export function getAttachmentHandler(
18
+ type: Attachment['type']
19
+ ): IAttachmentHandler {
20
+ console.log('[getAttachmentHandler] Getting handler for type:', type);
21
+ switch (type) {
22
+ case 'image':
23
+ return ImageAttachmentHandler;
24
+ case 'video':
25
+ return VideoAttachmentHandlerDefault;
26
+ case 'file':
27
+ return FileAttachmentHandlerDefault;
28
+ default:
29
+ throw new Error(`No handler for attachment type: ${type}`);
30
+ }
31
+ }
@@ -0,0 +1,28 @@
1
+ export interface ImageFile {
2
+ path: string;
3
+ filename: string;
4
+ size: number;
5
+ width: number;
6
+ height: number;
7
+ mime: string;
8
+ }
9
+
10
+ export interface UploadedImage {
11
+ url: string;
12
+ name: string;
13
+ width: number;
14
+ height: number;
15
+ size: number;
16
+ }
17
+
18
+ export interface ImageUploadConfig {
19
+ maxConcurrent?: number;
20
+ timeout?: number;
21
+ retryAttempts?: number;
22
+ }
23
+
24
+ export interface UploadProgress {
25
+ completed: number;
26
+ total: number;
27
+ percentage: number;
28
+ }
@@ -4,6 +4,7 @@ export const DChatMessageType = {
4
4
  Image: 'IMAGE',
5
5
  Video: 'VIDEO',
6
6
  File: 'FILE',
7
+ Merged: 'MERGED',
7
8
  Order: 'ORDER',
8
9
  Unsupported: 'UNSUPPORTED',
9
10
  } as const;
@@ -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;
@@ -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;