@stream-io/video-react-native-sdk 1.29.4-beta.0 → 1.30.0

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 (276) hide show
  1. package/CHANGELOG.md +3162 -0
  2. package/android/src/main/AndroidManifest.xml +1 -8
  3. package/android/src/main/AndroidManifestNew.xml +0 -11
  4. package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +5 -42
  5. package/android/src/main/java/com/streamvideo/reactnative/audio/utils/WebRtcAudioUtils.kt +6 -70
  6. package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt +4 -6
  7. package/android/src/main/java/com/streamvideo/reactnative/util/CallAliveServiceChecker.kt +95 -0
  8. package/dist/commonjs/components/Call/CallContent/CallContent.js +13 -7
  9. package/dist/commonjs/components/Call/CallContent/CallContent.js.map +1 -1
  10. package/dist/commonjs/components/Call/CallContent/RTCViewPipIOS.js +50 -14
  11. package/dist/commonjs/components/Call/CallContent/RTCViewPipIOS.js.map +1 -1
  12. package/dist/commonjs/components/Call/CallContent/RTCViewPipNative.js +27 -0
  13. package/dist/commonjs/components/Call/CallContent/RTCViewPipNative.js.map +1 -1
  14. package/dist/commonjs/components/Call/CallLayout/CallParticipantsGrid.js +19 -10
  15. package/dist/commonjs/components/Call/CallLayout/CallParticipantsGrid.js.map +1 -1
  16. package/dist/commonjs/components/Call/CallLayout/CallParticipantsSpotlight.js +12 -9
  17. package/dist/commonjs/components/Call/CallLayout/CallParticipantsSpotlight.js.map +1 -1
  18. package/dist/commonjs/components/Call/CallParticipantsList/CallParticipantsList.js +19 -4
  19. package/dist/commonjs/components/Call/CallParticipantsList/CallParticipantsList.js.map +1 -1
  20. package/dist/commonjs/hooks/push/index.js +2 -0
  21. package/dist/commonjs/hooks/push/index.js.map +1 -1
  22. package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js +160 -0
  23. package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +1 -0
  24. package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js +31 -18
  25. package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
  26. package/dist/commonjs/hooks/push/useProcessPushCallEffect.js +67 -0
  27. package/dist/commonjs/hooks/push/useProcessPushCallEffect.js.map +1 -0
  28. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +97 -64
  29. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  30. package/dist/commonjs/index.js +0 -1
  31. package/dist/commonjs/index.js.map +1 -1
  32. package/dist/commonjs/modules/call-manager/CallManager.js +0 -26
  33. package/dist/commonjs/modules/call-manager/CallManager.js.map +1 -1
  34. package/dist/commonjs/providers/StreamCall/index.js +6 -6
  35. package/dist/commonjs/providers/StreamCall/index.js.map +1 -1
  36. package/dist/commonjs/utils/StreamVideoRN/index.js +21 -33
  37. package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
  38. package/dist/commonjs/utils/hooks/index.js +0 -11
  39. package/dist/commonjs/utils/hooks/index.js.map +1 -1
  40. package/dist/commonjs/utils/internal/registerSDKGlobals.js +3 -52
  41. package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
  42. package/dist/commonjs/utils/push/android.js +202 -151
  43. package/dist/commonjs/utils/push/android.js.map +1 -1
  44. package/dist/commonjs/utils/push/internal/ios.js +34 -17
  45. package/dist/commonjs/utils/push/internal/ios.js.map +1 -1
  46. package/dist/commonjs/utils/push/internal/rxSubjects.js +45 -1
  47. package/dist/commonjs/utils/push/internal/rxSubjects.js.map +1 -1
  48. package/dist/commonjs/utils/push/internal/utils.js +20 -32
  49. package/dist/commonjs/utils/push/internal/utils.js.map +1 -1
  50. package/dist/commonjs/utils/push/ios.js.map +1 -1
  51. package/dist/commonjs/utils/push/libs/callkeep.js +17 -0
  52. package/dist/commonjs/utils/push/libs/callkeep.js.map +1 -0
  53. package/dist/commonjs/utils/push/libs/index.js +19 -8
  54. package/dist/commonjs/utils/push/libs/index.js.map +1 -1
  55. package/dist/commonjs/utils/push/libs/notifee/index.js +19 -0
  56. package/dist/commonjs/utils/push/libs/notifee/index.js.map +1 -1
  57. package/dist/commonjs/utils/push/libs/voipPushNotification.js +17 -0
  58. package/dist/commonjs/utils/push/libs/voipPushNotification.js.map +1 -0
  59. package/dist/commonjs/utils/push/setupIosCallKeepEvents.js +205 -0
  60. package/dist/commonjs/utils/push/setupIosCallKeepEvents.js.map +1 -0
  61. package/dist/commonjs/utils/push/setupIosVoipPushEvents.js +6 -7
  62. package/dist/commonjs/utils/push/setupIosVoipPushEvents.js.map +1 -1
  63. package/dist/commonjs/version.js +1 -1
  64. package/dist/commonjs/version.js.map +1 -1
  65. package/dist/module/components/Call/CallContent/CallContent.js +10 -4
  66. package/dist/module/components/Call/CallContent/CallContent.js.map +1 -1
  67. package/dist/module/components/Call/CallContent/RTCViewPipIOS.js +52 -16
  68. package/dist/module/components/Call/CallContent/RTCViewPipIOS.js.map +1 -1
  69. package/dist/module/components/Call/CallContent/RTCViewPipNative.js +27 -0
  70. package/dist/module/components/Call/CallContent/RTCViewPipNative.js.map +1 -1
  71. package/dist/module/components/Call/CallLayout/CallParticipantsGrid.js +19 -10
  72. package/dist/module/components/Call/CallLayout/CallParticipantsGrid.js.map +1 -1
  73. package/dist/module/components/Call/CallLayout/CallParticipantsSpotlight.js +15 -12
  74. package/dist/module/components/Call/CallLayout/CallParticipantsSpotlight.js.map +1 -1
  75. package/dist/module/components/Call/CallParticipantsList/CallParticipantsList.js +20 -5
  76. package/dist/module/components/Call/CallParticipantsList/CallParticipantsList.js.map +1 -1
  77. package/dist/module/hooks/push/index.js +2 -0
  78. package/dist/module/hooks/push/index.js.map +1 -1
  79. package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js +153 -0
  80. package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +1 -0
  81. package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js +31 -18
  82. package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
  83. package/dist/module/hooks/push/useProcessPushCallEffect.js +60 -0
  84. package/dist/module/hooks/push/useProcessPushCallEffect.js.map +1 -0
  85. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +99 -66
  86. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  87. package/dist/module/index.js +0 -1
  88. package/dist/module/index.js.map +1 -1
  89. package/dist/module/modules/call-manager/CallManager.js +0 -26
  90. package/dist/module/modules/call-manager/CallManager.js.map +1 -1
  91. package/dist/module/providers/StreamCall/index.js +6 -6
  92. package/dist/module/providers/StreamCall/index.js.map +1 -1
  93. package/dist/module/utils/StreamVideoRN/index.js +21 -33
  94. package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
  95. package/dist/module/utils/hooks/index.js +0 -1
  96. package/dist/module/utils/hooks/index.js.map +1 -1
  97. package/dist/module/utils/internal/registerSDKGlobals.js +3 -52
  98. package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
  99. package/dist/module/utils/push/android.js +204 -153
  100. package/dist/module/utils/push/android.js.map +1 -1
  101. package/dist/module/utils/push/internal/ios.js +34 -17
  102. package/dist/module/utils/push/internal/ios.js.map +1 -1
  103. package/dist/module/utils/push/internal/rxSubjects.js +44 -0
  104. package/dist/module/utils/push/internal/rxSubjects.js.map +1 -1
  105. package/dist/module/utils/push/internal/utils.js +19 -29
  106. package/dist/module/utils/push/internal/utils.js.map +1 -1
  107. package/dist/module/utils/push/ios.js.map +1 -1
  108. package/dist/module/utils/push/libs/callkeep.js +11 -0
  109. package/dist/module/utils/push/libs/callkeep.js.map +1 -0
  110. package/dist/module/utils/push/libs/index.js +2 -1
  111. package/dist/module/utils/push/libs/index.js.map +1 -1
  112. package/dist/module/utils/push/libs/notifee/index.js +18 -0
  113. package/dist/module/utils/push/libs/notifee/index.js.map +1 -1
  114. package/dist/module/utils/push/libs/voipPushNotification.js +11 -0
  115. package/dist/module/utils/push/libs/voipPushNotification.js.map +1 -0
  116. package/dist/module/utils/push/setupIosCallKeepEvents.js +199 -0
  117. package/dist/module/utils/push/setupIosCallKeepEvents.js.map +1 -0
  118. package/dist/module/utils/push/setupIosVoipPushEvents.js +6 -7
  119. package/dist/module/utils/push/setupIosVoipPushEvents.js.map +1 -1
  120. package/dist/module/version.js +1 -1
  121. package/dist/module/version.js.map +1 -1
  122. package/dist/typescript/components/Call/CallContent/CallContent.d.ts.map +1 -1
  123. package/dist/typescript/components/Call/CallContent/RTCViewPipIOS.d.ts.map +1 -1
  124. package/dist/typescript/components/Call/CallContent/RTCViewPipNative.d.ts +18 -0
  125. package/dist/typescript/components/Call/CallContent/RTCViewPipNative.d.ts.map +1 -1
  126. package/dist/typescript/components/Call/CallLayout/CallParticipantsGrid.d.ts.map +1 -1
  127. package/dist/typescript/components/Call/CallLayout/CallParticipantsSpotlight.d.ts.map +1 -1
  128. package/dist/typescript/components/Call/CallParticipantsList/CallParticipantsList.d.ts.map +1 -1
  129. package/dist/typescript/hooks/push/index.d.ts.map +1 -1
  130. package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts +5 -0
  131. package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts.map +1 -0
  132. package/dist/typescript/hooks/push/useIosVoipPushEventsSetupEffect.d.ts.map +1 -1
  133. package/dist/typescript/hooks/push/useProcessPushCallEffect.d.ts +8 -0
  134. package/dist/typescript/hooks/push/useProcessPushCallEffect.d.ts.map +1 -0
  135. package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
  136. package/dist/typescript/index.d.ts +0 -1
  137. package/dist/typescript/index.d.ts.map +1 -1
  138. package/dist/typescript/modules/call-manager/CallManager.d.ts +0 -5
  139. package/dist/typescript/modules/call-manager/CallManager.d.ts.map +1 -1
  140. package/dist/typescript/utils/StreamVideoRN/index.d.ts +2 -20
  141. package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
  142. package/dist/typescript/utils/StreamVideoRN/types.d.ts +29 -54
  143. package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
  144. package/dist/typescript/utils/hooks/index.d.ts +0 -1
  145. package/dist/typescript/utils/hooks/index.d.ts.map +1 -1
  146. package/dist/typescript/utils/internal/registerSDKGlobals.d.ts.map +1 -1
  147. package/dist/typescript/utils/push/android.d.ts +2 -1
  148. package/dist/typescript/utils/push/android.d.ts.map +1 -1
  149. package/dist/typescript/utils/push/internal/ios.d.ts.map +1 -1
  150. package/dist/typescript/utils/push/internal/rxSubjects.d.ts +33 -0
  151. package/dist/typescript/utils/push/internal/rxSubjects.d.ts.map +1 -1
  152. package/dist/typescript/utils/push/internal/utils.d.ts +1 -8
  153. package/dist/typescript/utils/push/internal/utils.d.ts.map +1 -1
  154. package/dist/typescript/utils/push/ios.d.ts +2 -1
  155. package/dist/typescript/utils/push/ios.d.ts.map +1 -1
  156. package/dist/typescript/utils/push/libs/callkeep.d.ts +3 -0
  157. package/dist/typescript/utils/push/libs/callkeep.d.ts.map +1 -0
  158. package/dist/typescript/utils/push/libs/index.d.ts +2 -1
  159. package/dist/typescript/utils/push/libs/index.d.ts.map +1 -1
  160. package/dist/typescript/utils/push/libs/notifee/index.d.ts +1 -0
  161. package/dist/typescript/utils/push/libs/notifee/index.d.ts.map +1 -1
  162. package/dist/typescript/utils/push/libs/voipPushNotification.d.ts +3 -0
  163. package/dist/typescript/utils/push/libs/voipPushNotification.d.ts.map +1 -0
  164. package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts +6 -0
  165. package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts.map +1 -0
  166. package/dist/typescript/utils/push/setupIosVoipPushEvents.d.ts.map +1 -1
  167. package/dist/typescript/version.d.ts +1 -1
  168. package/dist/typescript/version.d.ts.map +1 -1
  169. package/expo-config-plugin/dist/withAndroidManifest.js +33 -1
  170. package/expo-config-plugin/dist/withAndroidPermissions.js +7 -2
  171. package/expo-config-plugin/dist/withAppDelegate.js +197 -19
  172. package/expo-config-plugin/dist/withMainActivity.js +1 -1
  173. package/expo-config-plugin/dist/withiOSInfoPlist.js +3 -2
  174. package/ios/PictureInPicture/PictureInPictureAvatarView.swift +273 -0
  175. package/ios/PictureInPicture/PictureInPictureConnectionQualityIndicator.swift +162 -0
  176. package/ios/PictureInPicture/PictureInPictureContent.swift +173 -0
  177. package/ios/PictureInPicture/PictureInPictureContentState.swift +123 -0
  178. package/ios/PictureInPicture/PictureInPictureDelegateProxy.swift +89 -0
  179. package/ios/PictureInPicture/PictureInPictureEnforcedStopAdapter.swift +166 -0
  180. package/ios/PictureInPicture/PictureInPictureLogger.swift +16 -0
  181. package/ios/PictureInPicture/PictureInPictureParticipantOverlayView.swift +217 -0
  182. package/ios/PictureInPicture/PictureInPictureReconnectionView.swift +193 -0
  183. package/ios/PictureInPicture/StreamAVPictureInPictureVideoCallViewController.swift +125 -7
  184. package/ios/PictureInPicture/StreamPictureInPictureController.swift +237 -63
  185. package/ios/PictureInPicture/StreamPictureInPictureControllerProtocol.swift +30 -0
  186. package/ios/PictureInPicture/StreamPictureInPictureVideoRenderer.swift +384 -12
  187. package/ios/RTCViewPip.swift +187 -21
  188. package/ios/RTCViewPipManager.mm +9 -0
  189. package/ios/RTCViewPipManager.swift +3 -3
  190. package/ios/StreamInCallManager.m +0 -2
  191. package/ios/StreamInCallManager.swift +7 -19
  192. package/ios/StreamVideoReactNative.h +4 -7
  193. package/ios/StreamVideoReactNative.m +82 -189
  194. package/package.json +19 -14
  195. package/src/components/Call/CallContent/CallContent.tsx +16 -8
  196. package/src/components/Call/CallContent/RTCViewPipIOS.tsx +81 -15
  197. package/src/components/Call/CallContent/RTCViewPipNative.tsx +36 -0
  198. package/src/components/Call/CallLayout/CallParticipantsGrid.tsx +28 -14
  199. package/src/components/Call/CallLayout/CallParticipantsSpotlight.tsx +19 -10
  200. package/src/components/Call/CallParticipantsList/CallParticipantsList.tsx +20 -5
  201. package/src/hooks/push/index.ts +2 -0
  202. package/src/hooks/push/useIosCallkeepWithCallingStateEffect.ts +235 -0
  203. package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +34 -21
  204. package/src/hooks/push/useProcessPushCallEffect.ts +108 -0
  205. package/src/hooks/useAndroidKeepCallAliveEffect.ts +120 -94
  206. package/src/index.ts +0 -1
  207. package/src/modules/call-manager/CallManager.ts +0 -36
  208. package/src/modules/call-manager/native-module.d.ts +0 -7
  209. package/src/providers/StreamCall/index.tsx +6 -6
  210. package/src/utils/StreamVideoRN/index.ts +30 -40
  211. package/src/utils/StreamVideoRN/types.ts +29 -56
  212. package/src/utils/hooks/index.ts +0 -1
  213. package/src/utils/internal/registerSDKGlobals.ts +4 -47
  214. package/src/utils/push/android.ts +309 -227
  215. package/src/utils/push/internal/ios.ts +44 -28
  216. package/src/utils/push/internal/rxSubjects.ts +61 -0
  217. package/src/utils/push/internal/utils.ts +26 -45
  218. package/src/utils/push/ios.ts +6 -1
  219. package/src/utils/push/libs/callkeep.ts +16 -0
  220. package/src/utils/push/libs/index.ts +2 -1
  221. package/src/utils/push/libs/notifee/index.ts +27 -0
  222. package/src/utils/push/libs/voipPushNotification.ts +17 -0
  223. package/src/utils/push/setupIosCallKeepEvents.ts +252 -0
  224. package/src/utils/push/setupIosVoipPushEvents.ts +7 -11
  225. package/src/version.ts +1 -1
  226. package/android/src/main/java/com/streamvideo/reactnative/keepalive/KeepAliveNotification.kt +0 -83
  227. package/android/src/main/java/com/streamvideo/reactnative/keepalive/StreamCallKeepAliveHeadlessService.kt +0 -149
  228. package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js +0 -121
  229. package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js.map +0 -1
  230. package/dist/commonjs/utils/hooks/useDebouncedValue.js +0 -24
  231. package/dist/commonjs/utils/hooks/useDebouncedValue.js.map +0 -1
  232. package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js +0 -58
  233. package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js.map +0 -1
  234. package/dist/commonjs/utils/internal/callingx/callingx.js +0 -109
  235. package/dist/commonjs/utils/internal/callingx/callingx.js.map +0 -1
  236. package/dist/commonjs/utils/keepCallAliveHeadlessTask.js +0 -48
  237. package/dist/commonjs/utils/keepCallAliveHeadlessTask.js.map +0 -1
  238. package/dist/commonjs/utils/push/libs/callingx.js +0 -75
  239. package/dist/commonjs/utils/push/libs/callingx.js.map +0 -1
  240. package/dist/commonjs/utils/push/setupCallingExpEvents.js +0 -108
  241. package/dist/commonjs/utils/push/setupCallingExpEvents.js.map +0 -1
  242. package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js +0 -114
  243. package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js.map +0 -1
  244. package/dist/module/utils/hooks/useDebouncedValue.js +0 -19
  245. package/dist/module/utils/hooks/useDebouncedValue.js.map +0 -1
  246. package/dist/module/utils/internal/callingx/audioSessionPromise.js +0 -51
  247. package/dist/module/utils/internal/callingx/audioSessionPromise.js.map +0 -1
  248. package/dist/module/utils/internal/callingx/callingx.js +0 -100
  249. package/dist/module/utils/internal/callingx/callingx.js.map +0 -1
  250. package/dist/module/utils/keepCallAliveHeadlessTask.js +0 -42
  251. package/dist/module/utils/keepCallAliveHeadlessTask.js.map +0 -1
  252. package/dist/module/utils/push/libs/callingx.js +0 -67
  253. package/dist/module/utils/push/libs/callingx.js.map +0 -1
  254. package/dist/module/utils/push/setupCallingExpEvents.js +0 -102
  255. package/dist/module/utils/push/setupCallingExpEvents.js.map +0 -1
  256. package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts +0 -5
  257. package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts.map +0 -1
  258. package/dist/typescript/utils/hooks/useDebouncedValue.d.ts +0 -8
  259. package/dist/typescript/utils/hooks/useDebouncedValue.d.ts.map +0 -1
  260. package/dist/typescript/utils/internal/callingx/audioSessionPromise.d.ts +0 -16
  261. package/dist/typescript/utils/internal/callingx/audioSessionPromise.d.ts.map +0 -1
  262. package/dist/typescript/utils/internal/callingx/callingx.d.ts +0 -14
  263. package/dist/typescript/utils/internal/callingx/callingx.d.ts.map +0 -1
  264. package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts +0 -10
  265. package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts.map +0 -1
  266. package/dist/typescript/utils/push/libs/callingx.d.ts +0 -9
  267. package/dist/typescript/utils/push/libs/callingx.d.ts.map +0 -1
  268. package/dist/typescript/utils/push/setupCallingExpEvents.d.ts +0 -8
  269. package/dist/typescript/utils/push/setupCallingExpEvents.d.ts.map +0 -1
  270. package/src/hooks/push/useCallingExpWithCallingStateEffect.ts +0 -147
  271. package/src/utils/hooks/useDebouncedValue.ts +0 -21
  272. package/src/utils/internal/callingx/audioSessionPromise.ts +0 -53
  273. package/src/utils/internal/callingx/callingx.ts +0 -146
  274. package/src/utils/keepCallAliveHeadlessTask.ts +0 -54
  275. package/src/utils/push/libs/callingx.ts +0 -90
  276. package/src/utils/push/setupCallingExpEvents.ts +0 -130
@@ -4,7 +4,6 @@
4
4
  #import <React/RCTUIManagerUtils.h>
5
5
  #import <UIKit/UIKit.h>
6
6
  #import <CallKit/CallKit.h>
7
- #import <PushKit/PushKit.h>
8
7
  #import "StreamVideoReactNative.h"
9
8
  #import "WebRTCModule.h"
10
9
  #import "WebRTCModuleOptions.h"
@@ -15,8 +14,12 @@
15
14
  NSNotificationName const kBroadcastStartedNotification = @"iOS_BroadcastStarted";
16
15
  NSNotificationName const kBroadcastStoppedNotification = @"iOS_BroadcastStopped";
17
16
 
17
+ static NSMutableDictionary *_incomingCallUUIDsByCallID = nil;
18
+ static NSMutableDictionary *_incomingCallCidsByUUID = nil;
18
19
  static dispatch_queue_t _dictionaryQueue = nil;
19
20
 
21
+ static BOOL _shouldRejectCallWhenBusy = NO;
22
+
20
23
  void broadcastNotificationCallback(CFNotificationCenterRef center,
21
24
  void *observer,
22
25
  CFStringRef name,
@@ -57,196 +60,11 @@ RCT_EXPORT_MODULE();
57
60
  static dispatch_once_t onceToken;
58
61
  dispatch_once(&onceToken, ^{
59
62
  _dictionaryQueue = dispatch_queue_create("com.stream.video.dictionary", DISPATCH_QUEUE_SERIAL);
63
+ _incomingCallUUIDsByCallID = [NSMutableDictionary dictionary];
64
+ _incomingCallCidsByUUID = [NSMutableDictionary dictionary];
60
65
  });
61
66
  }
62
67
 
63
- +(BOOL)canRegisterCall {
64
- Class callingxClass = NSClassFromString(@"Callingx");
65
- if (!callingxClass) {
66
- #if DEBUG
67
- NSLog(@"[StreamVideoReactNative][canRegisterCall] Callingx not available");
68
- #endif
69
- return YES;
70
- }
71
-
72
- SEL selector = @selector(canRegisterCall);
73
- if (![callingxClass respondsToSelector:selector]) {
74
- #if DEBUG
75
- NSLog(@"[StreamVideoReactNative][canRegisterCall] Callingx does not respond to canRegisterCall selector");
76
- #endif
77
- return YES;
78
- }
79
-
80
- NSMethodSignature *signature = [callingxClass methodSignatureForSelector:selector];
81
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
82
- [invocation setTarget:callingxClass];
83
- [invocation setSelector:selector];
84
- [invocation invoke];
85
-
86
- BOOL canRegister = NO;
87
- [invocation getReturnValue:&canRegister];
88
-
89
- #if DEBUG
90
- NSLog(@"[StreamVideoReactNative][canRegisterCall] canRegisterCall = %@", canRegister ? @"YES" : @"NO");
91
- #endif
92
-
93
- return canRegister;
94
- }
95
-
96
- +(void)voipRegistration {
97
- Class voipManagerClass = NSClassFromString(@"Callingx.VoipNotificationsManager");
98
- if (!voipManagerClass) {
99
- // Fallback: Try the unmangled name (might work depending on Swift version)
100
- voipManagerClass = NSClassFromString(@"VoipNotificationsManager");
101
- }
102
-
103
- if (!voipManagerClass) {
104
- #if DEBUG
105
- NSLog(@"[StreamVideoReactNative][voipRegistration] VoipNotificationsManager not available");
106
- #endif
107
- return;
108
- }
109
-
110
- SEL selector = @selector(voipRegistration);
111
- if (![voipManagerClass respondsToSelector:selector]) {
112
- #if DEBUG
113
- NSLog(@"[StreamVideoReactNative][voipRegistration] VoipNotificationsManager does not respond to voipRegistration");
114
- #endif
115
- return;
116
- }
117
-
118
- [voipManagerClass voipRegistration];
119
- }
120
-
121
- +(void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
122
- Class voipManagerClass = NSClassFromString(@"Callingx.VoipNotificationsManager");
123
- if (!voipManagerClass) {
124
- // Fallback: Try the unmangled name (might work depending on Swift version)
125
- voipManagerClass = NSClassFromString(@"VoipNotificationsManager");
126
- }
127
-
128
- if (!voipManagerClass) {
129
- #if DEBUG
130
- NSLog(@"[StreamVideoReactNative][didUpdatePushCredentials] VoipNotificationsManager not available");
131
- #endif
132
- return;
133
- }
134
-
135
- SEL selector = @selector(didUpdatePushCredentials:forType:);
136
- if (![voipManagerClass respondsToSelector:selector]) {
137
- #if DEBUG
138
- NSLog(@"[StreamVideoReactNative][didUpdatePushCredentials] VoipNotificationsManager does not respond to didUpdatePushCredentials:forType:");
139
- #endif
140
- return;
141
- }
142
-
143
- [voipManagerClass didUpdatePushCredentials:credentials forType:type];
144
- }
145
-
146
- +(void)didReceiveIncomingPush:(PKPushPayload *)payload forType:(NSString *)type completionHandler: (void (^_Nullable)(void)) completion {
147
- NSDictionary *streamPayload = payload.dictionaryPayload[@"stream"];
148
- if (!streamPayload) {
149
- #if DEBUG
150
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Stream payload not found");
151
- #endif
152
- if (completion) {
153
- completion();
154
- }
155
- return;
156
- }
157
-
158
- NSString *createdCallerName = streamPayload[@"created_by_display_name"];
159
- NSString *callCid = streamPayload[@"call_cid"];
160
- if (!createdCallerName || !callCid) {
161
- #if DEBUG
162
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Missing required fields: created_by_display_name or call_cid");
163
- #endif
164
- if (completion) {
165
- completion();
166
- }
167
- return;
168
- }
169
-
170
- if (![StreamVideoReactNative canRegisterCall]) {
171
- if (completion) {
172
- completion();
173
- }
174
- return;
175
- }
176
-
177
- [StreamVideoReactNative reportNewIncomingCall:streamPayload forType:type completionHandler:completion];
178
- [StreamVideoReactNative didReceiveIncomingPushWithPayload:payload forType:type];
179
- }
180
-
181
- +(void)reportNewIncomingCall:(NSDictionary *)streamPayload forType:(NSString *)type completionHandler: (void (^_Nullable)(void)) completion {
182
- Class callingxClass = NSClassFromString(@"Callingx");
183
- if (!callingxClass) {
184
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Callingx not available");
185
- return;
186
- }
187
-
188
- SEL selector = @selector(reportNewIncomingCall:handle:handleType:hasVideo:localizedCallerName:supportsHolding:supportsDTMF:supportsGrouping:supportsUngrouping:payload:withCompletionHandler:);
189
- if (![callingxClass respondsToSelector:selector]) {
190
- #if DEBUG
191
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Callingx does not respond to selector");
192
- #endif
193
- return;
194
- }
195
-
196
- NSString *callCid = streamPayload[@"call_cid"];
197
- NSString *createdCallerName = streamPayload[@"created_by_display_name"];
198
- NSString *videoIncluded = streamPayload[@"video"];
199
- BOOL hasVideo = [videoIncluded isEqualToString:@"false"] ? NO : YES;
200
- NSString *handleType = @"generic";
201
- BOOL supportsHolding = NO;
202
- BOOL supportsDTMF = NO;
203
- BOOL supportsGrouping = NO;
204
- BOOL supportsUngrouping = NO;
205
- void (^completionHandler)(void) = completion;
206
-
207
- NSMethodSignature *signature = [callingxClass methodSignatureForSelector:selector];
208
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
209
- [invocation setTarget:callingxClass];
210
- [invocation setSelector:selector];
211
- [invocation setArgument:&callCid atIndex:2];
212
- [invocation setArgument:&createdCallerName atIndex:3];
213
- [invocation setArgument:&handleType atIndex:4];
214
- [invocation setArgument:&hasVideo atIndex:5];
215
- [invocation setArgument:&createdCallerName atIndex:6];
216
- [invocation setArgument:&supportsHolding atIndex:7];
217
- [invocation setArgument:&supportsDTMF atIndex:8];
218
- [invocation setArgument:&supportsGrouping atIndex:9];
219
- [invocation setArgument:&supportsUngrouping atIndex:10];
220
- [invocation setArgument:&streamPayload atIndex:11];
221
- [invocation setArgument:&completionHandler atIndex:12];
222
- [invocation invoke];
223
- }
224
-
225
- +(void)didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
226
- Class voipManagerClass = NSClassFromString(@"Callingx.VoipNotificationsManager");
227
- if (!voipManagerClass) {
228
- // Fallback: Try the unmangled name (might work depending on Swift version)
229
- voipManagerClass = NSClassFromString(@"VoipNotificationsManager");
230
- }
231
-
232
- if (!voipManagerClass) {
233
- #if DEBUG
234
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPushWithPayload] VoipNotificationsManager not available");
235
- #endif
236
- return;
237
- }
238
-
239
- SEL selector = @selector(didReceiveIncomingPushWithPayload:forType:);
240
- if (![voipManagerClass respondsToSelector:selector]) {
241
- #if DEBUG
242
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPushWithPayload] VoipNotificationsManager does not respond to didReceiveIncomingPushWithPayload:forType:");
243
- #endif
244
- return;
245
- }
246
-
247
- [voipManagerClass didReceiveIncomingPushWithPayload:payload forType:type];
248
- }
249
-
250
68
  -(instancetype)init {
251
69
  if ((self = [super init])) {
252
70
  _notificationCenter = CFNotificationCenterGetDarwinNotifyCenter();
@@ -373,6 +191,71 @@ RCT_EXPORT_METHOD(currentThermalState:(RCTPromiseResolveBlock)resolve rejecter:(
373
191
  }
374
192
  }
375
193
 
194
+ +(void)registerIncomingCall:(NSString *)cid uuid:(NSString *)uuid {
195
+ [StreamVideoReactNative initializeSharedDictionaries];
196
+ dispatch_sync(_dictionaryQueue, ^{
197
+
198
+ #ifdef DEBUG
199
+ NSLog(@"registerIncomingCall cid:%@ -> uuid:%@",cid,uuid);
200
+ #endif
201
+ NSString *lowercaseUUID = [uuid lowercaseString];
202
+ _incomingCallUUIDsByCallID[cid] = lowercaseUUID;
203
+ _incomingCallCidsByUUID[lowercaseUUID] = cid;
204
+ });
205
+ }
206
+
207
+ RCT_EXPORT_METHOD(getIncomingCallUUid:(NSString *)cid
208
+ resolver:(RCTPromiseResolveBlock)resolve
209
+ rejecter:(RCTPromiseRejectBlock)reject)
210
+ {
211
+ dispatch_sync(_dictionaryQueue, ^{
212
+ NSString *uuid = _incomingCallUUIDsByCallID[cid];
213
+ if (uuid) {
214
+ resolve(uuid);
215
+ } else {
216
+ NSString *errorString = [NSString stringWithFormat:@"requested incoming call not found for cid: %@", cid];
217
+ reject(@"access_failure", errorString, nil);
218
+ }
219
+ });
220
+ }
221
+
222
+ RCT_EXPORT_METHOD(getIncomingCallCid:(NSString *)uuid
223
+ resolver:(RCTPromiseResolveBlock)resolve
224
+ rejecter:(RCTPromiseRejectBlock)reject)
225
+ {
226
+ dispatch_sync(_dictionaryQueue, ^{
227
+ NSString *lowercaseUUID = [uuid lowercaseString];
228
+ NSString *foundCid = _incomingCallCidsByUUID[lowercaseUUID];
229
+
230
+ if (foundCid) {
231
+ resolve(foundCid);
232
+ } else {
233
+ NSString *errorString = [NSString stringWithFormat:@"requested incoming call not found for uuid: %@", uuid];
234
+ reject(@"access_failure", errorString, nil);
235
+ }
236
+ });
237
+ }
238
+
239
+ RCT_EXPORT_METHOD(removeIncomingCall:(NSString *)cid
240
+ resolver:(RCTPromiseResolveBlock)resolve
241
+ rejecter:(RCTPromiseRejectBlock)reject)
242
+ {
243
+ dispatch_sync(_dictionaryQueue, ^{
244
+ NSString *uuid = _incomingCallUUIDsByCallID[cid];
245
+ if (uuid) {
246
+ #ifdef DEBUG
247
+ NSLog(@"removeIncomingCall cid:%@ -> uuid:%@",cid,uuid);
248
+ #endif
249
+
250
+ [_incomingCallUUIDsByCallID removeObjectForKey:cid];
251
+ [_incomingCallCidsByUUID removeObjectForKey:uuid];
252
+ resolve(@YES);
253
+ } else {
254
+ resolve(@NO);
255
+ }
256
+ });
257
+ }
258
+
376
259
  RCT_EXPORT_METHOD(captureRef:(nonnull NSNumber *)reactTag
377
260
  options:(NSDictionary *)options
378
261
  resolver:(RCTPromiseResolveBlock)resolve
@@ -510,7 +393,17 @@ RCT_EXPORT_METHOD(checkPermission:(NSString *)permission
510
393
  ];
511
394
  }
512
395
 
513
- //current implementation will return any registered calls not only stream calls
396
+ +(BOOL)shouldRejectCallWhenBusy {
397
+ return _shouldRejectCallWhenBusy;
398
+ }
399
+
400
+ RCT_EXPORT_METHOD(setShouldRejectCallWhenBusy:(BOOL)shouldReject) {
401
+ _shouldRejectCallWhenBusy = shouldReject;
402
+ #ifdef DEBUG
403
+ NSLog(@"setShouldRejectCallWhenBusy: %@", shouldReject ? @"YES" : @"NO");
404
+ #endif
405
+ }
406
+
514
407
  + (BOOL)hasAnyActiveCall
515
408
  {
516
409
  CXCallObserver *callObserver = [[CXCallObserver alloc] init];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-react-native-sdk",
3
- "version": "1.29.4-beta.0",
3
+ "version": "1.30.0",
4
4
  "description": "Stream Video SDK for React Native",
5
5
  "author": "https://getstream.io",
6
6
  "homepage": "https://getstream.io/video/docs/react-native/",
@@ -50,8 +50,8 @@
50
50
  "!**/.*"
51
51
  ],
52
52
  "dependencies": {
53
- "@stream-io/video-client": "1.43.0-beta.0",
54
- "@stream-io/video-react-bindings": "1.13.7",
53
+ "@stream-io/video-client": "1.44.0",
54
+ "@stream-io/video-react-bindings": "1.13.9",
55
55
  "intl-pluralrules": "2.0.1",
56
56
  "lodash.merge": "^4.6.2",
57
57
  "react-native-url-polyfill": "^3.0.0",
@@ -65,17 +65,18 @@
65
65
  "@react-native-firebase/app": ">=17.5.0",
66
66
  "@react-native-firebase/messaging": ">=17.5.0",
67
67
  "@stream-io/noise-cancellation-react-native": ">=0.1.0",
68
- "@stream-io/react-native-callingx": ">=0.1.0",
69
- "@stream-io/react-native-webrtc": ">=137.1.2",
68
+ "@stream-io/react-native-webrtc": ">=137.1.0",
70
69
  "@stream-io/video-filters-react-native": ">=0.1.0",
71
70
  "expo": ">=47.0.0",
72
71
  "expo-build-properties": "*",
73
72
  "expo-notifications": "*",
74
73
  "react": ">=17.0.0",
75
74
  "react-native": ">=0.73.0",
75
+ "react-native-callkeep": ">=4.3.11",
76
76
  "react-native-gesture-handler": ">=2.8.0",
77
77
  "react-native-reanimated": ">=2.7.0",
78
- "react-native-svg": ">=13.6.0"
78
+ "react-native-svg": ">=13.6.0",
79
+ "react-native-voip-push-notification": ">=3.3.1"
79
80
  },
80
81
  "peerDependenciesMeta": {
81
82
  "@notifee/react-native": {
@@ -93,9 +94,6 @@
93
94
  "@stream-io/noise-cancellation-react-native": {
94
95
  "optional": true
95
96
  },
96
- "@stream-io/react-native-callingx": {
97
- "optional": true
98
- },
99
97
  "@stream-io/video-filters-react-native": {
100
98
  "optional": true
101
99
  },
@@ -108,11 +106,17 @@
108
106
  "expo-notifications": {
109
107
  "optional": true
110
108
  },
109
+ "react-native-callkeep": {
110
+ "optional": true
111
+ },
111
112
  "react-native-gesture-handler": {
112
113
  "optional": true
113
114
  },
114
115
  "react-native-reanimated": {
115
116
  "optional": true
117
+ },
118
+ "react-native-voip-push-notification": {
119
+ "optional": true
116
120
  }
117
121
  },
118
122
  "devDependencies": {
@@ -126,10 +130,9 @@
126
130
  "@react-native-firebase/app": "^23.4.0",
127
131
  "@react-native-firebase/messaging": "^23.4.0",
128
132
  "@react-native/babel-preset": "^0.81.5",
129
- "@stream-io/noise-cancellation-react-native": "0.5.0",
130
- "@stream-io/react-native-callingx": "0.1.0-beta.7",
131
- "@stream-io/react-native-webrtc": "137.1.2",
132
- "@stream-io/video-filters-react-native": "0.10.0",
133
+ "@stream-io/noise-cancellation-react-native": "^0.5.0",
134
+ "@stream-io/react-native-webrtc": "137.1.0",
135
+ "@stream-io/video-filters-react-native": "^0.10.0",
133
136
  "@testing-library/jest-native": "^5.4.3",
134
137
  "@testing-library/react-native": "13.3.3",
135
138
  "@tsconfig/node18": "^18.2.4",
@@ -145,9 +148,11 @@
145
148
  "react": "19.1.0",
146
149
  "react-native": "^0.81.5",
147
150
  "react-native-builder-bob": "~0.23",
151
+ "react-native-callkeep": "^4.3.16",
148
152
  "react-native-gesture-handler": "^2.28.0",
149
153
  "react-native-reanimated": "~4.1.2",
150
154
  "react-native-svg": "^15.14.0",
155
+ "react-native-voip-push-notification": "3.3.3",
151
156
  "react-native-worklets": "^0.5.0",
152
157
  "react-test-renderer": "19.1.0",
153
158
  "rimraf": "^6.0.1",
@@ -162,4 +167,4 @@
162
167
  "typescript"
163
168
  ]
164
169
  }
165
- }
170
+ }
@@ -21,11 +21,12 @@ import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
21
21
  import {
22
22
  CallingState,
23
23
  type StreamReaction,
24
+ type StreamVideoParticipant,
24
25
  videoLoggerSystem,
25
26
  } from '@stream-io/video-client';
27
+ import { debounceTime } from 'rxjs';
26
28
 
27
29
  import { Z_INDEX } from '../../../constants';
28
- import { useDebouncedValue } from '../../../utils/hooks';
29
30
  import {
30
31
  FloatingParticipantView as DefaultFloatingParticipantView,
31
32
  type FloatingParticipantViewProps,
@@ -134,16 +135,23 @@ export const CallContent = ({
134
135
  theme: { callContent },
135
136
  } = useTheme();
136
137
  const call = useCall();
137
- const {
138
- useHasOngoingScreenShare,
139
- useRemoteParticipants,
140
- useLocalParticipant,
141
- } = useCallStateHooks();
138
+ const { useHasOngoingScreenShare, useLocalParticipant } = useCallStateHooks();
142
139
 
143
140
  useAutoEnterPiPEffect(disablePictureInPicture);
144
141
 
145
- const _remoteParticipants = useRemoteParticipants();
146
- const remoteParticipants = useDebouncedValue(_remoteParticipants, 300); // we debounce the remote participants to avoid unnecessary rerenders that happen when participant tracks are all subscribed simultaneously
142
+ const [remoteParticipants, setRemoteParticipants] = useState<
143
+ StreamVideoParticipant[]
144
+ >(() => call?.state.remoteParticipants ?? []);
145
+ useEffect(() => {
146
+ if (!call) {
147
+ setRemoteParticipants([]);
148
+ return;
149
+ }
150
+ const sub = call.state.remoteParticipants$
151
+ .pipe(debounceTime(300))
152
+ .subscribe(setRemoteParticipants);
153
+ return () => sub.unsubscribe();
154
+ }, [call]);
147
155
  const localParticipant = useLocalParticipant();
148
156
  const isInPiPMode = useIsInPiPMode();
149
157
  const hasScreenShare = useHasOngoingScreenShare();
@@ -1,21 +1,25 @@
1
1
  import {
2
2
  CallingState,
3
+ SfuModels,
4
+ hasAudio,
5
+ hasPausedTrack,
3
6
  hasScreenShare,
4
- speakerLayoutSortPreset,
5
7
  type StreamVideoParticipant,
6
8
  videoLoggerSystem,
7
9
  type VideoTrackType,
10
+ hasVideo,
11
+ isPinned,
8
12
  } from '@stream-io/video-client';
9
13
  import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
10
14
  import type { MediaStream } from '@stream-io/react-native-webrtc';
11
- import React, { useEffect, useMemo, useCallback } from 'react';
15
+ import React, { useEffect, useCallback, useState } from 'react';
12
16
  import { findNodeHandle } from 'react-native';
13
17
  import {
14
18
  onNativeCallClosed,
15
19
  onNativeDimensionsUpdated,
16
20
  RTCViewPipNative,
17
21
  } from './RTCViewPipNative';
18
- import { useDebouncedValue } from '../../../utils/hooks';
22
+ import { debounceTime } from 'rxjs';
19
23
  import { shouldDisableIOSLocalVideoOnBackgroundRef } from '../../../utils/internal/shouldDisableIOSLocalVideoOnBackground';
20
24
  import { useTrackDimensions } from '../../../hooks/useTrackDimensions';
21
25
  import { isInPiPMode$ } from '../../../utils/internal/rxSubjects';
@@ -40,12 +44,26 @@ export const RTCViewPipIOS = React.memo((props: Props) => {
40
44
  onPiPChange,
41
45
  } = props;
42
46
  const call = useCall();
43
- const { useParticipants, useCameraState } = useCallStateHooks();
44
- const _allParticipants = useParticipants({
45
- sortBy: speakerLayoutSortPreset,
46
- });
47
+ const { useCameraState, useCallCallingState } = useCallStateHooks();
48
+ const callingState = useCallCallingState();
47
49
  const { direction } = useCameraState();
48
- const allParticipants = useDebouncedValue(_allParticipants, 300); // we debounce the participants to avoid unnecessary rerenders that happen when participant tracks are all subscribed simultaneously
50
+
51
+ const [allParticipants, setAllParticipants] = useState<
52
+ StreamVideoParticipant[]
53
+ >(call?.state.participants ?? []);
54
+
55
+ // we debounce the participants to avoid unnecessary rerenders
56
+ // that happen when participant tracks are all subscribed simultaneously
57
+ useEffect(() => {
58
+ if (!call) {
59
+ setAllParticipants([]);
60
+ return;
61
+ }
62
+ const subscription = call.state.participants$
63
+ .pipe(debounceTime(300))
64
+ .subscribe(setAllParticipants);
65
+ return () => subscription.unsubscribe();
66
+ }, [call]);
49
67
 
50
68
  const [dominantSpeaker, dominantSpeaker2] = allParticipants.filter(
51
69
  (participant) =>
@@ -118,24 +136,63 @@ export const RTCViewPipIOS = React.memo((props: Props) => {
118
136
  ? screenShareStream
119
137
  : videoStream) as unknown as MediaStream | undefined;
120
138
 
139
+ const isPublishingTrack =
140
+ isScreenSharing ||
141
+ (participantInSpotlight && hasVideo(participantInSpotlight));
142
+
143
+ const streamURL = isPublishingTrack
144
+ ? videoStreamToRender?.toURL()
145
+ : undefined;
146
+
121
147
  const mirror = isScreenSharing
122
148
  ? false
123
149
  : mirrorOverride !== undefined
124
150
  ? mirrorOverride
125
151
  : !!participantInSpotlight?.isLocalParticipant && direction === 'front';
126
152
 
127
- const streamURL = useMemo(() => {
128
- if (!videoStreamToRender) {
129
- return undefined;
130
- }
131
- return videoStreamToRender?.toURL();
132
- }, [videoStreamToRender]);
133
-
134
153
  const handlePiPChange = (event: { nativeEvent: { active: boolean } }) => {
135
154
  isInPiPMode$.next(event.nativeEvent.active);
136
155
  onPiPChange?.(event.nativeEvent.active);
137
156
  };
138
157
 
158
+ // Get participant info for avatar placeholder
159
+ const participantName = participantInSpotlight?.name || undefined;
160
+ const participantImageURL = participantInSpotlight?.image || undefined;
161
+
162
+ // Determine if the call is reconnecting or offline
163
+ const isReconnecting =
164
+ callingState === CallingState.MIGRATING ||
165
+ callingState === CallingState.RECONNECTING ||
166
+ callingState === CallingState.RECONNECTING_FAILED ||
167
+ callingState === CallingState.OFFLINE;
168
+
169
+ // Determine if the participant has audio enabled
170
+ const participantHasAudio = participantInSpotlight
171
+ ? hasAudio(participantInSpotlight)
172
+ : true;
173
+
174
+ // Determine if the video track is paused
175
+ const trackType: VideoTrackType = isScreenSharing
176
+ ? 'screenShareTrack'
177
+ : 'videoTrack';
178
+
179
+ const isVideoTrackPaused = participantInSpotlight
180
+ ? hasPausedTrack(participantInSpotlight, trackType)
181
+ : false;
182
+
183
+ // Determine if the participant is pinned
184
+ const participantIsPinned = participantInSpotlight
185
+ ? isPinned(participantInSpotlight)
186
+ : false;
187
+
188
+ // Determine if the participant is speaking
189
+ const participantIsSpeaking = participantInSpotlight?.isSpeaking ?? false;
190
+
191
+ // Get connection quality (convert enum to number: UNSPECIFIED=0, POOR=1, GOOD=2, EXCELLENT=3)
192
+ const participantConnectionQuality =
193
+ participantInSpotlight?.connectionQuality ??
194
+ SfuModels.ConnectionQuality.UNSPECIFIED;
195
+
139
196
  return (
140
197
  <>
141
198
  <RTCViewPipNative
@@ -143,6 +200,15 @@ export const RTCViewPipIOS = React.memo((props: Props) => {
143
200
  mirror={mirror}
144
201
  ref={nativeRef}
145
202
  onPiPChange={handlePiPChange}
203
+ participantName={participantName}
204
+ participantImageURL={participantImageURL}
205
+ isReconnecting={isReconnecting}
206
+ isScreenSharing={isScreenSharing}
207
+ hasAudio={participantHasAudio}
208
+ isTrackPaused={isVideoTrackPaused}
209
+ isPinned={participantIsPinned}
210
+ isSpeaking={participantIsSpeaking}
211
+ connectionQuality={participantConnectionQuality}
146
212
  />
147
213
  {participantInSpotlight && (
148
214
  <DimensionsUpdatedRenderless
@@ -18,6 +18,24 @@ type RTCViewPipNativeProps = {
18
18
  streamURL?: string;
19
19
  mirror?: boolean;
20
20
  onPiPChange?: (event: { nativeEvent: PiPChangeEvent }) => void;
21
+ /** The participant's name for the avatar placeholder when video is disabled */
22
+ participantName?: string;
23
+ /** The URL string for the participant's profile image */
24
+ participantImageURL?: string;
25
+ /** Whether the call is reconnecting - when true, shows reconnection view */
26
+ isReconnecting?: boolean;
27
+ /** Whether screen sharing is active (used for content state tracking) */
28
+ isScreenSharing?: boolean;
29
+ /** Whether the participant has audio enabled (shown in participant overlay) */
30
+ hasAudio?: boolean;
31
+ /** Whether the video track is paused (shown in participant overlay) */
32
+ isTrackPaused?: boolean;
33
+ /** Whether the participant is pinned (shown in participant overlay) */
34
+ isPinned?: boolean;
35
+ /** Whether the participant is currently speaking (shows border highlight) */
36
+ isSpeaking?: boolean;
37
+ /** The connection quality level (0: unknown, 1: poor, 2: good, 3: excellent) */
38
+ connectionQuality?: number;
21
39
  };
22
40
 
23
41
  const NativeComponent: HostComponent<RTCViewPipNativeProps> =
@@ -65,6 +83,24 @@ export const RTCViewPipNative = React.memo(
65
83
  mirror={props.mirror}
66
84
  // eslint-disable-next-line react/prop-types
67
85
  onPiPChange={props.onPiPChange}
86
+ // eslint-disable-next-line react/prop-types
87
+ participantName={props.participantName}
88
+ // eslint-disable-next-line react/prop-types
89
+ participantImageURL={props.participantImageURL}
90
+ // eslint-disable-next-line react/prop-types
91
+ isReconnecting={props.isReconnecting}
92
+ // eslint-disable-next-line react/prop-types
93
+ isScreenSharing={props.isScreenSharing}
94
+ // eslint-disable-next-line react/prop-types
95
+ hasAudio={props.hasAudio}
96
+ // eslint-disable-next-line react/prop-types
97
+ isTrackPaused={props.isTrackPaused}
98
+ // eslint-disable-next-line react/prop-types
99
+ isPinned={props.isPinned}
100
+ // eslint-disable-next-line react/prop-types
101
+ isSpeaking={props.isSpeaking}
102
+ // eslint-disable-next-line react/prop-types
103
+ connectionQuality={props.connectionQuality}
68
104
  // @ts-expect-error - types issue
69
105
  ref={ref}
70
106
  />