@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
@@ -0,0 +1,56 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ import { useChatSettingState } from '../hooks/useChatSettingState';
3
+ import { interpolate, resolveStringTable } from './strings';
4
+
5
+ /**
6
+ * UI translation hook. Reads the active locale + host overrides from
7
+ * `config.i18n` and returns a `t(key, vars?)` function.
8
+ *
9
+ * const t = useT();
10
+ * <SearchInput placeholder={t('search.placeholder')} />
11
+ * <span>{t('presence.onlineCount', { count })}</span>
12
+ *
13
+ * Locale resolves to the base language for captions (region is only used for
14
+ * message translation). Missing keys fall back to English, then to the raw
15
+ * key, so nothing ever renders blank.
16
+ *
17
+ * When the host doesn't set `config.i18n.locale` explicitly, this falls
18
+ * back to `langSource` - the same reader-language state the in-chat globe
19
+ * picker (LanguageSelectorButton) and `config.translates.readerLocale`
20
+ * drive (see useChatWrapperInit's resolveExternalReaderLocaleLangSource).
21
+ * So picking a language in the chat changes both message translations AND
22
+ * static captions together, as one language switch, unless the host is
23
+ * explicitly managing UI locale separately via `config.i18n.locale`.
24
+ */
25
+ /**
26
+ * The locale the UI is currently in, resolved by the same rule useT uses
27
+ * (explicit `config.i18n.locale`, else the reader's `langSource`).
28
+ *
29
+ * For anything Intl already localises - dates, numbers, relative times -
30
+ * where you need the locale itself rather than a string from the table.
31
+ * Without it components reach for a hardcoded 'en-US' and quietly render
32
+ * American dates under a Chinese UI (DateLabel did exactly that).
33
+ * Undefined means "no explicit choice", which Intl reads as the browser's
34
+ * own locale - the right default.
35
+ */
36
+ export const useUiLocale = (): string | undefined => {
37
+ const { config, langSource } = useChatSettingState();
38
+ return config?.i18n?.locale || langSource || undefined;
39
+ };
40
+
41
+ export const useT = () => {
42
+ const { config, langSource } = useChatSettingState();
43
+ const locale = config?.i18n?.locale || langSource;
44
+ const overrides = config?.i18n?.strings;
45
+
46
+ const table = useMemo(
47
+ () => resolveStringTable(locale, overrides),
48
+ [locale, overrides]
49
+ );
50
+
51
+ return useCallback(
52
+ (key: string, vars?: Record<string, string | number>): string =>
53
+ interpolate(table[key] ?? key, vars),
54
+ [table]
55
+ );
56
+ };
package/src/main.ts CHANGED
@@ -32,9 +32,22 @@ export { useChatRoomFocus } from './hooks/useChatRoomFocus';
32
32
  export { logoutService } from './hooks/useLogout';
33
33
  export { useQRCodeChat, handleQRChatId } from './hooks/useQRCodeChatHandler';
34
34
  export { resendMessage } from './utils/resendMessage';
35
- // Font loader — exposed so hosts can also load the font outside <Chat> if needed.
35
+ // Font loader, exposed so hosts can also load the font outside <Chat> if needed.
36
36
  export { useChatFonts } from './hooks/useChatFonts';
37
37
 
38
+ // Static UI i18n. `useT` is the in-component hook; `translateKey` is the
39
+ // one-shot for helpers outside React. Hosts extend or override any caption
40
+ // through `config.i18n.strings`, keyed by the same keys BUILTIN_STRINGS uses.
41
+ export { useT, useUiLocale } from './i18n/useT';
42
+ export {
43
+ BUILTIN_STRINGS,
44
+ DEFAULT_UI_LANGUAGE,
45
+ resolveStringTable,
46
+ toBaseLanguage,
47
+ translateKey,
48
+ } from './i18n/strings';
49
+ export type { UiStringTable } from './i18n/strings';
50
+
38
51
  // Public types — needed so consumers can type their `config` prop and
39
52
  // any event handlers they pass in.
40
53
  export type {
@@ -48,4 +61,8 @@ export type {
48
61
  TypographyConfig,
49
62
  RNFontSource,
50
63
  ChatTextStyle,
64
+ VideoCallsConfig,
65
+ VideoCallIcons,
51
66
  } from './types/types';
67
+ export type { Iso639_1Codes } from './types/models/language.model';
68
+ export type { TranslateMode } from './utils/translateModePolicy';
@@ -144,55 +144,90 @@ export function uploadFile(formData: FormData) {
144
144
  });
145
145
  }
146
146
 
147
- export async function uploadFileViaFetch(formData: FormData): Promise<{ data: any }> {
147
+ const UPLOAD_PATH = '/files/';
148
+
149
+ /**
150
+ * Multipart upload of a picked file, sent over `XMLHttpRequest`.
151
+ *
152
+ * The transport matters here, and both obvious alternatives are wrong:
153
+ *
154
+ * - `fetch`. Expo SDK 54 shipped a WinterCG-compliant fetch and SDK 57
155
+ * installs it as the GLOBAL fetch. It accepts only `Blob` / `File` /
156
+ * string form parts, so React Native's own `{ uri, type, name }` part
157
+ * — which is exactly what an image/document picker hands us — is
158
+ * rejected with "Unsupported FormDataPart implementation", surfacing
159
+ * to the caller as ERR_NETWORK. A host can set
160
+ * `EXPO_PUBLIC_USE_RN_FETCH=1`, but that opts their whole app out of
161
+ * Expo's fetch just to satisfy this SDK; not a cost we get to impose
162
+ * on a consumer.
163
+ * - axios. It forces its own `Content-Type: multipart/form-data`
164
+ * WITHOUT a boundary, so the server mis-parses one file as many and
165
+ * answers HTTP 413 TOO_MANY_FILES (bug #10 — this is why the upload
166
+ * was moved off axios in the first place).
167
+ *
168
+ * `XMLHttpRequest` avoids both. Expo replaces `fetch`, not `XHR`, so the
169
+ * request still goes through React Native's native networking module,
170
+ * which understands the `{ uri, type, name }` part, streams the file
171
+ * straight from disk (a 50MB video never lands in JS memory) and writes
172
+ * its own `Content-Type` with a valid boundary — which is precisely why
173
+ * we must NOT set that header ourselves below.
174
+ */
175
+ export function uploadFileMultipart(formData: FormData): Promise<{ data: any }> {
148
176
  const token = store.getState().chatSettingStore?.user?.token ?? '';
149
177
  const baseUrl = getCurrentBaseURL();
150
- const url = `${baseUrl.replace(/\/$/, '')}/files/`;
178
+ const url = `${baseUrl.replace(/\/$/, '')}${UPLOAD_PATH}`;
151
179
 
152
- pushLog('http', `→ POST ${url} (fetch)`, {
180
+ pushLog('http', `→ POST ${url} (xhr)`, {
153
181
  headers: { Authorization: token ? token.slice(0, 16) + '…' : '[empty]', Accept: '*/*' },
154
182
  });
155
183
 
156
- let res: Response;
157
- try {
158
- res = await fetch(url, {
159
- method: 'POST',
160
- headers: {
161
- Authorization: token,
162
- Accept: '*/*',
163
- },
164
- body: formData as any,
165
- });
166
- } catch (e: any) {
167
- pushLog('http', `← ERR fetch /files/`, {
168
- name: e?.name,
169
- message: e?.message,
170
- stack: e?.stack,
171
- });
172
- const err: any = new Error(e?.message || 'Network request failed');
173
- err.code = 'ERR_NETWORK';
174
- err.cause = e;
175
- err.config = { url: '/files/' };
176
- throw err;
177
- }
178
-
179
- if (!res.ok) {
180
- let body: any = null;
181
- try {
182
- body = await res.json();
183
- } catch {
184
- try { body = await res.text(); } catch { body = null; }
185
- }
186
- pushLog('http', `← ${res.status} POST /files/ (fetch)`, body);
187
- const err: any = new Error(`Upload failed: ${res.status}`);
188
- err.response = { status: res.status, statusText: res.statusText, data: body };
189
- err.config = { url: '/files/' };
190
- throw err;
191
- }
192
-
193
- const data = await res.json();
194
- pushLog('http', `← ${res.status} POST /files/ (fetch)`, {
195
- resultsCount: Array.isArray(data?.results) ? data.results.length : 'n/a',
184
+ return new Promise((resolve, reject) => {
185
+ const xhr = new XMLHttpRequest();
186
+
187
+ const failNetwork = (reason: string) => {
188
+ pushLog('http', `← ERR xhr ${UPLOAD_PATH}`, { reason });
189
+ const err: any = new Error(reason);
190
+ err.code = 'ERR_NETWORK';
191
+ err.config = { url: UPLOAD_PATH };
192
+ reject(err);
193
+ };
194
+
195
+ xhr.onload = () => {
196
+ const status = xhr.status;
197
+ let body: any = null;
198
+ try {
199
+ body = JSON.parse(xhr.responseText);
200
+ } catch {
201
+ body = xhr.responseText || null;
202
+ }
203
+
204
+ if (status < 200 || status >= 300) {
205
+ pushLog('http', `← ${status} POST ${UPLOAD_PATH} (xhr)`, body);
206
+ const err: any = new Error(`Upload failed: ${status}`);
207
+ // Shaped like an axios error so callers' `err.response.status`
208
+ // checks keep working — notably useSendMessage's retry with the
209
+ // singular "file" field on 500.
210
+ err.response = { status, statusText: xhr.statusText, data: body };
211
+ err.config = { url: UPLOAD_PATH };
212
+ reject(err);
213
+ return;
214
+ }
215
+
216
+ pushLog('http', `← ${status} POST ${UPLOAD_PATH} (xhr)`, {
217
+ resultsCount: Array.isArray(body?.results) ? body.results.length : 'n/a',
218
+ });
219
+ resolve({ data: body });
220
+ };
221
+
222
+ xhr.onerror = () => failNetwork('Network request failed');
223
+ xhr.ontimeout = () => failNetwork('Upload timed out');
224
+ xhr.onabort = () => failNetwork('Upload aborted');
225
+
226
+ xhr.open('POST', url);
227
+ xhr.setRequestHeader('Authorization', token);
228
+ xhr.setRequestHeader('Accept', '*/*');
229
+ // Deliberately no Content-Type — see the note above: RN fills it in
230
+ // along with the multipart boundary it generated.
231
+ xhr.send(formData as any);
196
232
  });
197
- return { data };
198
233
  }
@@ -2,10 +2,38 @@ import axios from 'axios';
2
2
  import { Platform } from 'react-native';
3
3
  import { store } from '../../roomStore';
4
4
 
5
- const PUSH_API_URL = 'https://push.ethoradev.com/api/v1';
5
+ // Both of these used to be hardcoded to the ethoradev environment
6
+ // (push.ethoradev.com, @xmpp.ethoradev.com). That is a development
7
+ // deployment: shipping it inside the SDK meant every host app, including
8
+ // production ones, registered its device against dev infrastructure and
9
+ // then quietly received no pushes. They are resolved from the host's own
10
+ // config now, with the production cluster as the fallback.
11
+ const DEFAULT_PUSH_API_URL = 'https://push.chat.ethora.com/api/v1';
12
+ const DEFAULT_XMPP_HOST = 'xmpp.chat.ethora.com';
13
+
14
+ /**
15
+ * Push service base URL. `config.pushNotifications.apiUrl` wins, so a
16
+ * self-hosted or enterprise deployment can point at its own service
17
+ * without forking the SDK.
18
+ */
19
+ const resolvePushApiUrl = (): string => {
20
+ const config = store.getState().chatSettingStore?.config;
21
+ return (
22
+ (config?.pushNotifications?.apiUrl || '').trim() || DEFAULT_PUSH_API_URL
23
+ );
24
+ };
25
+
26
+ /**
27
+ * The XMPP host the JID is qualified with. Must match the host the client
28
+ * actually connects to, or the push service files the subscription under a
29
+ * JID nothing ever sends to.
30
+ */
31
+ const resolveXmppHost = (): string => {
32
+ const config = store.getState().chatSettingStore?.config;
33
+ return (config?.xmppSettings?.host || '').trim() || DEFAULT_XMPP_HOST;
34
+ };
6
35
 
7
36
  const pushAxios = axios.create({
8
- baseURL: PUSH_API_URL,
9
37
  headers: {
10
38
  'Content-Type': 'application/json',
11
39
  },
@@ -21,7 +49,7 @@ export interface PushSubscriptionPayload {
21
49
  export async function subscribeToPushNotifications(
22
50
  fcmToken: string,
23
51
  userJid: string,
24
- projectName: string = '',
52
+ projectName: string = ''
25
53
  ): Promise<void> {
26
54
  const deviceType: 'web' | 'android' | 'ios' = Platform.select({
27
55
  ios: 'ios',
@@ -29,27 +57,30 @@ export async function subscribeToPushNotifications(
29
57
  default: 'web',
30
58
  }) as 'web' | 'android' | 'ios';
31
59
 
60
+ // `userJid` arrives as either a bare localpart or an already-qualified
61
+ // JID depending on the caller; don't double-qualify it.
62
+ const jid = userJid.includes('@')
63
+ ? userJid
64
+ : `${userJid}@${resolveXmppHost()}`;
65
+
32
66
  const payload: PushSubscriptionPayload = {
33
67
  projectId: projectName,
34
68
  registrationToken: fcmToken,
35
69
  deviceType,
36
- jid: `${userJid}@xmpp.ethoradev.com`,
70
+ jid,
37
71
  };
38
72
 
39
- console.log('payload', payload);
40
-
41
73
  try {
42
74
  const token = store.getState().chatSettingStore?.user?.token || '';
43
75
 
44
76
  const response = await pushAxios.post('/subscriptions', payload, {
77
+ baseURL: resolvePushApiUrl(),
45
78
  headers: {
46
79
  Authorization: `Bearer ${token}`,
47
80
  },
48
81
  });
49
- console.log('Successfully subscribed to push notifications', response.data);
50
82
  return response.data;
51
83
  } catch (error: any) {
52
84
  console.error('Failed to subscribe to push notifications:', error);
53
85
  }
54
86
  }
55
-
@@ -1,9 +1,66 @@
1
1
  import { ApiRoom, DeleteRoomMember, PostAddRoomMember, PostReportRoom, PostRoom, RoomMember } from '../../types/models/room.model';
2
2
  import { store } from '../../roomStore';
3
- import { addRoom } from '../../roomStore/roomsSlice';
3
+ import { addRoom, mergeUsersSet } from '../../roomStore/roomsSlice';
4
4
  import { IRoom } from '../../types/types';
5
5
  import http from '../apiClient';
6
6
 
7
+ /**
8
+ * Populate `state.rooms.usersSet` (the identity cache Message.tsx resolves
9
+ * sender display names from) from the `members` arrays the REST `/chats/my`
10
+ * response carries. This is how the web SDK hydrates usersSet — it does NOT
11
+ * depend on the XMPP `getRoomMembers` IQ, which errors (`type=error`) on the
12
+ * current backend and left every sender showing a raw JID instead of a name.
13
+ *
14
+ * Keying: a message sender's `user.id` localpart is `<appId>_<userId>`, but
15
+ * a REST member only carries its Mongo `_id` (= `<userId>`). We derive the
16
+ * appId from the logged-in user's own xmppUsername (also `<appId>_<userId>`)
17
+ * and index each member under every id form a lookup might use:
18
+ * - `<appId>_<_id>` (matches the message sender localpart — the key case)
19
+ * - `_id` (fallback)
20
+ * - `xmppUsername` (raw + localpart) when the API does return one
21
+ */
22
+ function dispatchUsersSetFromRestItems(items: ApiRoom[]): void {
23
+ if (!items?.length) {return;}
24
+ const ownXmpp = String(
25
+ store.getState().chatSettingStore?.user?.xmppUsername || ''
26
+ );
27
+ const appId = ownXmpp.includes('_') ? ownXmpp.split('_')[0] : '';
28
+
29
+ const members: Record<string, RoomMember> = {};
30
+ for (const item of items) {
31
+ const list = Array.isArray((item as any)?.members) ? (item as any).members : [];
32
+ for (const m of list) {
33
+ if (!m) {continue;}
34
+ const entry: RoomMember = {
35
+ firstName: m.firstName || '',
36
+ lastName: m.lastName || '',
37
+ xmppUsername: m.xmppUsername || (appId && m._id ? `${appId}_${m._id}` : m._id || ''),
38
+ _id: m._id || '',
39
+ role: m.role,
40
+ ban_status: m.ban_status,
41
+ last_active: m.last_active,
42
+ jid: m.jid,
43
+ name: m.name,
44
+ } as RoomMember;
45
+
46
+ const keys = new Set<string>();
47
+ if (appId && m._id) {keys.add(`${appId}_${m._id}`);}
48
+ if (m._id) {keys.add(m._id);}
49
+ if (m.xmppUsername) {
50
+ keys.add(m.xmppUsername);
51
+ keys.add(String(m.xmppUsername).split('@')[0]);
52
+ }
53
+ keys.forEach((k) => {
54
+ if (k) {members[k] = entry;}
55
+ });
56
+ }
57
+ }
58
+
59
+ if (Object.keys(members).length > 0) {
60
+ store.dispatch(mergeUsersSet({ members }));
61
+ }
62
+ }
63
+
7
64
  interface ApiRoomMember {
8
65
  _id: string;
9
66
  firstName?: string;
@@ -90,6 +147,8 @@ function dispatchRoomsFromRestItems(items: ApiRoom[]): void {
90
147
  };
91
148
  store.dispatch(addRoom({ roomData: room }));
92
149
  }
150
+ // Hydrate the sender-name identity cache from the same REST payload.
151
+ dispatchUsersSetFromRestItems(items);
93
152
  }
94
153
 
95
154
  const GET_ROOMS_CACHE_MS = 60_000;
@@ -273,6 +332,55 @@ export async function deleteRoom(name: string) {
273
332
  }
274
333
  }
275
334
 
335
+ // POST /v1/chats/call/create/{chatName}
336
+ // Swagger documents the body as `additionalProperties: true`, we forward
337
+ // `kind: 'audio' | 'video'` so the server can stamp it on the broadcast
338
+ // call-token stanza for the callee. When the server doesn't recognize the
339
+ // field both sides still fall through to a video call (the default), which
340
+ // matches the prior single-mode behavior.
341
+ // No timeout is set on the shared `http` client (matches web — neither SDK
342
+ // configures one anywhere), so a stalled connection leaves this request
343
+ // hanging indefinitely with nothing surfaced to the caller. Observed live
344
+ // on the iOS Simulator: the same call the backend answers in ~0.6s from a
345
+ // plain curl sat unresolved for 75+ seconds through the Simulator's network
346
+ // stack. The UI's own 30s "no answer" ring timeout (VideoCallOverlay)
347
+ // doesn't touch this request at all — it just gives up and shows an error
348
+ // while the POST keeps sitting there, so a request that DOES eventually
349
+ // resolve races a call the user already dismissed. Bound just this
350
+ // request, not the shared client: file uploads on the same client
351
+ // legitimately take longer than any call-placement call should ever need.
352
+ const CALL_CREATE_TIMEOUT_MS = 15000;
353
+
354
+ export async function createChatCall(
355
+ chatName: string,
356
+ options?: { kind?: 'audio' | 'video' }
357
+ ): Promise<void> {
358
+ const token = store.getState().chatSettingStore.user.token || '';
359
+ const kind = options?.kind || 'video';
360
+
361
+ try {
362
+ await http.post(
363
+ `/chats/call/create/${chatName}`,
364
+ { kind },
365
+ {
366
+ headers: {
367
+ Authorization: token,
368
+ },
369
+ timeout: CALL_CREATE_TIMEOUT_MS,
370
+ }
371
+ );
372
+ } catch (error: any) {
373
+ // Distinguish a timeout from a real server rejection — the caller
374
+ // (CallButtons) surfaces this string directly on the ring/error
375
+ // screen, and "the network is being slow" is a very different thing
376
+ // to tell the user than "the server said no".
377
+ if (error?.code === 'ECONNABORTED' || /timeout/i.test(String(error?.message))) {
378
+ throw new Error('Call request timed out — check your connection and try again');
379
+ }
380
+ throw new Error('Error creating chat call');
381
+ }
382
+ }
383
+
276
384
  export function clearRoomsRestCache() {
277
385
  lastGetRoomsResponse = null;
278
386
  lastGetRoomsResponseAt = 0;