@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
@@ -1,4 +1,4 @@
1
- import React, { FC, useEffect, useState } from 'react';
1
+ import React, { FC, useState } from 'react';
2
2
  import {
3
3
  ActivityIndicator,
4
4
  Animated,
@@ -12,27 +12,18 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
12
12
  import { VideoCallIcons } from '../../types/types';
13
13
  import { ProfileImagePlaceholder } from '../MainComponents/ProfileImagePlaceholder';
14
14
  import {
15
- CameraOffIcon,
16
- CameraOnIcon,
17
15
  FillVideoIcon,
18
16
  FitVideoIcon,
19
- HangUpIcon,
20
17
  MicOffIcon,
21
- MicOnIcon,
22
18
  MinimizeIcon,
23
- SpeakerIcon,
24
- SpeakerOffIcon,
25
- SwitchCameraIcon,
26
19
  } from './CallIcons';
27
20
  import { loadLiveKit } from './livekitRuntime';
28
- import {
29
- dismissCallDeviceError,
30
- switchCallCamera,
31
- toggleCallCamera,
32
- toggleCallMic,
33
- toggleCallSpeaker,
34
- useCallSession,
35
- } from './callSessionController';
21
+ import { loadWebRTC } from '../../calls/p2p/webrtcRuntime';
22
+ import { dismissCallDeviceError, useCallSession } from './callSessionController';
23
+ import { CallVideo } from './CallVideo';
24
+ import { CallControlBar } from './CallControlBar';
25
+ import { GroupCallView } from './GroupCallView';
26
+ import { formatCallDuration, useSharedCallElapsed } from './callElapsed';
36
27
  import { usePipTile } from './usePipTile';
37
28
  import { useT } from '../../i18n/useT';
38
29
 
@@ -40,11 +31,15 @@ const DEFAULT_PRIMARY = '#0052CD';
40
31
  const SURFACE_DARK = '#0B1220';
41
32
  const TEXT_ON_DARK = '#FFFFFF';
42
33
  const TEXT_MUTED = '#9AA4B2';
43
- const DANGER = '#E53935';
44
34
  const CONTROL_IDLE = 'rgba(255, 255, 255, 0.16)';
45
35
 
36
+ // Re-exported for the header strip, which shares the timer with this screen.
37
+ export { formatCallDuration, useSharedCallElapsed };
38
+
46
39
  export interface VideoCallSessionProps {
47
40
  kind?: 'audio' | 'video';
41
+ /** Group room call: everyone in a grid, instead of the 1:1 stage. */
42
+ isGroup?: boolean;
48
43
  /** Display name of the peer, shown until LiveKit reports theirs. */
49
44
  peerName?: string | null;
50
45
  primaryColor?: string;
@@ -55,42 +50,18 @@ export interface VideoCallSessionProps {
55
50
  }
56
51
 
57
52
  /**
58
- * Seconds since the call truly connected, counted from the server-set
59
- * `joinedAt` anchor so both sides show the same time (web's
60
- * useSharedCallElapsed). Null until the peer is in.
61
- */
62
- export const useSharedCallElapsed = (anchorAt: number | null): number | null => {
63
- const [, tick] = useState(0);
64
- useEffect(() => {
65
- if (anchorAt === null) {return;}
66
- const id = setInterval(() => tick((n) => n + 1), 1000);
67
- return () => clearInterval(id);
68
- }, [anchorAt]);
69
- if (anchorAt === null) {return null;}
70
- return Math.max(0, Math.floor((Date.now() - anchorAt) / 1000));
71
- };
72
-
73
- export const formatCallDuration = (totalSeconds: number): string => {
74
- const safe = Math.max(0, Math.floor(totalSeconds));
75
- const hours = Math.floor(safe / 3600);
76
- const minutes = Math.floor((safe % 3600) / 60);
77
- const seconds = safe % 60;
78
- const mm = String(minutes).padStart(2, '0');
79
- const ss = String(seconds).padStart(2, '0');
80
- return hours > 0 ? `${hours}:${mm}:${ss}` : `${mm}:${ss}`;
81
- };
82
-
83
- /**
84
- * The call screen, React Native edition. Pure view over the LiveKit session
85
- * owned by callSessionController.ts: it can unmount and remount (minimize,
86
- * leaving the chat screen) without touching the connection.
53
+ * The call screen, React Native edition. Pure view over the media session
54
+ * of the call (the LiveKit room in callSessionController.ts, or the peer to
55
+ * peer connection in p2pCallSession.ts): it can unmount and remount
56
+ * (minimize, leaving the chat screen) without touching the connection.
87
57
  *
88
58
  * The web SDK builds this on `@livekit/components-react` hooks, which
89
- * assume a DOM. Only the video surface comes from `@livekit/react-native`
90
- * (`<VideoTrack />`, `trackRef` prop, >= 2.7).
59
+ * assume a DOM. Only the video surfaces come from the native packages
60
+ * (`<CallVideo />`: LiveKit's `<VideoTrack />` or the fork's `<RTCView />`).
91
61
  */
92
62
  export const VideoCallSession: FC<VideoCallSessionProps> = ({
93
63
  kind = 'video',
64
+ isGroup = false,
94
65
  peerName,
95
66
  primaryColor = DEFAULT_PRIMARY,
96
67
  icons,
@@ -99,7 +70,8 @@ export const VideoCallSession: FC<VideoCallSessionProps> = ({
99
70
  }) => {
100
71
  const t = useT();
101
72
  const insets = useSafeAreaInsets();
102
- const runtime = loadLiveKit();
73
+ // A p2p call needs the WebRTC package only, a LiveKit call the LiveKit one.
74
+ const hasMedia = !!loadLiveKit() || !!loadWebRTC();
103
75
  const session = useCallSession();
104
76
  const pipTile = usePipTile({ topInset: insets.top });
105
77
  const elapsed = useSharedCallElapsed(session.anchorAt);
@@ -110,7 +82,7 @@ export const VideoCallSession: FC<VideoCallSessionProps> = ({
110
82
  // minimize stretches it to fill (the old behaviour) and back.
111
83
  const [fillRemote, setFillRemote] = useState(false);
112
84
 
113
- if (!runtime) {
85
+ if (!hasMedia) {
114
86
  return (
115
87
  <View style={[styles.canvas, styles.centered]}>
116
88
  <Text style={styles.errorText}>{t('call.error.sdkMissing')}</Text>
@@ -118,7 +90,20 @@ export const VideoCallSession: FC<VideoCallSessionProps> = ({
118
90
  );
119
91
  }
120
92
 
121
- const { VideoTrack } = runtime;
93
+ if (isGroup) {
94
+ return (
95
+ <GroupCallView
96
+ session={session}
97
+ kind={kind}
98
+ title={peerName}
99
+ primaryColor={primaryColor}
100
+ icons={icons}
101
+ onToggleMinimize={onToggleMinimize}
102
+ onHangup={onHangup}
103
+ />
104
+ );
105
+ }
106
+
122
107
  const {
123
108
  connected,
124
109
  remoteJoined,
@@ -126,11 +111,11 @@ export const VideoCallSession: FC<VideoCallSessionProps> = ({
126
111
  localVideo,
127
112
  micOn,
128
113
  cameraOn,
129
- speakerOn,
130
114
  deviceError,
131
115
  remoteMicMuted,
132
116
  facingMode,
133
117
  localVideoEpoch,
118
+ reconnecting,
134
119
  } = session;
135
120
  // The call slice's name (the chat title) first, as web does: LiveKit's
136
121
  // participant name is often just the opaque xmpp identity.
@@ -150,11 +135,16 @@ export const VideoCallSession: FC<VideoCallSessionProps> = ({
150
135
  const selfMirror = facingMode === 'user';
151
136
  // The local view remounts when the camera is re-acquired (switching
152
137
  // front/back), so it never keeps rendering the stopped stream.
138
+ // A p2p stream handle also carries its track ids (`key`), so a track that
139
+ // arrives or is replaced remounts the view.
153
140
  const videoKey = (ref: any) =>
154
- ref === localVideo ? `local-${localVideoEpoch}` : 'remote';
141
+ `${ref === localVideo ? `local-${localVideoEpoch}` : 'remote'}${
142
+ ref?.key ? `:${ref.key}` : ''
143
+ }`;
155
144
 
156
- const statusText =
157
- elapsed !== null
145
+ const statusText = reconnecting
146
+ ? t('call.status.reconnecting')
147
+ : elapsed !== null
158
148
  ? formatCallDuration(elapsed)
159
149
  : !connected
160
150
  ? t('call.status.connecting')
@@ -169,9 +159,9 @@ export const VideoCallSession: FC<VideoCallSessionProps> = ({
169
159
  {/* Stage */}
170
160
  <View style={styles.stage} onLayout={pipTile.onStageLayout}>
171
161
  {mainVideo ? (
172
- <VideoTrack
162
+ <CallVideo
173
163
  key={videoKey(mainVideo)}
174
- trackRef={mainVideo}
164
+ source={mainVideo}
175
165
  style={styles.remoteVideo}
176
166
  objectFit={mainFit}
177
167
  mirror={isSwapped && selfMirror}
@@ -232,9 +222,9 @@ export const VideoCallSession: FC<VideoCallSessionProps> = ({
232
222
  accessibilityRole="button"
233
223
  accessibilityLabel={t('call.action.swapVideo')}
234
224
  >
235
- <VideoTrack
225
+ <CallVideo
236
226
  key={videoKey(pipVideo)}
237
- trackRef={pipVideo}
227
+ source={pipVideo}
238
228
  style={styles.pipVideo}
239
229
  objectFit="cover"
240
230
  mirror={!isSwapped && selfMirror}
@@ -286,62 +276,12 @@ export const VideoCallSession: FC<VideoCallSessionProps> = ({
286
276
  </View>
287
277
 
288
278
  {/* Control bar */}
289
- <View style={[styles.controls, { paddingBottom: 20 + insets.bottom }]}>
290
- <TouchableOpacity
291
- accessibilityRole="button"
292
- accessibilityLabel={micOn ? t('call.action.muteMic') : t('call.action.unmuteMic')}
293
- onPress={toggleCallMic}
294
- style={[styles.controlButton, { backgroundColor: micOn ? CONTROL_IDLE : DANGER }]}
295
- >
296
- {micOn
297
- ? (icons?.micOn ?? <MicOnIcon color={TEXT_ON_DARK} />)
298
- : (icons?.micOff ?? <MicOffIcon color={TEXT_ON_DARK} />)}
299
- </TouchableOpacity>
300
-
301
- {isVideo && (
302
- <TouchableOpacity
303
- accessibilityRole="button"
304
- accessibilityLabel={
305
- cameraOn ? t('call.action.stopCamera') : t('call.action.startCamera')
306
- }
307
- onPress={toggleCallCamera}
308
- style={[styles.controlButton, { backgroundColor: cameraOn ? CONTROL_IDLE : DANGER }]}
309
- >
310
- {cameraOn
311
- ? (icons?.cameraOn ?? <CameraOnIcon color={TEXT_ON_DARK} />)
312
- : (icons?.cameraOff ?? <CameraOffIcon color={TEXT_ON_DARK} />)}
313
- </TouchableOpacity>
314
- )}
315
-
316
- {isVideo && cameraOn && (
317
- <TouchableOpacity
318
- accessibilityRole="button"
319
- accessibilityLabel={t('call.action.switchCamera')}
320
- onPress={switchCallCamera}
321
- style={[styles.controlButton, { backgroundColor: CONTROL_IDLE }]}
322
- >
323
- <SwitchCameraIcon color={TEXT_ON_DARK} />
324
- </TouchableOpacity>
325
- )}
326
-
327
- <TouchableOpacity
328
- accessibilityRole="button"
329
- accessibilityLabel={speakerOn ? t('call.action.speakerOff') : t('call.action.speakerOn')}
330
- onPress={toggleCallSpeaker}
331
- style={[styles.controlButton, { backgroundColor: CONTROL_IDLE }]}
332
- >
333
- {speakerOn ? <SpeakerIcon color={TEXT_ON_DARK} /> : <SpeakerOffIcon color={TEXT_ON_DARK} />}
334
- </TouchableOpacity>
335
-
336
- <TouchableOpacity
337
- accessibilityRole="button"
338
- accessibilityLabel={t('call.action.hangUp')}
339
- onPress={onHangup}
340
- style={[styles.controlButton, styles.hangupButton]}
341
- >
342
- {icons?.hangup ?? <HangUpIcon color={TEXT_ON_DARK} />}
343
- </TouchableOpacity>
344
- </View>
279
+ <CallControlBar
280
+ session={session}
281
+ isVideo={isVideo}
282
+ icons={icons}
283
+ onHangup={onHangup}
284
+ />
345
285
  </View>
346
286
  );
347
287
  };
@@ -454,24 +394,6 @@ const styles = StyleSheet.create({
454
394
  fitButton: {
455
395
  left: 60,
456
396
  },
457
- controls: {
458
- flexDirection: 'row',
459
- alignItems: 'center',
460
- justifyContent: 'center',
461
- gap: 16,
462
- paddingTop: 20,
463
- paddingHorizontal: 16,
464
- },
465
- controlButton: {
466
- width: 56,
467
- height: 56,
468
- borderRadius: 28,
469
- alignItems: 'center',
470
- justifyContent: 'center',
471
- },
472
- hangupButton: {
473
- backgroundColor: DANGER,
474
- },
475
397
  errorText: {
476
398
  color: TEXT_ON_DARK,
477
399
  fontSize: 14,
@@ -8,6 +8,7 @@ import {
8
8
  } from '../../networking/callTokenStanza';
9
9
  import { translateKey } from '../../i18n/strings';
10
10
  import { getGlobalXmppClient } from '../../utils/clientRegistry';
11
+ import { reportDeclineIfP2P } from '../../calls/declineReport';
11
12
 
12
13
  /**
13
14
  * Call teardown that doesn't need a mounted component.
@@ -48,6 +49,7 @@ export const terminateActiveCall = (state: CallSignalState): void => {
48
49
  };
49
50
 
50
51
  export const declineActiveCall = (): void => {
52
+ reportDeclineIfP2P(store.getState().call);
51
53
  sendCallStateSignal('declined');
52
54
  store.dispatch(declineIncomingCall());
53
55
  };
@@ -62,6 +64,7 @@ const DECLINE_SIGNAL_POLL_MS = 500;
62
64
  */
63
65
  export const declineActiveCallWhenOnline = (): void => {
64
66
  const call = store.getState().call;
67
+ reportDeclineIfP2P(call);
65
68
  const signal = {
66
69
  peerXmppUsername: call.peerXmppUsername,
67
70
  callId: call.callId,
@@ -0,0 +1,27 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ /**
4
+ * Seconds since the call truly connected, counted from the server-set
5
+ * `joinedAt` anchor so both sides show the same time (web's
6
+ * useSharedCallElapsed). Null until the peer is in.
7
+ */
8
+ export const useSharedCallElapsed = (anchorAt: number | null): number | null => {
9
+ const [, tick] = useState(0);
10
+ useEffect(() => {
11
+ if (anchorAt === null) {return;}
12
+ const id = setInterval(() => tick((n) => n + 1), 1000);
13
+ return () => clearInterval(id);
14
+ }, [anchorAt]);
15
+ if (anchorAt === null) {return null;}
16
+ return Math.max(0, Math.floor((Date.now() - anchorAt) / 1000));
17
+ };
18
+
19
+ export const formatCallDuration = (totalSeconds: number): string => {
20
+ const safe = Math.max(0, Math.floor(totalSeconds));
21
+ const hours = Math.floor(safe / 3600);
22
+ const minutes = Math.floor((safe % 3600) / 60);
23
+ const seconds = safe % 60;
24
+ const mm = String(minutes).padStart(2, '0');
25
+ const ss = String(seconds).padStart(2, '0');
26
+ return hours > 0 ? `${hours}:${mm}:${ss}` : `${mm}:${ss}`;
27
+ };
@@ -0,0 +1,13 @@
1
+ import type { CallState } from '../../roomStore/callSlice';
2
+
3
+ /**
4
+ * True while a call is far enough along to have a media session: connecting
5
+ * or in the call. A LiveKit call also needs its token (that is what the room
6
+ * is joined with); a peer to peer call has none, its media is the peer
7
+ * connection, so the phase alone decides.
8
+ */
9
+ export const callCanRenderSession = (
10
+ call: Pick<CallState, 'phase' | 'mode' | 'token'>
11
+ ): boolean =>
12
+ (call.phase === 'connecting' || call.phase === 'in-call') &&
13
+ (call.mode === 'p2p' || !!call.token);
@@ -4,6 +4,21 @@ import { store } from '../../roomStore';
4
4
  import { setCallError, setCallPhase } from '../../roomStore/callSlice';
5
5
  import { ensureLiveKitGlobals, loadLiveKit } from './livekitRuntime';
6
6
  import { terminateActiveCall, translateCallString } from './callActions';
7
+ import {
8
+ getP2PSessionSnapshot,
9
+ isP2PSessionActive,
10
+ setP2PMicEnabled,
11
+ switchP2PCamera,
12
+ toggleP2PCamera,
13
+ toggleP2PSpeaker,
14
+ dismissP2PDeviceError,
15
+ useP2PSession,
16
+ } from './p2pCallSession';
17
+ import {
18
+ CallParticipantView,
19
+ CallSessionSnapshot,
20
+ IDLE_SESSION,
21
+ } from './callSessionTypes';
7
22
 
8
23
  /**
9
24
  * The LiveKit connection of the current call, owned outside React.
@@ -22,64 +37,20 @@ import { terminateActiveCall, translateCallString } from './callActions';
22
37
  * only read the snapshot and call the controls.
23
38
  */
24
39
 
25
- export interface CallSessionSnapshot {
26
- /** A LiveKit room exists for the current call. */
27
- active: boolean;
28
- connected: boolean;
29
- /** Translated, dismissible camera/mic problem. Never fails the call. */
30
- deviceError: string | null;
31
- micOn: boolean;
32
- cameraOn: boolean;
33
- speakerOn: boolean;
34
- /** Which camera the local video comes from; only the front one is mirrored. */
35
- facingMode: 'user' | 'environment';
36
- /**
37
- * Bumped whenever the local camera track is re-acquired, so the self view
38
- * can remount onto the new stream instead of holding the stopped one.
39
- */
40
- localVideoEpoch: number;
41
- /** `{ participant, publication, source }` for `<VideoTrack />`, live and unmuted only. */
42
- remoteVideo: any;
43
- localVideo: any;
44
- remoteName: string | null;
45
- remoteJoined: boolean;
46
- /** Peer joined but has no live microphone. */
47
- remoteMicMuted: boolean;
48
- /**
49
- * When the call truly connected: the later of the two LiveKit `joinedAt`
50
- * stamps. The server sets them, so both sides count from the same moment
51
- * (web's useSharedCallElapsed). Null until the peer is in.
52
- */
53
- anchorAt: number | null;
54
- }
55
-
56
- const IDLE: CallSessionSnapshot = {
57
- active: false,
58
- connected: false,
59
- deviceError: null,
60
- micOn: true,
61
- cameraOn: false,
62
- speakerOn: false,
63
- facingMode: 'user',
64
- localVideoEpoch: 0,
65
- remoteVideo: null,
66
- localVideo: null,
67
- remoteName: null,
68
- remoteJoined: false,
69
- remoteMicMuted: false,
70
- anchorAt: null,
71
- };
40
+ export type { CallParticipantView, CallSessionSnapshot } from './callSessionTypes';
72
41
 
73
42
  interface Session {
74
43
  key: string;
75
44
  room: any;
76
45
  kind: 'audio' | 'video';
46
+ /** Group room call: many participants, the call outlives any one leaving. */
47
+ isGroup: boolean;
77
48
  disposed: boolean;
78
49
  everJoined: boolean;
79
50
  }
80
51
 
81
52
  let session: Session | null = null;
82
- let snapshot: CallSessionSnapshot = IDLE;
53
+ let snapshot: CallSessionSnapshot = IDLE_SESSION;
83
54
  const listeners = new Set<() => void>();
84
55
  let storeUnsubscribe: (() => void) | null = null;
85
56
 
@@ -97,9 +68,20 @@ const subscribe = (listener: () => void) => {
97
68
 
98
69
  const getSnapshot = () => snapshot;
99
70
 
100
- export const useCallSession = (): CallSessionSnapshot =>
71
+ const useLiveKitSession = (): CallSessionSnapshot =>
101
72
  useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
102
73
 
74
+ /**
75
+ * The media session of the current call, whichever transport carries it: a
76
+ * peer to peer connection (p2pCallSession.ts) when one is bound, else the
77
+ * LiveKit room. Callers never need to tell them apart.
78
+ */
79
+ export const useCallSession = (): CallSessionSnapshot => {
80
+ const livekit = useLiveKitSession();
81
+ const p2p = useP2PSession();
82
+ return p2p.active ? p2p : livekit;
83
+ };
84
+
103
85
  const sessionKey = (livekitUrl: string, token: string) => `${livekitUrl}|${token}`;
104
86
 
105
87
  // A device (camera/mic) permission/availability problem during enable,
@@ -134,6 +116,32 @@ const joinedAtMs = (participant: any): number => {
134
116
  return Number.isFinite(ms) ? ms : 0;
135
117
  };
136
118
 
119
+ const micMutedOf = (participant: any, Track: any): boolean => {
120
+ const mic = participant?.getTrackPublication?.(Track.Source.Microphone);
121
+ return !mic || mic.isMuted !== false;
122
+ };
123
+
124
+ // Everyone in a group call: us first, then the others in join order.
125
+ const groupParticipants = (room: any, Track: any): CallParticipantView[] => {
126
+ const speaking = new Set<string>(
127
+ (Array.from(room.activeSpeakers || []) as any[]).map((p) => p?.identity)
128
+ );
129
+ const view = (p: any, isLocal: boolean): CallParticipantView => ({
130
+ identity: String(p?.identity || ''),
131
+ name: String(p?.name || p?.identity || ''),
132
+ isLocal,
133
+ video: liveVideoRef(p, Track),
134
+ micMuted: micMutedOf(p, Track),
135
+ speaking: speaking.has(p?.identity),
136
+ });
137
+ return [
138
+ view(room.localParticipant, true),
139
+ ...(Array.from(room.remoteParticipants?.values?.() || []) as any[]).map((p) =>
140
+ view(p, false)
141
+ ),
142
+ ];
143
+ };
144
+
137
145
  const resync = () => {
138
146
  const current = session;
139
147
  const runtime = loadLiveKit();
@@ -148,6 +156,31 @@ const resync = () => {
148
156
  const localJoined = joinedAtMs(room.localParticipant);
149
157
  const remoteJoinedAt = joinedAtMs(remote);
150
158
 
159
+ if (current.isGroup) {
160
+ // A group call began when the first two were in; later joiners do not
161
+ // restart the clock (web's useSharedCallElapsed(group)).
162
+ const joins = [
163
+ localJoined,
164
+ ...(Array.from(room.remoteParticipants?.values?.() || []) as any[]).map(
165
+ joinedAtMs
166
+ ),
167
+ ].filter((ms) => ms > 0);
168
+ emit({
169
+ remoteJoined: !!remote,
170
+ remoteName: null,
171
+ remoteVideo: null,
172
+ localVideo: liveVideoRef(room.localParticipant, Track),
173
+ remoteMicMuted: false,
174
+ participants: groupParticipants(room, Track),
175
+ anchorAt: remote
176
+ ? joins.length >= 2
177
+ ? Math.min(...joins)
178
+ : snapshot.anchorAt ?? Date.now()
179
+ : null,
180
+ });
181
+ return;
182
+ }
183
+
151
184
  emit({
152
185
  remoteJoined: !!remote,
153
186
  remoteName: remote?.name || remote?.identity || null,
@@ -179,7 +212,7 @@ export const stopCallSession = (): void => {
179
212
  } catch {
180
213
  // Never let teardown throw.
181
214
  }
182
- snapshot = IDLE;
215
+ snapshot = IDLE_SESSION;
183
216
  listeners.forEach((listener) => listener());
184
217
  };
185
218
 
@@ -202,6 +235,8 @@ export interface StartCallSessionOptions {
202
235
  token: string;
203
236
  livekitUrl: string;
204
237
  kind: 'audio' | 'video';
238
+ /** Group room call: show everyone, and keep going while others remain. */
239
+ isGroup?: boolean;
205
240
  startWithMicOn?: boolean;
206
241
  startWithCameraOn?: boolean;
207
242
  }
@@ -214,6 +249,7 @@ export const startCallSession = ({
214
249
  token,
215
250
  livekitUrl,
216
251
  kind,
252
+ isGroup = false,
217
253
  startWithMicOn = true,
218
254
  startWithCameraOn = true,
219
255
  }: StartCallSessionOptions): void => {
@@ -251,11 +287,19 @@ export const startCallSession = ({
251
287
  }
252
288
  : {}),
253
289
  });
254
- const current: Session = { key, room, kind, disposed: false, everJoined: false };
290
+ const current: Session = {
291
+ key,
292
+ room,
293
+ kind,
294
+ isGroup,
295
+ disposed: false,
296
+ everJoined: false,
297
+ };
255
298
  session = current;
256
299
  snapshot = {
257
- ...IDLE,
300
+ ...IDLE_SESSION,
258
301
  active: true,
302
+ isGroup,
259
303
  micOn: startWithMicOn,
260
304
  cameraOn: kind === 'video' && startWithCameraOn,
261
305
  // Video calls belong on the loudspeaker, audio calls on the earpiece.
@@ -277,6 +321,7 @@ export const startCallSession = ({
277
321
  .on(RoomEvent.TrackMuted, onChange)
278
322
  .on(RoomEvent.TrackUnmuted, onChange)
279
323
  .on(RoomEvent.ParticipantConnected, onChange)
324
+ .on(RoomEvent.ActiveSpeakersChanged, onChange)
280
325
  .on(RoomEvent.MediaDevicesError, (error: unknown) => {
281
326
  if (current.disposed) {return;}
282
327
  emit({ deviceError: humanizeDeviceError(error) });
@@ -286,8 +331,13 @@ export const startCallSession = ({
286
331
  resync();
287
332
  // 1:1 semantics, as web's PeerLeaveWatcher: once the peer had been
288
333
  // in the room, their leaving IS the end of the call. Before they
289
- // join (outgoing "Ringing...") an empty room is expected.
290
- if (current.everJoined && (room.remoteParticipants?.size ?? 0) === 0) {
334
+ // join (outgoing "Ringing...") an empty room is expected. A group
335
+ // call goes on while anyone is left, and ends when we hang up.
336
+ if (
337
+ !current.isGroup &&
338
+ current.everJoined &&
339
+ (room.remoteParticipants?.size ?? 0) === 0
340
+ ) {
291
341
  terminateActiveCall('ended');
292
342
  }
293
343
  })
@@ -363,10 +413,19 @@ export const startCallSession = ({
363
413
 
364
414
  // ---- controls -----------------------------------------------------------
365
415
 
366
- export const toggleCallMic = (): Promise<void> => setCallMicEnabled(!snapshot.micOn);
416
+ // The controls act on whichever transport carries the call.
417
+ const currentSnapshot = (): CallSessionSnapshot =>
418
+ isP2PSessionActive() ? getP2PSessionSnapshot() : snapshot;
419
+
420
+ export const toggleCallMic = (): Promise<void> =>
421
+ setCallMicEnabled(!currentSnapshot().micOn);
367
422
 
368
423
  /** Set the mic to a given state (system call UI reports absolute values). */
369
424
  export const setCallMicEnabled = async (next: boolean): Promise<void> => {
425
+ if (isP2PSessionActive()) {
426
+ setP2PMicEnabled(next);
427
+ return;
428
+ }
370
429
  const current = session;
371
430
  if (!current || snapshot.micOn === next) {return;}
372
431
  emit({ micOn: next });
@@ -380,6 +439,10 @@ export const setCallMicEnabled = async (next: boolean): Promise<void> => {
380
439
  };
381
440
 
382
441
  export const toggleCallCamera = async (): Promise<void> => {
442
+ if (isP2PSessionActive()) {
443
+ await toggleP2PCamera();
444
+ return;
445
+ }
383
446
  const current = session;
384
447
  if (!current) {return;}
385
448
  const next = !snapshot.cameraOn;
@@ -397,6 +460,10 @@ export const toggleCallCamera = async (): Promise<void> => {
397
460
  let switchingCamera = false;
398
461
 
399
462
  export const switchCallCamera = async (): Promise<void> => {
463
+ if (isP2PSessionActive()) {
464
+ switchP2PCamera();
465
+ return;
466
+ }
400
467
  const current = session;
401
468
  const runtime = loadLiveKit();
402
469
  if (!current || !runtime || switchingCamera) {return;}
@@ -437,6 +504,10 @@ export const switchCallCamera = async (): Promise<void> => {
437
504
  };
438
505
 
439
506
  export const toggleCallSpeaker = async (): Promise<void> => {
507
+ if (isP2PSessionActive()) {
508
+ await toggleP2PSpeaker();
509
+ return;
510
+ }
440
511
  const runtime = loadLiveKit();
441
512
  if (!session || !runtime) {return;}
442
513
  const next = !snapshot.speakerOn;
@@ -459,6 +530,10 @@ export const toggleCallSpeaker = async (): Promise<void> => {
459
530
  };
460
531
 
461
532
  export const dismissCallDeviceError = (): void => {
533
+ if (isP2PSessionActive()) {
534
+ dismissP2PDeviceError();
535
+ return;
536
+ }
462
537
  emit({ deviceError: null });
463
538
  };
464
539