@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,718 @@
1
+ "use strict";
2
+
3
+ import { IceRestartPolicy } from './icePolicy';
4
+ import { P2PNegotiator } from './negotiator';
5
+
6
+ // One peer to peer call, from getUserMedia to hang-up. Everything that talks
7
+ // to the outside world is injected (RTCPeerConnection, getUserMedia, the
8
+ // signal transport, ICE credential refresh), so the class is plain TypeScript
9
+ // and runs under a fake connection in unit tests. The decisions live in the
10
+ // small pure modules next to it (negotiator, icePolicy, signalStanza); this
11
+ // class only wires them to a real connection and cleans up after itself.
12
+ //
13
+ // Media encryption: a WebRTC peer connection already encrypts media between
14
+ // the two peers with DTLS-SRTP, so the LiveKit insertable-streams E2EE layer
15
+ // (and its OMEMO key exchange) is deliberately NOT applied on this path.
16
+
17
+ const DEFAULT_TIMINGS = {
18
+ connectTimeoutMs: 25_000,
19
+ // While nobody has answered, the offer and candidates are sent again: a
20
+ // callee that was still reconnecting (woken by push) missed the first copy,
21
+ // and the stanzas are not stored for later. Duplicates are no-ops there.
22
+ offerResendMs: [4_000, 10_000]
23
+ };
24
+ export const describeMediaError = error => {
25
+ const name = error?.name || '';
26
+ const text = String(error?.message || '').toLowerCase();
27
+ if (name === 'NotAllowedError' || name === 'SecurityError' || text.includes('permission') || text.includes('denied')) {
28
+ return 'Camera or microphone permission denied';
29
+ }
30
+ if (name === 'NotFoundError' || name === 'OverconstrainedError') {
31
+ return 'No camera or microphone found on this device';
32
+ }
33
+ if (name === 'NotReadableError' || name === 'AbortError') {
34
+ return 'Your camera or microphone is already in use by another app';
35
+ }
36
+ return 'Could not access your camera or microphone';
37
+ };
38
+
39
+ /**
40
+ * What to show when the PEER ended the call for a reason that is a failure
41
+ * rather than a normal hang up / decline. Null means "just close the call".
42
+ */
43
+ export const remoteEndNotice = reason => {
44
+ switch (reason) {
45
+ case 'media-error':
46
+ return 'The other person could not access their camera or microphone';
47
+ case 'connect-timeout':
48
+ case 'connection-failed':
49
+ case 'negotiation-error':
50
+ case 'setup-error':
51
+ return 'The call could not be connected';
52
+ default:
53
+ return null;
54
+ }
55
+ };
56
+ const AUDIO_CONSTRAINTS = {
57
+ echoCancellation: true,
58
+ noiseSuppression: true,
59
+ autoGainControl: true
60
+ };
61
+ const VIDEO_CONSTRAINTS = {
62
+ width: {
63
+ ideal: 1280
64
+ },
65
+ height: {
66
+ ideal: 720
67
+ },
68
+ facingMode: 'user'
69
+ };
70
+ export class P2PCallController {
71
+ policy = new IceRestartPolicy();
72
+ listeners = new Set();
73
+ pc = null;
74
+ localStream = null;
75
+ audioTrack = null;
76
+ videoTrack = null;
77
+ videoSender = null;
78
+ ownedTracks = [];
79
+ remoteStream = null;
80
+ remoteCleanups = [];
81
+ queue = Promise.resolve();
82
+ timers = new Set();
83
+ graceTimer = null;
84
+ deadlineTimer = null;
85
+ connectTimer = null;
86
+ started = false;
87
+ disposed = false;
88
+ endSent = false;
89
+ connectedOnce = false;
90
+ negotiated = false;
91
+ cameraBusy = false;
92
+ lastConn = null;
93
+
94
+ // Outgoing candidates wait until the offer/answer they belong to is out, so
95
+ // the peer never sees a candidate before its description.
96
+ candidateGateOpen = false;
97
+ heldOutgoingCandidates = [];
98
+ sentCandidates = [];
99
+ lastOffer = null;
100
+ constructor(params, deps, events = {}, timings = {}) {
101
+ this.params = params;
102
+ this.deps = deps;
103
+ this.events = events;
104
+ this.timings = {
105
+ ...DEFAULT_TIMINGS,
106
+ ...timings
107
+ };
108
+ this.callId = params.callId;
109
+ this.role = params.role;
110
+ this.kind = params.kind;
111
+ this.negotiator = new P2PNegotiator({
112
+ callId: params.callId,
113
+ role: params.role,
114
+ peerLocal: params.peerLocal
115
+ });
116
+ this.snapshot = {
117
+ status: 'preparing',
118
+ localStream: null,
119
+ remoteStream: null,
120
+ micEnabled: params.startWithMicOn !== false,
121
+ camEnabled: params.kind === 'video' && params.startWithCameraOn !== false,
122
+ remoteVideoLive: false,
123
+ notice: null
124
+ };
125
+ }
126
+
127
+ // ---- observable state (useSyncExternalStore friendly) -------------------
128
+
129
+ subscribe = listener => {
130
+ this.listeners.add(listener);
131
+ return () => {
132
+ this.listeners.delete(listener);
133
+ };
134
+ };
135
+ getSnapshot = () => this.snapshot;
136
+ update(patch) {
137
+ this.snapshot = {
138
+ ...this.snapshot,
139
+ ...patch
140
+ };
141
+ for (const listener of Array.from(this.listeners)) listener();
142
+ }
143
+ log(message, detail) {
144
+ this.deps.log?.(`[p2p ${this.callId}] ${message}`, detail);
145
+ }
146
+
147
+ // ---- timers -------------------------------------------------------------
148
+
149
+ later(fn, ms) {
150
+ const id = setTimeout(() => {
151
+ this.timers.delete(id);
152
+ if (!this.disposed) fn();
153
+ }, ms);
154
+ this.timers.add(id);
155
+ return id;
156
+ }
157
+ cancel(id) {
158
+ if (id === null) return;
159
+ clearTimeout(id);
160
+ this.timers.delete(id);
161
+ }
162
+
163
+ // ---- lifecycle ----------------------------------------------------------
164
+
165
+ /**
166
+ * Caller: get media, build the connection, offer. Callee: get media, build
167
+ * the connection, then apply the offer that may already be waiting. Safe to
168
+ * call once; every failure ends the call with a message instead of throwing.
169
+ */
170
+ async start() {
171
+ if (this.started || this.disposed) return;
172
+ this.started = true;
173
+ this.update({
174
+ status: 'preparing'
175
+ });
176
+
177
+ // Credentials are fetched while the permission prompt is open.
178
+ const icePromise = this.params.iceServers.length > 0 ? Promise.resolve(this.params.iceServers) : this.deps.fetchIceServers().then(list => list || []).catch(() => []);
179
+ try {
180
+ await this.acquireMedia();
181
+ } catch (error) {
182
+ this.log('getUserMedia failed', error);
183
+ this.fail(describeMediaError(error), 'media-error');
184
+ return;
185
+ }
186
+ if (this.disposed) {
187
+ this.releaseMedia();
188
+ return;
189
+ }
190
+ const servers = await icePromise;
191
+ if (this.disposed) return;
192
+ try {
193
+ this.createConnection(servers);
194
+ } catch (error) {
195
+ this.log('peer connection setup failed', error);
196
+ this.fail('Could not start the call', 'setup-error');
197
+ return;
198
+ }
199
+ this.enqueue(async () => {
200
+ await this.runCommands(this.negotiator.markReady());
201
+ if (this.role === 'caller' && !this.disposed) {
202
+ await this.sendOffer(false);
203
+ this.update({
204
+ status: 'waiting'
205
+ });
206
+ this.scheduleOfferResends();
207
+ }
208
+ });
209
+ }
210
+
211
+ /** Feed a signal from the peer (already routed by callId). */
212
+ receive(signal) {
213
+ if (this.disposed) return;
214
+ const commands = this.negotiator.receive(signal);
215
+ // An end must act immediately: it can arrive while the permission prompt
216
+ // is still open, before the connection (and so the job queue) is running.
217
+ const end = commands.find(c => c.type === 'remote-end');
218
+ if (end && end.type === 'remote-end') {
219
+ this.handleRemoteEnd(end.reason);
220
+ return;
221
+ }
222
+ if (commands.length > 0) this.enqueue(() => this.runCommands(commands));
223
+ }
224
+
225
+ /** Local user hung up (or cancelled): tell the peer and release everything. */
226
+ hangup(reason = 'hangup') {
227
+ if (this.disposed) return;
228
+ this.sendEnd(reason);
229
+ this.dispose();
230
+ }
231
+
232
+ /**
233
+ * Release every resource: timers, listeners, media tracks, the connection.
234
+ * Idempotent, safe from any exit path. Tells the peer unless it is already
235
+ * known to be over.
236
+ */
237
+ dispose() {
238
+ if (this.disposed) return;
239
+ this.disposed = true;
240
+ if (this.started && !this.negotiator.isEnded) this.sendEnd('hangup');
241
+ for (const id of this.timers) clearTimeout(id);
242
+ this.timers.clear();
243
+ this.negotiator.stop();
244
+ for (const cleanup of this.remoteCleanups) {
245
+ try {
246
+ cleanup();
247
+ } catch {
248
+ /* listener already gone */
249
+ }
250
+ }
251
+ this.remoteCleanups = [];
252
+ const pc = this.pc;
253
+ this.pc = null;
254
+ if (pc) {
255
+ pc.onicecandidate = null;
256
+ pc.ontrack = null;
257
+ pc.onconnectionstatechange = null;
258
+ pc.oniceconnectionstatechange = null;
259
+ try {
260
+ pc.close();
261
+ } catch {
262
+ /* already closed */
263
+ }
264
+ }
265
+ this.releaseMedia();
266
+ this.snapshot = {
267
+ ...this.snapshot,
268
+ status: this.snapshot.status === 'failed' ? 'failed' : 'ended',
269
+ localStream: null,
270
+ remoteStream: null,
271
+ remoteVideoLive: false
272
+ };
273
+ for (const listener of Array.from(this.listeners)) listener();
274
+ this.listeners.clear();
275
+ this.events.onDisposed?.({
276
+ started: this.started
277
+ });
278
+ }
279
+ sendEnd(reason) {
280
+ if (this.endSent) return;
281
+ this.endSent = true;
282
+ try {
283
+ this.deps.sendSignal('end', {
284
+ reason
285
+ });
286
+ } catch (error) {
287
+ this.log('end signal failed', error);
288
+ }
289
+ }
290
+ fail(message, reason) {
291
+ if (this.disposed) return;
292
+ this.sendEnd(reason);
293
+ this.snapshot = {
294
+ ...this.snapshot,
295
+ status: 'failed',
296
+ notice: message
297
+ };
298
+ this.events.onFailed?.(message);
299
+ this.dispose();
300
+ }
301
+ handleRemoteEnd(reason) {
302
+ if (this.disposed) return;
303
+ // The peer already knows; do not echo an end back.
304
+ this.endSent = true;
305
+ this.snapshot = {
306
+ ...this.snapshot,
307
+ status: 'ended'
308
+ };
309
+ this.events.onRemoteEnd?.(reason);
310
+ this.dispose();
311
+ }
312
+
313
+ // ---- media --------------------------------------------------------------
314
+
315
+ async acquireMedia() {
316
+ const wantVideo = this.kind === 'video' && this.params.startWithCameraOn !== false;
317
+ const stream = await this.deps.getUserMedia({
318
+ audio: AUDIO_CONSTRAINTS,
319
+ video: wantVideo ? VIDEO_CONSTRAINTS : false
320
+ });
321
+ this.localStream = stream;
322
+ this.ownedTracks = stream.getTracks();
323
+ this.audioTrack = stream.getAudioTracks()[0] || null;
324
+ this.videoTrack = stream.getVideoTracks()[0] || null;
325
+ if (this.audioTrack && this.params.startWithMicOn === false) {
326
+ this.audioTrack.enabled = false;
327
+ }
328
+ this.update({
329
+ localStream: stream,
330
+ micEnabled: !!this.audioTrack && this.audioTrack.enabled,
331
+ camEnabled: !!this.videoTrack
332
+ });
333
+ }
334
+ releaseMedia() {
335
+ const tracks = new Set(this.ownedTracks);
336
+ this.localStream?.getTracks().forEach(t => tracks.add(t));
337
+ for (const track of tracks) {
338
+ try {
339
+ track.stop();
340
+ } catch {
341
+ /* already stopped */
342
+ }
343
+ }
344
+ this.ownedTracks = [];
345
+ this.audioTrack = null;
346
+ this.videoTrack = null;
347
+ this.videoSender = null;
348
+ this.localStream = null;
349
+ }
350
+ toggleMic() {
351
+ if (this.disposed || !this.audioTrack) return;
352
+ this.audioTrack.enabled = !this.audioTrack.enabled;
353
+ this.update({
354
+ micEnabled: this.audioTrack.enabled
355
+ });
356
+ }
357
+
358
+ /**
359
+ * Turning the camera off stops sending video and releases the device (the
360
+ * camera light goes out); turning it on opens the camera again and swaps it
361
+ * into the existing sender, so no renegotiation is needed.
362
+ */
363
+ async toggleCamera() {
364
+ if (this.disposed || this.kind !== 'video' || !this.videoSender || !this.localStream || this.cameraBusy) {
365
+ return;
366
+ }
367
+ this.cameraBusy = true;
368
+ try {
369
+ if (this.videoTrack) {
370
+ const track = this.videoTrack;
371
+ this.videoTrack = null;
372
+ try {
373
+ await this.videoSender.replaceTrack(null);
374
+ } catch (error) {
375
+ this.log('replaceTrack(null) failed', error);
376
+ }
377
+ try {
378
+ this.localStream.removeTrack(track);
379
+ } catch {
380
+ /* not in the stream */
381
+ }
382
+ track.stop();
383
+ this.ownedTracks = this.ownedTracks.filter(t => t !== track);
384
+ this.update({
385
+ camEnabled: false,
386
+ notice: null
387
+ });
388
+ } else {
389
+ const media = await this.deps.getUserMedia({
390
+ video: VIDEO_CONSTRAINTS
391
+ });
392
+ const track = media.getVideoTracks()[0];
393
+ if (!track) return;
394
+ if (this.disposed || !this.videoSender || !this.localStream) {
395
+ track.stop();
396
+ return;
397
+ }
398
+ await this.videoSender.replaceTrack(track);
399
+ this.localStream.addTrack(track);
400
+ this.videoTrack = track;
401
+ this.ownedTracks.push(track);
402
+ this.update({
403
+ camEnabled: true,
404
+ notice: null
405
+ });
406
+ }
407
+ } catch (error) {
408
+ this.log('camera toggle failed', error);
409
+ this.update({
410
+ notice: describeMediaError(error)
411
+ });
412
+ } finally {
413
+ this.cameraBusy = false;
414
+ }
415
+ }
416
+ dismissNotice() {
417
+ if (this.snapshot.notice) this.update({
418
+ notice: null
419
+ });
420
+ }
421
+
422
+ // ---- peer connection ----------------------------------------------------
423
+
424
+ createConnection(servers) {
425
+ const pc = this.deps.createPeerConnection({
426
+ iceServers: servers,
427
+ iceCandidatePoolSize: 2
428
+ });
429
+ this.pc = pc;
430
+ pc.onicecandidate = event => {
431
+ const c = event.candidate;
432
+ if (!c || !c.candidate) return;
433
+ const json = typeof c.toJSON === 'function' ? c.toJSON() : {
434
+ candidate: c.candidate,
435
+ sdpMid: c.sdpMid,
436
+ sdpMLineIndex: c.sdpMLineIndex
437
+ };
438
+ if (this.candidateGateOpen) this.emitCandidate(json);else this.heldOutgoingCandidates.push(json);
439
+ };
440
+ pc.ontrack = event => this.onRemoteTrack(event.track);
441
+ pc.onconnectionstatechange = () => this.onConnectionState();
442
+ pc.oniceconnectionstatechange = () => this.onConnectionState();
443
+ const stream = this.localStream;
444
+ if (stream) {
445
+ if (this.audioTrack) pc.addTrack(this.audioTrack, stream);
446
+ if (this.kind === 'video') {
447
+ if (this.videoTrack) {
448
+ this.videoSender = pc.addTrack(this.videoTrack, stream);
449
+ } else {
450
+ // Camera starts off: keep a video section so it can be turned on
451
+ // later without renegotiating.
452
+ this.videoSender = pc.addTransceiver('video', {
453
+ direction: 'sendrecv'
454
+ }).sender;
455
+ }
456
+ }
457
+ }
458
+ }
459
+ emitCandidate(candidate) {
460
+ this.sentCandidates.push(candidate);
461
+ this.deps.sendSignal('candidate', candidate);
462
+ }
463
+ openCandidateGate() {
464
+ this.candidateGateOpen = true;
465
+ const held = this.heldOutgoingCandidates;
466
+ this.heldOutgoingCandidates = [];
467
+ for (const candidate of held) this.emitCandidate(candidate);
468
+ }
469
+ onRemoteTrack(track) {
470
+ if (!this.remoteStream) this.remoteStream = this.deps.createMediaStream();
471
+ const stream = this.remoteStream;
472
+ if (!stream.getTracks().includes(track)) stream.addTrack(track);
473
+ const refresh = () => this.update({
474
+ remoteVideoLive: this.remoteVideoLive()
475
+ });
476
+ track.addEventListener('mute', refresh);
477
+ track.addEventListener('unmute', refresh);
478
+ track.addEventListener('ended', refresh);
479
+ this.remoteCleanups.push(() => {
480
+ track.removeEventListener('mute', refresh);
481
+ track.removeEventListener('unmute', refresh);
482
+ track.removeEventListener('ended', refresh);
483
+ });
484
+ this.update({
485
+ remoteStream: stream,
486
+ remoteVideoLive: this.remoteVideoLive()
487
+ });
488
+ }
489
+ remoteVideoLive() {
490
+ return (this.remoteStream?.getVideoTracks() || []).some(t => t.readyState === 'live' && !t.muted);
491
+ }
492
+
493
+ // ---- negotiation --------------------------------------------------------
494
+
495
+ enqueue(job) {
496
+ this.queue = this.queue.then(() => this.disposed ? undefined : job()).catch(error => {
497
+ this.log('negotiation step failed', error);
498
+ // A broken negotiation cannot recover on its own.
499
+ this.fail('Could not set up the call', 'negotiation-error');
500
+ });
501
+ }
502
+ async sendOffer(iceRestart) {
503
+ const pc = this.pc;
504
+ if (!pc || this.disposed) return;
505
+ this.candidateGateOpen = false;
506
+ const offer = await pc.createOffer(iceRestart ? {
507
+ iceRestart: true
508
+ } : undefined);
509
+ await pc.setLocalDescription(offer);
510
+ if (this.disposed) return;
511
+ const sdp = pc.localDescription?.sdp || offer.sdp || '';
512
+ this.negotiator.markLocalOffer();
513
+ this.lastOffer = {
514
+ type: 'offer',
515
+ sdp
516
+ };
517
+ this.sentCandidates = [];
518
+ this.deps.sendSignal('offer', this.lastOffer);
519
+ this.openCandidateGate();
520
+ }
521
+ scheduleOfferResends() {
522
+ for (const ms of this.timings.offerResendMs) {
523
+ this.later(() => {
524
+ if (!this.negotiator.awaitingAnswer || !this.lastOffer) return;
525
+ this.log('re-sending offer');
526
+ this.deps.sendSignal('offer', this.lastOffer);
527
+ for (const candidate of this.sentCandidates) {
528
+ this.deps.sendSignal('candidate', candidate);
529
+ }
530
+ }, ms);
531
+ }
532
+ }
533
+ async runCommands(commands) {
534
+ for (const command of commands) {
535
+ if (this.disposed || !this.pc) return;
536
+ switch (command.type) {
537
+ case 'apply-offer':
538
+ await this.applyOffer(command);
539
+ break;
540
+ case 'apply-answer':
541
+ await this.pc.setRemoteDescription({
542
+ type: 'answer',
543
+ sdp: command.sdp
544
+ });
545
+ await this.runCommands(this.negotiator.markRemoteApplied());
546
+ this.onNegotiated();
547
+ break;
548
+ case 'add-candidate':
549
+ try {
550
+ await this.pc.addIceCandidate(command.candidate);
551
+ } catch (error) {
552
+ // A candidate from a superseded ICE session; harmless.
553
+ this.log('addIceCandidate ignored', error);
554
+ }
555
+ break;
556
+ case 'remote-end':
557
+ // Handled synchronously in receive(); never queued.
558
+ break;
559
+ }
560
+ }
561
+ }
562
+ async applyOffer(command) {
563
+ const pc = this.pc;
564
+ if (!pc) return;
565
+ if (command.rollback && pc.signalingState === 'have-local-offer') {
566
+ await pc.setLocalDescription({
567
+ type: 'rollback'
568
+ });
569
+ }
570
+ await pc.setRemoteDescription({
571
+ type: 'offer',
572
+ sdp: command.sdp
573
+ });
574
+ await this.runCommands(this.negotiator.markRemoteApplied());
575
+ if (this.disposed || !this.pc) return;
576
+ this.candidateGateOpen = false;
577
+ const answer = await pc.createAnswer();
578
+ await pc.setLocalDescription(answer);
579
+ if (this.disposed) return;
580
+ this.deps.sendSignal('answer', {
581
+ type: 'answer',
582
+ sdp: pc.localDescription?.sdp || answer.sdp || ''
583
+ });
584
+ this.openCandidateGate();
585
+ if (command.initial) this.onNegotiated();
586
+ }
587
+ onNegotiated() {
588
+ if (this.negotiated || this.disposed) return;
589
+ this.negotiated = true;
590
+ if (!this.connectedOnce) {
591
+ this.update({
592
+ status: 'connecting'
593
+ });
594
+ this.connectTimer = this.later(() => {
595
+ if (!this.connectedOnce) {
596
+ this.fail('Could not connect the call', 'connect-timeout');
597
+ }
598
+ }, this.timings.connectTimeoutMs);
599
+ }
600
+ this.events.onNegotiated?.();
601
+ }
602
+
603
+ // ---- connection health --------------------------------------------------
604
+
605
+ connState() {
606
+ const pc = this.pc;
607
+ if (!pc) return 'closed';
608
+ const cs = pc.connectionState;
609
+ if (cs) return cs;
610
+ // Browsers without connectionState: map the ICE state.
611
+ switch (pc.iceConnectionState) {
612
+ case 'connected':
613
+ case 'completed':
614
+ return 'connected';
615
+ case 'disconnected':
616
+ return 'disconnected';
617
+ case 'failed':
618
+ return 'failed';
619
+ case 'closed':
620
+ return 'closed';
621
+ case 'checking':
622
+ return 'connecting';
623
+ default:
624
+ return 'new';
625
+ }
626
+ }
627
+ onConnectionState() {
628
+ if (this.disposed) return;
629
+ const state = this.connState();
630
+ if (state === this.lastConn) return;
631
+ this.lastConn = state;
632
+ this.log(`connection ${state}`);
633
+ if (state === 'connected') {
634
+ this.cancel(this.graceTimer);
635
+ this.cancel(this.deadlineTimer);
636
+ this.cancel(this.connectTimer);
637
+ this.graceTimer = this.deadlineTimer = this.connectTimer = null;
638
+ this.runIceAction(this.policy.onState(state));
639
+ this.update({
640
+ status: 'connected'
641
+ });
642
+ if (!this.connectedOnce) {
643
+ this.connectedOnce = true;
644
+ this.events.onConnected?.();
645
+ }
646
+ return;
647
+ }
648
+ if (state === 'connecting') {
649
+ if (this.connectedOnce) this.update({
650
+ status: 'reconnecting'
651
+ });
652
+ return;
653
+ }
654
+ if (state === 'disconnected' || state === 'failed') {
655
+ if (this.connectedOnce) this.update({
656
+ status: 'reconnecting'
657
+ });
658
+ this.runIceAction(this.policy.onState(state));
659
+ }
660
+ }
661
+ runIceAction(action) {
662
+ switch (action.type) {
663
+ case 'wait':
664
+ this.cancel(this.graceTimer);
665
+ this.graceTimer = this.later(() => {
666
+ this.graceTimer = null;
667
+ this.runIceAction(this.policy.onGraceElapsed());
668
+ }, action.ms);
669
+ break;
670
+ case 'restart':
671
+ this.cancel(this.graceTimer);
672
+ this.graceTimer = null;
673
+ this.cancel(this.deadlineTimer);
674
+ this.deadlineTimer = this.later(() => {
675
+ this.deadlineTimer = null;
676
+ const down = this.lastConn !== 'connected';
677
+ this.runIceAction(this.policy.onRestartDeadline(down));
678
+ }, action.deadlineMs);
679
+ this.enqueue(() => this.restartIce());
680
+ break;
681
+ case 'give-up':
682
+ this.fail('Connection lost', 'connection-failed');
683
+ break;
684
+ case 'recovered':
685
+ case 'none':
686
+ break;
687
+ }
688
+ }
689
+
690
+ /** ICE restart with fresh TURN credentials; the caller of this is the policy. */
691
+ async restartIce() {
692
+ const pc = this.pc;
693
+ if (!pc || this.disposed) return;
694
+ let fresh = null;
695
+ try {
696
+ fresh = await this.deps.fetchIceServers();
697
+ } catch {
698
+ fresh = null;
699
+ }
700
+ if (this.disposed || !this.pc) return;
701
+ if (fresh && fresh.length > 0) {
702
+ try {
703
+ pc.setConfiguration({
704
+ ...pc.getConfiguration(),
705
+ iceServers: fresh
706
+ });
707
+ } catch (error) {
708
+ this.log('setConfiguration failed', error);
709
+ }
710
+ }
711
+ // A negotiation is already in flight (e.g. the peer is restarting too);
712
+ // the restart deadline still guards the outcome.
713
+ if (pc.signalingState !== 'stable') return;
714
+ if (typeof pc.restartIce === 'function') pc.restartIce();
715
+ await this.sendOffer(true);
716
+ }
717
+ }
718
+ //# sourceMappingURL=P2PCallController.js.map