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

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 (217) hide show
  1. package/CHANGELOG.md +11 -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/Participant/ParticipantView/ParticipantLabel.js +2 -6
  9. package/dist/commonjs/components/Participant/ParticipantView/ParticipantLabel.js.map +1 -1
  10. package/dist/commonjs/hooks/push/index.js +2 -0
  11. package/dist/commonjs/hooks/push/index.js.map +1 -1
  12. package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js +160 -0
  13. package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +1 -0
  14. package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js +31 -18
  15. package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
  16. package/dist/commonjs/hooks/push/useProcessPushCallEffect.js +67 -0
  17. package/dist/commonjs/hooks/push/useProcessPushCallEffect.js.map +1 -0
  18. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +97 -64
  19. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  20. package/dist/commonjs/index.js +0 -1
  21. package/dist/commonjs/index.js.map +1 -1
  22. package/dist/commonjs/modules/call-manager/CallManager.js +0 -26
  23. package/dist/commonjs/modules/call-manager/CallManager.js.map +1 -1
  24. package/dist/commonjs/providers/StreamCall/index.js +6 -6
  25. package/dist/commonjs/providers/StreamCall/index.js.map +1 -1
  26. package/dist/commonjs/utils/StreamVideoRN/index.js +21 -35
  27. package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
  28. package/dist/commonjs/utils/internal/registerSDKGlobals.js +3 -53
  29. package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
  30. package/dist/commonjs/utils/push/android.js +202 -135
  31. package/dist/commonjs/utils/push/android.js.map +1 -1
  32. package/dist/commonjs/utils/push/internal/ios.js +34 -17
  33. package/dist/commonjs/utils/push/internal/ios.js.map +1 -1
  34. package/dist/commonjs/utils/push/internal/rxSubjects.js +45 -1
  35. package/dist/commonjs/utils/push/internal/rxSubjects.js.map +1 -1
  36. package/dist/commonjs/utils/push/internal/utils.js +53 -71
  37. package/dist/commonjs/utils/push/internal/utils.js.map +1 -1
  38. package/dist/commonjs/utils/push/ios.js.map +1 -1
  39. package/dist/commonjs/utils/push/libs/callkeep.js +17 -0
  40. package/dist/commonjs/utils/push/libs/callkeep.js.map +1 -0
  41. package/dist/commonjs/utils/push/libs/index.js +19 -8
  42. package/dist/commonjs/utils/push/libs/index.js.map +1 -1
  43. package/dist/commonjs/utils/push/libs/notifee/index.js +19 -0
  44. package/dist/commonjs/utils/push/libs/notifee/index.js.map +1 -1
  45. package/dist/commonjs/utils/push/libs/voipPushNotification.js +17 -0
  46. package/dist/commonjs/utils/push/libs/voipPushNotification.js.map +1 -0
  47. package/dist/commonjs/utils/push/setupIosCallKeepEvents.js +205 -0
  48. package/dist/commonjs/utils/push/setupIosCallKeepEvents.js.map +1 -0
  49. package/dist/commonjs/utils/push/setupIosVoipPushEvents.js +6 -7
  50. package/dist/commonjs/utils/push/setupIosVoipPushEvents.js.map +1 -1
  51. package/dist/commonjs/version.js +1 -1
  52. package/dist/commonjs/version.js.map +1 -1
  53. package/dist/module/components/Participant/ParticipantView/ParticipantLabel.js +2 -6
  54. package/dist/module/components/Participant/ParticipantView/ParticipantLabel.js.map +1 -1
  55. package/dist/module/hooks/push/index.js +2 -0
  56. package/dist/module/hooks/push/index.js.map +1 -1
  57. package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js +153 -0
  58. package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +1 -0
  59. package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js +31 -18
  60. package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
  61. package/dist/module/hooks/push/useProcessPushCallEffect.js +60 -0
  62. package/dist/module/hooks/push/useProcessPushCallEffect.js.map +1 -0
  63. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +99 -66
  64. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  65. package/dist/module/index.js +0 -1
  66. package/dist/module/index.js.map +1 -1
  67. package/dist/module/modules/call-manager/CallManager.js +0 -26
  68. package/dist/module/modules/call-manager/CallManager.js.map +1 -1
  69. package/dist/module/providers/StreamCall/index.js +6 -6
  70. package/dist/module/providers/StreamCall/index.js.map +1 -1
  71. package/dist/module/utils/StreamVideoRN/index.js +21 -35
  72. package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
  73. package/dist/module/utils/internal/registerSDKGlobals.js +3 -53
  74. package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
  75. package/dist/module/utils/push/android.js +204 -137
  76. package/dist/module/utils/push/android.js.map +1 -1
  77. package/dist/module/utils/push/internal/ios.js +34 -17
  78. package/dist/module/utils/push/internal/ios.js.map +1 -1
  79. package/dist/module/utils/push/internal/rxSubjects.js +44 -0
  80. package/dist/module/utils/push/internal/rxSubjects.js.map +1 -1
  81. package/dist/module/utils/push/internal/utils.js +50 -67
  82. package/dist/module/utils/push/internal/utils.js.map +1 -1
  83. package/dist/module/utils/push/ios.js.map +1 -1
  84. package/dist/module/utils/push/libs/callkeep.js +11 -0
  85. package/dist/module/utils/push/libs/callkeep.js.map +1 -0
  86. package/dist/module/utils/push/libs/index.js +2 -1
  87. package/dist/module/utils/push/libs/index.js.map +1 -1
  88. package/dist/module/utils/push/libs/notifee/index.js +18 -0
  89. package/dist/module/utils/push/libs/notifee/index.js.map +1 -1
  90. package/dist/module/utils/push/libs/voipPushNotification.js +11 -0
  91. package/dist/module/utils/push/libs/voipPushNotification.js.map +1 -0
  92. package/dist/module/utils/push/setupIosCallKeepEvents.js +199 -0
  93. package/dist/module/utils/push/setupIosCallKeepEvents.js.map +1 -0
  94. package/dist/module/utils/push/setupIosVoipPushEvents.js +6 -7
  95. package/dist/module/utils/push/setupIosVoipPushEvents.js.map +1 -1
  96. package/dist/module/version.js +1 -1
  97. package/dist/module/version.js.map +1 -1
  98. package/dist/typescript/components/Participant/ParticipantView/ParticipantLabel.d.ts.map +1 -1
  99. package/dist/typescript/hooks/push/index.d.ts.map +1 -1
  100. package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts +5 -0
  101. package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts.map +1 -0
  102. package/dist/typescript/hooks/push/useIosVoipPushEventsSetupEffect.d.ts.map +1 -1
  103. package/dist/typescript/hooks/push/useProcessPushCallEffect.d.ts +8 -0
  104. package/dist/typescript/hooks/push/useProcessPushCallEffect.d.ts.map +1 -0
  105. package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
  106. package/dist/typescript/index.d.ts +0 -1
  107. package/dist/typescript/index.d.ts.map +1 -1
  108. package/dist/typescript/modules/call-manager/CallManager.d.ts +0 -5
  109. package/dist/typescript/modules/call-manager/CallManager.d.ts.map +1 -1
  110. package/dist/typescript/utils/StreamVideoRN/index.d.ts +2 -22
  111. package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
  112. package/dist/typescript/utils/StreamVideoRN/types.d.ts +25 -59
  113. package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
  114. package/dist/typescript/utils/internal/registerSDKGlobals.d.ts.map +1 -1
  115. package/dist/typescript/utils/push/android.d.ts +2 -1
  116. package/dist/typescript/utils/push/android.d.ts.map +1 -1
  117. package/dist/typescript/utils/push/internal/ios.d.ts.map +1 -1
  118. package/dist/typescript/utils/push/internal/rxSubjects.d.ts +33 -0
  119. package/dist/typescript/utils/push/internal/rxSubjects.d.ts.map +1 -1
  120. package/dist/typescript/utils/push/internal/utils.d.ts +8 -14
  121. package/dist/typescript/utils/push/internal/utils.d.ts.map +1 -1
  122. package/dist/typescript/utils/push/ios.d.ts +2 -1
  123. package/dist/typescript/utils/push/ios.d.ts.map +1 -1
  124. package/dist/typescript/utils/push/libs/callkeep.d.ts +3 -0
  125. package/dist/typescript/utils/push/libs/callkeep.d.ts.map +1 -0
  126. package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts +2 -16
  127. package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts.map +1 -1
  128. package/dist/typescript/utils/push/libs/index.d.ts +2 -1
  129. package/dist/typescript/utils/push/libs/index.d.ts.map +1 -1
  130. package/dist/typescript/utils/push/libs/notifee/index.d.ts +1 -0
  131. package/dist/typescript/utils/push/libs/notifee/index.d.ts.map +1 -1
  132. package/dist/typescript/utils/push/libs/voipPushNotification.d.ts +3 -0
  133. package/dist/typescript/utils/push/libs/voipPushNotification.d.ts.map +1 -0
  134. package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts +6 -0
  135. package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts.map +1 -0
  136. package/dist/typescript/utils/push/setupIosVoipPushEvents.d.ts.map +1 -1
  137. package/dist/typescript/version.d.ts +1 -1
  138. package/dist/typescript/version.d.ts.map +1 -1
  139. package/expo-config-plugin/dist/withAndroidManifest.js +33 -1
  140. package/expo-config-plugin/dist/withAndroidPermissions.js +7 -2
  141. package/expo-config-plugin/dist/withAppDelegate.js +197 -19
  142. package/expo-config-plugin/dist/withMainActivity.js +1 -1
  143. package/expo-config-plugin/dist/withiOSInfoPlist.js +3 -2
  144. package/ios/StreamInCallManager.m +0 -2
  145. package/ios/StreamInCallManager.swift +7 -19
  146. package/ios/StreamVideoReactNative.h +4 -7
  147. package/ios/StreamVideoReactNative.m +82 -189
  148. package/package.json +16 -11
  149. package/src/components/Participant/ParticipantView/ParticipantLabel.tsx +2 -7
  150. package/src/hooks/push/index.ts +2 -0
  151. package/src/hooks/push/useIosCallkeepWithCallingStateEffect.ts +235 -0
  152. package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +34 -21
  153. package/src/hooks/push/useProcessPushCallEffect.ts +108 -0
  154. package/src/hooks/useAndroidKeepCallAliveEffect.ts +120 -94
  155. package/src/index.ts +0 -1
  156. package/src/modules/call-manager/CallManager.ts +0 -36
  157. package/src/modules/call-manager/native-module.d.ts +0 -7
  158. package/src/providers/StreamCall/index.tsx +6 -6
  159. package/src/utils/StreamVideoRN/index.ts +30 -42
  160. package/src/utils/StreamVideoRN/types.ts +25 -61
  161. package/src/utils/internal/registerSDKGlobals.ts +4 -52
  162. package/src/utils/push/android.ts +311 -198
  163. package/src/utils/push/internal/ios.ts +44 -28
  164. package/src/utils/push/internal/rxSubjects.ts +61 -0
  165. package/src/utils/push/internal/utils.ts +64 -108
  166. package/src/utils/push/ios.ts +6 -1
  167. package/src/utils/push/libs/callkeep.ts +16 -0
  168. package/src/utils/push/libs/index.ts +2 -1
  169. package/src/utils/push/libs/notifee/index.ts +27 -0
  170. package/src/utils/push/libs/voipPushNotification.ts +17 -0
  171. package/src/utils/push/setupIosCallKeepEvents.ts +252 -0
  172. package/src/utils/push/setupIosVoipPushEvents.ts +7 -11
  173. package/src/version.ts +1 -1
  174. package/android/src/main/java/com/streamvideo/reactnative/keepalive/KeepAliveNotification.kt +0 -83
  175. package/android/src/main/java/com/streamvideo/reactnative/keepalive/StreamCallKeepAliveHeadlessService.kt +0 -149
  176. package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js +0 -144
  177. package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js.map +0 -1
  178. package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js +0 -68
  179. package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js.map +0 -1
  180. package/dist/commonjs/utils/internal/callingx/callingx.js +0 -150
  181. package/dist/commonjs/utils/internal/callingx/callingx.js.map +0 -1
  182. package/dist/commonjs/utils/keepCallAliveHeadlessTask.js +0 -48
  183. package/dist/commonjs/utils/keepCallAliveHeadlessTask.js.map +0 -1
  184. package/dist/commonjs/utils/push/libs/callingx.js +0 -75
  185. package/dist/commonjs/utils/push/libs/callingx.js.map +0 -1
  186. package/dist/commonjs/utils/push/setupCallingExpEvents.js +0 -105
  187. package/dist/commonjs/utils/push/setupCallingExpEvents.js.map +0 -1
  188. package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js +0 -137
  189. package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js.map +0 -1
  190. package/dist/module/utils/internal/callingx/audioSessionPromise.js +0 -61
  191. package/dist/module/utils/internal/callingx/audioSessionPromise.js.map +0 -1
  192. package/dist/module/utils/internal/callingx/callingx.js +0 -140
  193. package/dist/module/utils/internal/callingx/callingx.js.map +0 -1
  194. package/dist/module/utils/keepCallAliveHeadlessTask.js +0 -42
  195. package/dist/module/utils/keepCallAliveHeadlessTask.js.map +0 -1
  196. package/dist/module/utils/push/libs/callingx.js +0 -67
  197. package/dist/module/utils/push/libs/callingx.js.map +0 -1
  198. package/dist/module/utils/push/setupCallingExpEvents.js +0 -99
  199. package/dist/module/utils/push/setupCallingExpEvents.js.map +0 -1
  200. package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts +0 -5
  201. package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts.map +0 -1
  202. package/dist/typescript/utils/internal/callingx/audioSessionPromise.d.ts +0 -16
  203. package/dist/typescript/utils/internal/callingx/audioSessionPromise.d.ts.map +0 -1
  204. package/dist/typescript/utils/internal/callingx/callingx.d.ts +0 -18
  205. package/dist/typescript/utils/internal/callingx/callingx.d.ts.map +0 -1
  206. package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts +0 -10
  207. package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts.map +0 -1
  208. package/dist/typescript/utils/push/libs/callingx.d.ts +0 -9
  209. package/dist/typescript/utils/push/libs/callingx.d.ts.map +0 -1
  210. package/dist/typescript/utils/push/setupCallingExpEvents.d.ts +0 -8
  211. package/dist/typescript/utils/push/setupCallingExpEvents.d.ts.map +0 -1
  212. package/src/hooks/push/useCallingExpWithCallingStateEffect.ts +0 -189
  213. package/src/utils/internal/callingx/audioSessionPromise.ts +0 -65
  214. package/src/utils/internal/callingx/callingx.ts +0 -194
  215. package/src/utils/keepCallAliveHeadlessTask.ts +0 -54
  216. package/src/utils/push/libs/callingx.ts +0 -89
  217. package/src/utils/push/setupCallingExpEvents.ts +0 -135
@@ -116,7 +116,7 @@ class StreamInCallManager: RCTEventEmitter {
116
116
  }
117
117
  } else {
118
118
  intendedCategory = .playAndRecord
119
- intendedMode = .voiceChat
119
+ intendedMode = defaultAudioDevice == .speaker ? .videoChat : .voiceChat
120
120
 
121
121
  // XCode 16 and older don't expose .allowBluetoothHFP
122
122
  // https://forums.swift.org/t/xcode-26-avaudiosession-categoryoptions-allowbluetooth-deprecated/80956
@@ -132,7 +132,6 @@ class StreamInCallManager: RCTEventEmitter {
132
132
  rtcConfig.category = intendedCategory.rawValue
133
133
  rtcConfig.mode = intendedMode.rawValue
134
134
  rtcConfig.categoryOptions = intendedOptions
135
- // This ensures WebRTC's internal state stays consistent during interruptions/route changes
136
135
  RTCAudioSessionConfiguration.setWebRTC(rtcConfig)
137
136
 
138
137
  let session = RTCAudioSession.sharedInstance()
@@ -141,7 +140,7 @@ class StreamInCallManager: RCTEventEmitter {
141
140
  session.unlockForConfiguration()
142
141
  }
143
142
  do {
144
- try session.setConfiguration(rtcConfig)
143
+ try session.setCategory(intendedCategory, mode: intendedMode, options: intendedOptions)
145
144
  if (wasRecording) {
146
145
  try adm.setRecording(wasRecording)
147
146
  }
@@ -267,11 +266,6 @@ class StreamInCallManager: RCTEventEmitter {
267
266
 
268
267
  @objc
269
268
  func logAudioState() {
270
- log(getAudioStateLog())
271
- }
272
-
273
- @objc(getAudioStateLog)
274
- func getAudioStateLog() -> String {
275
269
  let session = AVAudioSession.sharedInstance()
276
270
  let adm = getAudioDeviceModule()
277
271
 
@@ -284,7 +278,7 @@ class StreamInCallManager: RCTEventEmitter {
284
278
 
285
279
  let rtcAVSession = rtcSession.session
286
280
  let logString = """
287
- AVAudioSession State:
281
+ Audio State:
288
282
  Category: \(session.category.rawValue)
289
283
  Mode: \(session.mode.rawValue)
290
284
  Output Port: \(session.currentRoute.outputs.first?.portName ?? "N/A")
@@ -292,16 +286,10 @@ class StreamInCallManager: RCTEventEmitter {
292
286
  Category Options: \(session.categoryOptions)
293
287
  InputNumberOfChannels: \(session.inputNumberOfChannels)
294
288
  OutputNumberOfChannels: \(session.outputNumberOfChannels)
295
-
296
- AudioDeviceModule State:
297
- IsPlaying: \(adm.isPlaying)
298
- IsRecording: \(adm.isRecording)
299
- IsVoiceProcessingAGCEnabled: \(adm.isVoiceProcessingAGCEnabled)
300
- IsVoiceProcessingBypassed: \(adm.isVoiceProcessingBypassed)
301
- IsVoiceProcessingEnabled: \(adm.isVoiceProcessingEnabled)
302
- IsStereoPlayoutEnabled: \(adm.isStereoPlayoutEnabled)
289
+ AdmIsPlaying: \(adm.isPlaying)
290
+ AdmIsRecording: \(adm.isRecording)
303
291
 
304
- RTCAudioSession State:
292
+ RTC Audio State:
305
293
  Wrapped Category: \(rtcAVSession.category.rawValue)
306
294
  Wrapped Mode: \(rtcAVSession.mode.rawValue)
307
295
  Wrapped Output Port: \(rtcAVSession.currentRoute.outputs.first?.portName ?? "N/A")
@@ -312,7 +300,7 @@ class StreamInCallManager: RCTEventEmitter {
312
300
  IsActive: \(rtcSession.isActive)
313
301
  ActivationCount: \(rtcSession.activationCount)
314
302
  """
315
- return logString
303
+ log(logString)
316
304
  }
317
305
 
318
306
  @objc(muteAudioOutput)
@@ -1,19 +1,16 @@
1
1
  #import <React/RCTEventEmitter.h>
2
2
  #import <React/RCTBridge.h>
3
- #import <PushKit/PushKit.h>
4
3
 
5
4
  @interface StreamVideoReactNative : RCTEventEmitter <RCTBridgeModule>
6
5
 
7
6
  - (void)screenShareEventReceived:(NSString *)event;
8
7
 
9
- + (void)setup DEPRECATED_MSG_ATTRIBUTE("No need to use setup() anymore");
10
-
11
- + (BOOL)hasAnyActiveCall;
8
+ + (void)registerIncomingCall:(NSString *)cid uuid:(NSString *)uuid;
12
9
 
13
- + (void)voipRegistration;
10
+ + (void)setup DEPRECATED_MSG_ATTRIBUTE("No need to use setup() anymore");
14
11
 
15
- + (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type;
12
+ + (BOOL)shouldRejectCallWhenBusy;
16
13
 
17
- + (void)didReceiveIncomingPush:(PKPushPayload *)payload forType:(NSString *)type completionHandler: (void (^_Nullable)(void)) completion;
14
+ + (BOOL)hasAnyActiveCall;
18
15
 
19
16
  @end
@@ -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"
@@ -23,8 +22,12 @@
23
22
  NSNotificationName const kBroadcastStartedNotification = @"iOS_BroadcastStarted";
24
23
  NSNotificationName const kBroadcastStoppedNotification = @"iOS_BroadcastStopped";
25
24
 
25
+ static NSMutableDictionary *_incomingCallUUIDsByCallID = nil;
26
+ static NSMutableDictionary *_incomingCallCidsByUUID = nil;
26
27
  static dispatch_queue_t _dictionaryQueue = nil;
27
28
 
29
+ static BOOL _shouldRejectCallWhenBusy = NO;
30
+
28
31
  void broadcastNotificationCallback(CFNotificationCenterRef center,
29
32
  void *observer,
30
33
  CFStringRef name,
@@ -65,196 +68,11 @@ RCT_EXPORT_MODULE();
65
68
  static dispatch_once_t onceToken;
66
69
  dispatch_once(&onceToken, ^{
67
70
  _dictionaryQueue = dispatch_queue_create("com.stream.video.dictionary", DISPATCH_QUEUE_SERIAL);
71
+ _incomingCallUUIDsByCallID = [NSMutableDictionary dictionary];
72
+ _incomingCallCidsByUUID = [NSMutableDictionary dictionary];
68
73
  });
69
74
  }
70
75
 
71
- +(BOOL)canRegisterCall {
72
- Class callingxClass = NSClassFromString(@"Callingx");
73
- if (!callingxClass) {
74
- #if DEBUG
75
- NSLog(@"[StreamVideoReactNative][canRegisterCall] Callingx not available");
76
- #endif
77
- return YES;
78
- }
79
-
80
- SEL selector = @selector(canRegisterCall);
81
- if (![callingxClass respondsToSelector:selector]) {
82
- #if DEBUG
83
- NSLog(@"[StreamVideoReactNative][canRegisterCall] Callingx does not respond to canRegisterCall selector");
84
- #endif
85
- return YES;
86
- }
87
-
88
- NSMethodSignature *signature = [callingxClass methodSignatureForSelector:selector];
89
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
90
- [invocation setTarget:callingxClass];
91
- [invocation setSelector:selector];
92
- [invocation invoke];
93
-
94
- BOOL canRegister = NO;
95
- [invocation getReturnValue:&canRegister];
96
-
97
- #if DEBUG
98
- NSLog(@"[StreamVideoReactNative][canRegisterCall] canRegisterCall = %@", canRegister ? @"YES" : @"NO");
99
- #endif
100
-
101
- return canRegister;
102
- }
103
-
104
- +(void)voipRegistration {
105
- Class voipManagerClass = NSClassFromString(@"Callingx.VoipNotificationsManager");
106
- if (!voipManagerClass) {
107
- // Fallback: Try the unmangled name (might work depending on Swift version)
108
- voipManagerClass = NSClassFromString(@"VoipNotificationsManager");
109
- }
110
-
111
- if (!voipManagerClass) {
112
- #if DEBUG
113
- NSLog(@"[StreamVideoReactNative][voipRegistration] VoipNotificationsManager not available");
114
- #endif
115
- return;
116
- }
117
-
118
- SEL selector = @selector(voipRegistration);
119
- if (![voipManagerClass respondsToSelector:selector]) {
120
- #if DEBUG
121
- NSLog(@"[StreamVideoReactNative][voipRegistration] VoipNotificationsManager does not respond to voipRegistration");
122
- #endif
123
- return;
124
- }
125
-
126
- [voipManagerClass voipRegistration];
127
- }
128
-
129
- +(void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
130
- Class voipManagerClass = NSClassFromString(@"Callingx.VoipNotificationsManager");
131
- if (!voipManagerClass) {
132
- // Fallback: Try the unmangled name (might work depending on Swift version)
133
- voipManagerClass = NSClassFromString(@"VoipNotificationsManager");
134
- }
135
-
136
- if (!voipManagerClass) {
137
- #if DEBUG
138
- NSLog(@"[StreamVideoReactNative][didUpdatePushCredentials] VoipNotificationsManager not available");
139
- #endif
140
- return;
141
- }
142
-
143
- SEL selector = @selector(didUpdatePushCredentials:forType:);
144
- if (![voipManagerClass respondsToSelector:selector]) {
145
- #if DEBUG
146
- NSLog(@"[StreamVideoReactNative][didUpdatePushCredentials] VoipNotificationsManager does not respond to didUpdatePushCredentials:forType:");
147
- #endif
148
- return;
149
- }
150
-
151
- [voipManagerClass didUpdatePushCredentials:credentials forType:type];
152
- }
153
-
154
- +(void)didReceiveIncomingPush:(PKPushPayload *)payload forType:(NSString *)type completionHandler: (void (^_Nullable)(void)) completion {
155
- NSDictionary *streamPayload = payload.dictionaryPayload[@"stream"];
156
- if (!streamPayload) {
157
- #if DEBUG
158
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Stream payload not found");
159
- #endif
160
- if (completion) {
161
- completion();
162
- }
163
- return;
164
- }
165
-
166
- NSString *createdCallerName = streamPayload[@"created_by_display_name"];
167
- NSString *callCid = streamPayload[@"call_cid"];
168
- if (!createdCallerName || !callCid) {
169
- #if DEBUG
170
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Missing required fields: created_by_display_name or call_cid");
171
- #endif
172
- if (completion) {
173
- completion();
174
- }
175
- return;
176
- }
177
-
178
- if (![StreamVideoReactNative canRegisterCall]) {
179
- if (completion) {
180
- completion();
181
- }
182
- return;
183
- }
184
-
185
- [StreamVideoReactNative reportNewIncomingCall:streamPayload forType:type completionHandler:completion];
186
- [StreamVideoReactNative didReceiveIncomingPushWithPayload:payload forType:type];
187
- }
188
-
189
- +(void)reportNewIncomingCall:(NSDictionary *)streamPayload forType:(NSString *)type completionHandler: (void (^_Nullable)(void)) completion {
190
- Class callingxClass = NSClassFromString(@"Callingx");
191
- if (!callingxClass) {
192
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Callingx not available");
193
- return;
194
- }
195
-
196
- SEL selector = @selector(reportNewIncomingCall:handle:handleType:hasVideo:localizedCallerName:supportsHolding:supportsDTMF:supportsGrouping:supportsUngrouping:payload:withCompletionHandler:);
197
- if (![callingxClass respondsToSelector:selector]) {
198
- #if DEBUG
199
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Callingx does not respond to selector");
200
- #endif
201
- return;
202
- }
203
-
204
- NSString *callCid = streamPayload[@"call_cid"];
205
- NSString *createdCallerName = streamPayload[@"created_by_display_name"];
206
- NSString *videoIncluded = streamPayload[@"video"];
207
- BOOL hasVideo = [videoIncluded isEqualToString:@"false"] ? NO : YES;
208
- NSString *handleType = @"generic";
209
- BOOL supportsHolding = NO;
210
- BOOL supportsDTMF = NO;
211
- BOOL supportsGrouping = NO;
212
- BOOL supportsUngrouping = NO;
213
- void (^completionHandler)(void) = completion;
214
-
215
- NSMethodSignature *signature = [callingxClass methodSignatureForSelector:selector];
216
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
217
- [invocation setTarget:callingxClass];
218
- [invocation setSelector:selector];
219
- [invocation setArgument:&callCid atIndex:2];
220
- [invocation setArgument:&createdCallerName atIndex:3];
221
- [invocation setArgument:&handleType atIndex:4];
222
- [invocation setArgument:&hasVideo atIndex:5];
223
- [invocation setArgument:&createdCallerName atIndex:6];
224
- [invocation setArgument:&supportsHolding atIndex:7];
225
- [invocation setArgument:&supportsDTMF atIndex:8];
226
- [invocation setArgument:&supportsGrouping atIndex:9];
227
- [invocation setArgument:&supportsUngrouping atIndex:10];
228
- [invocation setArgument:&streamPayload atIndex:11];
229
- [invocation setArgument:&completionHandler atIndex:12];
230
- [invocation invoke];
231
- }
232
-
233
- +(void)didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
234
- Class voipManagerClass = NSClassFromString(@"Callingx.VoipNotificationsManager");
235
- if (!voipManagerClass) {
236
- // Fallback: Try the unmangled name (might work depending on Swift version)
237
- voipManagerClass = NSClassFromString(@"VoipNotificationsManager");
238
- }
239
-
240
- if (!voipManagerClass) {
241
- #if DEBUG
242
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPushWithPayload] VoipNotificationsManager not available");
243
- #endif
244
- return;
245
- }
246
-
247
- SEL selector = @selector(didReceiveIncomingPushWithPayload:forType:);
248
- if (![voipManagerClass respondsToSelector:selector]) {
249
- #if DEBUG
250
- NSLog(@"[StreamVideoReactNative][didReceiveIncomingPushWithPayload] VoipNotificationsManager does not respond to didReceiveIncomingPushWithPayload:forType:");
251
- #endif
252
- return;
253
- }
254
-
255
- [voipManagerClass didReceiveIncomingPushWithPayload:payload forType:type];
256
- }
257
-
258
76
  -(instancetype)init {
259
77
  if ((self = [super init])) {
260
78
  _notificationCenter = CFNotificationCenterGetDarwinNotifyCenter();
@@ -381,6 +199,71 @@ RCT_EXPORT_METHOD(currentThermalState:(RCTPromiseResolveBlock)resolve rejecter:(
381
199
  }
382
200
  }
383
201
 
202
+ +(void)registerIncomingCall:(NSString *)cid uuid:(NSString *)uuid {
203
+ [StreamVideoReactNative initializeSharedDictionaries];
204
+ dispatch_sync(_dictionaryQueue, ^{
205
+
206
+ #ifdef DEBUG
207
+ NSLog(@"registerIncomingCall cid:%@ -> uuid:%@",cid,uuid);
208
+ #endif
209
+ NSString *lowercaseUUID = [uuid lowercaseString];
210
+ _incomingCallUUIDsByCallID[cid] = lowercaseUUID;
211
+ _incomingCallCidsByUUID[lowercaseUUID] = cid;
212
+ });
213
+ }
214
+
215
+ RCT_EXPORT_METHOD(getIncomingCallUUid:(NSString *)cid
216
+ resolver:(RCTPromiseResolveBlock)resolve
217
+ rejecter:(RCTPromiseRejectBlock)reject)
218
+ {
219
+ dispatch_sync(_dictionaryQueue, ^{
220
+ NSString *uuid = _incomingCallUUIDsByCallID[cid];
221
+ if (uuid) {
222
+ resolve(uuid);
223
+ } else {
224
+ NSString *errorString = [NSString stringWithFormat:@"requested incoming call not found for cid: %@", cid];
225
+ reject(@"access_failure", errorString, nil);
226
+ }
227
+ });
228
+ }
229
+
230
+ RCT_EXPORT_METHOD(getIncomingCallCid:(NSString *)uuid
231
+ resolver:(RCTPromiseResolveBlock)resolve
232
+ rejecter:(RCTPromiseRejectBlock)reject)
233
+ {
234
+ dispatch_sync(_dictionaryQueue, ^{
235
+ NSString *lowercaseUUID = [uuid lowercaseString];
236
+ NSString *foundCid = _incomingCallCidsByUUID[lowercaseUUID];
237
+
238
+ if (foundCid) {
239
+ resolve(foundCid);
240
+ } else {
241
+ NSString *errorString = [NSString stringWithFormat:@"requested incoming call not found for uuid: %@", uuid];
242
+ reject(@"access_failure", errorString, nil);
243
+ }
244
+ });
245
+ }
246
+
247
+ RCT_EXPORT_METHOD(removeIncomingCall:(NSString *)cid
248
+ resolver:(RCTPromiseResolveBlock)resolve
249
+ rejecter:(RCTPromiseRejectBlock)reject)
250
+ {
251
+ dispatch_sync(_dictionaryQueue, ^{
252
+ NSString *uuid = _incomingCallUUIDsByCallID[cid];
253
+ if (uuid) {
254
+ #ifdef DEBUG
255
+ NSLog(@"removeIncomingCall cid:%@ -> uuid:%@",cid,uuid);
256
+ #endif
257
+
258
+ [_incomingCallUUIDsByCallID removeObjectForKey:cid];
259
+ [_incomingCallCidsByUUID removeObjectForKey:uuid];
260
+ resolve(@YES);
261
+ } else {
262
+ resolve(@NO);
263
+ }
264
+ });
265
+ }
266
+
384
267
  RCT_EXPORT_METHOD(captureRef:(nonnull NSNumber *)reactTag
385
268
  options:(NSDictionary *)options
386
269
  resolver:(RCTPromiseResolveBlock)resolve
@@ -518,7 +401,17 @@ RCT_EXPORT_METHOD(checkPermission:(NSString *)permission
518
401
  ];
519
402
  }
520
403
 
521
- //current implementation will return any registered calls not only stream calls
404
+ +(BOOL)shouldRejectCallWhenBusy {
405
+ return _shouldRejectCallWhenBusy;
406
+ }
407
+
408
+ RCT_EXPORT_METHOD(setShouldRejectCallWhenBusy:(BOOL)shouldReject) {
409
+ _shouldRejectCallWhenBusy = shouldReject;
410
+ #ifdef DEBUG
411
+ NSLog(@"setShouldRejectCallWhenBusy: %@", shouldReject ? @"YES" : @"NO");
412
+ #endif
413
+ }
414
+
522
415
  + (BOOL)hasAnyActiveCall
523
416
  {
524
417
  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.31.1-beta.0",
3
+ "version": "1.31.1",
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.44.6-beta.0",
54
- "@stream-io/video-react-bindings": "1.13.15-beta.0",
53
+ "@stream-io/video-client": "1.45.0",
54
+ "@stream-io/video-react-bindings": "1.13.15",
55
55
  "intl-pluralrules": "2.0.1",
56
56
  "react-native-url-polyfill": "^3.0.0",
57
57
  "rxjs": "~7.8.2",
@@ -64,7 +64,6 @@
64
64
  "@react-native-firebase/app": ">=17.5.0",
65
65
  "@react-native-firebase/messaging": ">=17.5.0",
66
66
  "@stream-io/noise-cancellation-react-native": ">=0.1.0",
67
- "@stream-io/react-native-callingx": ">=0.1.0",
68
67
  "@stream-io/react-native-webrtc": ">=137.1.3",
69
68
  "@stream-io/video-filters-react-native": ">=0.1.0",
70
69
  "expo": ">=47.0.0",
@@ -72,9 +71,11 @@
72
71
  "expo-notifications": "*",
73
72
  "react": ">=17.0.0",
74
73
  "react-native": ">=0.73.0",
74
+ "react-native-callkeep": ">=4.3.11",
75
75
  "react-native-gesture-handler": ">=2.8.0",
76
76
  "react-native-reanimated": ">=2.7.0",
77
- "react-native-svg": ">=13.6.0"
77
+ "react-native-svg": ">=13.6.0",
78
+ "react-native-voip-push-notification": ">=3.3.1"
78
79
  },
79
80
  "peerDependenciesMeta": {
80
81
  "@notifee/react-native": {
@@ -92,9 +93,6 @@
92
93
  "@stream-io/noise-cancellation-react-native": {
93
94
  "optional": true
94
95
  },
95
- "@stream-io/react-native-callingx": {
96
- "optional": true
97
- },
98
96
  "@stream-io/video-filters-react-native": {
99
97
  "optional": true
100
98
  },
@@ -107,11 +105,17 @@
107
105
  "expo-notifications": {
108
106
  "optional": true
109
107
  },
108
+ "react-native-callkeep": {
109
+ "optional": true
110
+ },
110
111
  "react-native-gesture-handler": {
111
112
  "optional": true
112
113
  },
113
114
  "react-native-reanimated": {
114
115
  "optional": true
116
+ },
117
+ "react-native-voip-push-notification": {
118
+ "optional": true
115
119
  }
116
120
  },
117
121
  "devDependencies": {
@@ -125,10 +129,9 @@
125
129
  "@react-native-firebase/app": "^23.4.0",
126
130
  "@react-native-firebase/messaging": "^23.4.0",
127
131
  "@react-native/babel-preset": "^0.81.5",
128
- "@stream-io/noise-cancellation-react-native": "0.6.1-beta.0",
129
- "@stream-io/react-native-callingx": "0.1.1-beta.1",
132
+ "@stream-io/noise-cancellation-react-native": "^0.6.0",
130
133
  "@stream-io/react-native-webrtc": "137.1.3",
131
- "@stream-io/video-filters-react-native": "0.11.1-beta.0",
134
+ "@stream-io/video-filters-react-native": "^0.11.0",
132
135
  "@testing-library/jest-native": "^5.4.3",
133
136
  "@testing-library/react-native": "13.3.3",
134
137
  "@tsconfig/node18": "^18.2.4",
@@ -143,9 +146,11 @@
143
146
  "react": "19.1.0",
144
147
  "react-native": "^0.81.5",
145
148
  "react-native-builder-bob": "~0.23",
149
+ "react-native-callkeep": "^4.3.16",
146
150
  "react-native-gesture-handler": "^2.28.0",
147
151
  "react-native-reanimated": "~4.1.2",
148
152
  "react-native-svg": "^15.14.0",
153
+ "react-native-voip-push-notification": "3.3.3",
149
154
  "react-native-worklets": "^0.5.0",
150
155
  "react-test-renderer": "19.1.0",
151
156
  "rimraf": "^6.0.1",
@@ -52,15 +52,10 @@ export const ParticipantLabel = ({
52
52
  const participantName = name ?? userId;
53
53
 
54
54
  const participantLabel = isLocalParticipant ? t('You') : participantName;
55
- const isPinningEnabled = pin?.isLocalPin;
56
55
  const isAudioMuted = !hasAudio(participant);
57
56
  const isVideoMuted = !hasVideo(participant);
58
57
  const isTrackPaused = trackType && hasPausedTrack(participant, trackType);
59
58
 
60
- const unPinParticipantHandler = () => {
61
- call?.unpin(sessionId);
62
- };
63
-
64
59
  if (trackType === 'screenShareTrack') {
65
60
  const screenShareText = isLocalParticipant
66
61
  ? t('You are sharing your screen')
@@ -133,10 +128,10 @@ export const ParticipantLabel = ({
133
128
  <BadNetwork color={colors.iconPrimary} size={iconSizes.sm} />
134
129
  </View>
135
130
  )}
136
- {isPinningEnabled && (
131
+ {pin && (
137
132
  <Pressable
138
133
  style={[styles.pinIconContainer, pinIconContainer]}
139
- onPress={unPinParticipantHandler}
134
+ onPress={pin.isLocalPin ? () => call?.unpin(sessionId) : undefined}
140
135
  >
141
136
  <PinVertical color={colors.iconPrimary} size={iconSizes.sm} />
142
137
  </Pressable>
@@ -1,4 +1,5 @@
1
1
  import { useIosVoipPushEventsSetupEffect } from './useIosVoipPushEventsSetupEffect';
2
+ import { useProcessPushCallEffect } from './useProcessPushCallEffect';
2
3
  import { useInitAndroidTokenAndRest } from './useInitAndroidTokenAndRest';
3
4
  import { useIosInitRemoteNotifications } from './useIosInitRemoteNotifications';
4
5
  import { useProcessPushNonRingingCallEffect } from './useProcessPushNonRingingCallEffect';
@@ -11,5 +12,6 @@ export const usePushRegisterEffect = () => {
11
12
  useIosInitRemoteNotifications();
12
13
  useIosVoipPushEventsSetupEffect();
13
14
  useProcessPushNonRingingCallEffect();
15
+ useProcessPushCallEffect();
14
16
  useInitAndroidTokenAndRest();
15
17
  };