@ethora/chat-component-rn 26.5.21 → 26.6.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 (352) 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/RoomList.js +23 -9
  13. package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
  14. package/lib/commonjs/components/MessageBubble/Message.js +72 -11
  15. package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
  16. package/lib/commonjs/components/MessageBubble/MessageTranslate.js +160 -0
  17. package/lib/commonjs/components/MessageBubble/MessageTranslate.js.map +1 -0
  18. package/lib/commonjs/components/MessageBubble/TranslatedMessageBody.js +59 -0
  19. package/lib/commonjs/components/MessageBubble/TranslatedMessageBody.js.map +1 -0
  20. package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +3 -3
  21. package/lib/commonjs/components/UsersList/UsersList.js +3 -1
  22. package/lib/commonjs/components/UsersList/UsersList.js.map +1 -1
  23. package/lib/commonjs/components/VideoCalls/CallButtons.js +159 -0
  24. package/lib/commonjs/components/VideoCalls/CallButtons.js.map +1 -0
  25. package/lib/commonjs/components/VideoCalls/CallIcons.js +328 -0
  26. package/lib/commonjs/components/VideoCalls/CallIcons.js.map +1 -0
  27. package/lib/commonjs/components/VideoCalls/VideoCallOverlay.js +550 -0
  28. package/lib/commonjs/components/VideoCalls/VideoCallOverlay.js.map +1 -0
  29. package/lib/commonjs/components/VideoCalls/VideoCallSession.js +636 -0
  30. package/lib/commonjs/components/VideoCalls/VideoCallSession.js.map +1 -0
  31. package/lib/commonjs/components/VideoCalls/livekitRuntime.js +91 -0
  32. package/lib/commonjs/components/VideoCalls/livekitRuntime.js.map +1 -0
  33. package/lib/commonjs/components/VideoCalls/useCallKeep.js +215 -0
  34. package/lib/commonjs/components/VideoCalls/useCallKeep.js.map +1 -0
  35. package/lib/commonjs/components/styled/AudioMessage.js +91 -33
  36. package/lib/commonjs/components/styled/AudioMessage.js.map +1 -1
  37. package/lib/commonjs/components/styled/RoomListComponents/index.js +13 -1
  38. package/lib/commonjs/components/styled/RoomListComponents/index.js.map +1 -1
  39. package/lib/commonjs/components/styled/SendInput.js +83 -49
  40. package/lib/commonjs/components/styled/SendInput.js.map +1 -1
  41. package/lib/commonjs/components/styled/StyledComponents.js +9 -4
  42. package/lib/commonjs/components/styled/StyledComponents.js.map +1 -1
  43. package/lib/commonjs/components/styled/StyledInputComponents/Composing.js +2 -0
  44. package/lib/commonjs/components/styled/StyledInputComponents/Composing.js.map +1 -1
  45. package/lib/commonjs/context/xmppProvider.js +10 -3
  46. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  47. package/lib/commonjs/helpers/callLogMessage.js +162 -0
  48. package/lib/commonjs/helpers/callLogMessage.js.map +1 -0
  49. package/lib/commonjs/helpers/callPush.js +61 -0
  50. package/lib/commonjs/helpers/callPush.js.map +1 -0
  51. package/lib/commonjs/helpers/constants/LANGUAGE_OPTIONS.js +24 -12
  52. package/lib/commonjs/helpers/constants/LANGUAGE_OPTIONS.js.map +1 -1
  53. package/lib/commonjs/helpers/createUserNameFromSetUser.js +51 -2
  54. package/lib/commonjs/helpers/createUserNameFromSetUser.js.map +1 -1
  55. package/lib/commonjs/helpers/getDataFromXml.js +19 -1
  56. package/lib/commonjs/helpers/getDataFromXml.js.map +1 -1
  57. package/lib/commonjs/helpers/incomingCallFromPush.js +74 -0
  58. package/lib/commonjs/helpers/incomingCallFromPush.js.map +1 -0
  59. package/lib/commonjs/helpers/insertMessageWithDelimiter.js +13 -1
  60. package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
  61. package/lib/commonjs/helpers/isUnresolvedSenderId.js +32 -0
  62. package/lib/commonjs/helpers/isUnresolvedSenderId.js.map +1 -0
  63. package/lib/commonjs/hooks/useChatSettingState.js +2 -0
  64. package/lib/commonjs/hooks/useChatSettingState.js.map +1 -1
  65. package/lib/commonjs/hooks/useMessageTranslation.js +51 -0
  66. package/lib/commonjs/hooks/useMessageTranslation.js.map +1 -0
  67. package/lib/commonjs/hooks/usePushNotifications.js +13 -3
  68. package/lib/commonjs/hooks/usePushNotifications.js.map +1 -1
  69. package/lib/commonjs/hooks/useSendMessage.js +12 -2
  70. package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
  71. package/lib/commonjs/i18n/strings.js +1308 -0
  72. package/lib/commonjs/i18n/strings.js.map +1 -0
  73. package/lib/commonjs/i18n/useT.js +60 -0
  74. package/lib/commonjs/i18n/useT.js.map +1 -0
  75. package/lib/commonjs/main.js +44 -0
  76. package/lib/commonjs/main.js.map +1 -1
  77. package/lib/commonjs/networking/api-requests/push.api.js +34 -5
  78. package/lib/commonjs/networking/api-requests/push.api.js.map +1 -1
  79. package/lib/commonjs/networking/api-requests/rooms.api.js +108 -0
  80. package/lib/commonjs/networking/api-requests/rooms.api.js.map +1 -1
  81. package/lib/commonjs/networking/callTokenStanza.js +531 -0
  82. package/lib/commonjs/networking/callTokenStanza.js.map +1 -0
  83. package/lib/commonjs/networking/outboundQueue.js.map +1 -1
  84. package/lib/commonjs/networking/stanzaHandlers.js +75 -8
  85. package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
  86. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js +47 -11
  87. package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  88. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js +2 -1
  89. package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  90. package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +42 -5
  91. package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
  92. package/lib/commonjs/networking/xmppClient.js +78 -16
  93. package/lib/commonjs/networking/xmppClient.js.map +1 -1
  94. package/lib/commonjs/roomStore/callSlice.js +144 -0
  95. package/lib/commonjs/roomStore/callSlice.js.map +1 -0
  96. package/lib/commonjs/roomStore/chatSettingsSlice.js +8 -2
  97. package/lib/commonjs/roomStore/chatSettingsSlice.js.map +1 -1
  98. package/lib/commonjs/roomStore/index.js +7 -1
  99. package/lib/commonjs/roomStore/index.js.map +1 -1
  100. package/lib/commonjs/roomStore/persistence.js +69 -5
  101. package/lib/commonjs/roomStore/persistence.js.map +1 -1
  102. package/lib/commonjs/roomStore/roomsSlice.js +136 -6
  103. package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
  104. package/lib/commonjs/utils/translateModePolicy.js +33 -0
  105. package/lib/commonjs/utils/translateModePolicy.js.map +1 -0
  106. package/lib/module/components/MainComponents/ChatHeader.js +20 -8
  107. package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
  108. package/lib/module/components/MainComponents/ChatWrapper.js +17 -0
  109. package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
  110. package/lib/module/components/MainComponents/LanguageSelectorButton.js +57 -0
  111. package/lib/module/components/MainComponents/LanguageSelectorButton.js.map +1 -0
  112. package/lib/module/components/MainComponents/LanguageSelectorModal.js +246 -0
  113. package/lib/module/components/MainComponents/LanguageSelectorModal.js.map +1 -0
  114. package/lib/module/components/MainComponents/RoomList.js +23 -9
  115. package/lib/module/components/MainComponents/RoomList.js.map +1 -1
  116. package/lib/module/components/MessageBubble/Message.js +73 -12
  117. package/lib/module/components/MessageBubble/Message.js.map +1 -1
  118. package/lib/module/components/MessageBubble/MessageTranslate.js +155 -0
  119. package/lib/module/components/MessageBubble/MessageTranslate.js.map +1 -0
  120. package/lib/module/components/MessageBubble/TranslatedMessageBody.js +53 -0
  121. package/lib/module/components/MessageBubble/TranslatedMessageBody.js.map +1 -0
  122. package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +3 -3
  123. package/lib/module/components/UsersList/UsersList.js +3 -1
  124. package/lib/module/components/UsersList/UsersList.js.map +1 -1
  125. package/lib/module/components/VideoCalls/CallButtons.js +154 -0
  126. package/lib/module/components/VideoCalls/CallButtons.js.map +1 -0
  127. package/lib/module/components/VideoCalls/CallIcons.js +309 -0
  128. package/lib/module/components/VideoCalls/CallIcons.js.map +1 -0
  129. package/lib/module/components/VideoCalls/VideoCallOverlay.js +544 -0
  130. package/lib/module/components/VideoCalls/VideoCallOverlay.js.map +1 -0
  131. package/lib/module/components/VideoCalls/VideoCallSession.js +630 -0
  132. package/lib/module/components/VideoCalls/VideoCallSession.js.map +1 -0
  133. package/lib/module/components/VideoCalls/livekitRuntime.js +83 -0
  134. package/lib/module/components/VideoCalls/livekitRuntime.js.map +1 -0
  135. package/lib/module/components/VideoCalls/useCallKeep.js +210 -0
  136. package/lib/module/components/VideoCalls/useCallKeep.js.map +1 -0
  137. package/lib/module/components/styled/AudioMessage.js +91 -33
  138. package/lib/module/components/styled/AudioMessage.js.map +1 -1
  139. package/lib/module/components/styled/RoomListComponents/index.js +13 -1
  140. package/lib/module/components/styled/RoomListComponents/index.js.map +1 -1
  141. package/lib/module/components/styled/SendInput.js +83 -49
  142. package/lib/module/components/styled/SendInput.js.map +1 -1
  143. package/lib/module/components/styled/StyledComponents.js +9 -4
  144. package/lib/module/components/styled/StyledComponents.js.map +1 -1
  145. package/lib/module/components/styled/StyledInputComponents/Composing.js +2 -0
  146. package/lib/module/components/styled/StyledInputComponents/Composing.js.map +1 -1
  147. package/lib/module/context/xmppProvider.js +11 -4
  148. package/lib/module/context/xmppProvider.js.map +1 -1
  149. package/lib/module/helpers/callLogMessage.js +152 -0
  150. package/lib/module/helpers/callLogMessage.js.map +1 -0
  151. package/lib/module/helpers/callPush.js +55 -0
  152. package/lib/module/helpers/callPush.js.map +1 -0
  153. package/lib/module/helpers/constants/LANGUAGE_OPTIONS.js +24 -12
  154. package/lib/module/helpers/constants/LANGUAGE_OPTIONS.js.map +1 -1
  155. package/lib/module/helpers/createUserNameFromSetUser.js +49 -1
  156. package/lib/module/helpers/createUserNameFromSetUser.js.map +1 -1
  157. package/lib/module/helpers/getDataFromXml.js +20 -1
  158. package/lib/module/helpers/getDataFromXml.js.map +1 -1
  159. package/lib/module/helpers/incomingCallFromPush.js +70 -0
  160. package/lib/module/helpers/incomingCallFromPush.js.map +1 -0
  161. package/lib/module/helpers/insertMessageWithDelimiter.js +13 -1
  162. package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
  163. package/lib/module/helpers/isUnresolvedSenderId.js +27 -0
  164. package/lib/module/helpers/isUnresolvedSenderId.js.map +1 -0
  165. package/lib/module/hooks/useChatSettingState.js +2 -0
  166. package/lib/module/hooks/useChatSettingState.js.map +1 -1
  167. package/lib/module/hooks/useMessageTranslation.js +46 -0
  168. package/lib/module/hooks/useMessageTranslation.js.map +1 -0
  169. package/lib/module/hooks/usePushNotifications.js +13 -3
  170. package/lib/module/hooks/usePushNotifications.js.map +1 -1
  171. package/lib/module/hooks/useSendMessage.js +12 -2
  172. package/lib/module/hooks/useSendMessage.js.map +1 -1
  173. package/lib/module/i18n/strings.js +1300 -0
  174. package/lib/module/i18n/strings.js.map +1 -0
  175. package/lib/module/i18n/useT.js +55 -0
  176. package/lib/module/i18n/useT.js.map +1 -0
  177. package/lib/module/main.js +7 -1
  178. package/lib/module/main.js.map +1 -1
  179. package/lib/module/networking/api-requests/push.api.js +35 -5
  180. package/lib/module/networking/api-requests/push.api.js.map +1 -1
  181. package/lib/module/networking/api-requests/rooms.api.js +109 -1
  182. package/lib/module/networking/api-requests/rooms.api.js.map +1 -1
  183. package/lib/module/networking/callTokenStanza.js +526 -0
  184. package/lib/module/networking/callTokenStanza.js.map +1 -0
  185. package/lib/module/networking/outboundQueue.js.map +1 -1
  186. package/lib/module/networking/stanzaHandlers.js +76 -9
  187. package/lib/module/networking/stanzaHandlers.js.map +1 -1
  188. package/lib/module/networking/xmpp/handleStanzas.xmpp.js +48 -11
  189. package/lib/module/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
  190. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js +1 -1
  191. package/lib/module/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
  192. package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +43 -5
  193. package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
  194. package/lib/module/networking/xmppClient.js +78 -16
  195. package/lib/module/networking/xmppClient.js.map +1 -1
  196. package/lib/module/roomStore/callSlice.js +130 -0
  197. package/lib/module/roomStore/callSlice.js.map +1 -0
  198. package/lib/module/roomStore/chatSettingsSlice.js +6 -1
  199. package/lib/module/roomStore/chatSettingsSlice.js.map +1 -1
  200. package/lib/module/roomStore/index.js +6 -1
  201. package/lib/module/roomStore/index.js.map +1 -1
  202. package/lib/module/roomStore/persistence.js +69 -5
  203. package/lib/module/roomStore/persistence.js.map +1 -1
  204. package/lib/module/roomStore/roomsSlice.js +134 -5
  205. package/lib/module/roomStore/roomsSlice.js.map +1 -1
  206. package/lib/module/utils/translateModePolicy.js +27 -0
  207. package/lib/module/utils/translateModePolicy.js.map +1 -0
  208. package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
  209. package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
  210. package/lib/typescript/components/MainComponents/LanguageSelectorButton.d.ts +12 -0
  211. package/lib/typescript/components/MainComponents/LanguageSelectorButton.d.ts.map +1 -0
  212. package/lib/typescript/components/MainComponents/LanguageSelectorModal.d.ts +31 -0
  213. package/lib/typescript/components/MainComponents/LanguageSelectorModal.d.ts.map +1 -0
  214. package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
  215. package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
  216. package/lib/typescript/components/MessageBubble/MessageTranslate.d.ts +44 -0
  217. package/lib/typescript/components/MessageBubble/MessageTranslate.d.ts.map +1 -0
  218. package/lib/typescript/components/MessageBubble/TranslatedMessageBody.d.ts +24 -0
  219. package/lib/typescript/components/MessageBubble/TranslatedMessageBody.d.ts.map +1 -0
  220. package/lib/typescript/components/UsersList/UsersList.d.ts.map +1 -1
  221. package/lib/typescript/components/VideoCalls/CallButtons.d.ts +16 -0
  222. package/lib/typescript/components/VideoCalls/CallButtons.d.ts.map +1 -0
  223. package/lib/typescript/components/VideoCalls/CallIcons.d.ts +30 -0
  224. package/lib/typescript/components/VideoCalls/CallIcons.d.ts.map +1 -0
  225. package/lib/typescript/components/VideoCalls/VideoCallOverlay.d.ts +10 -0
  226. package/lib/typescript/components/VideoCalls/VideoCallOverlay.d.ts.map +1 -0
  227. package/lib/typescript/components/VideoCalls/VideoCallSession.d.ts +38 -0
  228. package/lib/typescript/components/VideoCalls/VideoCallSession.d.ts.map +1 -0
  229. package/lib/typescript/components/VideoCalls/livekitRuntime.d.ts +52 -0
  230. package/lib/typescript/components/VideoCalls/livekitRuntime.d.ts.map +1 -0
  231. package/lib/typescript/components/VideoCalls/useCallKeep.d.ts +32 -0
  232. package/lib/typescript/components/VideoCalls/useCallKeep.d.ts.map +1 -0
  233. package/lib/typescript/components/styled/AudioMessage.d.ts.map +1 -1
  234. package/lib/typescript/components/styled/RoomListComponents/index.d.ts.map +1 -1
  235. package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
  236. package/lib/typescript/components/styled/StyledComponents.d.ts.map +1 -1
  237. package/lib/typescript/components/styled/StyledInputComponents/Composing.d.ts.map +1 -1
  238. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  239. package/lib/typescript/helpers/callLogMessage.d.ts +34 -0
  240. package/lib/typescript/helpers/callLogMessage.d.ts.map +1 -0
  241. package/lib/typescript/helpers/callPush.d.ts +23 -0
  242. package/lib/typescript/helpers/callPush.d.ts.map +1 -0
  243. package/lib/typescript/helpers/constants/LANGUAGE_OPTIONS.d.ts +14 -0
  244. package/lib/typescript/helpers/constants/LANGUAGE_OPTIONS.d.ts.map +1 -1
  245. package/lib/typescript/helpers/createUserNameFromSetUser.d.ts +33 -1
  246. package/lib/typescript/helpers/createUserNameFromSetUser.d.ts.map +1 -1
  247. package/lib/typescript/helpers/getDataFromXml.d.ts.map +1 -1
  248. package/lib/typescript/helpers/incomingCallFromPush.d.ts +14 -0
  249. package/lib/typescript/helpers/incomingCallFromPush.d.ts.map +1 -0
  250. package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
  251. package/lib/typescript/helpers/isUnresolvedSenderId.d.ts +2 -0
  252. package/lib/typescript/helpers/isUnresolvedSenderId.d.ts.map +1 -0
  253. package/lib/typescript/hooks/useChatSettingState.d.ts +2 -1
  254. package/lib/typescript/hooks/useChatSettingState.d.ts.map +1 -1
  255. package/lib/typescript/hooks/useMessageTranslation.d.ts +25 -0
  256. package/lib/typescript/hooks/useMessageTranslation.d.ts.map +1 -0
  257. package/lib/typescript/hooks/usePushNotifications.d.ts.map +1 -1
  258. package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
  259. package/lib/typescript/i18n/strings.d.ts +16 -0
  260. package/lib/typescript/i18n/strings.d.ts.map +1 -0
  261. package/lib/typescript/i18n/useT.d.ts +34 -0
  262. package/lib/typescript/i18n/useT.d.ts.map +1 -0
  263. package/lib/typescript/main.d.ts +6 -1
  264. package/lib/typescript/main.d.ts.map +1 -1
  265. package/lib/typescript/networking/api-requests/push.api.d.ts.map +1 -1
  266. package/lib/typescript/networking/api-requests/rooms.api.d.ts +3 -0
  267. package/lib/typescript/networking/api-requests/rooms.api.d.ts.map +1 -1
  268. package/lib/typescript/networking/callTokenStanza.d.ts +14 -0
  269. package/lib/typescript/networking/callTokenStanza.d.ts.map +1 -0
  270. package/lib/typescript/networking/outboundQueue.d.ts +1 -0
  271. package/lib/typescript/networking/outboundQueue.d.ts.map +1 -1
  272. package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
  273. package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
  274. package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts +10 -0
  275. package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts.map +1 -1
  276. package/lib/typescript/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts +16 -1
  277. package/lib/typescript/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts.map +1 -1
  278. package/lib/typescript/networking/xmppClient.d.ts +1 -1
  279. package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
  280. package/lib/typescript/roomStore/callSlice.d.ts +39 -0
  281. package/lib/typescript/roomStore/callSlice.d.ts.map +1 -0
  282. package/lib/typescript/roomStore/chatSettingsSlice.d.ts +10 -1
  283. package/lib/typescript/roomStore/chatSettingsSlice.d.ts.map +1 -1
  284. package/lib/typescript/roomStore/index.d.ts +4 -0
  285. package/lib/typescript/roomStore/index.d.ts.map +1 -1
  286. package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
  287. package/lib/typescript/roomStore/roomsSlice.d.ts +6 -1
  288. package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
  289. package/lib/typescript/types/models/language.model.d.ts +1 -1
  290. package/lib/typescript/types/models/language.model.d.ts.map +1 -1
  291. package/lib/typescript/types/models/message.model.d.ts +7 -0
  292. package/lib/typescript/types/models/message.model.d.ts.map +1 -1
  293. package/lib/typescript/types/types.d.ts +135 -1
  294. package/lib/typescript/types/types.d.ts.map +1 -1
  295. package/lib/typescript/utils/translateModePolicy.d.ts +20 -0
  296. package/lib/typescript/utils/translateModePolicy.d.ts.map +1 -0
  297. package/package.json +20 -4
  298. package/src/components/MainComponents/ChatHeader.tsx +30 -9
  299. package/src/components/MainComponents/ChatWrapper.tsx +15 -0
  300. package/src/components/MainComponents/LanguageSelectorButton.tsx +53 -0
  301. package/src/components/MainComponents/LanguageSelectorModal.tsx +276 -0
  302. package/src/components/MainComponents/RoomList.tsx +27 -9
  303. package/src/components/MessageBubble/Message.tsx +109 -17
  304. package/src/components/MessageBubble/MessageTranslate.tsx +182 -0
  305. package/src/components/MessageBubble/TranslatedMessageBody.tsx +59 -0
  306. package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +3 -3
  307. package/src/components/UsersList/UsersList.tsx +3 -1
  308. package/src/components/VideoCalls/CallButtons.tsx +171 -0
  309. package/src/components/VideoCalls/CallIcons.tsx +246 -0
  310. package/src/components/VideoCalls/VideoCallOverlay.tsx +627 -0
  311. package/src/components/VideoCalls/VideoCallSession.tsx +675 -0
  312. package/src/components/VideoCalls/livekitRuntime.ts +100 -0
  313. package/src/components/VideoCalls/useCallKeep.ts +252 -0
  314. package/src/components/styled/AudioMessage.tsx +97 -37
  315. package/src/components/styled/RoomListComponents/index.tsx +15 -3
  316. package/src/components/styled/SendInput.tsx +94 -51
  317. package/src/components/styled/StyledComponents.ts +9 -6
  318. package/src/components/styled/StyledInputComponents/Composing.tsx +7 -1
  319. package/src/context/xmppProvider.tsx +14 -1
  320. package/src/helpers/callLogMessage.ts +174 -0
  321. package/src/helpers/callPush.ts +90 -0
  322. package/src/helpers/constants/LANGUAGE_OPTIONS.ts +20 -5
  323. package/src/helpers/createUserNameFromSetUser.ts +68 -2
  324. package/src/helpers/getDataFromXml.ts +40 -4
  325. package/src/helpers/incomingCallFromPush.ts +83 -0
  326. package/src/helpers/insertMessageWithDelimiter.ts +27 -9
  327. package/src/helpers/isUnresolvedSenderId.ts +25 -0
  328. package/src/hooks/useChatSettingState.tsx +4 -0
  329. package/src/hooks/useMessageTranslation.ts +70 -0
  330. package/src/hooks/usePushNotifications.ts +15 -3
  331. package/src/hooks/useSendMessage.tsx +15 -2
  332. package/src/i18n/strings.ts +1322 -0
  333. package/src/i18n/useT.ts +56 -0
  334. package/src/main.ts +18 -1
  335. package/src/networking/api-requests/push.api.ts +39 -8
  336. package/src/networking/api-requests/rooms.api.ts +109 -1
  337. package/src/networking/callTokenStanza.ts +636 -0
  338. package/src/networking/outboundQueue.ts +1 -0
  339. package/src/networking/stanzaHandlers.ts +74 -15
  340. package/src/networking/xmpp/handleStanzas.xmpp.ts +52 -11
  341. package/src/networking/xmpp/sendTextMessage.xmpp.ts +1 -1
  342. package/src/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.ts +41 -5
  343. package/src/networking/xmppClient.ts +97 -28
  344. package/src/roomStore/callSlice.ts +190 -0
  345. package/src/roomStore/chatSettingsSlice.ts +16 -0
  346. package/src/roomStore/index.ts +5 -0
  347. package/src/roomStore/persistence.ts +103 -3
  348. package/src/roomStore/roomsSlice.ts +149 -4
  349. package/src/types/models/language.model.ts +17 -1
  350. package/src/types/models/message.model.ts +9 -0
  351. package/src/types/types.ts +142 -2
  352. package/src/utils/translateModePolicy.ts +31 -0
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.loadLiveKit = exports.isLiveKitAvailable = exports.ensureLiveKitGlobals = exports.__resetLiveKitRuntimeForTests = void 0;
7
+ /**
8
+ * Optional-dependency bridge for the LiveKit React Native SDK.
9
+ *
10
+ * Calls are opt-in (`config.videoCalls.enabled`), and the LiveKit packages
11
+ * are NATIVE modules: they need a dev build, they cannot run in Expo Go,
12
+ * and they add camera/microphone entitlements to whatever app installs
13
+ * them. Most hosts embedding this chat SDK don't want calls at all, so
14
+ * `@livekit/react-native` and `@livekit/react-native-webrtc` are declared
15
+ * as OPTIONAL peer dependencies.
16
+ *
17
+ * That means a plain top-level `import ... from '@livekit/react-native'`
18
+ * is not allowed anywhere in the SDK: Metro resolves imports at bundle
19
+ * time, so a chat-only host would fail to build over a feature it never
20
+ * switched on. Everything call-related goes through `loadLiveKit()`, which
21
+ * requires the modules lazily at call time and returns null when they
22
+ * aren't installed. Callers surface that as a friendly config error rather
23
+ * than a redbox.
24
+ */
25
+
26
+ let cached;
27
+ const isLiveKitAvailable = () => loadLiveKit() !== null;
28
+
29
+ /**
30
+ * Resolve the LiveKit runtime, or null when the optional native packages
31
+ * aren't installed in the host app. Result is memoised (including the
32
+ * failure) so a missing dependency doesn't re-throw on every render.
33
+ */
34
+ exports.isLiveKitAvailable = isLiveKitAvailable;
35
+ const loadLiveKit = () => {
36
+ if (cached !== undefined) {
37
+ return cached;
38
+ }
39
+ try {
40
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
41
+ const rn = require('@livekit/react-native');
42
+ // `livekit-client` is a hard dependency of @livekit/react-native, so
43
+ // if the first require succeeded this one will too. Read the enums
44
+ // from it rather than from the RN wrapper: the wrapper re-exports a
45
+ // moving subset across versions, the core package does not.
46
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
47
+ const core = require('livekit-client');
48
+ cached = {
49
+ Room: core.Room,
50
+ RoomEvent: core.RoomEvent,
51
+ Track: core.Track,
52
+ ConnectionState: core.ConnectionState,
53
+ VideoTrack: rn.VideoTrack,
54
+ AudioSession: rn.AudioSession,
55
+ registerGlobals: rn.registerGlobals
56
+ };
57
+ } catch {
58
+ cached = null;
59
+ }
60
+ return cached;
61
+ };
62
+ exports.loadLiveKit = loadLiveKit;
63
+ let globalsRegistered = false;
64
+
65
+ /**
66
+ * `registerGlobals()` patches RTCPeerConnection / MediaStream / navigator
67
+ * .mediaDevices onto the JS global scope so livekit-client (written for
68
+ * browsers) works on React Native. It must run exactly once per JS
69
+ * context, before the first `new Room()`. Calling it repeatedly is
70
+ * harmless in current versions but has thrown in older ones, so guard it.
71
+ */
72
+ const ensureLiveKitGlobals = runtime => {
73
+ if (globalsRegistered) {
74
+ return;
75
+ }
76
+ try {
77
+ runtime.registerGlobals?.();
78
+ } catch {
79
+ // Already registered by the host app (it may use LiveKit elsewhere).
80
+ }
81
+ globalsRegistered = true;
82
+ };
83
+
84
+ /** Reset memoised state. Test seam only. */
85
+ exports.ensureLiveKitGlobals = ensureLiveKitGlobals;
86
+ const __resetLiveKitRuntimeForTests = () => {
87
+ cached = undefined;
88
+ globalsRegistered = false;
89
+ };
90
+ exports.__resetLiveKitRuntimeForTests = __resetLiveKitRuntimeForTests;
91
+ //# sourceMappingURL=livekitRuntime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["cached","isLiveKitAvailable","loadLiveKit","exports","undefined","rn","require","core","Room","RoomEvent","Track","ConnectionState","VideoTrack","AudioSession","registerGlobals","globalsRegistered","ensureLiveKitGlobals","runtime","__resetLiveKitRuntimeForTests"],"sourceRoot":"../../../../src","sources":["components/VideoCalls/livekitRuntime.ts"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAmBA,IAAIA,MAAyC;AAEtC,MAAMC,kBAAkB,GAAGA,CAAA,KAAeC,WAAW,CAAC,CAAC,KAAK,IAAI;;AAEvE;AACA;AACA;AACA;AACA;AAJAC,OAAA,CAAAF,kBAAA,GAAAA,kBAAA;AAKO,MAAMC,WAAW,GAAGA,CAAA,KAA6B;EACtD,IAAIF,MAAM,KAAKI,SAAS,EAAE;IACxB,OAAOJ,MAAM;EACf;EAEA,IAAI;IACF;IACA,MAAMK,EAAE,GAAGC,OAAO,CAAC,uBAAuB,CAAC;IAC3C;IACA;IACA;IACA;IACA;IACA,MAAMC,IAAI,GAAGD,OAAO,CAAC,gBAAgB,CAAC;IAEtCN,MAAM,GAAG;MACPQ,IAAI,EAAED,IAAI,CAACC,IAAI;MACfC,SAAS,EAAEF,IAAI,CAACE,SAAS;MACzBC,KAAK,EAAEH,IAAI,CAACG,KAAK;MACjBC,eAAe,EAAEJ,IAAI,CAACI,eAAe;MACrCC,UAAU,EAAEP,EAAE,CAACO,UAAU;MACzBC,YAAY,EAAER,EAAE,CAACQ,YAAY;MAC7BC,eAAe,EAAET,EAAE,CAACS;IACtB,CAAC;EACH,CAAC,CAAC,MAAM;IACNd,MAAM,GAAG,IAAI;EACf;EAEA,OAAOA,MAAM;AACf,CAAC;AAACG,OAAA,CAAAD,WAAA,GAAAA,WAAA;AAEF,IAAIa,iBAAiB,GAAG,KAAK;;AAE7B;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,oBAAoB,GAAIC,OAAuB,IAAW;EACrE,IAAIF,iBAAiB,EAAE;IAAC;EAAO;EAC/B,IAAI;IACFE,OAAO,CAACH,eAAe,GAAG,CAAC;EAC7B,CAAC,CAAC,MAAM;IACN;EAAA;EAEFC,iBAAiB,GAAG,IAAI;AAC1B,CAAC;;AAED;AAAAZ,OAAA,CAAAa,oBAAA,GAAAA,oBAAA;AACO,MAAME,6BAA6B,GAAGA,CAAA,KAAY;EACvDlB,MAAM,GAAGI,SAAS;EAClBW,iBAAiB,GAAG,KAAK;AAC3B,CAAC;AAACZ,OAAA,CAAAe,6BAAA,GAAAA,6BAAA","ignoreList":[]}
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useCallKeep = exports.loadCallKeep = void 0;
7
+ var _react = require("react");
8
+ var _reactNative = require("react-native");
9
+ var _reactRedux = require("react-redux");
10
+ var _roomStore = require("../../roomStore");
11
+ var _callSlice = require("../../roomStore/callSlice");
12
+ var _callTokenStanza = require("../../networking/callTokenStanza");
13
+ /**
14
+ * Native incoming-call UI (Android ConnectionService / iOS CallKit) via
15
+ * the optional `react-native-callkeep` package.
16
+ *
17
+ * Why optional: CallKeep pulls a telecom-framework dependency into the
18
+ * host app and, on iOS, is only half a solution without PushKit. It is
19
+ * loaded lazily exactly like the LiveKit packages, so hosts that don't
20
+ * install it get the plain in-app ring screen and nothing breaks.
21
+ *
22
+ * Platform reality, stated plainly:
23
+ * - Android: full value. A ConnectionService call shows the system
24
+ * incoming-call screen over the lock screen.
25
+ * - iOS: this only fires while the app is running. A CallKit screen from
26
+ * a killed app requires a VoIP push over PushKit, which needs a
27
+ * separate Apple VoIP certificate and a separate send path on the
28
+ * backend (not FCM). Until that exists, iOS falls back to the regular
29
+ * data push and the in-app ring screen.
30
+ */
31
+
32
+ let cachedCallKeep;
33
+ const loadCallKeep = () => {
34
+ if (cachedCallKeep !== undefined) {
35
+ return cachedCallKeep;
36
+ }
37
+ try {
38
+ // The JS package being installed does NOT mean the native side is
39
+ // linked: a host can `npm i react-native-callkeep` and skip
40
+ // `pod install`, or (very common in this repo) node_modules can carry
41
+ // it over from another branch whose build did link it. In that state
42
+ // requiring the package builds a `new NativeEventEmitter(null)` at
43
+ // module scope, which throws an invariant that RN surfaces as an
44
+ // uncaught redbox on every render of the call overlay — the whole app
45
+ // becomes unusable over a feature the host never switched on.
46
+ // Probing NativeModules first keeps the optional dependency genuinely
47
+ // optional: no native module => behave exactly as if it isn't installed.
48
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
49
+ const {
50
+ NativeModules
51
+ } = require('react-native');
52
+ if (!NativeModules?.RNCallKeep) {
53
+ cachedCallKeep = null;
54
+ return cachedCallKeep;
55
+ }
56
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
57
+ const mod = require('react-native-callkeep');
58
+ cachedCallKeep = mod?.default || mod;
59
+ } catch {
60
+ cachedCallKeep = null;
61
+ }
62
+ return cachedCallKeep;
63
+ };
64
+
65
+ // CallKeep identifies calls by UUID. Our callIds aren't UUIDs, so derive a
66
+ // stable v4-shaped string from the callId: same call always maps to the
67
+ // same UUID, which is what endCall() needs to dismiss the right screen.
68
+ exports.loadCallKeep = loadCallKeep;
69
+ const toUuid = seed => {
70
+ let hash = 0x811c9dc5;
71
+ const bytes = [];
72
+ for (let i = 0; i < 32; i++) {
73
+ const ch = seed.charCodeAt(i % Math.max(1, seed.length)) + i;
74
+ hash ^= ch;
75
+ hash = Math.imul(hash, 0x01000193) >>> 0;
76
+ bytes.push(hash & 0xff);
77
+ }
78
+ const hex = bytes.map(b => b.toString(16).padStart(2, '0')).join('');
79
+ return [hex.slice(0, 8), hex.slice(8, 12), '4' + hex.slice(13, 16), (parseInt(hex[16], 16) & 0x3 | 0x8).toString(16) + hex.slice(17, 20), hex.slice(20, 32)].join('-');
80
+ };
81
+ const useCallKeep = () => {
82
+ const dispatch = (0, _reactRedux.useDispatch)();
83
+ const call = (0, _reactRedux.useSelector)(state => state.call);
84
+ const callKeep = (0, _react.useMemo)(() => loadCallKeep(), []);
85
+ const activeUuidRef = (0, _react.useRef)(null);
86
+ const readyRef = (0, _react.useRef)(false);
87
+
88
+ // One-time native setup.
89
+ (0, _react.useEffect)(() => {
90
+ if (!callKeep) {
91
+ return;
92
+ }
93
+ let cancelled = false;
94
+ (async () => {
95
+ try {
96
+ await callKeep.setup({
97
+ ios: {
98
+ appName: 'Ethora',
99
+ supportsVideo: true
100
+ },
101
+ android: {
102
+ alertTitle: 'Permissions required',
103
+ alertDescription: 'This application needs to access your phone accounts to show incoming calls',
104
+ cancelButton: 'Cancel',
105
+ okButton: 'ok',
106
+ additionalPermissions: [],
107
+ foregroundService: {
108
+ channelId: 'com.ethora.chat.calls',
109
+ channelName: 'Incoming calls',
110
+ notificationTitle: 'Call in progress'
111
+ }
112
+ }
113
+ });
114
+ if (cancelled) {
115
+ return;
116
+ }
117
+ callKeep.setAvailable?.(true);
118
+ readyRef.current = true;
119
+ } catch {
120
+ // Host didn't grant phone-account permission, or the module isn't
121
+ // linked. The in-app ring screen still works, so stay quiet.
122
+ readyRef.current = false;
123
+ }
124
+ })();
125
+ return () => {
126
+ cancelled = true;
127
+ };
128
+ }, [callKeep]);
129
+
130
+ // Bridge native answer/end actions back into Redux.
131
+ (0, _react.useEffect)(() => {
132
+ if (!callKeep) {
133
+ return;
134
+ }
135
+ const onAnswer = () => {
136
+ // The user answered from the system screen, which on Android may
137
+ // mean the app was not even in the foreground.
138
+ callKeep.backToForeground?.();
139
+ if (_roomStore.store.getState().call.direction === 'incoming') {
140
+ dispatch((0, _callSlice.acceptIncomingCall)());
141
+ }
142
+ };
143
+ const onEnd = () => {
144
+ const snapshot = _roomStore.store.getState().call;
145
+ if (snapshot.phase === 'idle') {
146
+ return;
147
+ }
148
+ if (snapshot.direction === 'incoming' && snapshot.phase === 'ringing-incoming') {
149
+ (0, _callTokenStanza.sendCallStateSignal)('declined');
150
+ dispatch((0, _callSlice.declineIncomingCall)());
151
+ }
152
+ };
153
+ callKeep.addEventListener('answerCall', onAnswer);
154
+ callKeep.addEventListener('endCall', onEnd);
155
+ return () => {
156
+ callKeep.removeEventListener('answerCall');
157
+ callKeep.removeEventListener('endCall');
158
+ };
159
+ }, [callKeep, dispatch]);
160
+
161
+ // Show / dismiss the native screen as the call state changes.
162
+ (0, _react.useEffect)(() => {
163
+ if (!callKeep || !readyRef.current) {
164
+ return;
165
+ }
166
+ const isRinging = call.direction === 'incoming' && call.phase === 'ringing-incoming';
167
+ if (isRinging && !activeUuidRef.current) {
168
+ const uuid = toUuid(call.callId || call.roomJid || String(Date.now()));
169
+ activeUuidRef.current = uuid;
170
+ try {
171
+ callKeep.displayIncomingCall(uuid, call.peerXmppUsername || call.roomName || 'Ethora', call.roomName || undefined, 'generic', call.kind === 'video');
172
+ } catch {
173
+ activeUuidRef.current = null;
174
+ }
175
+ return;
176
+ }
177
+
178
+ // Any exit from ringing (answered in-app, declined, peer cancelled)
179
+ // must tear the system screen down or it hangs around ringing.
180
+ if (!isRinging && activeUuidRef.current && call.phase !== 'connecting' && call.phase !== 'in-call') {
181
+ try {
182
+ callKeep.endCall(activeUuidRef.current);
183
+ } catch {
184
+ // Screen already gone.
185
+ }
186
+ activeUuidRef.current = null;
187
+ }
188
+ if (call.phase === 'idle' && activeUuidRef.current) {
189
+ try {
190
+ callKeep.endCall(activeUuidRef.current);
191
+ } catch {
192
+ // noop
193
+ }
194
+ activeUuidRef.current = null;
195
+ }
196
+ }, [callKeep, call.direction, call.phase, call.callId, call.roomJid, call.roomName, call.peerXmppUsername, call.kind]);
197
+
198
+ // Nothing to clean up on unmount beyond the active screen: this hook
199
+ // lives for the lifetime of the provider.
200
+ (0, _react.useEffect)(() => () => {
201
+ if (callKeep && activeUuidRef.current) {
202
+ try {
203
+ callKeep.endCall(activeUuidRef.current);
204
+ } catch {
205
+ // noop
206
+ }
207
+ }
208
+ }, [callKeep]);
209
+
210
+ // iOS-only note kept as a runtime no-op so the import isn't unused when
211
+ // the platform check is tree-shaken in release builds.
212
+ void _reactNative.Platform.OS;
213
+ };
214
+ exports.useCallKeep = useCallKeep;
215
+ //# sourceMappingURL=useCallKeep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","require","_reactNative","_reactRedux","_roomStore","_callSlice","_callTokenStanza","cachedCallKeep","loadCallKeep","undefined","NativeModules","RNCallKeep","mod","default","exports","toUuid","seed","hash","bytes","i","ch","charCodeAt","Math","max","length","imul","push","hex","map","b","toString","padStart","join","slice","parseInt","useCallKeep","dispatch","useDispatch","call","useSelector","state","callKeep","useMemo","activeUuidRef","useRef","readyRef","useEffect","cancelled","setup","ios","appName","supportsVideo","android","alertTitle","alertDescription","cancelButton","okButton","additionalPermissions","foregroundService","channelId","channelName","notificationTitle","setAvailable","current","onAnswer","backToForeground","store","getState","direction","acceptIncomingCall","onEnd","snapshot","phase","sendCallStateSignal","declineIncomingCall","addEventListener","removeEventListener","isRinging","uuid","callId","roomJid","String","Date","now","displayIncomingCall","peerXmppUsername","roomName","kind","endCall","Platform","OS"],"sourceRoot":"../../../../src","sources":["components/VideoCalls/useCallKeep.ts"],"mappings":"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","ignoreList":[]}
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
- var _expoAv = require("expo-av");
9
+ var _expoAudio = require("expo-audio");
10
10
  var FileSystem = _interopRequireWildcard(require("expo-file-system/legacy"));
11
11
  var _reactNativeWebview = require("react-native-webview");
12
12
  var _icons = require("../../assets/icons");
@@ -129,11 +129,11 @@ const getContainerExtension = container => {
129
129
  }
130
130
  };
131
131
 
132
- // AVFoundation (expo-av) and the iOS WKWebView <audio> element cannot
132
+ // AVFoundation (expo-audio) and the iOS WKWebView <audio> element cannot
133
133
  // demux/decode WebM or Ogg Opus — only `AudioContext.decodeAudioData` can
134
134
  // on iOS. So on iOS those two containers go through the WebView decoder.
135
135
  // Everything else (mp3/m4a/aac/wav), and ALL of Android (ExoPlayer handles
136
- // Opus natively), plays straight through expo-av.
136
+ // Opus natively), plays straight through expo-audio.
137
137
  const requiresWebAudioDecode = container => _reactNative.Platform.OS === 'ios' && (container === 'webm' || container === 'ogg');
138
138
 
139
139
  // The WebView is used ONLY as a decoder, never as a player. Two iOS facts
@@ -145,7 +145,7 @@ const requiresWebAudioDecode = container => _reactNative.Platform.OS === 'ios' &
145
145
  // cannot supply, so both hang silently.
146
146
  // Therefore the page decodes Opus → PCM, re-encodes to a WAV blob, and ships
147
147
  // the bytes back to RN as base64. RN writes the WAV to cache and plays it
148
- // through expo-av (native, no gesture limits, real play/pause/seek).
148
+ // through expo-audio (native, no gesture limits, real play/pause/seek).
149
149
  const WEB_DECODER_HTML = `<!doctype html>
150
150
  <html>
151
151
  <head>
@@ -248,6 +248,10 @@ const AudioMessage = ({
248
248
  config
249
249
  } = (0, _useChatSettingState.useChatSettingState)();
250
250
  const soundRef = (0, _react.useRef)(null);
251
+ // expo-audio delivers progress through an event subscription instead of
252
+ // expo-av's `onPlaybackStatusUpdate` callback argument, so the handle has
253
+ // to be held and removed alongside the player itself.
254
+ const statusSubRef = (0, _react.useRef)(null);
251
255
  const webViewRef = (0, _react.useRef)(null);
252
256
  const preparedRef = (0, _react.useRef)(null);
253
257
  const bridgeReadyRef = (0, _react.useRef)(false);
@@ -268,6 +272,29 @@ const AudioMessage = ({
268
272
  loadingTimerRef.current = null;
269
273
  }
270
274
  };
275
+
276
+ // expo-audio players are native shared objects: they are NOT garbage
277
+ // collected with the component, so every one we create has to be
278
+ // explicitly `remove()`d (expo-av's `unloadAsync` equivalent) and its
279
+ // status subscription torn down first.
280
+ const releasePlayer = () => {
281
+ statusSubRef.current?.remove();
282
+ statusSubRef.current = null;
283
+ const player = soundRef.current;
284
+ soundRef.current = null;
285
+ if (player) {
286
+ try {
287
+ player.pause();
288
+ } catch {
289
+ /* already released */
290
+ }
291
+ try {
292
+ player.remove();
293
+ } catch {
294
+ /* already released */
295
+ }
296
+ }
297
+ };
271
298
  const fail = reason => {
272
299
  clearLoadingGuard();
273
300
  if (unmountedRef.current) {
@@ -290,7 +317,7 @@ const AudioMessage = ({
290
317
  };
291
318
 
292
319
  // Hard ceiling on the loading spinner — whatever stalls (a hung network
293
- // request, a WebView that never decodes, expo-av wedging on a bad file)
320
+ // request, a WebView that never decodes, a player that never loads)
294
321
  // the control resolves to an error state instead of spinning forever
295
322
  // (the customer-reported "stuck spinner").
296
323
  const armLoadingGuard = () => {
@@ -402,49 +429,72 @@ const AudioMessage = ({
402
429
  webViewRef.current.injectJavaScript(`window.__decodeAudio(${JSON.stringify(base64)}); true;`);
403
430
  }
404
431
  };
432
+
433
+ // expo-audio reports times in SECONDS (expo-av used milliseconds); the
434
+ // whole UI below is millisecond-based, so convert at this boundary and
435
+ // nowhere else.
405
436
  const onPlaybackStatusUpdate = status => {
406
437
  if (!status.isLoaded) {
407
- if (status.error) {
408
- logAudioDebug('playback status error', {
409
- src,
410
- error: status.error
411
- });
412
- }
413
438
  return;
414
439
  }
415
- setPosition(status.positionMillis);
416
- setDuration(status.durationMillis ?? 0);
417
- setIsPlaying(status.isPlaying);
440
+ setPosition(Math.max(0, status.currentTime * 1000));
441
+ setDuration(status.duration > 0 ? status.duration * 1000 : 0);
442
+ setIsPlaying(status.playing);
418
443
  if (status.didJustFinish) {
419
444
  didFinishRef.current = true;
420
445
  setIsPlaying(false);
421
446
  setPosition(0);
422
- void soundRef.current?.setStatusAsync({
423
- shouldPlay: false,
424
- positionMillis: 0
425
- });
447
+ const player = soundRef.current;
448
+ if (player) {
449
+ player.pause();
450
+ void player.seekTo(0);
451
+ }
426
452
  }
427
453
  };
428
454
  const startNativePlayback = async localUri => {
429
455
  try {
430
- await _expoAv.Audio.setAudioModeAsync({
431
- playsInSilentModeIOS: true
456
+ await (0, _expoAudio.setAudioModeAsync)({
457
+ playsInSilentMode: true
432
458
  });
433
459
  } catch {
434
460
  /* non-fatal — still plays through the ringer channel */
435
461
  }
436
- const {
437
- sound
438
- } = await withTimeout(_expoAv.Audio.Sound.createAsync({
462
+ // expo-audio has no awaitable `createAsync`: the player is constructed
463
+ // synchronously and loads in the background, reporting `isLoaded` via
464
+ // the status event. Wait for that first loaded status (same 12s budget
465
+ // expo-av's createAsync had) so the spinner still resolves to either
466
+ // real playback or the error state, never to a silent dead button.
467
+ const player = (0, _expoAudio.createAudioPlayer)({
439
468
  uri: localUri
440
469
  }, {
441
- shouldPlay: true
442
- }, onPlaybackStatusUpdate), 12000, 'audio_create_timeout');
470
+ updateInterval: 250
471
+ });
472
+ let settleLoaded = null;
473
+ const loaded = new Promise(resolve => {
474
+ settleLoaded = resolve;
475
+ });
476
+ const subscription = player.addListener('playbackStatusUpdate', status => {
477
+ if (status.isLoaded && settleLoaded) {
478
+ settleLoaded();
479
+ settleLoaded = null;
480
+ }
481
+ onPlaybackStatusUpdate(status);
482
+ });
483
+ try {
484
+ await withTimeout(loaded, 12000, 'audio_create_timeout');
485
+ } catch (error) {
486
+ subscription.remove();
487
+ player.remove();
488
+ throw error;
489
+ }
443
490
  if (unmountedRef.current) {
444
- void sound.unloadAsync();
491
+ subscription.remove();
492
+ player.remove();
445
493
  return;
446
494
  }
447
- soundRef.current = sound;
495
+ soundRef.current = player;
496
+ statusSubRef.current = subscription;
497
+ player.play();
448
498
  clearLoadingGuard();
449
499
  setIsLoading(false);
450
500
  setPlaybackError(false);
@@ -514,14 +564,21 @@ const AudioMessage = ({
514
564
  // decoded-WAV from the WebView path) → plain toggle.
515
565
  if (soundRef.current) {
516
566
  try {
567
+ // `play()` / `pause()` emit NO status event of their own (expo-av's
568
+ // playAsync/pauseAsync resolved with one). Playing state only ever
569
+ // reaches us through the periodic time observer, and that observer
570
+ // stops while paused — so without setting this here the button
571
+ // would latch on "pause" forever and never resume.
517
572
  if (isPlaying) {
518
- await soundRef.current.pauseAsync();
573
+ soundRef.current.pause();
574
+ setIsPlaying(false);
519
575
  } else {
520
576
  if (didFinishRef.current) {
521
- await soundRef.current.setPositionAsync(0);
577
+ await soundRef.current.seekTo(0);
522
578
  didFinishRef.current = false;
523
579
  }
524
- await soundRef.current.playAsync();
580
+ soundRef.current.play();
581
+ setIsPlaying(true);
525
582
  }
526
583
  } catch (error) {
527
584
  fail(error);
@@ -557,7 +614,7 @@ const AudioMessage = ({
557
614
  return () => {
558
615
  unmountedRef.current = true;
559
616
  clearLoadingGuard();
560
- soundRef.current?.unloadAsync();
617
+ releasePlayer();
561
618
  };
562
619
  // eslint-disable-next-line react-hooks/exhaustive-deps
563
620
  }, []);
@@ -565,8 +622,7 @@ const AudioMessage = ({
565
622
  // Full reset whenever the source changes (component reused for a new
566
623
  // message / re-render with a different src).
567
624
  (0, _react.useEffect)(() => {
568
- soundRef.current?.unloadAsync();
569
- soundRef.current = null;
625
+ releasePlayer();
570
626
  preparedRef.current = null;
571
627
  bridgeReadyRef.current = false;
572
628
  injectedRef.current = false;
@@ -604,6 +660,8 @@ const AudioMessage = ({
604
660
  }) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
605
661
  style: styles.container,
606
662
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
663
+ testID: "audio-play-button",
664
+ accessibilityLabel: "audio-play-button",
607
665
  style: [styles.playButton, {
608
666
  backgroundColor: primaryColor
609
667
  }],