@ethora/chat-component-rn 26.5.21 → 26.6.11

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 (372) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +3 -3
  3. package/index.js +1 -1
  4. package/lib/commonjs/components/MainComponents/ChatHeader.js +20 -8
  5. package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
  6. package/lib/commonjs/components/MainComponents/ChatWrapper.js +17 -0
  7. package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
  8. package/lib/commonjs/components/MainComponents/LanguageSelectorButton.js +62 -0
  9. package/lib/commonjs/components/MainComponents/LanguageSelectorButton.js.map +1 -0
  10. package/lib/commonjs/components/MainComponents/LanguageSelectorModal.js +253 -0
  11. package/lib/commonjs/components/MainComponents/LanguageSelectorModal.js.map +1 -0
  12. package/lib/commonjs/components/MainComponents/MediaMessage.js +7 -1
  13. package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
  14. package/lib/commonjs/components/MainComponents/RoomList.js +23 -9
  15. package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
  16. package/lib/commonjs/components/MessageBubble/Message.js +72 -11
  17. package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
  18. package/lib/commonjs/components/MessageBubble/MessageTranslate.js +160 -0
  19. package/lib/commonjs/components/MessageBubble/MessageTranslate.js.map +1 -0
  20. package/lib/commonjs/components/MessageBubble/TranslatedMessageBody.js +59 -0
  21. package/lib/commonjs/components/MessageBubble/TranslatedMessageBody.js.map +1 -0
  22. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +3 -3
  23. package/lib/commonjs/components/UsersList/UsersList.js +3 -1
  24. package/lib/commonjs/components/UsersList/UsersList.js.map +1 -1
  25. package/lib/commonjs/components/VideoCalls/CallButtons.js +159 -0
  26. package/lib/commonjs/components/VideoCalls/CallButtons.js.map +1 -0
  27. package/lib/commonjs/components/VideoCalls/CallIcons.js +328 -0
  28. package/lib/commonjs/components/VideoCalls/CallIcons.js.map +1 -0
  29. package/lib/commonjs/components/VideoCalls/VideoCallOverlay.js +550 -0
  30. package/lib/commonjs/components/VideoCalls/VideoCallOverlay.js.map +1 -0
  31. package/lib/commonjs/components/VideoCalls/VideoCallSession.js +636 -0
  32. package/lib/commonjs/components/VideoCalls/VideoCallSession.js.map +1 -0
  33. package/lib/commonjs/components/VideoCalls/livekitRuntime.js +91 -0
  34. package/lib/commonjs/components/VideoCalls/livekitRuntime.js.map +1 -0
  35. package/lib/commonjs/components/VideoCalls/useCallKeep.js +215 -0
  36. package/lib/commonjs/components/VideoCalls/useCallKeep.js.map +1 -0
  37. package/lib/commonjs/components/styled/AudioMessage.js +91 -33
  38. package/lib/commonjs/components/styled/AudioMessage.js.map +1 -1
  39. package/lib/commonjs/components/styled/RoomListComponents/index.js +13 -1
  40. package/lib/commonjs/components/styled/RoomListComponents/index.js.map +1 -1
  41. package/lib/commonjs/components/styled/SendInput.js +83 -49
  42. package/lib/commonjs/components/styled/SendInput.js.map +1 -1
  43. package/lib/commonjs/components/styled/StyledComponents.js +9 -4
  44. package/lib/commonjs/components/styled/StyledComponents.js.map +1 -1
  45. package/lib/commonjs/components/styled/StyledInputComponents/Composing.js +2 -0
  46. package/lib/commonjs/components/styled/StyledInputComponents/Composing.js.map +1 -1
  47. package/lib/commonjs/components/styled/VideoMessage.js +110 -26
  48. package/lib/commonjs/components/styled/VideoMessage.js.map +1 -1
  49. package/lib/commonjs/context/xmppProvider.js +10 -3
  50. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  51. package/lib/commonjs/helpers/callLogMessage.js +162 -0
  52. package/lib/commonjs/helpers/callLogMessage.js.map +1 -0
  53. package/lib/commonjs/helpers/callPush.js +61 -0
  54. package/lib/commonjs/helpers/callPush.js.map +1 -0
  55. package/lib/commonjs/helpers/constants/LANGUAGE_OPTIONS.js +24 -12
  56. package/lib/commonjs/helpers/constants/LANGUAGE_OPTIONS.js.map +1 -1
  57. package/lib/commonjs/helpers/createUserNameFromSetUser.js +51 -2
  58. package/lib/commonjs/helpers/createUserNameFromSetUser.js.map +1 -1
  59. package/lib/commonjs/helpers/getDataFromXml.js +19 -1
  60. package/lib/commonjs/helpers/getDataFromXml.js.map +1 -1
  61. package/lib/commonjs/helpers/incomingCallFromPush.js +74 -0
  62. package/lib/commonjs/helpers/incomingCallFromPush.js.map +1 -0
  63. package/lib/commonjs/helpers/insertMessageWithDelimiter.js +13 -1
  64. package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
  65. package/lib/commonjs/helpers/isUnresolvedSenderId.js +32 -0
  66. package/lib/commonjs/helpers/isUnresolvedSenderId.js.map +1 -0
  67. package/lib/commonjs/hooks/useChatSettingState.js +2 -0
  68. package/lib/commonjs/hooks/useChatSettingState.js.map +1 -1
  69. package/lib/commonjs/hooks/useMessageTranslation.js +51 -0
  70. package/lib/commonjs/hooks/useMessageTranslation.js.map +1 -0
  71. package/lib/commonjs/hooks/usePushNotifications.js +13 -3
  72. package/lib/commonjs/hooks/usePushNotifications.js.map +1 -1
  73. package/lib/commonjs/hooks/useSendMessage.js +14 -4
  74. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  75. package/lib/commonjs/i18n/strings.js +1308 -0
  76. package/lib/commonjs/i18n/strings.js.map +1 -0
  77. package/lib/commonjs/i18n/useT.js +60 -0
  78. package/lib/commonjs/i18n/useT.js.map +1 -0
  79. package/lib/commonjs/main.js +44 -0
  80. package/lib/commonjs/main.js.map +1 -1
  81. package/lib/commonjs/networking/api-requests/auth.api.js +81 -52
  82. package/lib/commonjs/networking/api-requests/auth.api.js.map +1 -1
  83. package/lib/commonjs/networking/api-requests/push.api.js +34 -5
  84. package/lib/commonjs/networking/api-requests/push.api.js.map +1 -1
  85. package/lib/commonjs/networking/api-requests/rooms.api.js +108 -0
  86. package/lib/commonjs/networking/api-requests/rooms.api.js.map +1 -1
  87. package/lib/commonjs/networking/callTokenStanza.js +531 -0
  88. package/lib/commonjs/networking/callTokenStanza.js.map +1 -0
  89. package/lib/commonjs/networking/outboundQueue.js.map +1 -1
  90. package/lib/commonjs/networking/stanzaHandlers.js +75 -8
  91. package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
  92. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js +47 -11
  93. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  94. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js +2 -1
  95. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  96. package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +42 -5
  97. package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
  98. package/lib/commonjs/networking/xmppClient.js +78 -16
  99. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  100. package/lib/commonjs/roomStore/callSlice.js +144 -0
  101. package/lib/commonjs/roomStore/callSlice.js.map +1 -0
  102. package/lib/commonjs/roomStore/chatSettingsSlice.js +8 -2
  103. package/lib/commonjs/roomStore/chatSettingsSlice.js.map +1 -1
  104. package/lib/commonjs/roomStore/index.js +7 -1
  105. package/lib/commonjs/roomStore/index.js.map +1 -1
  106. package/lib/commonjs/roomStore/persistence.js +69 -5
  107. package/lib/commonjs/roomStore/persistence.js.map +1 -1
  108. package/lib/commonjs/roomStore/roomsSlice.js +136 -6
  109. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  110. package/lib/commonjs/utils/translateModePolicy.js +33 -0
  111. package/lib/commonjs/utils/translateModePolicy.js.map +1 -0
  112. package/lib/module/components/MainComponents/ChatHeader.js +20 -8
  113. package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
  114. package/lib/module/components/MainComponents/ChatWrapper.js +17 -0
  115. package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
  116. package/lib/module/components/MainComponents/LanguageSelectorButton.js +57 -0
  117. package/lib/module/components/MainComponents/LanguageSelectorButton.js.map +1 -0
  118. package/lib/module/components/MainComponents/LanguageSelectorModal.js +246 -0
  119. package/lib/module/components/MainComponents/LanguageSelectorModal.js.map +1 -0
  120. package/lib/module/components/MainComponents/MediaMessage.js +7 -1
  121. package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
  122. package/lib/module/components/MainComponents/RoomList.js +23 -9
  123. package/lib/module/components/MainComponents/RoomList.js.map +1 -1
  124. package/lib/module/components/MessageBubble/Message.js +73 -12
  125. package/lib/module/components/MessageBubble/Message.js.map +1 -1
  126. package/lib/module/components/MessageBubble/MessageTranslate.js +155 -0
  127. package/lib/module/components/MessageBubble/MessageTranslate.js.map +1 -0
  128. package/lib/module/components/MessageBubble/TranslatedMessageBody.js +53 -0
  129. package/lib/module/components/MessageBubble/TranslatedMessageBody.js.map +1 -0
  130. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +3 -3
  131. package/lib/module/components/UsersList/UsersList.js +3 -1
  132. package/lib/module/components/UsersList/UsersList.js.map +1 -1
  133. package/lib/module/components/VideoCalls/CallButtons.js +154 -0
  134. package/lib/module/components/VideoCalls/CallButtons.js.map +1 -0
  135. package/lib/module/components/VideoCalls/CallIcons.js +309 -0
  136. package/lib/module/components/VideoCalls/CallIcons.js.map +1 -0
  137. package/lib/module/components/VideoCalls/VideoCallOverlay.js +544 -0
  138. package/lib/module/components/VideoCalls/VideoCallOverlay.js.map +1 -0
  139. package/lib/module/components/VideoCalls/VideoCallSession.js +630 -0
  140. package/lib/module/components/VideoCalls/VideoCallSession.js.map +1 -0
  141. package/lib/module/components/VideoCalls/livekitRuntime.js +83 -0
  142. package/lib/module/components/VideoCalls/livekitRuntime.js.map +1 -0
  143. package/lib/module/components/VideoCalls/useCallKeep.js +210 -0
  144. package/lib/module/components/VideoCalls/useCallKeep.js.map +1 -0
  145. package/lib/module/components/styled/AudioMessage.js +91 -33
  146. package/lib/module/components/styled/AudioMessage.js.map +1 -1
  147. package/lib/module/components/styled/RoomListComponents/index.js +13 -1
  148. package/lib/module/components/styled/RoomListComponents/index.js.map +1 -1
  149. package/lib/module/components/styled/SendInput.js +83 -49
  150. package/lib/module/components/styled/SendInput.js.map +1 -1
  151. package/lib/module/components/styled/StyledComponents.js +9 -4
  152. package/lib/module/components/styled/StyledComponents.js.map +1 -1
  153. package/lib/module/components/styled/StyledInputComponents/Composing.js +2 -0
  154. package/lib/module/components/styled/StyledInputComponents/Composing.js.map +1 -1
  155. package/lib/module/components/styled/VideoMessage.js +111 -27
  156. package/lib/module/components/styled/VideoMessage.js.map +1 -1
  157. package/lib/module/context/xmppProvider.js +11 -4
  158. package/lib/module/context/xmppProvider.js.map +1 -1
  159. package/lib/module/helpers/callLogMessage.js +152 -0
  160. package/lib/module/helpers/callLogMessage.js.map +1 -0
  161. package/lib/module/helpers/callPush.js +55 -0
  162. package/lib/module/helpers/callPush.js.map +1 -0
  163. package/lib/module/helpers/constants/LANGUAGE_OPTIONS.js +24 -12
  164. package/lib/module/helpers/constants/LANGUAGE_OPTIONS.js.map +1 -1
  165. package/lib/module/helpers/createUserNameFromSetUser.js +49 -1
  166. package/lib/module/helpers/createUserNameFromSetUser.js.map +1 -1
  167. package/lib/module/helpers/getDataFromXml.js +20 -1
  168. package/lib/module/helpers/getDataFromXml.js.map +1 -1
  169. package/lib/module/helpers/incomingCallFromPush.js +70 -0
  170. package/lib/module/helpers/incomingCallFromPush.js.map +1 -0
  171. package/lib/module/helpers/insertMessageWithDelimiter.js +13 -1
  172. package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
  173. package/lib/module/helpers/isUnresolvedSenderId.js +27 -0
  174. package/lib/module/helpers/isUnresolvedSenderId.js.map +1 -0
  175. package/lib/module/hooks/useChatSettingState.js +2 -0
  176. package/lib/module/hooks/useChatSettingState.js.map +1 -1
  177. package/lib/module/hooks/useMessageTranslation.js +46 -0
  178. package/lib/module/hooks/useMessageTranslation.js.map +1 -0
  179. package/lib/module/hooks/usePushNotifications.js +13 -3
  180. package/lib/module/hooks/usePushNotifications.js.map +1 -1
  181. package/lib/module/hooks/useSendMessage.js +15 -5
  182. package/lib/module/hooks/useSendMessage.js.map +1 -1
  183. package/lib/module/i18n/strings.js +1300 -0
  184. package/lib/module/i18n/strings.js.map +1 -0
  185. package/lib/module/i18n/useT.js +55 -0
  186. package/lib/module/i18n/useT.js.map +1 -0
  187. package/lib/module/main.js +7 -1
  188. package/lib/module/main.js.map +1 -1
  189. package/lib/module/networking/api-requests/auth.api.js +80 -51
  190. package/lib/module/networking/api-requests/auth.api.js.map +1 -1
  191. package/lib/module/networking/api-requests/push.api.js +35 -5
  192. package/lib/module/networking/api-requests/push.api.js.map +1 -1
  193. package/lib/module/networking/api-requests/rooms.api.js +109 -1
  194. package/lib/module/networking/api-requests/rooms.api.js.map +1 -1
  195. package/lib/module/networking/callTokenStanza.js +526 -0
  196. package/lib/module/networking/callTokenStanza.js.map +1 -0
  197. package/lib/module/networking/outboundQueue.js.map +1 -1
  198. package/lib/module/networking/stanzaHandlers.js +76 -9
  199. package/lib/module/networking/stanzaHandlers.js.map +1 -1
  200. package/lib/module/networking/xmpp/handleStanzas.xmpp.js +48 -11
  201. package/lib/module/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  202. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js +1 -1
  203. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  204. package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +43 -5
  205. package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
  206. package/lib/module/networking/xmppClient.js +78 -16
  207. package/lib/module/networking/xmppClient.js.map +1 -1
  208. package/lib/module/roomStore/callSlice.js +130 -0
  209. package/lib/module/roomStore/callSlice.js.map +1 -0
  210. package/lib/module/roomStore/chatSettingsSlice.js +6 -1
  211. package/lib/module/roomStore/chatSettingsSlice.js.map +1 -1
  212. package/lib/module/roomStore/index.js +6 -1
  213. package/lib/module/roomStore/index.js.map +1 -1
  214. package/lib/module/roomStore/persistence.js +69 -5
  215. package/lib/module/roomStore/persistence.js.map +1 -1
  216. package/lib/module/roomStore/roomsSlice.js +134 -5
  217. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  218. package/lib/module/utils/translateModePolicy.js +27 -0
  219. package/lib/module/utils/translateModePolicy.js.map +1 -0
  220. package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
  221. package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
  222. package/lib/typescript/components/MainComponents/LanguageSelectorButton.d.ts +12 -0
  223. package/lib/typescript/components/MainComponents/LanguageSelectorButton.d.ts.map +1 -0
  224. package/lib/typescript/components/MainComponents/LanguageSelectorModal.d.ts +31 -0
  225. package/lib/typescript/components/MainComponents/LanguageSelectorModal.d.ts.map +1 -0
  226. package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
  227. package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
  228. package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
  229. package/lib/typescript/components/MessageBubble/MessageTranslate.d.ts +44 -0
  230. package/lib/typescript/components/MessageBubble/MessageTranslate.d.ts.map +1 -0
  231. package/lib/typescript/components/MessageBubble/TranslatedMessageBody.d.ts +24 -0
  232. package/lib/typescript/components/MessageBubble/TranslatedMessageBody.d.ts.map +1 -0
  233. package/lib/typescript/components/UsersList/UsersList.d.ts.map +1 -1
  234. package/lib/typescript/components/VideoCalls/CallButtons.d.ts +16 -0
  235. package/lib/typescript/components/VideoCalls/CallButtons.d.ts.map +1 -0
  236. package/lib/typescript/components/VideoCalls/CallIcons.d.ts +30 -0
  237. package/lib/typescript/components/VideoCalls/CallIcons.d.ts.map +1 -0
  238. package/lib/typescript/components/VideoCalls/VideoCallOverlay.d.ts +10 -0
  239. package/lib/typescript/components/VideoCalls/VideoCallOverlay.d.ts.map +1 -0
  240. package/lib/typescript/components/VideoCalls/VideoCallSession.d.ts +38 -0
  241. package/lib/typescript/components/VideoCalls/VideoCallSession.d.ts.map +1 -0
  242. package/lib/typescript/components/VideoCalls/livekitRuntime.d.ts +52 -0
  243. package/lib/typescript/components/VideoCalls/livekitRuntime.d.ts.map +1 -0
  244. package/lib/typescript/components/VideoCalls/useCallKeep.d.ts +32 -0
  245. package/lib/typescript/components/VideoCalls/useCallKeep.d.ts.map +1 -0
  246. package/lib/typescript/components/styled/AudioMessage.d.ts.map +1 -1
  247. package/lib/typescript/components/styled/RoomListComponents/index.d.ts.map +1 -1
  248. package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
  249. package/lib/typescript/components/styled/StyledComponents.d.ts.map +1 -1
  250. package/lib/typescript/components/styled/StyledInputComponents/Composing.d.ts.map +1 -1
  251. package/lib/typescript/components/styled/VideoMessage.d.ts +2 -0
  252. package/lib/typescript/components/styled/VideoMessage.d.ts.map +1 -1
  253. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  254. package/lib/typescript/helpers/callLogMessage.d.ts +34 -0
  255. package/lib/typescript/helpers/callLogMessage.d.ts.map +1 -0
  256. package/lib/typescript/helpers/callPush.d.ts +23 -0
  257. package/lib/typescript/helpers/callPush.d.ts.map +1 -0
  258. package/lib/typescript/helpers/constants/LANGUAGE_OPTIONS.d.ts +14 -0
  259. package/lib/typescript/helpers/constants/LANGUAGE_OPTIONS.d.ts.map +1 -1
  260. package/lib/typescript/helpers/createUserNameFromSetUser.d.ts +33 -1
  261. package/lib/typescript/helpers/createUserNameFromSetUser.d.ts.map +1 -1
  262. package/lib/typescript/helpers/getDataFromXml.d.ts.map +1 -1
  263. package/lib/typescript/helpers/incomingCallFromPush.d.ts +14 -0
  264. package/lib/typescript/helpers/incomingCallFromPush.d.ts.map +1 -0
  265. package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
  266. package/lib/typescript/helpers/isUnresolvedSenderId.d.ts +2 -0
  267. package/lib/typescript/helpers/isUnresolvedSenderId.d.ts.map +1 -0
  268. package/lib/typescript/hooks/useChatSettingState.d.ts +2 -1
  269. package/lib/typescript/hooks/useChatSettingState.d.ts.map +1 -1
  270. package/lib/typescript/hooks/useMessageTranslation.d.ts +25 -0
  271. package/lib/typescript/hooks/useMessageTranslation.d.ts.map +1 -0
  272. package/lib/typescript/hooks/usePushNotifications.d.ts.map +1 -1
  273. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  274. package/lib/typescript/i18n/strings.d.ts +16 -0
  275. package/lib/typescript/i18n/strings.d.ts.map +1 -0
  276. package/lib/typescript/i18n/useT.d.ts +34 -0
  277. package/lib/typescript/i18n/useT.d.ts.map +1 -0
  278. package/lib/typescript/main.d.ts +6 -1
  279. package/lib/typescript/main.d.ts.map +1 -1
  280. package/lib/typescript/networking/api-requests/auth.api.d.ts +27 -1
  281. package/lib/typescript/networking/api-requests/auth.api.d.ts.map +1 -1
  282. package/lib/typescript/networking/api-requests/push.api.d.ts.map +1 -1
  283. package/lib/typescript/networking/api-requests/rooms.api.d.ts +3 -0
  284. package/lib/typescript/networking/api-requests/rooms.api.d.ts.map +1 -1
  285. package/lib/typescript/networking/callTokenStanza.d.ts +14 -0
  286. package/lib/typescript/networking/callTokenStanza.d.ts.map +1 -0
  287. package/lib/typescript/networking/outboundQueue.d.ts +1 -0
  288. package/lib/typescript/networking/outboundQueue.d.ts.map +1 -1
  289. package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
  290. package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
  291. package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts +10 -0
  292. package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts.map +1 -1
  293. package/lib/typescript/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts +16 -1
  294. package/lib/typescript/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts.map +1 -1
  295. package/lib/typescript/networking/xmppClient.d.ts +1 -1
  296. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  297. package/lib/typescript/roomStore/callSlice.d.ts +39 -0
  298. package/lib/typescript/roomStore/callSlice.d.ts.map +1 -0
  299. package/lib/typescript/roomStore/chatSettingsSlice.d.ts +10 -1
  300. package/lib/typescript/roomStore/chatSettingsSlice.d.ts.map +1 -1
  301. package/lib/typescript/roomStore/index.d.ts +4 -0
  302. package/lib/typescript/roomStore/index.d.ts.map +1 -1
  303. package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
  304. package/lib/typescript/roomStore/roomsSlice.d.ts +6 -1
  305. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  306. package/lib/typescript/types/models/language.model.d.ts +1 -1
  307. package/lib/typescript/types/models/language.model.d.ts.map +1 -1
  308. package/lib/typescript/types/models/message.model.d.ts +7 -0
  309. package/lib/typescript/types/models/message.model.d.ts.map +1 -1
  310. package/lib/typescript/types/types.d.ts +135 -1
  311. package/lib/typescript/types/types.d.ts.map +1 -1
  312. package/lib/typescript/utils/translateModePolicy.d.ts +20 -0
  313. package/lib/typescript/utils/translateModePolicy.d.ts.map +1 -0
  314. package/package.json +20 -4
  315. package/src/components/MainComponents/ChatHeader.tsx +30 -9
  316. package/src/components/MainComponents/ChatWrapper.tsx +15 -0
  317. package/src/components/MainComponents/LanguageSelectorButton.tsx +53 -0
  318. package/src/components/MainComponents/LanguageSelectorModal.tsx +276 -0
  319. package/src/components/MainComponents/MediaMessage.tsx +5 -0
  320. package/src/components/MainComponents/RoomList.tsx +27 -9
  321. package/src/components/MessageBubble/Message.tsx +109 -17
  322. package/src/components/MessageBubble/MessageTranslate.tsx +182 -0
  323. package/src/components/MessageBubble/TranslatedMessageBody.tsx +59 -0
  324. package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +3 -3
  325. package/src/components/UsersList/UsersList.tsx +3 -1
  326. package/src/components/VideoCalls/CallButtons.tsx +171 -0
  327. package/src/components/VideoCalls/CallIcons.tsx +246 -0
  328. package/src/components/VideoCalls/VideoCallOverlay.tsx +627 -0
  329. package/src/components/VideoCalls/VideoCallSession.tsx +675 -0
  330. package/src/components/VideoCalls/livekitRuntime.ts +100 -0
  331. package/src/components/VideoCalls/useCallKeep.ts +252 -0
  332. package/src/components/styled/AudioMessage.tsx +97 -37
  333. package/src/components/styled/RoomListComponents/index.tsx +15 -3
  334. package/src/components/styled/SendInput.tsx +94 -51
  335. package/src/components/styled/StyledComponents.ts +9 -6
  336. package/src/components/styled/StyledInputComponents/Composing.tsx +7 -1
  337. package/src/components/styled/VideoMessage.tsx +114 -20
  338. package/src/context/xmppProvider.tsx +14 -1
  339. package/src/helpers/callLogMessage.ts +174 -0
  340. package/src/helpers/callPush.ts +90 -0
  341. package/src/helpers/constants/LANGUAGE_OPTIONS.ts +20 -5
  342. package/src/helpers/createUserNameFromSetUser.ts +68 -2
  343. package/src/helpers/getDataFromXml.ts +40 -4
  344. package/src/helpers/incomingCallFromPush.ts +83 -0
  345. package/src/helpers/insertMessageWithDelimiter.ts +27 -9
  346. package/src/helpers/isUnresolvedSenderId.ts +25 -0
  347. package/src/hooks/useChatSettingState.tsx +4 -0
  348. package/src/hooks/useMessageTranslation.ts +70 -0
  349. package/src/hooks/usePushNotifications.ts +15 -3
  350. package/src/hooks/useSendMessage.tsx +18 -5
  351. package/src/i18n/strings.ts +1322 -0
  352. package/src/i18n/useT.ts +56 -0
  353. package/src/main.ts +18 -1
  354. package/src/networking/api-requests/auth.api.ts +79 -44
  355. package/src/networking/api-requests/push.api.ts +39 -8
  356. package/src/networking/api-requests/rooms.api.ts +109 -1
  357. package/src/networking/callTokenStanza.ts +636 -0
  358. package/src/networking/outboundQueue.ts +1 -0
  359. package/src/networking/stanzaHandlers.ts +74 -15
  360. package/src/networking/xmpp/handleStanzas.xmpp.ts +52 -11
  361. package/src/networking/xmpp/sendTextMessage.xmpp.ts +1 -1
  362. package/src/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.ts +41 -5
  363. package/src/networking/xmppClient.ts +97 -28
  364. package/src/roomStore/callSlice.ts +190 -0
  365. package/src/roomStore/chatSettingsSlice.ts +16 -0
  366. package/src/roomStore/index.ts +5 -0
  367. package/src/roomStore/persistence.ts +103 -3
  368. package/src/roomStore/roomsSlice.ts +149 -4
  369. package/src/types/models/language.model.ts +17 -1
  370. package/src/types/models/message.model.ts +9 -0
  371. package/src/types/types.ts +142 -2
  372. package/src/utils/translateModePolicy.ts +31 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ethora/chat-component-rn",
3
- "version": "26.5.21",
3
+ "version": "26.6.11",
4
4
  "description": "Drop-in XMPP chat component for React Native / Expo. <Chat config={...}/> and you're done.",
5
5
  "main": "index.js",
6
6
  "module": "lib/module/main.js",
@@ -43,9 +43,11 @@
43
43
  ]
44
44
  },
45
45
  "peerDependencies": {
46
+ "@livekit/react-native": ">=2.7.0",
47
+ "@livekit/react-native-webrtc": ">=125.0.0",
46
48
  "@react-native-async-storage/async-storage": ">=1.21.0",
47
49
  "@react-native-community/netinfo": ">=11.0.0",
48
- "expo-av": ">=15.0.0",
50
+ "expo-audio": ">=1.0.0",
49
51
  "expo-clipboard": ">=7.0.0",
50
52
  "expo-document-picker": ">=13.0.0",
51
53
  "expo-file-system": ">=19.0.0",
@@ -56,12 +58,22 @@
56
58
  "expo-video": ">=2.0.0",
57
59
  "react": ">=18.0.0",
58
60
  "react-native": ">=0.73.0",
61
+ "react-native-callkeep": ">=4.3.0",
59
62
  "react-native-gesture-handler": ">=2.0.0",
60
63
  "react-native-get-random-values": ">=1.10.0",
61
64
  "react-native-reanimated": ">=3.0.0",
62
65
  "react-native-svg": ">=14.0.0"
63
66
  },
64
67
  "peerDependenciesMeta": {
68
+ "@livekit/react-native": {
69
+ "optional": true
70
+ },
71
+ "@livekit/react-native-webrtc": {
72
+ "optional": true
73
+ },
74
+ "react-native-callkeep": {
75
+ "optional": true
76
+ },
65
77
  "react-native-svg": {
66
78
  "optional": false
67
79
  },
@@ -77,7 +89,7 @@
77
89
  "react-native-gesture-handler": {
78
90
  "optional": true
79
91
  },
80
- "expo-av": {
92
+ "expo-audio": {
81
93
  "optional": true
82
94
  },
83
95
  "expo-clipboard": {
@@ -136,6 +148,8 @@
136
148
  "@babel/core": "^7.25.2",
137
149
  "@babel/preset-env": "^7.25.3",
138
150
  "@babel/runtime": "^7.25.0",
151
+ "@livekit/react-native": "2.7.6",
152
+ "@livekit/react-native-webrtc": "125.0.11",
139
153
  "@react-native-async-storage/async-storage": "2.2.0",
140
154
  "@react-native-community/netinfo": "11.4.1",
141
155
  "@types/jest": "^29.5.12",
@@ -145,7 +159,7 @@
145
159
  "eslint": "^8.19.0",
146
160
  "eslint-config-expo": "~9.2.0",
147
161
  "expo": "~54.0.0",
148
- "expo-av": "~16.0.8",
162
+ "expo-audio": "~1.1.1",
149
163
  "expo-build-properties": "^55.0.14",
150
164
  "expo-clipboard": "~8.0.8",
151
165
  "expo-document-picker": "~14.0.0",
@@ -156,11 +170,13 @@
156
170
  "expo-video": "~3.0.16",
157
171
  "jest": "^29.6.3",
158
172
  "jest-expo": "~54.0.0",
173
+ "livekit-client": "2.9.0",
159
174
  "patch-package": "^8.0.1",
160
175
  "prettier": "2.8.8",
161
176
  "react": "19.1.0",
162
177
  "react-native": "0.81.5",
163
178
  "react-native-builder-bob": "^0.41.0",
179
+ "react-native-callkeep": "4.3.16",
164
180
  "react-native-gesture-handler": "~2.28.0",
165
181
  "react-native-get-random-values": "~1.11.0",
166
182
  "react-native-reanimated": "~4.1.0",
@@ -13,6 +13,8 @@ import { IRoom } from '../../types/types';
13
13
  import { ProfileImagePlaceholder } from './ProfileImagePlaceholder';
14
14
  import Button from '../styled/Button';
15
15
  import { BackIcon, BurgerMenuIcon } from '../../assets/icons';
16
+ import { CallButtons } from '../VideoCalls/CallButtons';
17
+ import { LanguageSelectorButton } from './LanguageSelectorButton';
16
18
  import { useDispatch } from 'react-redux';
17
19
  import Composing from '../styled/StyledInputComponents/Composing';
18
20
  import {
@@ -30,6 +32,7 @@ import { View, StyleSheet, Text, Keyboard } from 'react-native';
30
32
  import { getIconColor } from '../../helpers/getIconColor';
31
33
  import { resolveHeaderHeight } from '../../helpers/headerLayout';
32
34
  import { getElementFont } from '../../helpers/getElementFont';
35
+ import { useT } from '../../i18n/useT';
33
36
 
34
37
  interface ChatHeaderProps {
35
38
  currentRoom: IRoom;
@@ -47,6 +50,7 @@ const ChatHeader: React.FC<ChatHeaderProps> = ({
47
50
  const roomState = useRoomState(currentRoom.jid).room;
48
51
  const composing = roomState?.composing;
49
52
  const { config } = useChatSettingState();
53
+ const t = useT();
50
54
 
51
55
  const handleChangeChat = (chat: IRoom) => {
52
56
  dispatch(setCurrentRoom({ roomJID: chat.jid }));
@@ -172,7 +176,14 @@ const ChatHeader: React.FC<ChatHeaderProps> = ({
172
176
  <ChatContainerHeaderLabel
173
177
  style={[styles.subLabel, getElementFont(config, 'headerSubtitle')]}
174
178
  >
175
- <Text>{`${currentRoom?.usersCnt} users`}</Text>
179
+ <Text>
180
+ {t(
181
+ Number(currentRoom?.usersCnt) === 1
182
+ ? 'header.userCountSingular'
183
+ : 'header.userCountPlural',
184
+ { count: Number(currentRoom?.usersCnt) || 0 }
185
+ )}
186
+ </Text>
176
187
  </ChatContainerHeaderLabel>
177
188
  )}
178
189
  </View>
@@ -180,13 +191,15 @@ const ChatHeader: React.FC<ChatHeaderProps> = ({
180
191
  </ChatContainerHeaderBoxInfo>
181
192
  </CenterContainer>
182
193
 
183
- {!config?.disableChatInfo?.disableRoomMenu ? (
184
- <View style={styles.rightContainer}>
194
+ <View style={styles.rightContainer}>
195
+ {/* Renders nothing unless config.videoCalls is on and this is a
196
+ 1:1 room, so it costs non-call hosts nothing. */}
197
+ <LanguageSelectorButton />
198
+ <CallButtons />
199
+ {!config?.disableChatInfo?.disableRoomMenu && (
185
200
  <RoomMenu handleLeaveClick={handleLeaveClick} />
186
- </View>
187
- ) : (
188
- <View style={styles.rightContainer} />
189
- )}
201
+ )}
202
+ </View>
190
203
  </ChatContainerHeader>
191
204
  {config?.chatHeaderAdditional?.enabled &&
192
205
  config.chatHeaderAdditional.element()}
@@ -209,8 +222,16 @@ const styles = StyleSheet.create({
209
222
  width: '15%',
210
223
  },
211
224
  rightContainer: {
212
- alignItems: 'flex-end',
213
- width: '15%',
225
+ flexDirection: 'row',
226
+ alignItems: 'center',
227
+ justifyContent: 'flex-end',
228
+ gap: 4,
229
+ // Sized to its icons rather than a fixed 25%: the cluster is 1 to 4
230
+ // icons depending on config (globe, audio call, video call, room menu),
231
+ // and a fixed share either cramped them together or reserved dead space
232
+ // that the title could have used. `flexShrink: 0` keeps them intact
233
+ // while CenterContainer (flex:1, min-width:0) absorbs the difference.
234
+ flexShrink: 0,
214
235
  },
215
236
  });
216
237
 
@@ -129,6 +129,21 @@ const ChatWrapper: FC<ChatWrapperProps> = ({
129
129
  client.setActiveRoomJid?.(activeRoomJID || null);
130
130
  }, [client, activeRoomJID]);
131
131
 
132
+ // Pull the MUC roster as soon as a room opens (not just when the
133
+ // profile modal is opened — see ChatProfileModal). Message sender
134
+ // names fall back to the raw jid when a message doesn't carry its
135
+ // own senderFirstName/senderLastName, and that fallback depends on
136
+ // usersSet being populated; without this, any room the reader hasn't
137
+ // separately opened the profile modal for shows jids instead of names.
138
+ useEffect(() => {
139
+ if (!client || !activeRoomJID) {return;}
140
+ try {
141
+ client.getRoomMembersStanza?.(activeRoomJID);
142
+ } catch {
143
+ /* non-fatal */
144
+ }
145
+ }, [client, activeRoomJID]);
146
+
132
147
  const seededRoomJID = useMemo(
133
148
  () =>
134
149
  roomJID
@@ -0,0 +1,53 @@
1
+ import React, { FC, useState } from 'react';
2
+ import { StyleSheet, TouchableOpacity } from 'react-native';
3
+ import { useChatSettingState } from '../../hooks/useChatSettingState';
4
+ import { getIconColor } from '../../helpers/getIconColor';
5
+ import { useT } from '../../i18n/useT';
6
+ import { GlobeIcon, LanguageSelectorModal } from './LanguageSelectorModal';
7
+
8
+ /**
9
+ * Globe button in the chat header that opens the reader's language picker.
10
+ *
11
+ * Renders only when translation is on. A host that drives the reader's
12
+ * language from its own settings screen (via `config.translates
13
+ * .readerLocale`) can hide this with `showLanguageSelector: false` rather
14
+ * than shipping two competing controls.
15
+ */
16
+ export const LanguageSelectorButton: FC = () => {
17
+ const { config } = useChatSettingState();
18
+ const t = useT();
19
+ const [open, setOpen] = useState(false);
20
+
21
+ const translates = config?.translates;
22
+ const enabled = Boolean(translates?.enabled || config?.enableTranslates);
23
+ if (!enabled || translates?.showLanguageSelector === false) {
24
+ return null;
25
+ }
26
+
27
+ return (
28
+ <>
29
+ <TouchableOpacity
30
+ accessibilityRole="button"
31
+ accessibilityLabel={t('language.select')}
32
+ onPress={() => setOpen(true)}
33
+ style={styles.button}
34
+ hitSlop={8}
35
+ >
36
+ <GlobeIcon color={getIconColor(config)} size={20} />
37
+ </TouchableOpacity>
38
+ <LanguageSelectorModal visible={open} onClose={() => setOpen(false)} />
39
+ </>
40
+ );
41
+ };
42
+
43
+ const styles = StyleSheet.create({
44
+ button: {
45
+ width: 36,
46
+ height: 36,
47
+ borderRadius: 18,
48
+ alignItems: 'center',
49
+ justifyContent: 'center',
50
+ },
51
+ });
52
+
53
+ export default LanguageSelectorButton;
@@ -0,0 +1,276 @@
1
+ import React, { FC, useCallback } from 'react';
2
+ import {
3
+ Modal,
4
+ Pressable,
5
+ ScrollView,
6
+ StyleSheet,
7
+ Text,
8
+ TouchableOpacity,
9
+ View,
10
+ } from 'react-native';
11
+ import Svg, { Circle, Path } from 'react-native-svg';
12
+ import { useDispatch } from 'react-redux';
13
+ import {
14
+ setLangSource,
15
+ setTranslateMode,
16
+ } from '../../roomStore/chatSettingsSlice';
17
+ import { useChatSettingState } from '../../hooks/useChatSettingState';
18
+ import { LANGUAGE_OPTIONS } from '../../helpers/constants/LANGUAGE_OPTIONS';
19
+ import { Iso639_1Codes } from '../../types/models/language.model';
20
+ import {
21
+ canReaderChooseTranslateMode,
22
+ resolveTranslateMode,
23
+ } from '../../utils/translateModePolicy';
24
+ import { useT } from '../../i18n/useT';
25
+ import { toBaseLanguage } from '../../i18n/strings';
26
+ import { getIconColor } from '../../helpers/getIconColor';
27
+
28
+ const TEXT_PRIMARY = '#141414';
29
+ const TEXT_MUTED = '#8C8C8C';
30
+ const DIVIDER = '#F0F0F0';
31
+
32
+ /**
33
+ * Ported verbatim from the web SDK's GlobeIcon (src/assets/icons.tsx) so
34
+ * both platforms draw the same mark. The previous RN shape was hand-rolled
35
+ * on a 24-box with two mirrored beziers whose meridian bulged only ~21% of
36
+ * the radius, which collapsed into a thin lens rather than reading as a
37
+ * sphere.
38
+ */
39
+ export const GlobeIcon: FC<{ color?: string; size?: number }> = ({
40
+ color = '#8C8C8C',
41
+ size = 20,
42
+ }) => (
43
+ <Svg width={size} height={size} viewBox="0 0 20 20" fill="none">
44
+ <Circle cx="10" cy="10" r="7.5" stroke={color} strokeWidth={1.5} />
45
+ <Path
46
+ d="M2.5 10h15M10 2.5c2 2.1 3 4.7 3 7.5s-1 5.4-3 7.5c-2-2.1-3-4.7-3-7.5s1-5.4 3-7.5Z"
47
+ stroke={color}
48
+ strokeWidth={1.5}
49
+ strokeLinecap="round"
50
+ strokeLinejoin="round"
51
+ fill="none"
52
+ />
53
+ </Svg>
54
+ );
55
+
56
+ /**
57
+ * The reader's language control.
58
+ *
59
+ * One switch drives two things on purpose: the language messages get
60
+ * translated INTO, and (through useT falling back to `langSource`) the
61
+ * language the interface itself is in. A reader who picks Français expects
62
+ * the whole chat in French, not French messages inside an English UI.
63
+ *
64
+ * The auto/manual switcher only renders when the host hasn't pinned
65
+ * `config.translates.forceType`, and the language list only when
66
+ * `showLanguageList` isn't false, for hosts that drive the reader's
67
+ * language from their own settings screen via `readerLocale`.
68
+ */
69
+ export const LanguageSelectorModal: FC<{
70
+ visible: boolean;
71
+ onClose: () => void;
72
+ }> = ({ visible, onClose }) => {
73
+ const dispatch = useDispatch();
74
+ const t = useT();
75
+ const { config, langSource, translateMode } = useChatSettingState();
76
+
77
+ const translates = config?.translates;
78
+ const effectiveMode = resolveTranslateMode(translates, translateMode);
79
+ const showModeSwitcher = canReaderChooseTranslateMode(translates);
80
+ const showLanguageList = translates?.showLanguageList !== false;
81
+ const activeLocale = translates?.readerLocale || langSource;
82
+
83
+ const selectLanguage = useCallback(
84
+ (id: Iso639_1Codes) => {
85
+ dispatch(setLangSource(id));
86
+ onClose();
87
+ },
88
+ [dispatch, onClose]
89
+ );
90
+
91
+ return (
92
+ <Modal
93
+ visible={visible}
94
+ transparent
95
+ animationType="fade"
96
+ onRequestClose={onClose}
97
+ >
98
+ {/* Backdrop closes on tap; the card swallows the press so a tap
99
+ inside it doesn't dismiss. */}
100
+ <Pressable style={styles.backdrop} onPress={onClose}>
101
+ <Pressable style={styles.card} onPress={() => {}}>
102
+ <Text style={styles.title}>{t('language.select')}</Text>
103
+
104
+ {showModeSwitcher && (
105
+ <View style={styles.section}>
106
+ <Text style={styles.sectionLabel}>
107
+ {t('translation.modeLabel')}
108
+ </Text>
109
+ <View style={styles.segmented}>
110
+ {(['auto', 'manual'] as const).map((mode) => {
111
+ const selected = effectiveMode === mode;
112
+ return (
113
+ <TouchableOpacity
114
+ key={mode}
115
+ accessibilityRole="radio"
116
+ accessibilityState={{ selected }}
117
+ onPress={() => dispatch(setTranslateMode(mode))}
118
+ style={[
119
+ styles.segment,
120
+ selected && styles.segmentSelected,
121
+ ]}
122
+ >
123
+ <Text
124
+ style={[
125
+ styles.segmentText,
126
+ selected && styles.segmentTextSelected,
127
+ ]}
128
+ >
129
+ {mode === 'auto'
130
+ ? t('translation.modeAuto')
131
+ : t('translation.modeManual')}
132
+ </Text>
133
+ </TouchableOpacity>
134
+ );
135
+ })}
136
+ </View>
137
+ </View>
138
+ )}
139
+
140
+ {showLanguageList && (
141
+ <View style={styles.section}>
142
+ <Text style={styles.sectionLabel}>{t('language.select')}</Text>
143
+ <ScrollView style={styles.list}>
144
+ {LANGUAGE_OPTIONS.map((option) => {
145
+ // Compare on the base language so a reader on "fr" still
146
+ // sees "Français" (id fr-CA) ticked.
147
+ const selected =
148
+ !!activeLocale &&
149
+ toBaseLanguage(activeLocale) === toBaseLanguage(option.id);
150
+ return (
151
+ <TouchableOpacity
152
+ key={option.id}
153
+ accessibilityRole="radio"
154
+ accessibilityState={{ selected }}
155
+ onPress={() => selectLanguage(option.id)}
156
+ style={styles.listRow}
157
+ >
158
+ <Text
159
+ style={[
160
+ styles.listRowText,
161
+ selected && styles.listRowTextSelected,
162
+ ]}
163
+ >
164
+ {option.name}
165
+ </Text>
166
+ {selected && (
167
+ <Text
168
+ style={[
169
+ styles.check,
170
+ { color: getIconColor(config) },
171
+ ]}
172
+ >
173
+ ✓
174
+ </Text>
175
+ )}
176
+ </TouchableOpacity>
177
+ );
178
+ })}
179
+ </ScrollView>
180
+ </View>
181
+ )}
182
+
183
+ <TouchableOpacity onPress={onClose} style={styles.closeButton}>
184
+ <Text style={[styles.closeText, { color: getIconColor(config) }]}>
185
+ {t('action.cancel')}
186
+ </Text>
187
+ </TouchableOpacity>
188
+ </Pressable>
189
+ </Pressable>
190
+ </Modal>
191
+ );
192
+ };
193
+
194
+ const styles = StyleSheet.create({
195
+ backdrop: {
196
+ flex: 1,
197
+ backgroundColor: 'rgba(0,0,0,0.4)',
198
+ alignItems: 'center',
199
+ justifyContent: 'center',
200
+ padding: 24,
201
+ },
202
+ card: {
203
+ width: '100%',
204
+ maxWidth: 420,
205
+ maxHeight: '80%',
206
+ backgroundColor: '#fff',
207
+ borderRadius: 20,
208
+ padding: 20,
209
+ gap: 16,
210
+ },
211
+ title: {
212
+ fontSize: 18,
213
+ color: TEXT_PRIMARY,
214
+ },
215
+ section: {
216
+ gap: 8,
217
+ },
218
+ sectionLabel: {
219
+ fontSize: 13,
220
+ color: TEXT_MUTED,
221
+ },
222
+ segmented: {
223
+ flexDirection: 'row',
224
+ borderRadius: 12,
225
+ backgroundColor: '#F5F7F9',
226
+ padding: 4,
227
+ gap: 4,
228
+ },
229
+ segment: {
230
+ flex: 1,
231
+ paddingVertical: 10,
232
+ borderRadius: 9,
233
+ alignItems: 'center',
234
+ },
235
+ segmentSelected: {
236
+ backgroundColor: '#fff',
237
+ },
238
+ segmentText: {
239
+ fontSize: 14,
240
+ color: TEXT_MUTED,
241
+ },
242
+ segmentTextSelected: {
243
+ color: TEXT_PRIMARY,
244
+ fontWeight: '600',
245
+ },
246
+ list: {
247
+ maxHeight: 260,
248
+ },
249
+ listRow: {
250
+ flexDirection: 'row',
251
+ alignItems: 'center',
252
+ justifyContent: 'space-between',
253
+ paddingVertical: 14,
254
+ borderBottomWidth: 1,
255
+ borderBottomColor: DIVIDER,
256
+ },
257
+ listRowText: {
258
+ fontSize: 16,
259
+ color: TEXT_PRIMARY,
260
+ },
261
+ listRowTextSelected: {
262
+ fontWeight: '600',
263
+ },
264
+ check: {
265
+ fontSize: 16,
266
+ },
267
+ closeButton: {
268
+ alignItems: 'center',
269
+ paddingVertical: 12,
270
+ },
271
+ closeText: {
272
+ fontSize: 15,
273
+ },
274
+ });
275
+
276
+ export default LanguageSelectorModal;
@@ -183,6 +183,11 @@ const MediaMessage: React.FC<MediaMessageProps> = ({
183
183
  <CustomMessageVideo
184
184
  fileName={displayName}
185
185
  fileURL={location || ''}
186
+ // `messageText` is the message's locationPreview — the poster
187
+ // frame the backend generated for this video. Handing it over
188
+ // lets the bubble render as a still + play badge instead of
189
+ // mounting a video surface per row (see VideoMessage).
190
+ previewURL={messageText}
186
191
  mimetype={mimeType}
187
192
  />
188
193
  );
@@ -25,6 +25,7 @@ import Button from '../styled/Button';
25
25
  import { HeaderRoomList } from '../Header/HeaderRoomList';
26
26
  import { HeaderRoomListMenu } from '../Menu/HeaderRoomListMenu';
27
27
  import { getIconColor } from '../../helpers/getIconColor';
28
+ import { useT } from '../../i18n/useT';
28
29
 
29
30
  const LONG_PRESS_THRESHOLD = 200;
30
31
 
@@ -40,6 +41,7 @@ const RoomList: React.FC<RoomListProps> = ({
40
41
  onRoomClick,
41
42
  }) => {
42
43
  const { config } = useChatSettingState();
44
+ const t = useT();
43
45
 
44
46
  const [open, setOpen] = useState(false);
45
47
  const [searchTerm, setSearchTerm] = useState('');
@@ -178,6 +180,20 @@ const RoomList: React.FC<RoomListProps> = ({
178
180
  <>
179
181
  <View style={styles.scrollContainer}>
180
182
  <HeaderRoomList setDrawerOpen={toggleDrawer} />
183
+ {/* Search sits ABOVE the list rather than in its
184
+ ListHeaderComponent. As a list header it was simply the
185
+ first scrolling row, so the moment you scrolled the rooms
186
+ it slid up and disappeared behind the opaque header band.
187
+ Fixed here it stays reachable, which is the entire point
188
+ of a search field over a long list. */}
189
+ <View style={styles.searchBar}>
190
+ <SearchInput
191
+ icon={<SearchIcon height={20} />}
192
+ value={searchTerm}
193
+ onChangeText={handleSearchChange}
194
+ placeholder={t('search.placeholder')}
195
+ />
196
+ </View>
181
197
  <FlatList
182
198
  data={filteredChats}
183
199
  keyExtractor={(item) => item.jid}
@@ -195,14 +211,6 @@ const RoomList: React.FC<RoomListProps> = ({
195
211
  <ChatRoomItem chat={item} config={config} />
196
212
  </Pressable>
197
213
  )}
198
- ListHeaderComponent={
199
- <SearchInput
200
- icon={<SearchIcon height={20} />}
201
- value={searchTerm}
202
- onChangeText={handleSearchChange}
203
- placeholder="Search..."
204
- />
205
- }
206
214
  style={styles.chatList}
207
215
  />
208
216
 
@@ -241,9 +249,19 @@ const styles = StyleSheet.create({
241
249
  padding: 16,
242
250
  justifyContent: 'space-between',
243
251
  },
252
+ searchBar: {
253
+ // `row` matters: SearchInputWrapper is `flex: 1` plus a fixed 44px
254
+ // height. In a column parent that flex resolves VERTICALLY against a
255
+ // parent with no height of its own and collapses the field to nothing
256
+ // but its magnifier. As a row it resolves to width, which is what it
257
+ // meant back when the field was a list-header child.
258
+ flexDirection: 'row',
259
+ paddingTop: 8,
260
+ paddingHorizontal: 16,
261
+ backgroundColor: '#FAFAFA',
262
+ },
244
263
  chatList: {
245
264
  flex: 1,
246
- paddingTop: 8,
247
265
  paddingHorizontal: 16,
248
266
  backgroundColor: '#FAFAFA',
249
267
  },