@ethora/chat-component-rn 26.10.10 → 26.10.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 (483) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +125 -0
  3. package/lib/commonjs/booking/index.js +44 -0
  4. package/lib/commonjs/booking/index.js.map +1 -0
  5. package/lib/commonjs/booking/pendingScheduledCall.js +275 -0
  6. package/lib/commonjs/booking/pendingScheduledCall.js.map +1 -0
  7. package/lib/commonjs/booking/scheduleForm.js +91 -0
  8. package/lib/commonjs/booking/scheduleForm.js.map +1 -0
  9. package/lib/commonjs/booking/scheduledCall.js +141 -0
  10. package/lib/commonjs/booking/scheduledCall.js.map +1 -0
  11. package/lib/commonjs/booking/scheduledCallActions.js +128 -0
  12. package/lib/commonjs/booking/scheduledCallActions.js.map +1 -0
  13. package/lib/commonjs/booking/scheduledCallLink.js +143 -0
  14. package/lib/commonjs/booking/scheduledCallLink.js.map +1 -0
  15. package/lib/commonjs/booking/scheduledCallStore.js +64 -0
  16. package/lib/commonjs/booking/scheduledCallStore.js.map +1 -0
  17. package/lib/commonjs/booking/startRoomCall.js +84 -0
  18. package/lib/commonjs/booking/startRoomCall.js.map +1 -0
  19. package/lib/commonjs/calls/callBusy.js +18 -0
  20. package/lib/commonjs/calls/callBusy.js.map +1 -0
  21. package/lib/commonjs/calls/callDisplay.js +73 -0
  22. package/lib/commonjs/calls/callDisplay.js.map +1 -0
  23. package/lib/commonjs/calls/callMode.js +175 -0
  24. package/lib/commonjs/calls/callMode.js.map +1 -0
  25. package/lib/commonjs/calls/declineReport.js +20 -0
  26. package/lib/commonjs/calls/declineReport.js.map +1 -0
  27. package/lib/commonjs/calls/p2p/P2PCallController.js +724 -0
  28. package/lib/commonjs/calls/p2p/P2PCallController.js.map +1 -0
  29. package/lib/commonjs/calls/p2p/icePolicy.js +107 -0
  30. package/lib/commonjs/calls/p2p/icePolicy.js.map +1 -0
  31. package/lib/commonjs/calls/p2p/negotiator.js +202 -0
  32. package/lib/commonjs/calls/p2p/negotiator.js.map +1 -0
  33. package/lib/commonjs/calls/p2p/p2pRuntime.js +147 -0
  34. package/lib/commonjs/calls/p2p/p2pRuntime.js.map +1 -0
  35. package/lib/commonjs/calls/p2p/signalInbox.js +98 -0
  36. package/lib/commonjs/calls/p2p/signalInbox.js.map +1 -0
  37. package/lib/commonjs/calls/p2p/signalStanza.js +141 -0
  38. package/lib/commonjs/calls/p2p/signalStanza.js.map +1 -0
  39. package/lib/commonjs/calls/p2p/webrtcRuntime.js +53 -0
  40. package/lib/commonjs/calls/p2p/webrtcRuntime.js.map +1 -0
  41. package/lib/commonjs/calls/senderTrust.js +43 -0
  42. package/lib/commonjs/calls/senderTrust.js.map +1 -0
  43. package/lib/commonjs/calls/startCall.js +51 -0
  44. package/lib/commonjs/calls/startCall.js.map +1 -0
  45. package/lib/commonjs/components/Booking/BookingIcons.js +55 -0
  46. package/lib/commonjs/components/Booking/BookingIcons.js.map +1 -0
  47. package/lib/commonjs/components/Booking/ScheduleCallButton.js +64 -0
  48. package/lib/commonjs/components/Booking/ScheduleCallButton.js.map +1 -0
  49. package/lib/commonjs/components/Booking/ScheduleCallSheet.js +351 -0
  50. package/lib/commonjs/components/Booking/ScheduleCallSheet.js.map +1 -0
  51. package/lib/commonjs/components/Booking/ScheduledCallCard.js +203 -0
  52. package/lib/commonjs/components/Booking/ScheduledCallCard.js.map +1 -0
  53. package/lib/commonjs/components/Booking/ScheduledCallHost.js +23 -0
  54. package/lib/commonjs/components/Booking/ScheduledCallHost.js.map +1 -0
  55. package/lib/commonjs/components/Booking/ScheduledCallMessage.js +55 -0
  56. package/lib/commonjs/components/Booking/ScheduledCallMessage.js.map +1 -0
  57. package/lib/commonjs/components/Booking/ScheduledCallPreJoin.js +235 -0
  58. package/lib/commonjs/components/Booking/ScheduledCallPreJoin.js.map +1 -0
  59. package/lib/commonjs/components/Booking/bookingShared.js +305 -0
  60. package/lib/commonjs/components/Booking/bookingShared.js.map +1 -0
  61. package/lib/commonjs/components/MainComponents/ChatHeader.js +2 -1
  62. package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
  63. package/lib/commonjs/components/MainComponents/LanguageSelectorButton.js +5 -2
  64. package/lib/commonjs/components/MainComponents/LanguageSelectorButton.js.map +1 -1
  65. package/lib/commonjs/components/MainComponents/LanguageSelectorModal.js +6 -3
  66. package/lib/commonjs/components/MainComponents/LanguageSelectorModal.js.map +1 -1
  67. package/lib/commonjs/components/MainComponents/MessageContainer.js +13 -0
  68. package/lib/commonjs/components/MainComponents/MessageContainer.js.map +1 -1
  69. package/lib/commonjs/components/MainComponents/ReduxWrapper.js +10 -0
  70. package/lib/commonjs/components/MainComponents/ReduxWrapper.js.map +1 -1
  71. package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js +19 -15
  72. package/lib/commonjs/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -1
  73. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js +15 -8
  74. package/lib/commonjs/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  75. package/lib/commonjs/components/Modals/UserSettingsModal/LanguageCard.js +1 -1
  76. package/lib/commonjs/components/Modals/UserSettingsModal/LanguageCard.js.map +1 -1
  77. package/lib/commonjs/components/VideoCalls/ActiveCallBar.js +3 -2
  78. package/lib/commonjs/components/VideoCalls/ActiveCallBar.js.map +1 -1
  79. package/lib/commonjs/components/VideoCalls/CallButtons.js +19 -11
  80. package/lib/commonjs/components/VideoCalls/CallButtons.js.map +1 -1
  81. package/lib/commonjs/components/VideoCalls/CallControlBar.js +119 -0
  82. package/lib/commonjs/components/VideoCalls/CallControlBar.js.map +1 -0
  83. package/lib/commonjs/components/VideoCalls/CallVideo.js +49 -0
  84. package/lib/commonjs/components/VideoCalls/CallVideo.js.map +1 -0
  85. package/lib/commonjs/components/VideoCalls/GroupCallView.js +281 -0
  86. package/lib/commonjs/components/VideoCalls/GroupCallView.js.map +1 -0
  87. package/lib/commonjs/components/VideoCalls/P2PCallRunner.js +151 -0
  88. package/lib/commonjs/components/VideoCalls/P2PCallRunner.js.map +1 -0
  89. package/lib/commonjs/components/VideoCalls/VideoCallOverlay.js +38 -14
  90. package/lib/commonjs/components/VideoCalls/VideoCallOverlay.js.map +1 -1
  91. package/lib/commonjs/components/VideoCalls/VideoCallSession.js +57 -128
  92. package/lib/commonjs/components/VideoCalls/VideoCallSession.js.map +1 -1
  93. package/lib/commonjs/components/VideoCalls/callActions.js +3 -0
  94. package/lib/commonjs/components/VideoCalls/callActions.js.map +1 -1
  95. package/lib/commonjs/components/VideoCalls/callElapsed.js +38 -0
  96. package/lib/commonjs/components/VideoCalls/callElapsed.js.map +1 -0
  97. package/lib/commonjs/components/VideoCalls/callLive.js +15 -0
  98. package/lib/commonjs/components/VideoCalls/callLive.js.map +1 -0
  99. package/lib/commonjs/components/VideoCalls/callSessionController.js +81 -24
  100. package/lib/commonjs/components/VideoCalls/callSessionController.js.map +1 -1
  101. package/lib/commonjs/components/VideoCalls/callSessionTypes.js +41 -0
  102. package/lib/commonjs/components/VideoCalls/callSessionTypes.js.map +1 -0
  103. package/lib/commonjs/components/VideoCalls/groupLayout.js +43 -0
  104. package/lib/commonjs/components/VideoCalls/groupLayout.js.map +1 -0
  105. package/lib/commonjs/components/VideoCalls/p2pCallSession.js +272 -0
  106. package/lib/commonjs/components/VideoCalls/p2pCallSession.js.map +1 -0
  107. package/lib/commonjs/components/VideoCalls/useCallKeep.js +7 -2
  108. package/lib/commonjs/components/VideoCalls/useCallKeep.js.map +1 -1
  109. package/lib/commonjs/components/VideoCalls/useOngoingCallNotification.js +2 -1
  110. package/lib/commonjs/components/VideoCalls/useOngoingCallNotification.js.map +1 -1
  111. package/lib/commonjs/context/xmppProvider.js +2 -1
  112. package/lib/commonjs/context/xmppProvider.js.map +1 -1
  113. package/lib/commonjs/helpers/callPush.js +3 -1
  114. package/lib/commonjs/helpers/callPush.js.map +1 -1
  115. package/lib/commonjs/helpers/incomingCallFromPush.js +63 -7
  116. package/lib/commonjs/helpers/incomingCallFromPush.js.map +1 -1
  117. package/lib/commonjs/helpers/pushPayload.js +5 -0
  118. package/lib/commonjs/helpers/pushPayload.js.map +1 -1
  119. package/lib/commonjs/helpers/reportRoom.js +76 -0
  120. package/lib/commonjs/helpers/reportRoom.js.map +1 -0
  121. package/lib/commonjs/i18n/strings.js +444 -0
  122. package/lib/commonjs/i18n/strings.js.map +1 -1
  123. package/lib/commonjs/main.js +93 -0
  124. package/lib/commonjs/main.js.map +1 -1
  125. package/lib/commonjs/networking/api-requests/callState.api.js +75 -0
  126. package/lib/commonjs/networking/api-requests/callState.api.js.map +1 -0
  127. package/lib/commonjs/networking/api-requests/push.api.js +29 -6
  128. package/lib/commonjs/networking/api-requests/push.api.js.map +1 -1
  129. package/lib/commonjs/networking/api-requests/rooms.api.js +8 -2
  130. package/lib/commonjs/networking/api-requests/rooms.api.js.map +1 -1
  131. package/lib/commonjs/networking/api-requests/scheduledCalls.api.js +141 -0
  132. package/lib/commonjs/networking/api-requests/scheduledCalls.api.js.map +1 -0
  133. package/lib/commonjs/networking/callTokenStanza.js +210 -50
  134. package/lib/commonjs/networking/callTokenStanza.js.map +1 -1
  135. package/lib/commonjs/roomStore/callSlice.js +59 -4
  136. package/lib/commonjs/roomStore/callSlice.js.map +1 -1
  137. package/lib/commonjs/services/appBadge.js +80 -0
  138. package/lib/commonjs/services/appBadge.js.map +1 -0
  139. package/lib/commonjs/services/languageSettings.js +47 -15
  140. package/lib/commonjs/services/languageSettings.js.map +1 -1
  141. package/lib/commonjs/services/pushRegistration.js +21 -5
  142. package/lib/commonjs/services/pushRegistration.js.map +1 -1
  143. package/lib/commonjs/version.js +1 -1
  144. package/lib/module/booking/index.js +5 -0
  145. package/lib/module/booking/index.js.map +1 -0
  146. package/lib/module/booking/pendingScheduledCall.js +261 -0
  147. package/lib/module/booking/pendingScheduledCall.js.map +1 -0
  148. package/lib/module/booking/scheduleForm.js +79 -0
  149. package/lib/module/booking/scheduleForm.js.map +1 -0
  150. package/lib/module/booking/scheduledCall.js +129 -0
  151. package/lib/module/booking/scheduledCall.js.map +1 -0
  152. package/lib/module/booking/scheduledCallActions.js +118 -0
  153. package/lib/module/booking/scheduledCallActions.js.map +1 -0
  154. package/lib/module/booking/scheduledCallLink.js +136 -0
  155. package/lib/module/booking/scheduledCallLink.js.map +1 -0
  156. package/lib/module/booking/scheduledCallStore.js +60 -0
  157. package/lib/module/booking/scheduledCallStore.js.map +1 -0
  158. package/lib/module/booking/startRoomCall.js +80 -0
  159. package/lib/module/booking/startRoomCall.js.map +1 -0
  160. package/lib/module/calls/callBusy.js +13 -0
  161. package/lib/module/calls/callBusy.js.map +1 -0
  162. package/lib/module/calls/callDisplay.js +65 -0
  163. package/lib/module/calls/callDisplay.js.map +1 -0
  164. package/lib/module/calls/callMode.js +168 -0
  165. package/lib/module/calls/callMode.js.map +1 -0
  166. package/lib/module/calls/declineReport.js +16 -0
  167. package/lib/module/calls/declineReport.js.map +1 -0
  168. package/lib/module/calls/p2p/P2PCallController.js +718 -0
  169. package/lib/module/calls/p2p/P2PCallController.js.map +1 -0
  170. package/lib/module/calls/p2p/icePolicy.js +102 -0
  171. package/lib/module/calls/p2p/icePolicy.js.map +1 -0
  172. package/lib/module/calls/p2p/negotiator.js +197 -0
  173. package/lib/module/calls/p2p/negotiator.js.map +1 -0
  174. package/lib/module/calls/p2p/p2pRuntime.js +137 -0
  175. package/lib/module/calls/p2p/p2pRuntime.js.map +1 -0
  176. package/lib/module/calls/p2p/signalInbox.js +93 -0
  177. package/lib/module/calls/p2p/signalInbox.js.map +1 -0
  178. package/lib/module/calls/p2p/signalStanza.js +135 -0
  179. package/lib/module/calls/p2p/signalStanza.js.map +1 -0
  180. package/lib/module/calls/p2p/webrtcRuntime.js +46 -0
  181. package/lib/module/calls/p2p/webrtcRuntime.js.map +1 -0
  182. package/lib/module/calls/senderTrust.js +38 -0
  183. package/lib/module/calls/senderTrust.js.map +1 -0
  184. package/lib/module/calls/startCall.js +47 -0
  185. package/lib/module/calls/startCall.js.map +1 -0
  186. package/lib/module/components/Booking/BookingIcons.js +48 -0
  187. package/lib/module/components/Booking/BookingIcons.js.map +1 -0
  188. package/lib/module/components/Booking/ScheduleCallButton.js +59 -0
  189. package/lib/module/components/Booking/ScheduleCallButton.js.map +1 -0
  190. package/lib/module/components/Booking/ScheduleCallSheet.js +345 -0
  191. package/lib/module/components/Booking/ScheduleCallSheet.js.map +1 -0
  192. package/lib/module/components/Booking/ScheduledCallCard.js +197 -0
  193. package/lib/module/components/Booking/ScheduledCallCard.js.map +1 -0
  194. package/lib/module/components/Booking/ScheduledCallHost.js +18 -0
  195. package/lib/module/components/Booking/ScheduledCallHost.js.map +1 -0
  196. package/lib/module/components/Booking/ScheduledCallMessage.js +48 -0
  197. package/lib/module/components/Booking/ScheduledCallMessage.js.map +1 -0
  198. package/lib/module/components/Booking/ScheduledCallPreJoin.js +229 -0
  199. package/lib/module/components/Booking/ScheduledCallPreJoin.js.map +1 -0
  200. package/lib/module/components/Booking/bookingShared.js +291 -0
  201. package/lib/module/components/Booking/bookingShared.js.map +1 -0
  202. package/lib/module/components/MainComponents/ChatHeader.js +2 -1
  203. package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
  204. package/lib/module/components/MainComponents/LanguageSelectorButton.js +5 -2
  205. package/lib/module/components/MainComponents/LanguageSelectorButton.js.map +1 -1
  206. package/lib/module/components/MainComponents/LanguageSelectorModal.js +7 -4
  207. package/lib/module/components/MainComponents/LanguageSelectorModal.js.map +1 -1
  208. package/lib/module/components/MainComponents/MessageContainer.js +13 -0
  209. package/lib/module/components/MainComponents/MessageContainer.js.map +1 -1
  210. package/lib/module/components/MainComponents/ReduxWrapper.js +10 -0
  211. package/lib/module/components/MainComponents/ReduxWrapper.js.map +1 -1
  212. package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js +21 -15
  213. package/lib/module/components/Modals/ChatProfileModal/ReportChatModal.js.map +1 -1
  214. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js +17 -10
  215. package/lib/module/components/Modals/UserProfileModal/UserProfileModal.js.map +1 -1
  216. package/lib/module/components/Modals/UserSettingsModal/LanguageCard.js +1 -1
  217. package/lib/module/components/Modals/UserSettingsModal/LanguageCard.js.map +1 -1
  218. package/lib/module/components/VideoCalls/ActiveCallBar.js +3 -2
  219. package/lib/module/components/VideoCalls/ActiveCallBar.js.map +1 -1
  220. package/lib/module/components/VideoCalls/CallButtons.js +19 -11
  221. package/lib/module/components/VideoCalls/CallButtons.js.map +1 -1
  222. package/lib/module/components/VideoCalls/CallControlBar.js +113 -0
  223. package/lib/module/components/VideoCalls/CallControlBar.js.map +1 -0
  224. package/lib/module/components/VideoCalls/CallVideo.js +43 -0
  225. package/lib/module/components/VideoCalls/CallVideo.js.map +1 -0
  226. package/lib/module/components/VideoCalls/GroupCallView.js +275 -0
  227. package/lib/module/components/VideoCalls/GroupCallView.js.map +1 -0
  228. package/lib/module/components/VideoCalls/P2PCallRunner.js +147 -0
  229. package/lib/module/components/VideoCalls/P2PCallRunner.js.map +1 -0
  230. package/lib/module/components/VideoCalls/VideoCallOverlay.js +38 -14
  231. package/lib/module/components/VideoCalls/VideoCallOverlay.js.map +1 -1
  232. package/lib/module/components/VideoCalls/VideoCallSession.js +46 -127
  233. package/lib/module/components/VideoCalls/VideoCallSession.js.map +1 -1
  234. package/lib/module/components/VideoCalls/callActions.js +3 -0
  235. package/lib/module/components/VideoCalls/callActions.js.map +1 -1
  236. package/lib/module/components/VideoCalls/callElapsed.js +33 -0
  237. package/lib/module/components/VideoCalls/callElapsed.js.map +1 -0
  238. package/lib/module/components/VideoCalls/callLive.js +10 -0
  239. package/lib/module/components/VideoCalls/callLive.js.map +1 -0
  240. package/lib/module/components/VideoCalls/callSessionController.js +80 -24
  241. package/lib/module/components/VideoCalls/callSessionController.js.map +1 -1
  242. package/lib/module/components/VideoCalls/callSessionTypes.js +37 -0
  243. package/lib/module/components/VideoCalls/callSessionTypes.js.map +1 -0
  244. package/lib/module/components/VideoCalls/groupLayout.js +36 -0
  245. package/lib/module/components/VideoCalls/groupLayout.js.map +1 -0
  246. package/lib/module/components/VideoCalls/p2pCallSession.js +256 -0
  247. package/lib/module/components/VideoCalls/p2pCallSession.js.map +1 -0
  248. package/lib/module/components/VideoCalls/useCallKeep.js +8 -2
  249. package/lib/module/components/VideoCalls/useCallKeep.js.map +1 -1
  250. package/lib/module/components/VideoCalls/useOngoingCallNotification.js +2 -1
  251. package/lib/module/components/VideoCalls/useOngoingCallNotification.js.map +1 -1
  252. package/lib/module/context/xmppProvider.js +2 -1
  253. package/lib/module/context/xmppProvider.js.map +1 -1
  254. package/lib/module/helpers/callPush.js +3 -1
  255. package/lib/module/helpers/callPush.js.map +1 -1
  256. package/lib/module/helpers/incomingCallFromPush.js +63 -7
  257. package/lib/module/helpers/incomingCallFromPush.js.map +1 -1
  258. package/lib/module/helpers/pushPayload.js +5 -0
  259. package/lib/module/helpers/pushPayload.js.map +1 -1
  260. package/lib/module/helpers/reportRoom.js +70 -0
  261. package/lib/module/helpers/reportRoom.js.map +1 -0
  262. package/lib/module/i18n/strings.js +444 -0
  263. package/lib/module/i18n/strings.js.map +1 -1
  264. package/lib/module/main.js +5 -0
  265. package/lib/module/main.js.map +1 -1
  266. package/lib/module/networking/api-requests/callState.api.js +66 -0
  267. package/lib/module/networking/api-requests/callState.api.js.map +1 -0
  268. package/lib/module/networking/api-requests/push.api.js +29 -6
  269. package/lib/module/networking/api-requests/push.api.js.map +1 -1
  270. package/lib/module/networking/api-requests/rooms.api.js +8 -2
  271. package/lib/module/networking/api-requests/rooms.api.js.map +1 -1
  272. package/lib/module/networking/api-requests/scheduledCalls.api.js +130 -0
  273. package/lib/module/networking/api-requests/scheduledCalls.api.js.map +1 -0
  274. package/lib/module/networking/callTokenStanza.js +210 -50
  275. package/lib/module/networking/callTokenStanza.js.map +1 -1
  276. package/lib/module/roomStore/callSlice.js +57 -3
  277. package/lib/module/roomStore/callSlice.js.map +1 -1
  278. package/lib/module/services/appBadge.js +74 -0
  279. package/lib/module/services/appBadge.js.map +1 -0
  280. package/lib/module/services/languageSettings.js +44 -13
  281. package/lib/module/services/languageSettings.js.map +1 -1
  282. package/lib/module/services/pushRegistration.js +21 -5
  283. package/lib/module/services/pushRegistration.js.map +1 -1
  284. package/lib/module/version.js +1 -1
  285. package/lib/typescript/booking/index.d.ts +3 -0
  286. package/lib/typescript/booking/index.d.ts.map +1 -0
  287. package/lib/typescript/booking/pendingScheduledCall.d.ts +80 -0
  288. package/lib/typescript/booking/pendingScheduledCall.d.ts.map +1 -0
  289. package/lib/typescript/booking/scheduleForm.d.ts +28 -0
  290. package/lib/typescript/booking/scheduleForm.d.ts.map +1 -0
  291. package/lib/typescript/booking/scheduledCall.d.ts +52 -0
  292. package/lib/typescript/booking/scheduledCall.d.ts.map +1 -0
  293. package/lib/typescript/booking/scheduledCallActions.d.ts +22 -0
  294. package/lib/typescript/booking/scheduledCallActions.d.ts.map +1 -0
  295. package/lib/typescript/booking/scheduledCallLink.d.ts +37 -0
  296. package/lib/typescript/booking/scheduledCallLink.d.ts.map +1 -0
  297. package/lib/typescript/booking/scheduledCallStore.d.ts +47 -0
  298. package/lib/typescript/booking/scheduledCallStore.d.ts.map +1 -0
  299. package/lib/typescript/booking/startRoomCall.d.ts +12 -0
  300. package/lib/typescript/booking/startRoomCall.d.ts.map +1 -0
  301. package/lib/typescript/calls/callBusy.d.ts +9 -0
  302. package/lib/typescript/calls/callBusy.d.ts.map +1 -0
  303. package/lib/typescript/calls/callDisplay.d.ts +23 -0
  304. package/lib/typescript/calls/callDisplay.d.ts.map +1 -0
  305. package/lib/typescript/calls/callMode.d.ts +106 -0
  306. package/lib/typescript/calls/callMode.d.ts.map +1 -0
  307. package/lib/typescript/calls/declineReport.d.ts +11 -0
  308. package/lib/typescript/calls/declineReport.d.ts.map +1 -0
  309. package/lib/typescript/calls/p2p/P2PCallController.d.ts +150 -0
  310. package/lib/typescript/calls/p2p/P2PCallController.d.ts.map +1 -0
  311. package/lib/typescript/calls/p2p/icePolicy.d.ts +37 -0
  312. package/lib/typescript/calls/p2p/icePolicy.d.ts.map +1 -0
  313. package/lib/typescript/calls/p2p/negotiator.d.ts +57 -0
  314. package/lib/typescript/calls/p2p/negotiator.d.ts.map +1 -0
  315. package/lib/typescript/calls/p2p/p2pRuntime.d.ts +41 -0
  316. package/lib/typescript/calls/p2p/p2pRuntime.d.ts.map +1 -0
  317. package/lib/typescript/calls/p2p/signalInbox.d.ts +35 -0
  318. package/lib/typescript/calls/p2p/signalInbox.d.ts.map +1 -0
  319. package/lib/typescript/calls/p2p/signalStanza.d.ts +52 -0
  320. package/lib/typescript/calls/p2p/signalStanza.d.ts.map +1 -0
  321. package/lib/typescript/calls/p2p/webrtcRuntime.d.ts +32 -0
  322. package/lib/typescript/calls/p2p/webrtcRuntime.d.ts.map +1 -0
  323. package/lib/typescript/calls/senderTrust.d.ts +8 -0
  324. package/lib/typescript/calls/senderTrust.d.ts.map +1 -0
  325. package/lib/typescript/calls/startCall.d.ts +17 -0
  326. package/lib/typescript/calls/startCall.d.ts.map +1 -0
  327. package/lib/typescript/components/Booking/BookingIcons.d.ts +9 -0
  328. package/lib/typescript/components/Booking/BookingIcons.d.ts.map +1 -0
  329. package/lib/typescript/components/Booking/ScheduleCallButton.d.ts +11 -0
  330. package/lib/typescript/components/Booking/ScheduleCallButton.d.ts.map +1 -0
  331. package/lib/typescript/components/Booking/ScheduleCallSheet.d.ts +4 -0
  332. package/lib/typescript/components/Booking/ScheduleCallSheet.d.ts.map +1 -0
  333. package/lib/typescript/components/Booking/ScheduledCallCard.d.ts +14 -0
  334. package/lib/typescript/components/Booking/ScheduledCallCard.d.ts.map +1 -0
  335. package/lib/typescript/components/Booking/ScheduledCallHost.d.ts +10 -0
  336. package/lib/typescript/components/Booking/ScheduledCallHost.d.ts.map +1 -0
  337. package/lib/typescript/components/Booking/ScheduledCallMessage.d.ts +20 -0
  338. package/lib/typescript/components/Booking/ScheduledCallMessage.d.ts.map +1 -0
  339. package/lib/typescript/components/Booking/ScheduledCallPreJoin.d.ts +8 -0
  340. package/lib/typescript/components/Booking/ScheduledCallPreJoin.d.ts.map +1 -0
  341. package/lib/typescript/components/Booking/bookingShared.d.ts +199 -0
  342. package/lib/typescript/components/Booking/bookingShared.d.ts.map +1 -0
  343. package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
  344. package/lib/typescript/components/MainComponents/LanguageSelectorButton.d.ts +3 -1
  345. package/lib/typescript/components/MainComponents/LanguageSelectorButton.d.ts.map +1 -1
  346. package/lib/typescript/components/MainComponents/LanguageSelectorModal.d.ts.map +1 -1
  347. package/lib/typescript/components/MainComponents/MessageContainer.d.ts.map +1 -1
  348. package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts.map +1 -1
  349. package/lib/typescript/components/Modals/ChatProfileModal/ReportChatModal.d.ts.map +1 -1
  350. package/lib/typescript/components/Modals/UserProfileModal/UserProfileModal.d.ts.map +1 -1
  351. package/lib/typescript/components/Modals/UserSettingsModal/LanguageCard.d.ts.map +1 -1
  352. package/lib/typescript/components/VideoCalls/ActiveCallBar.d.ts.map +1 -1
  353. package/lib/typescript/components/VideoCalls/CallButtons.d.ts +2 -1
  354. package/lib/typescript/components/VideoCalls/CallButtons.d.ts.map +1 -1
  355. package/lib/typescript/components/VideoCalls/CallControlBar.d.ts +17 -0
  356. package/lib/typescript/components/VideoCalls/CallControlBar.d.ts.map +1 -0
  357. package/lib/typescript/components/VideoCalls/CallVideo.d.ts +23 -0
  358. package/lib/typescript/components/VideoCalls/CallVideo.d.ts.map +1 -0
  359. package/lib/typescript/components/VideoCalls/GroupCallView.d.ts +22 -0
  360. package/lib/typescript/components/VideoCalls/GroupCallView.d.ts.map +1 -0
  361. package/lib/typescript/components/VideoCalls/P2PCallRunner.d.ts +2 -0
  362. package/lib/typescript/components/VideoCalls/P2PCallRunner.d.ts.map +1 -0
  363. package/lib/typescript/components/VideoCalls/VideoCallOverlay.d.ts.map +1 -1
  364. package/lib/typescript/components/VideoCalls/VideoCallSession.d.ts +10 -12
  365. package/lib/typescript/components/VideoCalls/VideoCallSession.d.ts.map +1 -1
  366. package/lib/typescript/components/VideoCalls/callActions.d.ts.map +1 -1
  367. package/lib/typescript/components/VideoCalls/callElapsed.d.ts +8 -0
  368. package/lib/typescript/components/VideoCalls/callElapsed.d.ts.map +1 -0
  369. package/lib/typescript/components/VideoCalls/callLive.d.ts +9 -0
  370. package/lib/typescript/components/VideoCalls/callLive.d.ts.map +1 -0
  371. package/lib/typescript/components/VideoCalls/callSessionController.d.ts +10 -31
  372. package/lib/typescript/components/VideoCalls/callSessionController.d.ts.map +1 -1
  373. package/lib/typescript/components/VideoCalls/callSessionTypes.d.ts +60 -0
  374. package/lib/typescript/components/VideoCalls/callSessionTypes.d.ts.map +1 -0
  375. package/lib/typescript/components/VideoCalls/groupLayout.d.ts +23 -0
  376. package/lib/typescript/components/VideoCalls/groupLayout.d.ts.map +1 -0
  377. package/lib/typescript/components/VideoCalls/p2pCallSession.d.ts +31 -0
  378. package/lib/typescript/components/VideoCalls/p2pCallSession.d.ts.map +1 -0
  379. package/lib/typescript/components/VideoCalls/useCallKeep.d.ts.map +1 -1
  380. package/lib/typescript/components/VideoCalls/useOngoingCallNotification.d.ts.map +1 -1
  381. package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
  382. package/lib/typescript/helpers/callPush.d.ts +11 -1
  383. package/lib/typescript/helpers/callPush.d.ts.map +1 -1
  384. package/lib/typescript/helpers/incomingCallFromPush.d.ts.map +1 -1
  385. package/lib/typescript/helpers/pushPayload.d.ts +1 -1
  386. package/lib/typescript/helpers/pushPayload.d.ts.map +1 -1
  387. package/lib/typescript/helpers/reportRoom.d.ts +19 -0
  388. package/lib/typescript/helpers/reportRoom.d.ts.map +1 -0
  389. package/lib/typescript/i18n/strings.d.ts.map +1 -1
  390. package/lib/typescript/main.d.ts +6 -1
  391. package/lib/typescript/main.d.ts.map +1 -1
  392. package/lib/typescript/networking/api-requests/callState.api.d.ts +25 -0
  393. package/lib/typescript/networking/api-requests/callState.api.d.ts.map +1 -0
  394. package/lib/typescript/networking/api-requests/push.api.d.ts +9 -2
  395. package/lib/typescript/networking/api-requests/push.api.d.ts.map +1 -1
  396. package/lib/typescript/networking/api-requests/rooms.api.d.ts +2 -1
  397. package/lib/typescript/networking/api-requests/rooms.api.d.ts.map +1 -1
  398. package/lib/typescript/networking/api-requests/scheduledCalls.api.d.ts +86 -0
  399. package/lib/typescript/networking/api-requests/scheduledCalls.api.d.ts.map +1 -0
  400. package/lib/typescript/networking/callTokenStanza.d.ts.map +1 -1
  401. package/lib/typescript/roomStore/callSlice.d.ts +23 -1
  402. package/lib/typescript/roomStore/callSlice.d.ts.map +1 -1
  403. package/lib/typescript/services/appBadge.d.ts +3 -0
  404. package/lib/typescript/services/appBadge.d.ts.map +1 -0
  405. package/lib/typescript/services/languageSettings.d.ts +7 -0
  406. package/lib/typescript/services/languageSettings.d.ts.map +1 -1
  407. package/lib/typescript/services/pushRegistration.d.ts.map +1 -1
  408. package/lib/typescript/types/types.d.ts +67 -4
  409. package/lib/typescript/types/types.d.ts.map +1 -1
  410. package/lib/typescript/version.d.ts +1 -1
  411. package/package.json +1 -1
  412. package/src/booking/index.ts +10 -0
  413. package/src/booking/pendingScheduledCall.ts +272 -0
  414. package/src/booking/scheduleForm.ts +84 -0
  415. package/src/booking/scheduledCall.ts +163 -0
  416. package/src/booking/scheduledCallActions.ts +141 -0
  417. package/src/booking/scheduledCallLink.ts +145 -0
  418. package/src/booking/scheduledCallStore.ts +69 -0
  419. package/src/booking/startRoomCall.ts +103 -0
  420. package/src/calls/callBusy.ts +10 -0
  421. package/src/calls/callDisplay.ts +74 -0
  422. package/src/calls/callMode.ts +286 -0
  423. package/src/calls/declineReport.ts +16 -0
  424. package/src/calls/p2p/P2PCallController.ts +813 -0
  425. package/src/calls/p2p/icePolicy.ts +99 -0
  426. package/src/calls/p2p/negotiator.ts +186 -0
  427. package/src/calls/p2p/p2pRuntime.ts +164 -0
  428. package/src/calls/p2p/signalInbox.ts +117 -0
  429. package/src/calls/p2p/signalStanza.ts +205 -0
  430. package/src/calls/p2p/webrtcRuntime.ts +60 -0
  431. package/src/calls/senderTrust.ts +40 -0
  432. package/src/calls/startCall.ts +56 -0
  433. package/src/components/Booking/BookingIcons.tsx +44 -0
  434. package/src/components/Booking/ScheduleCallButton.tsx +66 -0
  435. package/src/components/Booking/ScheduleCallSheet.tsx +380 -0
  436. package/src/components/Booking/ScheduledCallCard.tsx +216 -0
  437. package/src/components/Booking/ScheduledCallHost.tsx +18 -0
  438. package/src/components/Booking/ScheduledCallMessage.tsx +62 -0
  439. package/src/components/Booking/ScheduledCallPreJoin.tsx +230 -0
  440. package/src/components/Booking/bookingShared.tsx +295 -0
  441. package/src/components/MainComponents/ChatHeader.tsx +2 -0
  442. package/src/components/MainComponents/LanguageSelectorButton.tsx +9 -2
  443. package/src/components/MainComponents/LanguageSelectorModal.tsx +10 -6
  444. package/src/components/MainComponents/MessageContainer.tsx +15 -0
  445. package/src/components/MainComponents/ReduxWrapper.tsx +10 -0
  446. package/src/components/Modals/ChatProfileModal/ReportChatModal.tsx +22 -22
  447. package/src/components/Modals/UserProfileModal/UserProfileModal.tsx +28 -9
  448. package/src/components/Modals/UserSettingsModal/LanguageCard.tsx +9 -7
  449. package/src/components/VideoCalls/ActiveCallBar.tsx +6 -5
  450. package/src/components/VideoCalls/CallButtons.tsx +23 -12
  451. package/src/components/VideoCalls/CallControlBar.tsx +131 -0
  452. package/src/components/VideoCalls/CallVideo.tsx +59 -0
  453. package/src/components/VideoCalls/GroupCallView.tsx +324 -0
  454. package/src/components/VideoCalls/P2PCallRunner.tsx +192 -0
  455. package/src/components/VideoCalls/VideoCallOverlay.tsx +62 -17
  456. package/src/components/VideoCalls/VideoCallSession.tsx +55 -133
  457. package/src/components/VideoCalls/callActions.ts +3 -0
  458. package/src/components/VideoCalls/callElapsed.ts +27 -0
  459. package/src/components/VideoCalls/callLive.ts +13 -0
  460. package/src/components/VideoCalls/callSessionController.ts +130 -55
  461. package/src/components/VideoCalls/callSessionTypes.ts +80 -0
  462. package/src/components/VideoCalls/groupLayout.ts +48 -0
  463. package/src/components/VideoCalls/p2pCallSession.ts +291 -0
  464. package/src/components/VideoCalls/useCallKeep.ts +9 -2
  465. package/src/components/VideoCalls/useOngoingCallNotification.ts +2 -2
  466. package/src/context/xmppProvider.tsx +3 -0
  467. package/src/helpers/callPush.ts +13 -1
  468. package/src/helpers/incomingCallFromPush.ts +65 -7
  469. package/src/helpers/pushPayload.ts +9 -1
  470. package/src/helpers/reportRoom.ts +93 -0
  471. package/src/i18n/strings.ts +444 -0
  472. package/src/main.ts +33 -0
  473. package/src/networking/api-requests/callState.api.ts +83 -0
  474. package/src/networking/api-requests/push.api.ts +28 -3
  475. package/src/networking/api-requests/rooms.api.ts +12 -3
  476. package/src/networking/api-requests/scheduledCalls.api.ts +232 -0
  477. package/src/networking/callTokenStanza.ts +247 -50
  478. package/src/roomStore/callSlice.ts +86 -2
  479. package/src/services/appBadge.ts +85 -0
  480. package/src/services/languageSettings.ts +43 -8
  481. package/src/services/pushRegistration.ts +34 -3
  482. package/src/types/types.ts +70 -4
  483. package/src/version.ts +1 -1
@@ -0,0 +1,324 @@
1
+ import React, { FC } from 'react';
2
+ import {
3
+ ScrollView,
4
+ StyleSheet,
5
+ Text,
6
+ TouchableOpacity,
7
+ useWindowDimensions,
8
+ View,
9
+ } from 'react-native';
10
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
11
+ import { VideoCallIcons } from '../../types/types';
12
+ import { ProfileImagePlaceholder } from '../MainComponents/ProfileImagePlaceholder';
13
+ import { CallVideo } from './CallVideo';
14
+ import { CallControlBar } from './CallControlBar';
15
+ import { MicOffIcon, MinimizeIcon } from './CallIcons';
16
+ import { dismissCallDeviceError } from './callSessionController';
17
+ import type { CallParticipantView, CallSessionSnapshot } from './callSessionTypes';
18
+ import { gridColumns, pickVideoTiles, speakingNames } from './groupLayout';
19
+ import { formatCallDuration, useSharedCallElapsed } from './callElapsed';
20
+ import { useT } from '../../i18n/useT';
21
+
22
+ const SURFACE_DARK = '#0B1220';
23
+ const TILE_DARK = '#111827';
24
+ const TEXT_ON_DARK = '#FFFFFF';
25
+ const TEXT_MUTED = 'rgba(255, 255, 255, 0.7)';
26
+ const DANGER = '#E53935';
27
+ const GAP = 8;
28
+ const PAD = 12;
29
+
30
+ interface GroupCallViewProps {
31
+ session: CallSessionSnapshot;
32
+ kind: 'audio' | 'video';
33
+ /** Room name; a neutral label is shown when it is empty. */
34
+ title?: string | null;
35
+ primaryColor: string;
36
+ icons?: VideoCallIcons;
37
+ onToggleMinimize?: () => void;
38
+ onHangup: () => void;
39
+ }
40
+
41
+ interface TileProps {
42
+ participant: CallParticipantView;
43
+ width: number;
44
+ height: number;
45
+ showVideo: boolean;
46
+ primaryColor: string;
47
+ youLabel: string;
48
+ fallbackName: string;
49
+ micOffLabel: string;
50
+ }
51
+
52
+ const ParticipantTile: FC<TileProps> = ({
53
+ participant,
54
+ width,
55
+ height,
56
+ showVideo,
57
+ primaryColor,
58
+ youLabel,
59
+ fallbackName,
60
+ micOffLabel,
61
+ }) => {
62
+ const name = participant.isLocal
63
+ ? youLabel
64
+ : participant.name || fallbackName;
65
+ return (
66
+ <View
67
+ testID="group-call-tile"
68
+ accessibilityLabel={name}
69
+ style={[
70
+ styles.tile,
71
+ { width, height },
72
+ participant.speaking
73
+ ? [styles.tileSpeaking, { borderColor: primaryColor }]
74
+ : styles.tileIdle,
75
+ ]}
76
+ >
77
+ {showVideo && participant.video ? (
78
+ <CallVideo
79
+ source={participant.video}
80
+ style={StyleSheet.absoluteFill}
81
+ objectFit="cover"
82
+ // Mirror our own camera like every call app.
83
+ mirror={participant.isLocal}
84
+ zOrder={0}
85
+ />
86
+ ) : (
87
+ <ProfileImagePlaceholder
88
+ name={name}
89
+ size={Math.max(48, Math.min(96, Math.round(width * 0.4)))}
90
+ />
91
+ )}
92
+ <View style={styles.nameTag}>
93
+ {participant.micMuted && (
94
+ <View
95
+ accessibilityLabel={micOffLabel}
96
+ style={styles.micOffBadge}
97
+ >
98
+ <MicOffIcon color={TEXT_ON_DARK} size={11} />
99
+ </View>
100
+ )}
101
+ <Text style={styles.nameText} numberOfLines={1}>
102
+ {name}
103
+ </Text>
104
+ </View>
105
+ </View>
106
+ );
107
+ };
108
+
109
+ /**
110
+ * The group call screen: everyone in the room as a grid of tiles, the person
111
+ * who is speaking outlined, a mic-off badge on anyone muted. Cameras are drawn
112
+ * for at most MAX_VIDEO_TILES people (speakers first). Nothing here assumes
113
+ * two people; the 1:1 layout stays in VideoCallSession.
114
+ */
115
+ export const GroupCallView: FC<GroupCallViewProps> = ({
116
+ session,
117
+ kind,
118
+ title,
119
+ primaryColor,
120
+ icons,
121
+ onToggleMinimize,
122
+ onHangup,
123
+ }) => {
124
+ const t = useT();
125
+ const insets = useSafeAreaInsets();
126
+ const { width, height } = useWindowDimensions();
127
+ const elapsed = useSharedCallElapsed(session.anchorAt);
128
+ const { participants, deviceError, connected } = session;
129
+ const isVideo = kind === 'video';
130
+
131
+ const columns = gridColumns(participants.length, width > height);
132
+ const tileWidth = Math.floor(
133
+ (width - PAD * 2 - GAP * (columns - 1)) / columns
134
+ );
135
+ const tileHeight =
136
+ columns === 1
137
+ ? Math.round(tileWidth * 0.75)
138
+ : Math.round(tileWidth * (isVideo ? 1.15 : 0.85));
139
+ const videoIds = isVideo ? pickVideoTiles(participants) : new Set<string>();
140
+
141
+ const speaking = speakingNames(participants, t('call.participant.you'));
142
+ const countLabel = t('call.status.participants', { count: participants.length });
143
+ const status =
144
+ elapsed !== null
145
+ ? `${countLabel} · ${formatCallDuration(elapsed)}`
146
+ : !connected
147
+ ? t('call.status.connecting')
148
+ : t('call.status.waitingForOthers');
149
+ const heading =
150
+ title || (isVideo ? t('call.groupVideoCall') : t('call.groupAudioCall'));
151
+
152
+ return (
153
+ <View style={styles.canvas}>
154
+ <View style={[styles.header, { paddingTop: 14 + insets.top }]}>
155
+ <Text style={styles.headerTitle} numberOfLines={1}>
156
+ {heading}
157
+ </Text>
158
+ <Text style={styles.headerStatus} numberOfLines={1}>
159
+ {status}
160
+ </Text>
161
+ {speaking.length > 0 && (
162
+ <Text style={styles.headerSpeaking} numberOfLines={1}>
163
+ {t('call.status.speaking', { names: speaking.join(', ') })}
164
+ </Text>
165
+ )}
166
+ </View>
167
+
168
+ {onToggleMinimize && (
169
+ <TouchableOpacity
170
+ accessibilityRole="button"
171
+ accessibilityLabel={t('call.action.minimize')}
172
+ onPress={onToggleMinimize}
173
+ style={[styles.minimizeButton, { top: 12 + insets.top }]}
174
+ >
175
+ <MinimizeIcon color={TEXT_ON_DARK} size={20} />
176
+ </TouchableOpacity>
177
+ )}
178
+
179
+ {!!deviceError && (
180
+ <TouchableOpacity
181
+ style={styles.deviceErrorBanner}
182
+ onPress={dismissCallDeviceError}
183
+ accessibilityRole="button"
184
+ >
185
+ <Text style={styles.deviceErrorText} numberOfLines={2}>
186
+ {deviceError}
187
+ </Text>
188
+ </TouchableOpacity>
189
+ )}
190
+
191
+ <ScrollView
192
+ testID="group-call-grid"
193
+ style={styles.scroll}
194
+ contentContainerStyle={styles.grid}
195
+ >
196
+ {participants.map((participant) => (
197
+ <ParticipantTile
198
+ key={participant.identity || (participant.isLocal ? 'local' : participant.name)}
199
+ participant={participant}
200
+ width={tileWidth}
201
+ height={tileHeight}
202
+ showVideo={videoIds.has(participant.identity)}
203
+ primaryColor={primaryColor}
204
+ youLabel={t('call.participant.you')}
205
+ fallbackName={t('call.participant.default')}
206
+ micOffLabel={t('call.participant.micOff')}
207
+ />
208
+ ))}
209
+ </ScrollView>
210
+
211
+ <CallControlBar
212
+ session={session}
213
+ isVideo={isVideo}
214
+ icons={icons}
215
+ onHangup={onHangup}
216
+ />
217
+ </View>
218
+ );
219
+ };
220
+
221
+ const styles = StyleSheet.create({
222
+ canvas: {
223
+ flex: 1,
224
+ backgroundColor: SURFACE_DARK,
225
+ },
226
+ header: {
227
+ paddingHorizontal: 64,
228
+ paddingBottom: 10,
229
+ alignItems: 'center',
230
+ gap: 2,
231
+ },
232
+ headerTitle: {
233
+ color: TEXT_ON_DARK,
234
+ fontSize: 16,
235
+ fontWeight: '600',
236
+ },
237
+ headerStatus: {
238
+ color: TEXT_MUTED,
239
+ fontSize: 13,
240
+ fontVariant: ['tabular-nums'],
241
+ },
242
+ headerSpeaking: {
243
+ color: TEXT_MUTED,
244
+ fontSize: 12,
245
+ },
246
+ minimizeButton: {
247
+ position: 'absolute',
248
+ left: 16,
249
+ width: 36,
250
+ height: 36,
251
+ borderRadius: 18,
252
+ alignItems: 'center',
253
+ justifyContent: 'center',
254
+ backgroundColor: 'rgba(255, 255, 255, 0.14)',
255
+ zIndex: 6,
256
+ },
257
+ scroll: {
258
+ flex: 1,
259
+ },
260
+ grid: {
261
+ flexDirection: 'row',
262
+ flexWrap: 'wrap',
263
+ justifyContent: 'center',
264
+ alignContent: 'flex-start',
265
+ gap: GAP,
266
+ paddingHorizontal: PAD,
267
+ paddingBottom: PAD,
268
+ },
269
+ tile: {
270
+ borderRadius: 16,
271
+ overflow: 'hidden',
272
+ backgroundColor: TILE_DARK,
273
+ alignItems: 'center',
274
+ justifyContent: 'center',
275
+ },
276
+ tileSpeaking: {
277
+ borderWidth: 3,
278
+ },
279
+ tileIdle: {
280
+ borderWidth: 1,
281
+ borderColor: 'rgba(255, 255, 255, 0.12)',
282
+ },
283
+ nameTag: {
284
+ position: 'absolute',
285
+ left: 8,
286
+ bottom: 8,
287
+ maxWidth: '90%',
288
+ flexDirection: 'row',
289
+ alignItems: 'center',
290
+ gap: 6,
291
+ paddingVertical: 3,
292
+ paddingHorizontal: 8,
293
+ borderRadius: 999,
294
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
295
+ },
296
+ nameText: {
297
+ color: TEXT_ON_DARK,
298
+ fontSize: 13,
299
+ flexShrink: 1,
300
+ },
301
+ micOffBadge: {
302
+ width: 18,
303
+ height: 18,
304
+ borderRadius: 9,
305
+ backgroundColor: DANGER,
306
+ alignItems: 'center',
307
+ justifyContent: 'center',
308
+ },
309
+ deviceErrorBanner: {
310
+ marginHorizontal: 16,
311
+ marginBottom: 8,
312
+ backgroundColor: 'rgba(229, 57, 53, 0.92)',
313
+ borderRadius: 12,
314
+ paddingVertical: 10,
315
+ paddingHorizontal: 14,
316
+ },
317
+ deviceErrorText: {
318
+ color: TEXT_ON_DARK,
319
+ fontSize: 13,
320
+ textAlign: 'center',
321
+ },
322
+ });
323
+
324
+ export default GroupCallView;
@@ -0,0 +1,192 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import { useDispatch, useSelector } from 'react-redux';
3
+ import { RootState, store } from '../../roomStore';
4
+ import { endCall, setCallError, setCallPhase } from '../../roomStore/callSlice';
5
+ import { useChatSettingState } from '../../hooks/useChatSettingState';
6
+ import {
7
+ P2PCallController,
8
+ remoteEndNotice,
9
+ } from '../../calls/p2p/P2PCallController';
10
+ import {
11
+ acquireP2PController,
12
+ createNativeP2PDeps,
13
+ p2pInbox,
14
+ releaseP2PController,
15
+ } from '../../calls/p2p/p2pRuntime';
16
+ import { isP2PAvailable } from '../../calls/p2p/webrtcRuntime';
17
+ import {
18
+ reportCallConnected,
19
+ reportCallDeclined,
20
+ reportCallEnded,
21
+ reportCallRinging,
22
+ } from '../../networking/api-requests/callState.api';
23
+ import { translateCallString } from './callActions';
24
+ import {
25
+ bindP2PSession,
26
+ localizeP2PMessage,
27
+ startP2PController,
28
+ } from './p2pCallSession';
29
+
30
+ // Headless owner of the p2p controller for the call in the redux call slice.
31
+ // It builds the controller when a p2p call needs one, wires its events back
32
+ // into the slice, and releases it on EVERY way a call can stop (the phase goes
33
+ // idle or error, the call changes, the overlay unmounts), which is what keeps
34
+ // camera, microphone and the peer connection from leaking.
35
+ //
36
+ // caller: the controller exists from the moment the create response says
37
+ // `p2p` and starts at once (media, offer);
38
+ // callee: the controller exists while the incoming call rings, so the
39
+ // caller's offer / candidates / cancel are caught, but it only
40
+ // starts (media, answer) after the user accepts.
41
+ //
42
+ // RN specific: the call also rings from a VoIP push, with the app still
43
+ // starting. The caller keeps re-sending its offer for the whole ring window
44
+ // (longer than on web) because a cold-started callee may need several seconds
45
+ // to bring the XMPP socket up.
46
+
47
+ const RN_OFFER_RESEND_MS = [4_000, 10_000, 18_000, 26_000];
48
+
49
+ const isCurrentCall = (callId: string): boolean => {
50
+ const current = store.getState().call;
51
+ return current.phase !== 'idle' && current.callId === callId;
52
+ };
53
+
54
+ export const P2PCallRunner: React.FC = () => {
55
+ const dispatch = useDispatch();
56
+ const call = useSelector((state: RootState) => state.call);
57
+ const { config } = useChatSettingState();
58
+ const videoCalls = config?.videoCalls;
59
+ const enabled = videoCalls?.enabled === true;
60
+
61
+ const callId = call.callId;
62
+ const isIncoming = call.direction === 'incoming';
63
+ const wantsController =
64
+ enabled &&
65
+ call.mode === 'p2p' &&
66
+ !!callId &&
67
+ (isIncoming
68
+ ? call.phase === 'ringing-incoming' ||
69
+ call.phase === 'connecting' ||
70
+ call.phase === 'in-call'
71
+ : call.direction === 'outgoing' &&
72
+ call.iceServers !== null &&
73
+ (call.phase === 'requesting' ||
74
+ call.phase === 'connecting' ||
75
+ call.phase === 'in-call'));
76
+ // The callee waits on the ring screen; everyone else starts right away.
77
+ const shouldStart = wantsController && !(isIncoming && call.phase === 'ringing-incoming');
78
+
79
+ // Latest config values for the controller without re-running the effect.
80
+ const optionsRef = useRef({
81
+ startWithMicOn: videoCalls?.startWithMicOn,
82
+ startWithCameraOn: videoCalls?.startWithCameraOn,
83
+ });
84
+ optionsRef.current = {
85
+ startWithMicOn: videoCalls?.startWithMicOn,
86
+ startWithCameraOn: videoCalls?.startWithCameraOn,
87
+ };
88
+
89
+ useEffect(() => {
90
+ if (!wantsController || !callId) return;
91
+
92
+ if (!isP2PAvailable()) {
93
+ // The WebRTC package is not in this build: nothing can carry the call.
94
+ // A callee also tells the caller instead of letting them ring on.
95
+ if (store.getState().call.direction === 'incoming') {
96
+ reportCallDeclined(callId);
97
+ }
98
+ dispatch(setCallError(translateCallString('call.error.sdkMissing')));
99
+ return;
100
+ }
101
+
102
+ const snapshot = store.getState().call;
103
+ const peer = String(snapshot.peerXmppUsername || '').trim();
104
+ const role = snapshot.direction === 'incoming' ? 'callee' : 'caller';
105
+ if (!peer) {
106
+ // Without the peer's address there is nobody to signal.
107
+ dispatch(setCallError(translateCallString('call.error.p2pNoPeer')));
108
+ return;
109
+ }
110
+
111
+ const controller = acquireP2PController(callId, () => {
112
+ const peerLocal = peer.split('@')[0];
113
+ return new P2PCallController(
114
+ {
115
+ callId,
116
+ role,
117
+ kind: snapshot.kind,
118
+ peerLocal,
119
+ iceServers: snapshot.iceServers || [],
120
+ startWithMicOn: optionsRef.current.startWithMicOn,
121
+ startWithCameraOn: optionsRef.current.startWithCameraOn,
122
+ },
123
+ createNativeP2PDeps({ callId, peerXmppUsername: peer }),
124
+ {
125
+ onNegotiated: () => {
126
+ if (
127
+ role === 'caller' &&
128
+ isCurrentCall(callId) &&
129
+ store.getState().call.phase === 'requesting'
130
+ ) {
131
+ dispatch(setCallPhase('connecting'));
132
+ }
133
+ },
134
+ onConnected: () => {
135
+ if (!isCurrentCall(callId)) return;
136
+ dispatch(setCallPhase('in-call'));
137
+ // One side is enough to start the server-side call timer.
138
+ if (role === 'caller') reportCallConnected(callId);
139
+ },
140
+ onRemoteEnd: (reason) => {
141
+ if (!isCurrentCall(callId)) return;
142
+ const notice = remoteEndNotice(reason);
143
+ dispatch(notice ? setCallError(localizeP2PMessage(notice)) : endCall());
144
+ },
145
+ onFailed: (message) => {
146
+ if (isCurrentCall(callId)) {
147
+ dispatch(setCallError(localizeP2PMessage(message)));
148
+ }
149
+ },
150
+ // Whatever ended it, tell the server the call is over (idempotent, so
151
+ // it does not matter that the peer reports it too). A callee that
152
+ // never accepted ends through the decline report instead.
153
+ onDisposed: ({ started }) => {
154
+ if (started) reportCallEnded(callId);
155
+ },
156
+ },
157
+ { offerResendMs: RN_OFFER_RESEND_MS }
158
+ );
159
+ });
160
+
161
+ const unbind = bindP2PSession(controller, snapshot.kind);
162
+ const detach = p2pInbox.attach(callId, (signal) =>
163
+ controller.receive(signal)
164
+ );
165
+ if (shouldStart) void startP2PController(controller, snapshot.kind);
166
+
167
+ return () => {
168
+ detach();
169
+ unbind();
170
+ releaseP2PController(callId);
171
+ };
172
+ }, [wantsController, shouldStart, callId, dispatch]);
173
+
174
+ // Callee: the incoming UI is on screen, let the server (and so the caller)
175
+ // know the phone is ringing. Once per call.
176
+ const ringingReportedRef = useRef<string | null>(null);
177
+ useEffect(() => {
178
+ if (
179
+ enabled &&
180
+ call.mode === 'p2p' &&
181
+ isIncoming &&
182
+ call.phase === 'ringing-incoming' &&
183
+ callId &&
184
+ ringingReportedRef.current !== callId
185
+ ) {
186
+ ringingReportedRef.current = callId;
187
+ reportCallRinging(callId);
188
+ }
189
+ }, [enabled, call.mode, isIncoming, call.phase, callId]);
190
+
191
+ return null;
192
+ };
@@ -35,7 +35,9 @@ import { sendCallStateSignal } from '../../networking/callTokenStanza';
35
35
  import { useTheme } from '../../hooks/useTheme';
36
36
  import type { ChatTheme } from '../../theme/theme';
37
37
  import { VideoCallSession } from './VideoCallSession';
38
+ import { P2PCallRunner } from './P2PCallRunner';
38
39
  import { startCallSession } from './callSessionController';
40
+ import { callCanRenderSession } from './callLive';
39
41
  import { declineActiveCall, terminateActiveCall } from './callActions';
40
42
  import {
41
43
  CALL_BAR_HEIGHT,
@@ -197,7 +199,7 @@ const RingingCard: FC<RingingCardProps> = ({
197
199
  <View style={styles.ringingIdentity}>
198
200
  <Text style={[styles.ringingName, { color: theme.text }]}>
199
201
  {roomName ||
200
- (variant === 'incoming' ? t('call.unknownCaller') : t('call.title'))}
202
+ (variant === 'incoming' ? t('call.incomingNeutral') : t('call.title'))}
201
203
  </Text>
202
204
  <View style={styles.ringingSubtitleRow}>
203
205
  {kind === 'audio' ? (
@@ -470,7 +472,14 @@ const VideoCallOverlayInner: FC = () => {
470
472
 
471
473
  const videoCallsConfig = config?.videoCalls;
472
474
  const enabled = videoCallsConfig?.enabled === true;
473
- const livekitUrl = (videoCallsConfig?.livekitUrl || '').trim();
475
+ // The server's own LiveKit URL (call-token or create response) wins over
476
+ // the host config.
477
+ const livekitUrl = (
478
+ call.livekitUrl ||
479
+ videoCallsConfig?.livekitUrl ||
480
+ ''
481
+ ).trim();
482
+ const isP2P = call.mode === 'p2p';
474
483
  const primaryColor = theme.primary || config?.colors?.primary || DEFAULT_PRIMARY;
475
484
 
476
485
  const isOpen = enabled && call.phase !== 'idle';
@@ -486,10 +495,11 @@ const VideoCallOverlayInner: FC = () => {
486
495
  // Shared with the header strip (ActiveCallBar), which expands it again.
487
496
  const { minimized, systemRinging } = useCallUi();
488
497
 
489
- const canRenderSession =
490
- !!call.token &&
491
- (call.phase === 'connecting' || call.phase === 'in-call') &&
492
- !!livekitUrl;
498
+ // A p2p call has no LiveKit token or URL: the media is the peer connection
499
+ // owned by P2PCallRunner.
500
+ const canRenderSession = isP2P
501
+ ? callCanRenderSession(call)
502
+ : callCanRenderSession(call) && !!livekitUrl;
493
503
  const isMinimized = minimized && canRenderSession;
494
504
  // Expanding from the header strip slides the call down from the top
495
505
  // instead of fading it in.
@@ -502,16 +512,17 @@ const VideoCallOverlayInner: FC = () => {
502
512
  // Join the LiveKit room once the call has a token. Idempotent, and the
503
513
  // controller tears itself down when the call slice leaves these phases.
504
514
  useEffect(() => {
505
- if (!enabled || !canRenderSession || !call.token) {return;}
515
+ if (!enabled || isP2P || !canRenderSession || !call.token) {return;}
506
516
  startCallSession({
507
517
  token: call.token,
508
518
  livekitUrl,
509
519
  kind: call.kind,
520
+ isGroup: call.isGroup,
510
521
  startWithMicOn: videoCallsConfig?.startWithMicOn,
511
522
  startWithCameraOn: videoCallsConfig?.startWithCameraOn,
512
523
  });
513
524
  // eslint-disable-next-line react-hooks/exhaustive-deps
514
- }, [enabled, canRenderSession, call.token, livekitUrl, call.kind]);
525
+ }, [enabled, isP2P, canRenderSession, call.token, livekitUrl, call.kind, call.isGroup]);
515
526
 
516
527
  // Give up on an unanswered outgoing dial. Unlike web (which only shows
517
528
  useEffect(() => {
@@ -575,6 +586,11 @@ const VideoCallOverlayInner: FC = () => {
575
586
 
576
587
  const ringingHeader = useMemo(() => {
577
588
  if (call.direction === 'incoming') {
589
+ if (call.isGroup) {
590
+ return call.kind === 'audio'
591
+ ? t('call.incomingGroupAudio')
592
+ : t('call.incomingGroupVideo');
593
+ }
578
594
  return call.kind === 'audio'
579
595
  ? t('call.incomingAudio')
580
596
  : t('call.incomingVideo');
@@ -583,16 +599,38 @@ const VideoCallOverlayInner: FC = () => {
583
599
  if (call.phase === 'connecting') {return t('call.connecting');}
584
600
  if (call.phase === 'error') {return t('call.failed');}
585
601
  return t('call.title');
586
- }, [call.direction, call.phase, call.kind, t]);
602
+ }, [call.direction, call.phase, call.kind, call.isGroup, t]);
587
603
 
588
604
  const ringingSubtitle = useMemo(() => {
605
+ // The card title is the room's name; make it clear it is a group ring.
606
+ const label = call.isGroup
607
+ ? call.kind === 'audio'
608
+ ? t('call.groupAudioCall')
609
+ : t('call.groupVideoCall')
610
+ : call.kind === 'audio'
611
+ ? t('call.audioCall')
612
+ : t('call.videoCall');
589
613
  if (call.direction === 'incoming') {
590
- return call.kind === 'audio' ? t('call.audioCall') : t('call.videoCall');
614
+ // "<person> is calling in <room>" once both are known.
615
+ return call.isGroup && call.callerName && call.roomName
616
+ ? t('call.callingIn', { caller: call.callerName, room: call.roomName })
617
+ : label;
618
+ }
619
+ if (call.phase === 'connecting') {
620
+ return isP2P ? t('call.connecting') : t('call.connectingToRoom');
591
621
  }
592
- if (call.phase === 'connecting') {return t('call.connectingToRoom');}
593
622
  if (call.phase === 'error') {return t('call.tryAgainLater');}
594
- return call.kind === 'audio' ? t('call.audioCall') : t('call.videoCall');
595
- }, [call.direction, call.kind, call.phase, t]);
623
+ return label;
624
+ }, [
625
+ call.direction,
626
+ call.kind,
627
+ call.phase,
628
+ call.isGroup,
629
+ call.callerName,
630
+ call.roomName,
631
+ isP2P,
632
+ t,
633
+ ]);
596
634
 
597
635
  if (!isOpen) {
598
636
  return null;
@@ -610,6 +648,7 @@ const VideoCallOverlayInner: FC = () => {
610
648
  const renderSession = (collapse: () => void) => (
611
649
  <VideoCallSession
612
650
  kind={call.kind}
651
+ isGroup={call.isGroup}
613
652
  peerName={call.roomName}
614
653
  primaryColor={primaryColor}
615
654
  icons={videoCallsConfig?.icons}
@@ -670,7 +709,7 @@ const VideoCallOverlayInner: FC = () => {
670
709
  theme={theme}
671
710
  errorMessage={
672
711
  call.error ||
673
- (!livekitUrl ? t('call.error.missingLivekitUrl') : null)
712
+ (!livekitUrl && !isP2P ? t('call.error.missingLivekitUrl') : null)
674
713
  }
675
714
  onDismiss={() => dispatch(resetCall())}
676
715
  />
@@ -697,10 +736,16 @@ export const VideoCallOverlay: FC = () => {
697
736
  const callId = useSelector(
698
737
  (state: RootState) => state.call.callId || String(state.call.startedAt || '')
699
738
  );
739
+ // The runner is headless and owns the p2p controller. It sits beside the
740
+ // boundary, not inside it: a crash in the call UI blanks the screen, it
741
+ // must not tear the call down.
700
742
  return (
701
- <CallErrorBoundary resetKey={callId}>
702
- <VideoCallOverlayInner />
703
- </CallErrorBoundary>
743
+ <>
744
+ <P2PCallRunner />
745
+ <CallErrorBoundary resetKey={callId}>
746
+ <VideoCallOverlayInner />
747
+ </CallErrorBoundary>
748
+ </>
704
749
  );
705
750
  };
706
751