@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,99 @@
1
+ // ICE restart policy for a p2p call, kept apart from the RTCPeerConnection so
2
+ // it can be reasoned about and tested on its own. The controller feeds it the
3
+ // connection state and runs the timers; the policy only decides.
4
+ //
5
+ // - `disconnected` is often transient (a Wi-Fi blip heals by itself), so the
6
+ // first reaction is to wait a grace period and restart only if it has not
7
+ // recovered;
8
+ // - `failed` is terminal for that ICE session, so restart straight away;
9
+ // - one restart per outage, and a small cap per call so a flapping network
10
+ // ends in a clean failure instead of an endless loop;
11
+ // - a restart that does not bring the connection back within a deadline
12
+ // gives up.
13
+
14
+ export type P2PConnState =
15
+ | 'new'
16
+ | 'connecting'
17
+ | 'connected'
18
+ | 'disconnected'
19
+ | 'failed'
20
+ | 'closed';
21
+
22
+ export type IceAction =
23
+ | { type: 'none' }
24
+ | { type: 'wait'; ms: number } // re-check with onGraceElapsed() after ms
25
+ | { type: 'restart'; deadlineMs: number } // restart; onRestartDeadline() after deadlineMs
26
+ | { type: 'recovered' }
27
+ | { type: 'give-up'; reason: string };
28
+
29
+ export interface IcePolicyOptions {
30
+ graceMs?: number;
31
+ restartDeadlineMs?: number;
32
+ maxRestartsPerCall?: number;
33
+ }
34
+
35
+ export class IceRestartPolicy {
36
+ private readonly graceMs: number;
37
+ private readonly restartDeadlineMs: number;
38
+ private readonly maxRestarts: number;
39
+ private restarts = 0;
40
+ private attemptedThisOutage = false;
41
+ private inOutage = false;
42
+
43
+ constructor(options: IcePolicyOptions = {}) {
44
+ this.graceMs = options.graceMs ?? 3_000;
45
+ this.restartDeadlineMs = options.restartDeadlineMs ?? 15_000;
46
+ this.maxRestarts = options.maxRestartsPerCall ?? 3;
47
+ }
48
+
49
+ get restartCount(): number {
50
+ return this.restarts;
51
+ }
52
+
53
+ private tryRestart(): IceAction {
54
+ if (this.attemptedThisOutage) {
55
+ return { type: 'give-up', reason: 'restart-did-not-recover' };
56
+ }
57
+ if (this.restarts >= this.maxRestarts) {
58
+ return { type: 'give-up', reason: 'too-many-restarts' };
59
+ }
60
+ this.attemptedThisOutage = true;
61
+ this.restarts += 1;
62
+ return { type: 'restart', deadlineMs: this.restartDeadlineMs };
63
+ }
64
+
65
+ onState(state: P2PConnState): IceAction {
66
+ switch (state) {
67
+ case 'connected': {
68
+ const wasOutage = this.inOutage;
69
+ this.inOutage = false;
70
+ this.attemptedThisOutage = false;
71
+ return wasOutage ? { type: 'recovered' } : { type: 'none' };
72
+ }
73
+ case 'disconnected': {
74
+ this.inOutage = true;
75
+ if (this.attemptedThisOutage) return { type: 'none' };
76
+ return { type: 'wait', ms: this.graceMs };
77
+ }
78
+ case 'failed': {
79
+ this.inOutage = true;
80
+ return this.tryRestart();
81
+ }
82
+ default:
83
+ return { type: 'none' };
84
+ }
85
+ }
86
+
87
+ /** The grace period after `disconnected` ran out without recovery. */
88
+ onGraceElapsed(): IceAction {
89
+ if (!this.inOutage) return { type: 'none' };
90
+ return this.tryRestart();
91
+ }
92
+
93
+ /** The restart deadline ran out; `stillDown` is the state at that moment. */
94
+ onRestartDeadline(stillDown: boolean): IceAction {
95
+ return stillDown
96
+ ? { type: 'give-up', reason: 'restart-timeout' }
97
+ : { type: 'none' };
98
+ }
99
+ }
@@ -0,0 +1,186 @@
1
+ import type { P2PSignal } from './signalStanza';
2
+
3
+ // The pure half of the p2p signalling state machine: given the stream of
4
+ // signals from the peer and a few "we are ready" notifications, it says WHAT
5
+ // to do next (apply an offer, apply an answer, add a candidate, stop) without
6
+ // touching an RTCPeerConnection. The controller executes the commands.
7
+ //
8
+ // Rules it enforces:
9
+ // - one negotiation per callId; signals for another callId or from anyone but
10
+ // the expected peer are ignored;
11
+ // - the callee may receive the offer before it has accepted (and before it
12
+ // has local media): the first offer wins, later initial offers are ignored,
13
+ // and it is held until markReady();
14
+ // - candidates that arrive before the remote description is applied are held
15
+ // and flushed right after it;
16
+ // - duplicates (same SDP delivered twice, e.g. the caller re-sending its
17
+ // offer) are no-ops;
18
+ // - after the first exchange, a new offer is a renegotiation (ICE restart).
19
+ // If both sides restart at once (glare) the caller is "impolite" and keeps
20
+ // its own offer; the callee is "polite" and yields to the caller's.
21
+
22
+ export type P2PRole = 'caller' | 'callee';
23
+
24
+ export type NegotiatorCommand =
25
+ | { type: 'apply-offer'; sdp: string; initial: boolean; rollback: boolean }
26
+ | { type: 'apply-answer'; sdp: string }
27
+ | { type: 'add-candidate'; candidate: RTCIceCandidateInit }
28
+ | { type: 'remote-end'; reason: string };
29
+
30
+ const MAX_HELD_CANDIDATES = 64;
31
+
32
+ export class P2PNegotiator {
33
+ readonly callId: string;
34
+ readonly role: P2PRole;
35
+ private readonly peerLocal: string;
36
+
37
+ private ready = false;
38
+ private ended = false;
39
+ private remoteDescriptionSet = false;
40
+ private initialOfferTaken = false;
41
+ private heldOffer: string | null = null;
42
+ private localOfferPending = false;
43
+ private lastOfferSdp: string | null = null;
44
+ private lastAnswerSdp: string | null = null;
45
+ private heldCandidates: RTCIceCandidateInit[] = [];
46
+ // The caller re-sends its offer and candidates while unanswered, so the same
47
+ // candidate can arrive more than once; each is applied (or held) only once.
48
+ private seenCandidates = new Set<string>();
49
+
50
+ constructor(params: { callId: string; role: P2PRole; peerLocal: string }) {
51
+ this.callId = params.callId;
52
+ this.role = params.role;
53
+ this.peerLocal = String(params.peerLocal || '')
54
+ .split('@')[0]
55
+ .toLowerCase();
56
+ }
57
+
58
+ get isEnded(): boolean {
59
+ return this.ended;
60
+ }
61
+
62
+ /** True while we have sent an offer and not yet received its answer. */
63
+ get awaitingAnswer(): boolean {
64
+ return this.localOfferPending;
65
+ }
66
+
67
+ private accepts(signal: P2PSignal): boolean {
68
+ if (this.ended) return false;
69
+ if (signal.callId !== this.callId) return false;
70
+ if (this.peerLocal && signal.fromLocal !== this.peerLocal) return false;
71
+ return true;
72
+ }
73
+
74
+ receive(signal: P2PSignal): NegotiatorCommand[] {
75
+ if (!this.accepts(signal)) return [];
76
+
77
+ switch (signal.signal) {
78
+ case 'end': {
79
+ this.ended = true;
80
+ this.heldOffer = null;
81
+ this.heldCandidates = [];
82
+ const reason = (signal.payload as { reason?: string }).reason;
83
+ return [{ type: 'remote-end', reason: reason || 'ended' }];
84
+ }
85
+
86
+ case 'offer': {
87
+ const sdp = (signal.payload as { sdp: string }).sdp;
88
+ if (sdp === this.lastOfferSdp) return [];
89
+ if (!this.initialOfferTaken) {
90
+ // Only the callee ever receives the first offer.
91
+ if (this.role !== 'callee') return [];
92
+ this.initialOfferTaken = true;
93
+ this.lastOfferSdp = sdp;
94
+ if (!this.ready) {
95
+ this.heldOffer = sdp;
96
+ return [];
97
+ }
98
+ return [{ type: 'apply-offer', sdp, initial: true, rollback: false }];
99
+ }
100
+ // Renegotiation. Before the initial exchange finished, or before we
101
+ // are ready, there is nothing sensible to apply it to.
102
+ if (!this.ready || !this.remoteDescriptionSet) return [];
103
+ if (this.localOfferPending) {
104
+ if (this.role === 'caller') return []; // impolite: keep ours
105
+ this.localOfferPending = false; // polite: roll ours back
106
+ this.lastOfferSdp = sdp;
107
+ return [{ type: 'apply-offer', sdp, initial: false, rollback: true }];
108
+ }
109
+ this.lastOfferSdp = sdp;
110
+ return [{ type: 'apply-offer', sdp, initial: false, rollback: false }];
111
+ }
112
+
113
+ case 'answer': {
114
+ if (!this.localOfferPending) return [];
115
+ const sdp = (signal.payload as { sdp: string }).sdp;
116
+ if (sdp === this.lastAnswerSdp) return [];
117
+ this.lastAnswerSdp = sdp;
118
+ this.localOfferPending = false;
119
+ return [{ type: 'apply-answer', sdp }];
120
+ }
121
+
122
+ case 'candidate': {
123
+ const c = signal.payload as RTCIceCandidateInit;
124
+ // An empty candidate string is the end-of-candidates marker; nothing
125
+ // needs to be added for it.
126
+ if (!c.candidate) return [];
127
+ const key = `${c.candidate}|${c.sdpMid ?? ''}|${c.sdpMLineIndex ?? ''}`;
128
+ if (this.seenCandidates.has(key)) return [];
129
+ this.seenCandidates.add(key);
130
+ if (this.remoteDescriptionSet) {
131
+ return [{ type: 'add-candidate', candidate: c }];
132
+ }
133
+ if (this.heldCandidates.length < MAX_HELD_CANDIDATES) {
134
+ this.heldCandidates.push(c);
135
+ }
136
+ return [];
137
+ }
138
+ }
139
+ return [];
140
+ }
141
+
142
+ /**
143
+ * Local media and the peer connection exist. For the callee this releases
144
+ * the offer that arrived while it was still on the ring screen.
145
+ */
146
+ markReady(): NegotiatorCommand[] {
147
+ if (this.ended) return [];
148
+ this.ready = true;
149
+ if (this.heldOffer !== null) {
150
+ const sdp = this.heldOffer;
151
+ this.heldOffer = null;
152
+ return [{ type: 'apply-offer', sdp, initial: true, rollback: false }];
153
+ }
154
+ return [];
155
+ }
156
+
157
+ /** We created and set a local offer; its answer is now expected. */
158
+ markLocalOffer(): void {
159
+ this.localOfferPending = true;
160
+ this.lastAnswerSdp = null;
161
+ // The caller's own first offer IS its initial exchange, so any offer it
162
+ // receives afterwards is a renegotiation, not a second "first offer".
163
+ if (this.role === 'caller') this.initialOfferTaken = true;
164
+ }
165
+
166
+ /**
167
+ * A remote description (offer or answer) was applied to the connection.
168
+ * Returns the candidates that were waiting for it.
169
+ */
170
+ markRemoteApplied(): NegotiatorCommand[] {
171
+ this.remoteDescriptionSet = true;
172
+ const held = this.heldCandidates;
173
+ this.heldCandidates = [];
174
+ return held.map((candidate) => ({
175
+ type: 'add-candidate' as const,
176
+ candidate,
177
+ }));
178
+ }
179
+
180
+ /** Local teardown: later signals are ignored. */
181
+ stop(): void {
182
+ this.ended = true;
183
+ this.heldOffer = null;
184
+ this.heldCandidates = [];
185
+ }
186
+ }
@@ -0,0 +1,164 @@
1
+ import { Element } from 'ltx';
2
+ import { store } from '../../roomStore';
3
+ import { getGlobalXmppClient } from '../../utils/clientRegistry';
4
+ import { ethoraLogger } from '../../helpers/ethoraLogger';
5
+ import { fetchIceServers } from '../../networking/api-requests/callState.api';
6
+ import { P2PSignalInbox } from './signalInbox';
7
+ import {
8
+ buildP2PSignalStanza,
9
+ isP2PSignalFresh,
10
+ parseP2PSignalStanza,
11
+ P2PSignalName,
12
+ P2PSignalPayload,
13
+ } from './signalStanza';
14
+ import { loadWebRTC } from './webrtcRuntime';
15
+ import type { P2PCallController, P2PCallDeps } from './P2PCallController';
16
+
17
+ // The glue between the XMPP stanza stream, the redux call state and the
18
+ // per-call controller. Native WebRTC / XMPP specifics live here so the
19
+ // controller and the pure modules stay free of them.
20
+
21
+ /** Signals that arrive for a call nobody is handling yet wait here. */
22
+ export const p2pInbox = new P2PSignalInbox();
23
+
24
+ /**
25
+ * Entry point for an incoming `<data type="call-p2p">` message (called from
26
+ * the stanza router). Stale, replayed, malformed or self-sent signals are
27
+ * dropped; the rest go to the inbox, which delivers or briefly holds them.
28
+ */
29
+ export const handleP2PSignalStanza = (inner: Element): void => {
30
+ const signal = parseP2PSignalStanza(inner);
31
+ if (!signal || !signal.fromLocal) return;
32
+ if (!isP2PSignalFresh(signal)) return;
33
+
34
+ const self = String(store.getState().chatSettingStore.user?.xmppUsername || '')
35
+ .split('@')[0]
36
+ .toLowerCase();
37
+ if (signal.fromLocal === self) return;
38
+
39
+ p2pInbox.receive(signal);
40
+ };
41
+
42
+ /** Sends one signal straight to the peer's bare JID over the live XMPP client. */
43
+ export const sendP2PSignal = (params: {
44
+ peerXmppUsername: string;
45
+ callId: string;
46
+ signal: P2PSignalName;
47
+ payload: P2PSignalPayload;
48
+ }): boolean => {
49
+ const xmppClient = getGlobalXmppClient();
50
+ const host = (xmppClient as any)?.host || '';
51
+ const peer = String(params.peerXmppUsername || '').trim();
52
+ if (!xmppClient || !host || !peer) return false;
53
+ try {
54
+ const stanza = buildP2PSignalStanza({
55
+ to: peer.includes('@') ? peer : `${peer}@${host}`,
56
+ callId: params.callId,
57
+ signal: params.signal,
58
+ payload: params.payload,
59
+ });
60
+ (xmppClient as any).client?.send?.(stanza);
61
+ return true;
62
+ } catch (error) {
63
+ ethoraLogger.log('[p2p] failed to send signal', error);
64
+ return false;
65
+ }
66
+ };
67
+
68
+ /**
69
+ * The real native dependencies for one call's controller: the WebRTC classes
70
+ * of `@livekit/react-native-webrtc`, loaded lazily (see webrtcRuntime). Each
71
+ * call fails with a clear error when the package is missing, which the
72
+ * controller turns into a user-facing "could not start the call".
73
+ */
74
+ export const createNativeP2PDeps = (params: {
75
+ callId: string;
76
+ peerXmppUsername: string;
77
+ }): P2PCallDeps => {
78
+ const rtc = () => {
79
+ const runtime = loadWebRTC();
80
+ if (!runtime) throw new Error('WebRTC is not available');
81
+ return runtime;
82
+ };
83
+ return {
84
+ createPeerConnection: (config) =>
85
+ new (rtc().RTCPeerConnection)(config) as unknown as RTCPeerConnection,
86
+ getUserMedia: (constraints) =>
87
+ rtc().mediaDevices.getUserMedia(constraints) as Promise<MediaStream>,
88
+ createMediaStream: () => new (rtc().MediaStream)() as unknown as MediaStream,
89
+ fetchIceServers: async () => {
90
+ const response = await fetchIceServers();
91
+ return response && response.iceServers.length > 0
92
+ ? response.iceServers
93
+ : null;
94
+ },
95
+ sendSignal: (signal, payload) => {
96
+ sendP2PSignal({
97
+ peerXmppUsername: params.peerXmppUsername,
98
+ callId: params.callId,
99
+ signal,
100
+ payload,
101
+ });
102
+ },
103
+ log: (message, detail) => ethoraLogger.log(message, detail),
104
+ };
105
+ };
106
+
107
+ // ---- the one active controller --------------------------------------------
108
+
109
+ let active: { key: string; controller: P2PCallController } | null = null;
110
+ let pendingDispose: ReturnType<typeof setTimeout> | null = null;
111
+ const activeListeners = new Set<() => void>();
112
+
113
+ const notifyActive = () => {
114
+ for (const listener of Array.from(activeListeners)) listener();
115
+ };
116
+
117
+ export const getActiveP2PController = (): P2PCallController | null =>
118
+ active?.controller ?? null;
119
+
120
+ export const subscribeActiveP2P = (listener: () => void): (() => void) => {
121
+ activeListeners.add(listener);
122
+ return () => {
123
+ activeListeners.delete(listener);
124
+ };
125
+ };
126
+
127
+ /**
128
+ * Returns the controller for `key`, creating it on first use. Effects that
129
+ * unmount and immediately remount (React StrictMode, a parent re-keying) get
130
+ * the SAME controller back instead of tearing the call down and starting a
131
+ * second negotiation: release() only disposes after a tick, and acquire()
132
+ * within that tick cancels it.
133
+ */
134
+ export const acquireP2PController = (
135
+ key: string,
136
+ create: () => P2PCallController
137
+ ): P2PCallController => {
138
+ if (pendingDispose) {
139
+ clearTimeout(pendingDispose);
140
+ pendingDispose = null;
141
+ }
142
+ if (active && active.key === key) return active.controller;
143
+ if (active) {
144
+ active.controller.dispose();
145
+ active = null;
146
+ }
147
+ active = { key, controller: create() };
148
+ notifyActive();
149
+ return active.controller;
150
+ };
151
+
152
+ export const releaseP2PController = (key: string): void => {
153
+ if (!active || active.key !== key) return;
154
+ const released = active;
155
+ if (pendingDispose) clearTimeout(pendingDispose);
156
+ pendingDispose = setTimeout(() => {
157
+ pendingDispose = null;
158
+ if (active === released) {
159
+ active = null;
160
+ notifyActive();
161
+ }
162
+ released.controller.dispose();
163
+ }, 0);
164
+ };
@@ -0,0 +1,117 @@
1
+ import type { P2PSignal } from './signalStanza';
2
+
3
+ // Routes incoming p2p signals to the call that owns them.
4
+ //
5
+ // Signals can arrive before anyone is listening: the caller's offer and first
6
+ // candidates are on the wire while the callee is still on the ring screen (the
7
+ // controller only exists after Accept), and may even overtake the relayed
8
+ // call-token that tells the callee the call exists. So signals for a callId
9
+ // with no listener are held briefly and replayed in order when a controller
10
+ // attaches. The hold is small and bounded on purpose: a signal for a call that
11
+ // never materialises is just dropped when its time is up, so unknown callIds
12
+ // stay inert (they never raise UI and never grow memory without limit).
13
+
14
+ export interface SignalInboxOptions {
15
+ /** How long signals for a call with no listener are kept. */
16
+ ttlMs?: number;
17
+ /** Most distinct unclaimed callIds held at once (oldest dropped first). */
18
+ maxPendingCalls?: number;
19
+ /** Most signals kept per unclaimed call. */
20
+ maxPerCall?: number;
21
+ now?: () => number;
22
+ }
23
+
24
+ export type SignalDelivery = 'delivered' | 'buffered' | 'dropped';
25
+
26
+ type Handler = (signal: P2PSignal) => void;
27
+
28
+ const CLOSED_MEMORY = 16;
29
+
30
+ export class P2PSignalInbox {
31
+ private readonly ttlMs: number;
32
+ private readonly maxPendingCalls: number;
33
+ private readonly maxPerCall: number;
34
+ private readonly now: () => number;
35
+ private readonly pending = new Map<
36
+ string,
37
+ { firstAt: number; signals: P2PSignal[] }
38
+ >();
39
+ private readonly handlers = new Map<string, Handler>();
40
+ // Calls that already ended: late stragglers for them are dropped instead of
41
+ // being buffered for a controller that will never come.
42
+ private readonly closed: string[] = [];
43
+
44
+ constructor(options: SignalInboxOptions = {}) {
45
+ this.ttlMs = options.ttlMs ?? 20_000;
46
+ this.maxPendingCalls = options.maxPendingCalls ?? 8;
47
+ this.maxPerCall = options.maxPerCall ?? 96;
48
+ this.now = options.now ?? Date.now;
49
+ }
50
+
51
+ private sweep(): void {
52
+ const cutoff = this.now() - this.ttlMs;
53
+ for (const [callId, entry] of this.pending) {
54
+ if (entry.firstAt < cutoff) this.pending.delete(callId);
55
+ }
56
+ }
57
+
58
+ receive(signal: P2PSignal): SignalDelivery {
59
+ const handler = this.handlers.get(signal.callId);
60
+ if (handler) {
61
+ handler(signal);
62
+ return 'delivered';
63
+ }
64
+ if (this.closed.includes(signal.callId)) return 'dropped';
65
+
66
+ this.sweep();
67
+ let entry = this.pending.get(signal.callId);
68
+ if (!entry) {
69
+ if (this.pending.size >= this.maxPendingCalls) {
70
+ const oldest = this.pending.keys().next().value;
71
+ if (oldest !== undefined) this.pending.delete(oldest);
72
+ }
73
+ entry = { firstAt: this.now(), signals: [] };
74
+ this.pending.set(signal.callId, entry);
75
+ }
76
+ if (entry.signals.length >= this.maxPerCall) return 'dropped';
77
+ entry.signals.push(signal);
78
+ return 'buffered';
79
+ }
80
+
81
+ /**
82
+ * Starts delivering a call's signals to `handler`, replaying anything held
83
+ * for it first (in arrival order). Returns a detach function that also
84
+ * marks the call closed.
85
+ */
86
+ attach(callId: string, handler: Handler): () => void {
87
+ const idx = this.closed.indexOf(callId);
88
+ if (idx >= 0) this.closed.splice(idx, 1);
89
+
90
+ this.sweep();
91
+ const held = this.pending.get(callId);
92
+ this.pending.delete(callId);
93
+ this.handlers.set(callId, handler);
94
+ if (held) {
95
+ for (const signal of held.signals) handler(signal);
96
+ }
97
+ return () => {
98
+ if (this.handlers.get(callId) === handler) this.handlers.delete(callId);
99
+ this.close(callId);
100
+ };
101
+ }
102
+
103
+ /** The call is over: forget held signals and drop future stragglers. */
104
+ close(callId: string): void {
105
+ this.pending.delete(callId);
106
+ if (!this.closed.includes(callId)) {
107
+ this.closed.push(callId);
108
+ if (this.closed.length > CLOSED_MEMORY) this.closed.shift();
109
+ }
110
+ }
111
+
112
+ clear(): void {
113
+ this.pending.clear();
114
+ this.handlers.clear();
115
+ this.closed.length = 0;
116
+ }
117
+ }