@ethora/chat-component-rn 26.5.5 → 26.5.10

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 (420) hide show
  1. package/CHANGELOG.md +177 -0
  2. package/README.md +67 -10
  3. package/index.js +24 -0
  4. package/lib/commonjs/assets/icons.js +5 -1
  5. package/lib/commonjs/assets/icons.js.map +1 -1
  6. package/lib/commonjs/components/ContextMenu/ContextMenuComponents.js +11 -5
  7. package/lib/commonjs/components/ContextMenu/ContextMenuComponents.js.map +1 -1
  8. package/lib/commonjs/components/MainComponents/ChatHeader.js +7 -1
  9. package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
  10. package/lib/commonjs/components/MainComponents/ChatRoom.js +66 -34
  11. package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
  12. package/lib/commonjs/components/MainComponents/ChatWrapper.js +59 -14
  13. package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
  14. package/lib/commonjs/components/MainComponents/MediaMessage.js +15 -7
  15. package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
  16. package/lib/commonjs/components/MainComponents/MessageContainer.js +2 -2
  17. package/lib/commonjs/components/MainComponents/MessageContainer.js.map +1 -1
  18. package/lib/commonjs/components/MainComponents/MessageList.js +175 -30
  19. package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
  20. package/lib/commonjs/components/MainComponents/ReduxWrapper.js +17 -8
  21. package/lib/commonjs/components/MainComponents/ReduxWrapper.js.map +1 -1
  22. package/lib/commonjs/components/MainComponents/SystemMessage.js +34 -22
  23. package/lib/commonjs/components/MainComponents/SystemMessage.js.map +1 -1
  24. package/lib/commonjs/components/MessageBubble/Message.js +117 -19
  25. package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
  26. package/lib/commonjs/components/MessageBubble/MessageInteractions.js +82 -22
  27. package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
  28. package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js +16 -4
  29. package/lib/commonjs/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
  30. package/lib/commonjs/components/Modals/FilePreviewModal/DocumentViewer.js +104 -0
  31. package/lib/commonjs/components/Modals/FilePreviewModal/DocumentViewer.js.map +1 -0
  32. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +175 -40
  33. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  34. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js +29 -1
  35. package/lib/commonjs/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  36. package/lib/commonjs/components/Modals/Modal/Modal.js +5 -1
  37. package/lib/commonjs/components/Modals/Modal/Modal.js.map +1 -1
  38. package/lib/commonjs/components/Modals/ModalWrapper/ModalWrapper.js +78 -39
  39. package/lib/commonjs/components/Modals/ModalWrapper/ModalWrapper.js.map +1 -1
  40. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +3 -3
  41. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  42. package/lib/commonjs/components/Modals/styledModalComponents.js +4 -9
  43. package/lib/commonjs/components/Modals/styledModalComponents.js.map +1 -1
  44. package/lib/commonjs/components/styled/MediaFilePreview.js +115 -5
  45. package/lib/commonjs/components/styled/MediaFilePreview.js.map +1 -1
  46. package/lib/commonjs/components/styled/MessageImage.js +49 -10
  47. package/lib/commonjs/components/styled/MessageImage.js.map +1 -1
  48. package/lib/commonjs/components/styled/NewMessageLabel.js +8 -6
  49. package/lib/commonjs/components/styled/NewMessageLabel.js.map +1 -1
  50. package/lib/commonjs/components/styled/SendInput.js +53 -29
  51. package/lib/commonjs/components/styled/SendInput.js.map +1 -1
  52. package/lib/commonjs/components/styled/StyledInputComponents/MediaComponents.js +14 -4
  53. package/lib/commonjs/components/styled/StyledInputComponents/MediaComponents.js.map +1 -1
  54. package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js +7 -2
  55. package/lib/commonjs/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
  56. package/lib/commonjs/components/styled/UnsupportedType.js +5 -1
  57. package/lib/commonjs/components/styled/UnsupportedType.js.map +1 -1
  58. package/lib/commonjs/components/styled/VideoMessage.js +60 -22
  59. package/lib/commonjs/components/styled/VideoMessage.js.map +1 -1
  60. package/lib/commonjs/context/MessageNotificationContext.js +7 -7
  61. package/lib/commonjs/context/MessageNotificationContext.js.map +1 -1
  62. package/lib/commonjs/context/xmppProvider.js +315 -34
  63. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  64. package/lib/commonjs/helpers/chatAutoEnterer.js +2 -7
  65. package/lib/commonjs/helpers/chatAutoEnterer.js.map +1 -1
  66. package/lib/commonjs/helpers/historyPreloadScheduler.js +4 -1
  67. package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
  68. package/lib/commonjs/helpers/insertMessageWithDelimiter.js +15 -5
  69. package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
  70. package/lib/commonjs/helpers/keyboardLayout.js +18 -0
  71. package/lib/commonjs/helpers/keyboardLayout.js.map +1 -0
  72. package/lib/commonjs/helpers/mediaDimensions.js +51 -0
  73. package/lib/commonjs/helpers/mediaDimensions.js.map +1 -0
  74. package/lib/commonjs/helpers/mimeToExtension.js +131 -0
  75. package/lib/commonjs/helpers/mimeToExtension.js.map +1 -0
  76. package/lib/commonjs/helpers/normalizeRoomJid.js +20 -0
  77. package/lib/commonjs/helpers/normalizeRoomJid.js.map +1 -0
  78. package/lib/commonjs/helpers/resolveInitBeforeLoadUser.js +73 -1
  79. package/lib/commonjs/helpers/resolveInitBeforeLoadUser.js.map +1 -1
  80. package/lib/commonjs/hooks/useChatRoomFocus.js +87 -0
  81. package/lib/commonjs/hooks/useChatRoomFocus.js.map +1 -0
  82. package/lib/commonjs/hooks/useChatWrapperInit.js +22 -10
  83. package/lib/commonjs/hooks/useChatWrapperInit.js.map +1 -1
  84. package/lib/commonjs/hooks/useEventHandlers.js +9 -1
  85. package/lib/commonjs/hooks/useEventHandlers.js.map +1 -1
  86. package/lib/commonjs/hooks/useHeapSender.js +1 -1
  87. package/lib/commonjs/hooks/useHeapSender.js.map +1 -1
  88. package/lib/commonjs/hooks/useLogout.js +3 -3
  89. package/lib/commonjs/hooks/useLogout.js.map +1 -1
  90. package/lib/commonjs/hooks/useMessageHeapState.js +6 -2
  91. package/lib/commonjs/hooks/useMessageHeapState.js.map +1 -1
  92. package/lib/commonjs/hooks/usePushNotifications.js +6 -2
  93. package/lib/commonjs/hooks/usePushNotifications.js.map +1 -1
  94. package/lib/commonjs/hooks/useRoomState.js +2 -0
  95. package/lib/commonjs/hooks/useRoomState.js.map +1 -1
  96. package/lib/commonjs/hooks/useSendMessage.js +249 -14
  97. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  98. package/lib/commonjs/hooks/useUnreadMessagesCounter.js +12 -14
  99. package/lib/commonjs/hooks/useUnreadMessagesCounter.js.map +1 -1
  100. package/lib/commonjs/main.js +7 -0
  101. package/lib/commonjs/main.js.map +1 -1
  102. package/lib/commonjs/networking/api-requests/auth.api.js +74 -1
  103. package/lib/commonjs/networking/api-requests/auth.api.js.map +1 -1
  104. package/lib/commonjs/networking/apiClient.js +2 -1
  105. package/lib/commonjs/networking/apiClient.js.map +1 -1
  106. package/lib/commonjs/networking/outboundQueue.js +92 -0
  107. package/lib/commonjs/networking/outboundQueue.js.map +1 -0
  108. package/lib/commonjs/networking/xmpp/createTimeoutPromise.xmpp.js +4 -1
  109. package/lib/commonjs/networking/xmpp/createTimeoutPromise.xmpp.js.map +1 -1
  110. package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js +7 -8
  111. package/lib/commonjs/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
  112. package/lib/commonjs/networking/xmpp/getRoomsPaged.xmpp.js +26 -3
  113. package/lib/commonjs/networking/xmpp/getRoomsPaged.xmpp.js.map +1 -1
  114. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js +26 -8
  115. package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  116. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js +2 -1
  117. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  118. package/lib/commonjs/networking/xmppClient.js +371 -26
  119. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  120. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js +22 -6
  121. package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  122. package/lib/commonjs/roomStore/roomHeapSlice.js +26 -8
  123. package/lib/commonjs/roomStore/roomHeapSlice.js.map +1 -1
  124. package/lib/commonjs/roomStore/roomsSlice.js +157 -23
  125. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  126. package/lib/commonjs/utils/installPromiseRejectionTracker.js +83 -0
  127. package/lib/commonjs/utils/installPromiseRejectionTracker.js.map +1 -0
  128. package/lib/commonjs/utils/resendMessage.js +1 -1
  129. package/lib/commonjs/utils/resendMessage.js.map +1 -1
  130. package/lib/module/assets/icons.js +5 -1
  131. package/lib/module/assets/icons.js.map +1 -1
  132. package/lib/module/components/ContextMenu/ContextMenuComponents.js +11 -5
  133. package/lib/module/components/ContextMenu/ContextMenuComponents.js.map +1 -1
  134. package/lib/module/components/MainComponents/ChatHeader.js +7 -1
  135. package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
  136. package/lib/module/components/MainComponents/ChatRoom.js +67 -35
  137. package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
  138. package/lib/module/components/MainComponents/ChatWrapper.js +59 -14
  139. package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
  140. package/lib/module/components/MainComponents/MediaMessage.js +15 -7
  141. package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
  142. package/lib/module/components/MainComponents/MessageContainer.js +2 -2
  143. package/lib/module/components/MainComponents/MessageContainer.js.map +1 -1
  144. package/lib/module/components/MainComponents/MessageList.js +176 -31
  145. package/lib/module/components/MainComponents/MessageList.js.map +1 -1
  146. package/lib/module/components/MainComponents/ReduxWrapper.js +18 -8
  147. package/lib/module/components/MainComponents/ReduxWrapper.js.map +1 -1
  148. package/lib/module/components/MainComponents/SystemMessage.js +33 -21
  149. package/lib/module/components/MainComponents/SystemMessage.js.map +1 -1
  150. package/lib/module/components/MessageBubble/Message.js +118 -20
  151. package/lib/module/components/MessageBubble/Message.js.map +1 -1
  152. package/lib/module/components/MessageBubble/MessageInteractions.js +84 -24
  153. package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
  154. package/lib/module/components/Modals/AttachSheet/AttachSheet.js +15 -3
  155. package/lib/module/components/Modals/AttachSheet/AttachSheet.js.map +1 -1
  156. package/lib/module/components/Modals/FilePreviewModal/DocumentViewer.js +99 -0
  157. package/lib/module/components/Modals/FilePreviewModal/DocumentViewer.js.map +1 -0
  158. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +179 -42
  159. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js.map +1 -1
  160. package/lib/module/components/Modals/FilePreviewModal/PdfView.js +31 -3
  161. package/lib/module/components/Modals/FilePreviewModal/PdfView.js.map +1 -1
  162. package/lib/module/components/Modals/Modal/Modal.js +5 -1
  163. package/lib/module/components/Modals/Modal/Modal.js.map +1 -1
  164. package/lib/module/components/Modals/ModalWrapper/ModalWrapper.js +80 -41
  165. package/lib/module/components/Modals/ModalWrapper/ModalWrapper.js.map +1 -1
  166. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +3 -3
  167. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  168. package/lib/module/components/Modals/styledModalComponents.js +4 -9
  169. package/lib/module/components/Modals/styledModalComponents.js.map +1 -1
  170. package/lib/module/components/styled/MediaFilePreview.js +116 -6
  171. package/lib/module/components/styled/MediaFilePreview.js.map +1 -1
  172. package/lib/module/components/styled/MessageImage.js +51 -12
  173. package/lib/module/components/styled/MessageImage.js.map +1 -1
  174. package/lib/module/components/styled/NewMessageLabel.js +8 -6
  175. package/lib/module/components/styled/NewMessageLabel.js.map +1 -1
  176. package/lib/module/components/styled/SendInput.js +54 -30
  177. package/lib/module/components/styled/SendInput.js.map +1 -1
  178. package/lib/module/components/styled/StyledInputComponents/MediaComponents.js +14 -4
  179. package/lib/module/components/styled/StyledInputComponents/MediaComponents.js.map +1 -1
  180. package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js +7 -2
  181. package/lib/module/components/styled/StyledInputComponents/StyledInputComponents.js.map +1 -1
  182. package/lib/module/components/styled/UnsupportedType.js +5 -1
  183. package/lib/module/components/styled/UnsupportedType.js.map +1 -1
  184. package/lib/module/components/styled/VideoMessage.js +61 -23
  185. package/lib/module/components/styled/VideoMessage.js.map +1 -1
  186. package/lib/module/context/MessageNotificationContext.js +7 -7
  187. package/lib/module/context/MessageNotificationContext.js.map +1 -1
  188. package/lib/module/context/xmppProvider.js +319 -37
  189. package/lib/module/context/xmppProvider.js.map +1 -1
  190. package/lib/module/helpers/chatAutoEnterer.js +2 -7
  191. package/lib/module/helpers/chatAutoEnterer.js.map +1 -1
  192. package/lib/module/helpers/historyPreloadScheduler.js +4 -1
  193. package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
  194. package/lib/module/helpers/insertMessageWithDelimiter.js +15 -5
  195. package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
  196. package/lib/module/helpers/keyboardLayout.js +12 -0
  197. package/lib/module/helpers/keyboardLayout.js.map +1 -0
  198. package/lib/module/helpers/mediaDimensions.js +46 -0
  199. package/lib/module/helpers/mediaDimensions.js.map +1 -0
  200. package/lib/module/helpers/mimeToExtension.js +124 -0
  201. package/lib/module/helpers/mimeToExtension.js.map +1 -0
  202. package/lib/module/helpers/normalizeRoomJid.js +15 -0
  203. package/lib/module/helpers/normalizeRoomJid.js.map +1 -0
  204. package/lib/module/helpers/resolveInitBeforeLoadUser.js +71 -0
  205. package/lib/module/helpers/resolveInitBeforeLoadUser.js.map +1 -1
  206. package/lib/module/hooks/useChatRoomFocus.js +82 -0
  207. package/lib/module/hooks/useChatRoomFocus.js.map +1 -0
  208. package/lib/module/hooks/useChatWrapperInit.js +22 -10
  209. package/lib/module/hooks/useChatWrapperInit.js.map +1 -1
  210. package/lib/module/hooks/useEventHandlers.js +9 -1
  211. package/lib/module/hooks/useEventHandlers.js.map +1 -1
  212. package/lib/module/hooks/useHeapSender.js +1 -1
  213. package/lib/module/hooks/useHeapSender.js.map +1 -1
  214. package/lib/module/hooks/useLogout.js +3 -3
  215. package/lib/module/hooks/useLogout.js.map +1 -1
  216. package/lib/module/hooks/useMessageHeapState.js +6 -2
  217. package/lib/module/hooks/useMessageHeapState.js.map +1 -1
  218. package/lib/module/hooks/usePushNotifications.js +6 -2
  219. package/lib/module/hooks/usePushNotifications.js.map +1 -1
  220. package/lib/module/hooks/useRoomState.js +2 -0
  221. package/lib/module/hooks/useRoomState.js.map +1 -1
  222. package/lib/module/hooks/useSendMessage.js +252 -17
  223. package/lib/module/hooks/useSendMessage.js.map +1 -1
  224. package/lib/module/hooks/useUnreadMessagesCounter.js +12 -14
  225. package/lib/module/hooks/useUnreadMessagesCounter.js.map +1 -1
  226. package/lib/module/main.js +1 -0
  227. package/lib/module/main.js.map +1 -1
  228. package/lib/module/networking/api-requests/auth.api.js +74 -2
  229. package/lib/module/networking/api-requests/auth.api.js.map +1 -1
  230. package/lib/module/networking/apiClient.js +2 -1
  231. package/lib/module/networking/apiClient.js.map +1 -1
  232. package/lib/module/networking/outboundQueue.js +84 -0
  233. package/lib/module/networking/outboundQueue.js.map +1 -0
  234. package/lib/module/networking/xmpp/createTimeoutPromise.xmpp.js +4 -1
  235. package/lib/module/networking/xmpp/createTimeoutPromise.xmpp.js.map +1 -1
  236. package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js +7 -8
  237. package/lib/module/networking/xmpp/flushLastViewedToPrivateStore.js.map +1 -1
  238. package/lib/module/networking/xmpp/getRoomsPaged.xmpp.js +26 -3
  239. package/lib/module/networking/xmpp/getRoomsPaged.xmpp.js.map +1 -1
  240. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js +26 -8
  241. package/lib/module/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
  242. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js +2 -1
  243. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  244. package/lib/module/networking/xmppClient.js +371 -26
  245. package/lib/module/networking/xmppClient.js.map +1 -1
  246. package/lib/module/roomStore/Middleware/unreadMidlleware.js +22 -6
  247. package/lib/module/roomStore/Middleware/unreadMidlleware.js.map +1 -1
  248. package/lib/module/roomStore/roomHeapSlice.js +24 -7
  249. package/lib/module/roomStore/roomHeapSlice.js.map +1 -1
  250. package/lib/module/roomStore/roomsSlice.js +154 -22
  251. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  252. package/lib/module/utils/installPromiseRejectionTracker.js +78 -0
  253. package/lib/module/utils/installPromiseRejectionTracker.js.map +1 -0
  254. package/lib/module/utils/resendMessage.js +1 -1
  255. package/lib/module/utils/resendMessage.js.map +1 -1
  256. package/lib/typescript/assets/icons.d.ts +8 -4
  257. package/lib/typescript/assets/icons.d.ts.map +1 -1
  258. package/lib/typescript/components/ContextMenu/ContextMenuComponents.d.ts.map +1 -1
  259. package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
  260. package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
  261. package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
  262. package/lib/typescript/components/MainComponents/MediaMessage.d.ts +1 -0
  263. package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
  264. package/lib/typescript/components/MainComponents/MessageContainer.d.ts.map +1 -1
  265. package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
  266. package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts +1 -0
  267. package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts.map +1 -1
  268. package/lib/typescript/components/MainComponents/SystemMessage.d.ts +0 -7
  269. package/lib/typescript/components/MainComponents/SystemMessage.d.ts.map +1 -1
  270. package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
  271. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts +4 -2
  272. package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
  273. package/lib/typescript/components/Modals/AttachSheet/AttachSheet.d.ts.map +1 -1
  274. package/lib/typescript/components/Modals/FilePreviewModal/DocumentViewer.d.ts +29 -0
  275. package/lib/typescript/components/Modals/FilePreviewModal/DocumentViewer.d.ts.map +1 -0
  276. package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts +0 -1
  277. package/lib/typescript/components/Modals/FilePreviewModal/FilePreviewModal.d.ts.map +1 -1
  278. package/lib/typescript/components/Modals/FilePreviewModal/PdfView.d.ts.map +1 -1
  279. package/lib/typescript/components/Modals/Modal/Modal.d.ts.map +1 -1
  280. package/lib/typescript/components/Modals/ModalWrapper/ModalWrapper.d.ts +6 -0
  281. package/lib/typescript/components/Modals/ModalWrapper/ModalWrapper.d.ts.map +1 -1
  282. package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
  283. package/lib/typescript/components/Modals/styledModalComponents.d.ts.map +1 -1
  284. package/lib/typescript/components/styled/MediaFilePreview.d.ts.map +1 -1
  285. package/lib/typescript/components/styled/MessageImage.d.ts.map +1 -1
  286. package/lib/typescript/components/styled/NewMessageLabel.d.ts +1 -5
  287. package/lib/typescript/components/styled/NewMessageLabel.d.ts.map +1 -1
  288. package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
  289. package/lib/typescript/components/styled/StyledInputComponents/MediaComponents.d.ts +9 -1
  290. package/lib/typescript/components/styled/StyledInputComponents/MediaComponents.d.ts.map +1 -1
  291. package/lib/typescript/components/styled/StyledInputComponents/StyledInputComponents.d.ts.map +1 -1
  292. package/lib/typescript/components/styled/UnsupportedType.d.ts +1 -0
  293. package/lib/typescript/components/styled/UnsupportedType.d.ts.map +1 -1
  294. package/lib/typescript/components/styled/VideoMessage.d.ts.map +1 -1
  295. package/lib/typescript/context/xmppProvider.d.ts +1 -0
  296. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  297. package/lib/typescript/helpers/chatAutoEnterer.d.ts.map +1 -1
  298. package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
  299. package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
  300. package/lib/typescript/helpers/keyboardLayout.d.ts +9 -0
  301. package/lib/typescript/helpers/keyboardLayout.d.ts.map +1 -0
  302. package/lib/typescript/helpers/mediaDimensions.d.ts +9 -0
  303. package/lib/typescript/helpers/mediaDimensions.d.ts.map +1 -0
  304. package/lib/typescript/helpers/mimeToExtension.d.ts +37 -0
  305. package/lib/typescript/helpers/mimeToExtension.d.ts.map +1 -0
  306. package/lib/typescript/helpers/normalizeRoomJid.d.ts +2 -0
  307. package/lib/typescript/helpers/normalizeRoomJid.d.ts.map +1 -0
  308. package/lib/typescript/helpers/resolveInitBeforeLoadUser.d.ts +18 -0
  309. package/lib/typescript/helpers/resolveInitBeforeLoadUser.d.ts.map +1 -1
  310. package/lib/typescript/hooks/useChatRoomFocus.d.ts +42 -0
  311. package/lib/typescript/hooks/useChatRoomFocus.d.ts.map +1 -0
  312. package/lib/typescript/hooks/useChatWrapperInit.d.ts.map +1 -1
  313. package/lib/typescript/hooks/useEventHandlers.d.ts +6 -0
  314. package/lib/typescript/hooks/useEventHandlers.d.ts.map +1 -1
  315. package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
  316. package/lib/typescript/hooks/useMessageHeapState.d.ts +2 -0
  317. package/lib/typescript/hooks/useMessageHeapState.d.ts.map +1 -1
  318. package/lib/typescript/hooks/usePushNotifications.d.ts.map +1 -1
  319. package/lib/typescript/hooks/useRoomState.d.ts +1 -0
  320. package/lib/typescript/hooks/useRoomState.d.ts.map +1 -1
  321. package/lib/typescript/hooks/useSendMessage.d.ts +2 -1
  322. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  323. package/lib/typescript/hooks/useUnreadMessagesCounter.d.ts.map +1 -1
  324. package/lib/typescript/main.d.ts +1 -0
  325. package/lib/typescript/main.d.ts.map +1 -1
  326. package/lib/typescript/networking/api-requests/auth.api.d.ts +3 -0
  327. package/lib/typescript/networking/api-requests/auth.api.d.ts.map +1 -1
  328. package/lib/typescript/networking/apiClient.d.ts.map +1 -1
  329. package/lib/typescript/networking/outboundQueue.d.ts +57 -0
  330. package/lib/typescript/networking/outboundQueue.d.ts.map +1 -0
  331. package/lib/typescript/networking/xmpp/createTimeoutPromise.xmpp.d.ts.map +1 -1
  332. package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts +1 -1
  333. package/lib/typescript/networking/xmpp/flushLastViewedToPrivateStore.d.ts.map +1 -1
  334. package/lib/typescript/networking/xmpp/getRoomsPaged.xmpp.d.ts +1 -1
  335. package/lib/typescript/networking/xmpp/getRoomsPaged.xmpp.d.ts.map +1 -1
  336. package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
  337. package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts.map +1 -1
  338. package/lib/typescript/networking/xmppClient.d.ts +58 -5
  339. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  340. package/lib/typescript/roomStore/Middleware/unreadMidlleware.d.ts.map +1 -1
  341. package/lib/typescript/roomStore/roomHeapSlice.d.ts +22 -1
  342. package/lib/typescript/roomStore/roomHeapSlice.d.ts.map +1 -1
  343. package/lib/typescript/roomStore/roomsSlice.d.ts +8 -1
  344. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  345. package/lib/typescript/types/models/media.model.d.ts +1 -0
  346. package/lib/typescript/types/models/media.model.d.ts.map +1 -1
  347. package/lib/typescript/types/models/xmpp.model.d.ts +1 -1
  348. package/lib/typescript/types/models/xmpp.model.d.ts.map +1 -1
  349. package/lib/typescript/types/types.d.ts +10 -0
  350. package/lib/typescript/types/types.d.ts.map +1 -1
  351. package/lib/typescript/utils/installPromiseRejectionTracker.d.ts +20 -0
  352. package/lib/typescript/utils/installPromiseRejectionTracker.d.ts.map +1 -0
  353. package/lib/typescript/utils/resendMessage.d.ts.map +1 -1
  354. package/package.json +18 -2
  355. package/src/assets/icons.tsx +23 -14
  356. package/src/components/ContextMenu/ContextMenuComponents.tsx +10 -5
  357. package/src/components/MainComponents/ChatHeader.tsx +5 -1
  358. package/src/components/MainComponents/ChatRoom.tsx +81 -61
  359. package/src/components/MainComponents/ChatWrapper.tsx +100 -21
  360. package/src/components/MainComponents/MediaMessage.tsx +18 -8
  361. package/src/components/MainComponents/MessageContainer.tsx +4 -2
  362. package/src/components/MainComponents/MessageList.tsx +185 -31
  363. package/src/components/MainComponents/ReduxWrapper.tsx +19 -9
  364. package/src/components/MainComponents/SystemMessage.tsx +38 -26
  365. package/src/components/MessageBubble/Message.tsx +110 -27
  366. package/src/components/MessageBubble/MessageInteractions.tsx +98 -29
  367. package/src/components/Modals/AttachSheet/AttachSheet.tsx +17 -3
  368. package/src/components/Modals/FilePreviewModal/DocumentViewer.tsx +93 -0
  369. package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +182 -37
  370. package/src/components/Modals/FilePreviewModal/PdfView.tsx +32 -4
  371. package/src/components/Modals/Modal/Modal.tsx +4 -1
  372. package/src/components/Modals/ModalWrapper/ModalWrapper.tsx +77 -44
  373. package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +19 -15
  374. package/src/components/Modals/styledModalComponents.tsx +4 -9
  375. package/src/components/styled/MediaFilePreview.tsx +111 -5
  376. package/src/components/styled/MessageImage.tsx +58 -14
  377. package/src/components/styled/NewMessageLabel.tsx +8 -5
  378. package/src/components/styled/SendInput.tsx +67 -29
  379. package/src/components/styled/StyledInputComponents/MediaComponents.tsx +15 -5
  380. package/src/components/styled/StyledInputComponents/StyledInputComponents.tsx +7 -2
  381. package/src/components/styled/UnsupportedType.tsx +7 -1
  382. package/src/components/styled/VideoMessage.tsx +59 -18
  383. package/src/context/MessageNotificationContext.tsx +8 -8
  384. package/src/context/xmppProvider.tsx +337 -32
  385. package/src/helpers/chatAutoEnterer.ts +2 -8
  386. package/src/helpers/historyPreloadScheduler.ts +4 -1
  387. package/src/helpers/insertMessageWithDelimiter.ts +22 -15
  388. package/src/helpers/keyboardLayout.ts +18 -0
  389. package/src/helpers/mediaDimensions.ts +47 -0
  390. package/src/helpers/mimeToExtension.ts +135 -0
  391. package/src/helpers/normalizeRoomJid.ts +6 -0
  392. package/src/helpers/resolveInitBeforeLoadUser.ts +79 -0
  393. package/src/hooks/useChatRoomFocus.ts +95 -0
  394. package/src/hooks/useChatWrapperInit.ts +51 -46
  395. package/src/hooks/useEventHandlers.tsx +24 -1
  396. package/src/hooks/useHeapSender.tsx +2 -1
  397. package/src/hooks/useLogout.tsx +3 -3
  398. package/src/hooks/useMessageHeapState.tsx +6 -2
  399. package/src/hooks/usePushNotifications.ts +21 -8
  400. package/src/hooks/useRoomState.tsx +4 -0
  401. package/src/hooks/useSendMessage.tsx +333 -17
  402. package/src/hooks/useUnreadMessagesCounter.ts +13 -16
  403. package/src/main.ts +1 -0
  404. package/src/networking/api-requests/auth.api.ts +60 -2
  405. package/src/networking/apiClient.ts +2 -1
  406. package/src/networking/outboundQueue.ts +98 -0
  407. package/src/networking/xmpp/createTimeoutPromise.xmpp.ts +5 -1
  408. package/src/networking/xmpp/flushLastViewedToPrivateStore.ts +11 -13
  409. package/src/networking/xmpp/getRoomsPaged.xmpp.ts +27 -3
  410. package/src/networking/xmpp/presenceInRoom.xmpp.ts +24 -9
  411. package/src/networking/xmpp/sendTextMessage.xmpp.ts +2 -1
  412. package/src/networking/xmppClient.ts +399 -31
  413. package/src/roomStore/Middleware/unreadMidlleware.tsx +23 -5
  414. package/src/roomStore/roomHeapSlice.ts +47 -4
  415. package/src/roomStore/roomsSlice.ts +177 -27
  416. package/src/types/models/media.model.ts +3 -0
  417. package/src/types/models/xmpp.model.ts +2 -1
  418. package/src/types/types.ts +25 -0
  419. package/src/utils/installPromiseRejectionTracker.ts +91 -0
  420. package/src/utils/resendMessage.ts +2 -1
@@ -1,31 +1,79 @@
1
- import { View } from 'react-native';
1
+ import { View, Text, StyleSheet, Modal, TouchableOpacity, SafeAreaView } from 'react-native';
2
2
  import {
3
3
  MediaContainer,
4
4
  MediaImage,
5
5
  } from './StyledInputComponents/StyledInputComponents';
6
6
  import { FileIcon } from '../../assets/icons';
7
7
  import { RemoveButton, RemoveButtonText } from './StyledComponents';
8
- import { FC } from 'react';
8
+ import { FC, useState } from 'react';
9
9
  import { MediaFile } from '../../types/types';
10
+ import { useVideoPlayer, VideoView } from 'expo-video';
10
11
 
11
12
  interface MediaFilePreviewProps {
12
13
  filePreviews: MediaFile[];
13
14
  handleRemoveImage: (index: number) => void;
14
15
  }
15
16
 
17
+ const VideoThumb: FC<{ uri: string; onPress: () => void }> = ({
18
+ uri,
19
+ onPress,
20
+ }) => {
21
+ const player = useVideoPlayer(uri, (p) => {
22
+ p.muted = true;
23
+ });
24
+ return (
25
+ <TouchableOpacity
26
+ activeOpacity={0.8}
27
+ onPress={onPress}
28
+ style={styles.videoThumb}
29
+ >
30
+ <VideoView
31
+ player={player}
32
+ style={StyleSheet.absoluteFill}
33
+ contentFit="cover"
34
+ nativeControls={false}
35
+ surfaceType="textureView"
36
+ pointerEvents="none"
37
+ />
38
+ <View style={styles.playOverlay}>
39
+ <Text style={styles.playIcon}>▶</Text>
40
+ </View>
41
+ </TouchableOpacity>
42
+ );
43
+ };
44
+
45
+ const FullscreenPreviewVideo: FC<{ uri: string }> = ({ uri }) => {
46
+ const player = useVideoPlayer(uri, (p) => {
47
+ p.play();
48
+ });
49
+ return (
50
+ <VideoView
51
+ player={player}
52
+ style={styles.fullVideo}
53
+ contentFit="contain"
54
+ nativeControls
55
+ surfaceType="textureView"
56
+ />
57
+ );
58
+ };
59
+
16
60
  export const MediaFilePreview: FC<MediaFilePreviewProps> = ({
17
61
  filePreviews,
18
62
  handleRemoveImage,
19
63
  }) => {
64
+ const [previewUri, setPreviewUri] = useState<string | null>(null);
65
+
20
66
  return (
21
67
  <MediaContainer>
22
68
  {filePreviews.map((file, index) => {
23
- const isImageOrVideo =
24
- file.type?.startsWith('image') || file.type?.startsWith('video');
69
+ const isImage = file.type?.startsWith('image');
70
+ const isVideo = file.type?.startsWith('video');
25
71
  return (
26
72
  <View key={`${file.name}_${index}`}>
27
- {isImageOrVideo ? (
73
+ {isImage ? (
28
74
  <MediaImage source={{ uri: file.uri }} />
75
+ ) : isVideo ? (
76
+ <VideoThumb uri={file.uri} onPress={() => setPreviewUri(file.uri)} />
29
77
  ) : (
30
78
  <View style={{ width: 70, height: 70, borderRadius: 8 }}>
31
79
  <FileIcon width={70} height={70} />
@@ -37,6 +85,64 @@ export const MediaFilePreview: FC<MediaFilePreviewProps> = ({
37
85
  </View>
38
86
  );
39
87
  })}
88
+
89
+ <Modal visible={!!previewUri} animationType="fade" transparent>
90
+ <SafeAreaView style={styles.modalContainer}>
91
+ <TouchableOpacity
92
+ style={styles.closeButton}
93
+ onPress={() => setPreviewUri(null)}
94
+ >
95
+ <Text style={styles.closeText}>✕</Text>
96
+ </TouchableOpacity>
97
+ {previewUri && <FullscreenPreviewVideo uri={previewUri} />}
98
+ </SafeAreaView>
99
+ </Modal>
40
100
  </MediaContainer>
41
101
  );
42
102
  };
103
+
104
+ const styles = StyleSheet.create({
105
+ videoThumb: {
106
+ width: 70,
107
+ height: 70,
108
+ borderRadius: 8,
109
+ overflow: 'hidden',
110
+ backgroundColor: '#1a1a1a',
111
+ },
112
+ playOverlay: {
113
+ ...StyleSheet.absoluteFillObject,
114
+ justifyContent: 'center',
115
+ alignItems: 'center',
116
+ backgroundColor: 'rgba(0,0,0,0.3)',
117
+ },
118
+ playIcon: {
119
+ fontSize: 24,
120
+ color: '#fff',
121
+ },
122
+ modalContainer: {
123
+ flex: 1,
124
+ backgroundColor: '#000',
125
+ justifyContent: 'center',
126
+ },
127
+ closeButton: {
128
+ position: 'absolute',
129
+ top: 60,
130
+ right: 20,
131
+ zIndex: 10,
132
+ width: 36,
133
+ height: 36,
134
+ borderRadius: 18,
135
+ backgroundColor: 'rgba(255,255,255,0.2)',
136
+ justifyContent: 'center',
137
+ alignItems: 'center',
138
+ },
139
+ closeText: {
140
+ fontSize: 18,
141
+ color: '#fff',
142
+ fontWeight: '600',
143
+ },
144
+ fullVideo: {
145
+ width: '100%',
146
+ height: '70%',
147
+ },
148
+ });
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import { Container } from './StyledInputComponents/MediaComponents';
3
3
  import { useDispatch } from 'react-redux';
4
4
  import {
@@ -6,44 +6,88 @@ import {
6
6
  setActiveModal,
7
7
  } from '../../roomStore/chatSettingsSlice';
8
8
  import { MODAL_TYPES } from '../../helpers/constants/MODAL_TYPES';
9
- import { ActivityIndicator, Image, TouchableOpacity } from 'react-native';
9
+ import { ActivityIndicator, Image, TouchableOpacity, View } from 'react-native';
10
+ import {
11
+ defaultMediaDims,
12
+ fitMediaDimensions,
13
+ MediaDims,
14
+ } from '../../helpers/mediaDimensions';
15
+
10
16
  interface CustomMessageImageProps {
11
17
  fileURL: string;
12
18
  fileName: string;
13
19
  mimetype: string;
14
20
  }
15
21
 
22
+ const FALLBACK_IMAGE =
23
+ 'https://as2.ftcdn.net/v2/jpg/02/51/95/53/1000_F_251955356_FAQH0U1y1TZw3ZcdPGybwUkH90a3VAhb.jpg';
24
+
16
25
  const CustomMessageImage: React.FC<CustomMessageImageProps> = ({
17
26
  fileURL,
18
27
  fileName,
19
28
  mimetype,
20
29
  }) => {
21
- const [error, setError] = useState(false);
22
30
  const [loading, setLoading] = useState(true);
31
+ // Start with a neutral box; swap to the real aspect ratio once the
32
+ // image's natural dimensions are known so it's shown scaled, not cropped.
33
+ const [dims, setDims] = useState<MediaDims>(defaultMediaDims());
23
34
 
24
35
  const dispatch = useDispatch();
25
36
 
37
+ useEffect(() => {
38
+ if (!fileURL) {
39
+ return;
40
+ }
41
+ let active = true;
42
+ Image.getSize(
43
+ fileURL,
44
+ (w, h) => {
45
+ if (active) {
46
+ setDims(fitMediaDimensions(w, h));
47
+ }
48
+ },
49
+ () => {
50
+ /* keep the default box if the size probe fails */
51
+ }
52
+ );
53
+ return () => {
54
+ active = false;
55
+ };
56
+ }, [fileURL]);
57
+
26
58
  const handleOpen = () => {
27
59
  dispatch(setActiveFile({ fileName, fileURL, mimetype }));
28
60
  dispatch(setActiveModal(MODAL_TYPES.FILE_PREVIEW));
29
61
  };
30
62
 
31
63
  return (
32
- <Container>
33
- <TouchableOpacity onPress={handleOpen}>
34
- {loading && <ActivityIndicator size="small" color="#0052CD" />}
64
+ <Container style={{ width: dims.width }}>
65
+ <TouchableOpacity onPress={handleOpen} activeOpacity={0.9}>
66
+ {loading && (
67
+ <View
68
+ style={{
69
+ position: 'absolute',
70
+ width: dims.width,
71
+ height: dims.height,
72
+ alignItems: 'center',
73
+ justifyContent: 'center',
74
+ zIndex: 1,
75
+ }}
76
+ >
77
+ <ActivityIndicator size="small" color="#0052CD" />
78
+ </View>
79
+ )}
35
80
  <Image
36
- src={
37
- fileURL ||
38
- 'https://as2.ftcdn.net/v2/jpg/02/51/95/53/1000_F_251955356_FAQH0U1y1TZw3ZcdPGybwUkH90a3VAhb.jpg'
39
- }
81
+ source={{ uri: fileURL || FALLBACK_IMAGE }}
40
82
  style={{
41
- borderRadius: 16,
42
- width: 150,
43
- height: 200,
83
+ width: dims.width,
84
+ height: dims.height,
85
+ borderRadius: 10,
86
+ backgroundColor: 'rgba(0, 0, 0, 0)',
44
87
  }}
45
- onError={() => setError(true)}
46
88
  onLoadEnd={() => setLoading(false)}
89
+ // The box already matches the natural aspect ratio, so 'cover'
90
+ // fills it edge-to-edge with no actual cropping or letterboxing.
47
91
  resizeMode="cover"
48
92
  />
49
93
  </TouchableOpacity>
@@ -24,23 +24,26 @@ export const StyledLabel = styled.View`
24
24
  margin: 10px 0px;
25
25
  `;
26
26
 
27
- export const StyledLabelText = styled.Text<{ color?: string }>`
28
- color: ${(props) => (props?.color ? props?.color : '#0052CD')};
27
+ export const StyledLabelText = styled.Text`
28
+ color: #ffffff;
29
29
  font-size: 12px;
30
30
  line-height: 14px;
31
- font-weight: 400;
31
+ font-weight: 500;
32
32
  `;
33
33
 
34
+ // `color` is kept for CustomNewMessageLabel API parity, but the built-in
35
+ // label always renders WHITE text — it sits on a dark (#3f3f3f) pill, where
36
+ // the previous primary/blue text was unreadable.
34
37
  interface NewMessageLabelProps {
35
38
  color?: string;
36
39
  }
37
40
 
38
- const NewMessageLabel: React.FC<NewMessageLabelProps> = ({ color }) => {
41
+ const NewMessageLabel: React.FC<NewMessageLabelProps> = () => {
39
42
  return (
40
43
  <Container>
41
44
  <Line />
42
45
  <StyledLabel>
43
- <StyledLabelText color={color}>New messages</StyledLabelText>
46
+ <StyledLabelText>New messages</StyledLabelText>
44
47
  </StyledLabel>
45
48
  <Line />
46
49
  </Container>
@@ -9,7 +9,7 @@ import {
9
9
  import { IConfig, MediaFile } from '../../types/types';
10
10
  import Button from './Button';
11
11
  import { SendIcon, AttachIcon } from '../../assets/icons';
12
- import { KeyboardAvoidingView, Platform, View, TouchableOpacity, Alert, ActionSheetIOS, Linking } from 'react-native';
12
+ import { KeyboardAvoidingView, View, TouchableOpacity, Alert, Linking } from 'react-native';
13
13
  import AttachSheet from '../Modals/AttachSheet/AttachSheet';
14
14
  import { MediaFilePreview } from './MediaFilePreview';
15
15
  import * as ImagePicker from 'expo-image-picker';
@@ -19,6 +19,21 @@ import * as ImageManipulator from 'expo-image-manipulator';
19
19
  // iOS photos default to HEIC; many web backends (incl. ours) 500 on
20
20
  // HEIC uploads because they can't decode it. Convert to JPEG before
21
21
  // upload — JPEG is universally supported. JPEGs pass through.
22
+ // Server rejects uploads over its body-size cap with HTTP 413 (Request
23
+ // Entity Too Large). Guard client-side so the user gets a clear message
24
+ // instead of a silent failed bubble. 50 MB matches the backend limit.
25
+ const MAX_MEDIA_BYTES = 50 * 1024 * 1024;
26
+
27
+ const formatBytes = (bytes: number): string => {
28
+ if (bytes >= 1024 * 1024) {
29
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
30
+ }
31
+ if (bytes >= 1024) {
32
+ return `${(bytes / 1024).toFixed(0)} KB`;
33
+ }
34
+ return `${bytes} B`;
35
+ };
36
+
22
37
  const normalizeImageAsset = async (asset: ImagePicker.ImagePickerAsset) => {
23
38
  const mime = (asset.mimeType || '').toLowerCase();
24
39
  const looksLikeHeic =
@@ -72,7 +87,6 @@ const SendInput: React.FC<SendInputProps> = ({
72
87
  const [isRecording, setIsRecording] = useState(false);
73
88
  const [isFocused, setIsFocused] = useState(false);
74
89
  const [filePreviews, setFilePreviews] = useState<MediaFile[]>([]);
75
- const [inputHeight, setInputHeight] = useState(40);
76
90
  const [showMediaMenu, setShowMediaMenu] = useState(false);
77
91
 
78
92
  // Refs shadow `message` and `filePreviews` so handleSendClick can:
@@ -90,6 +104,21 @@ const SendInput: React.FC<SendInputProps> = ({
90
104
  const sendingRef = useRef(false);
91
105
 
92
106
  const handleFileSelect = (files: MediaFile[]) => {
107
+ // Enforce the upload size cap before anything reaches the network.
108
+ // The backend rejects oversized bodies with HTTP 413; catching it
109
+ // here gives a clear message instead of a silent failed bubble.
110
+ const oversize = files.find(
111
+ (f) => typeof f.size === 'number' && f.size > MAX_MEDIA_BYTES
112
+ );
113
+ if (oversize) {
114
+ Alert.alert(
115
+ 'File too large',
116
+ `"${oversize.name}" is ${formatBytes(oversize.size!)}. The maximum allowed size is ${Math.round(
117
+ MAX_MEDIA_BYTES / (1024 * 1024)
118
+ )} MB.`
119
+ );
120
+ return;
121
+ }
93
122
  filePreviewsRef.current = files;
94
123
  setFilePreviews([...files]);
95
124
  };
@@ -117,6 +146,7 @@ const SendInput: React.FC<SendInputProps> = ({
117
146
  const result = await ImagePicker.launchCameraAsync({
118
147
  mediaTypes: ['images', 'videos'],
119
148
  quality: 0.9,
149
+ videoQuality: ImagePicker.UIImagePickerControllerQualityType.Medium,
120
150
  });
121
151
  if (result.canceled || !result.assets?.[0]) {return;}
122
152
  const asset = result.assets[0];
@@ -126,13 +156,19 @@ const SendInput: React.FC<SendInputProps> = ({
126
156
  uri: asset.uri,
127
157
  type: asset.mimeType || 'video/mp4',
128
158
  name: asset.fileName || asset.uri.split('/').pop() || `camera_${Date.now()}.mp4`,
159
+ size: (asset as any).fileSize,
129
160
  },
130
161
  ]);
131
162
  return;
132
163
  }
133
164
  const normalized = await normalizeImageAsset(asset);
134
165
  handleFileSelect([
135
- { uri: normalized.uri, type: normalized.mime, name: normalized.name },
166
+ {
167
+ uri: normalized.uri,
168
+ type: normalized.mime,
169
+ name: normalized.name,
170
+ size: (asset as any).fileSize,
171
+ },
136
172
  ]);
137
173
  } catch (error) {
138
174
  console.error('Camera error:', error);
@@ -151,6 +187,8 @@ const SendInput: React.FC<SendInputProps> = ({
151
187
  mediaTypes: ['images', 'videos'],
152
188
  allowsEditing: false,
153
189
  quality: 0.9,
190
+ preferredAssetRepresentationMode:
191
+ ImagePicker.UIImagePickerPreferredAssetRepresentationMode.Compatible,
154
192
  });
155
193
  if (result.canceled || !result.assets?.[0]) {return;}
156
194
  const asset = result.assets[0];
@@ -162,13 +200,19 @@ const SendInput: React.FC<SendInputProps> = ({
162
200
  uri: asset.uri,
163
201
  type: asset.mimeType || 'video/mp4',
164
202
  name: asset.fileName || asset.uri.split('/').pop() || `gallery_${Date.now()}.mp4`,
203
+ size: (asset as any).fileSize,
165
204
  },
166
205
  ]);
167
206
  return;
168
207
  }
169
208
  const normalized = await normalizeImageAsset(asset);
170
209
  handleFileSelect([
171
- { uri: normalized.uri, type: normalized.mime, name: normalized.name },
210
+ {
211
+ uri: normalized.uri,
212
+ type: normalized.mime,
213
+ name: normalized.name,
214
+ size: (asset as any).fileSize,
215
+ },
172
216
  ]);
173
217
  } catch (error) {
174
218
  console.error('Gallery error:', error);
@@ -189,6 +233,7 @@ const SendInput: React.FC<SendInputProps> = ({
189
233
  uri: asset.uri,
190
234
  type: asset.mimeType || 'application/octet-stream',
191
235
  name: asset.name || `file_${Date.now()}`,
236
+ size: asset.size ?? undefined,
192
237
  },
193
238
  ]);
194
239
  } catch (err) {
@@ -197,21 +242,7 @@ const SendInput: React.FC<SendInputProps> = ({
197
242
  };
198
243
 
199
244
  const handleAttachPress = () => {
200
- if (Platform.OS === 'ios') {
201
- ActionSheetIOS.showActionSheetWithOptions(
202
- {
203
- options: ['Cancel', 'Camera', 'Photo Library', 'Document'],
204
- cancelButtonIndex: 0,
205
- },
206
- (buttonIndex) => {
207
- if (buttonIndex === 1) {handleCameraSelection();}
208
- else if (buttonIndex === 2) {handleGallerySelection();}
209
- else if (buttonIndex === 3) {handleFileSelection();}
210
- }
211
- );
212
- } else {
213
- setShowMediaMenu(true);
214
- }
245
+ setShowMediaMenu(true);
215
246
  };
216
247
 
217
248
  const handleRemoveImage = (index: number) => {
@@ -333,17 +364,15 @@ const SendInput: React.FC<SendInputProps> = ({
333
364
  }}
334
365
  editable={!isLoading || !isMessageProcessing}
335
366
  multiline={true}
336
- // maxHeight={72}
337
- onContentSizeChange={(event) => {
338
- setInputHeight(
339
- Math.min(
340
- 72,
341
- Math.max(40, event.nativeEvent.contentSize.height)
342
- )
343
- );
344
- }}
367
+ // No fixed height: a multiline TextInput auto-grows to fit
368
+ // its content between min/max. Locking `height` made iOS
369
+ // top-align the text inside the taller box (it looked like
370
+ // the text had dropped). minHeight keeps the 40px tap
371
+ // target; the row's align-items:center vertically centres
372
+ // the content-sized input.
345
373
  style={{
346
- height: inputHeight,
374
+ minHeight: 40,
375
+ maxHeight: 120,
347
376
  flex: 1,
348
377
  }}
349
378
  />
@@ -368,6 +397,15 @@ const SendInput: React.FC<SendInputProps> = ({
368
397
  borderRadius: 20,
369
398
  alignItems: 'center',
370
399
  justifyContent: 'center',
400
+ // The shared Button (CustomButton) bakes in `margin: 0 10px`,
401
+ // which pushed the send button 10px further from the input
402
+ // and from the right edge than the attach button (a raw
403
+ // TouchableOpacity with no margin). Zero it so both sides of
404
+ // the input use the row's uniform gap:8 + 16px container
405
+ // padding. Longhand left/right to override the styled
406
+ // longhand (marginHorizontal loses to marginLeft/Right in RN).
407
+ marginLeft: 0,
408
+ marginRight: 0,
371
409
  backgroundColor:
372
410
  message || filePreviews.length > 0
373
411
  ? config?.colors?.primary
@@ -3,9 +3,15 @@ import styled from 'styled-components/native';
3
3
  export const Container = styled.View`
4
4
  margin: 0;
5
5
  cursor: pointer;
6
- display: flex;
7
- align-items: center;
8
- justify-content: center;
6
+ /* The media has an explicit (scaled) width set inline. Its horizontal
7
+ position inside the bubble is driven by the bubble's align-items
8
+ (set per-sender in Message.tsx): own messages push the media to the
9
+ right edge, others to the left — so the media stays flush with the
10
+ text bubbles on the same side instead of leaving a gap. */
11
+ align-items: flex-start;
12
+ align-self: auto;
13
+ overflow: hidden;
14
+ border-radius: 10px;
9
15
  `;
10
16
 
11
17
  export const FullScreenImage = styled.Image`
@@ -66,11 +72,15 @@ export const FileInformation = styled.View`
66
72
  gap: 8px;
67
73
  `;
68
74
 
69
- export const FileName = styled.Text`
75
+ export const FileName = styled.Text<{
76
+ isUser: boolean;
77
+ colorIsUser: string| undefined;
78
+ colorUsers: string | undefined;
79
+ }>`
70
80
  font-size: 14px;
71
81
  font-weight: 500;
72
82
  flex-grow: 1;
73
- color: #fff;
83
+ color: ${({isUser, colorIsUser, colorUsers}) => isUser? colorIsUser : colorUsers};
74
84
  overflow: hidden;
75
85
  `;
76
86
 
@@ -46,16 +46,21 @@ export const MessageInput = styled.TextInput<{
46
46
  isFocused?: boolean;
47
47
  color?: string;
48
48
  }>`
49
- padding: 10px 14px;
49
+ padding: 8px 14px;
50
50
  border-radius: 20px;
51
51
  border-width: 1px;
52
52
  border-color: ${(props) =>
53
53
  props.isFocused ? props.color || '#0052CD' : 'transparent'};
54
54
  color: #141414;
55
+ font-size: 16px;
55
56
  background-color: #f5f7f9;
56
57
  flex: 1;
58
+ /* No explicit line-height: on iOS a line-height larger than the
59
+ font's natural metrics drops the glyph to the bottom of the line
60
+ box (looked like the text "sank"). Equal vertical padding + the
61
+ natural line height centers single-line text in the min-height
62
+ box. text-align-vertical / include-font-padding stay for Android. */
57
63
  text-align-vertical: center;
58
- line-height: 20px;
59
64
  include-font-padding: false;
60
65
  `;
61
66
 
@@ -23,6 +23,7 @@ interface FileDownloadProps {
23
23
  fileURL: string;
24
24
  mimetype: string;
25
25
  size?: string;
26
+ isUser: boolean;
26
27
  }
27
28
 
28
29
  const FileDownload: React.FC<FileDownloadProps> = ({
@@ -30,6 +31,7 @@ const FileDownload: React.FC<FileDownloadProps> = ({
30
31
  fileURL,
31
32
  mimetype,
32
33
  size,
34
+ isUser,
33
35
  }) => {
34
36
  const dispatch = useDispatch();
35
37
  const { config } = useChatSettingState();
@@ -81,7 +83,11 @@ const FileDownload: React.FC<FileDownloadProps> = ({
81
83
  <FileIcon />
82
84
  </BackgroundFile>
83
85
  <FileInformation>
84
- <FileName>{formatFileName(fileName, 20)}</FileName>
86
+ <FileName
87
+ isUser={isUser}
88
+ colorIsUser={config?.colors?.primary}
89
+ colorUsers={config?.colors?.secondary}
90
+ >{formatFileName(fileName, 20)}</FileName>
85
91
  {size && (
86
92
  <FileSizeContainer>
87
93
  <FileSize>{formatFileSize(size)}</FileSize>
@@ -1,12 +1,18 @@
1
- import React from 'react';
2
- import { TouchableOpacity, StyleSheet } from 'react-native';
3
- import { Video, ResizeMode } from 'expo-av';
1
+ import React, { useEffect, useState } from 'react';
2
+ import { TouchableOpacity, StyleSheet, View } from 'react-native';
3
+ import { useVideoPlayer, VideoView } from 'expo-video';
4
4
  import { useDispatch } from 'react-redux';
5
5
  import {
6
6
  setActiveFile,
7
7
  setActiveModal,
8
8
  } from '../../roomStore/chatSettingsSlice';
9
9
  import { MODAL_TYPES } from '../../helpers/constants/MODAL_TYPES';
10
+ import { PlayIcon } from '../../assets/icons';
11
+ import {
12
+ defaultMediaDims,
13
+ fitMediaDimensions,
14
+ MediaDims,
15
+ } from '../../helpers/mediaDimensions';
10
16
 
11
17
  interface CustomMessageVideoProps {
12
18
  fileName: string;
@@ -20,6 +26,21 @@ const CustomMessageVideo: React.FC<CustomMessageVideoProps> = ({
20
26
  mimetype,
21
27
  }) => {
22
28
  const dispatch = useDispatch();
29
+ const [dims, setDims] = useState<MediaDims>(defaultMediaDims());
30
+
31
+ const player = useVideoPlayer(fileURL, (p) => {
32
+ p.muted = true;
33
+ });
34
+
35
+ useEffect(() => {
36
+ const sub = player.addListener('statusChange', () => {
37
+ const size = player.videoTrack?.size;
38
+ if (size?.width && size?.height) {
39
+ setDims(fitMediaDimensions(size.width, size.height));
40
+ }
41
+ });
42
+ return () => sub.remove();
43
+ }, [player]);
23
44
 
24
45
  const handleOpen = () => {
25
46
  dispatch(setActiveFile({ fileName, fileURL, mimetype }));
@@ -27,14 +48,24 @@ const CustomMessageVideo: React.FC<CustomMessageVideoProps> = ({
27
48
  };
28
49
 
29
50
  return (
30
- <TouchableOpacity style={styles.container} onPress={handleOpen}>
31
- <Video
32
- source={{ uri: fileURL }}
51
+ <TouchableOpacity
52
+ onPress={handleOpen}
53
+ activeOpacity={0.9}
54
+ style={[styles.wrapper, { width: dims.width, height: dims.height }]}
55
+ >
56
+ <VideoView
57
+ player={player}
33
58
  style={styles.video}
34
- useNativeControls
35
- resizeMode={ResizeMode.CONTAIN}
36
- shouldPlay={false}
59
+ contentFit="cover"
60
+ nativeControls={false}
61
+ surfaceType="textureView"
62
+ pointerEvents="none"
37
63
  />
64
+ <View style={styles.overlay} pointerEvents="none">
65
+ <View style={styles.playButton}>
66
+ <PlayIcon width={28} height={28} />
67
+ </View>
68
+ </View>
38
69
  </TouchableOpacity>
39
70
  );
40
71
  };
@@ -42,16 +73,26 @@ const CustomMessageVideo: React.FC<CustomMessageVideoProps> = ({
42
73
  export default CustomMessageVideo;
43
74
 
44
75
  const styles = StyleSheet.create({
45
- container: {
46
- margin: 0,
47
- alignItems: 'center',
48
- justifyContent: 'center',
49
- width: '100%',
50
- },
51
- video: {
52
- width: 300,
53
- height: 200,
76
+ wrapper: {
54
77
  borderRadius: 10,
78
+ overflow: 'hidden',
55
79
  backgroundColor: '#000',
56
80
  },
81
+ video: {
82
+ width: '100%',
83
+ height: '100%',
84
+ },
85
+ overlay: {
86
+ ...StyleSheet.absoluteFillObject,
87
+ justifyContent: 'center',
88
+ alignItems: 'center',
89
+ },
90
+ playButton: {
91
+ width: 48,
92
+ height: 48,
93
+ borderRadius: 24,
94
+ backgroundColor: 'rgba(0, 0, 0, 0.55)',
95
+ justifyContent: 'center',
96
+ alignItems: 'center',
97
+ },
57
98
  });