@stream-io/video-react-native-sdk 1.28.3 → 1.29.0-beta.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 (240) hide show
  1. package/android/src/main/AndroidManifest.xml +8 -1
  2. package/android/src/main/AndroidManifestNew.xml +11 -0
  3. package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +42 -5
  4. package/android/src/main/java/com/streamvideo/reactnative/audio/utils/WebRtcAudioUtils.kt +70 -6
  5. package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt +6 -4
  6. package/android/src/main/java/com/streamvideo/reactnative/keepalive/KeepAliveNotification.kt +83 -0
  7. package/android/src/main/java/com/streamvideo/reactnative/keepalive/StreamCallKeepAliveHeadlessService.kt +134 -0
  8. package/dist/commonjs/components/Call/CallLayout/CallParticipantsGrid.js +3 -1
  9. package/dist/commonjs/components/Call/CallLayout/CallParticipantsGrid.js.map +1 -1
  10. package/dist/commonjs/components/Call/CallLayout/CallParticipantsSpotlight.js +5 -2
  11. package/dist/commonjs/components/Call/CallLayout/CallParticipantsSpotlight.js.map +1 -1
  12. package/dist/commonjs/components/Call/CallParticipantsList/CallParticipantsList.js +6 -3
  13. package/dist/commonjs/components/Call/CallParticipantsList/CallParticipantsList.js.map +1 -1
  14. package/dist/commonjs/components/Participant/FloatingParticipantView/index.js +3 -1
  15. package/dist/commonjs/components/Participant/FloatingParticipantView/index.js.map +1 -1
  16. package/dist/commonjs/components/Participant/ParticipantView/ParticipantView.js +3 -1
  17. package/dist/commonjs/components/Participant/ParticipantView/ParticipantView.js.map +1 -1
  18. package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer/index.js +3 -2
  19. package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer/index.js.map +1 -1
  20. package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js +216 -0
  21. package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
  22. package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
  23. package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
  24. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +64 -97
  25. package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  26. package/dist/commonjs/index.js +1 -0
  27. package/dist/commonjs/index.js.map +1 -1
  28. package/dist/commonjs/modules/call-manager/CallManager.js +26 -0
  29. package/dist/commonjs/modules/call-manager/CallManager.js.map +1 -1
  30. package/dist/commonjs/providers/StreamCall/index.js +6 -6
  31. package/dist/commonjs/providers/StreamCall/index.js.map +1 -1
  32. package/dist/commonjs/utils/StreamVideoRN/index.js +33 -21
  33. package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
  34. package/dist/commonjs/utils/internal/audioSessionPromise.js +46 -0
  35. package/dist/commonjs/utils/internal/audioSessionPromise.js.map +1 -0
  36. package/dist/commonjs/utils/internal/callingx.js +84 -0
  37. package/dist/commonjs/utils/internal/callingx.js.map +1 -0
  38. package/dist/commonjs/utils/internal/registerSDKGlobals.js +52 -3
  39. package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
  40. package/dist/commonjs/utils/keepCallAliveHeadlessTask.js +48 -0
  41. package/dist/commonjs/utils/keepCallAliveHeadlessTask.js.map +1 -0
  42. package/dist/commonjs/utils/push/android.js +145 -200
  43. package/dist/commonjs/utils/push/android.js.map +1 -1
  44. package/dist/commonjs/utils/push/internal/ios.js +16 -34
  45. package/dist/commonjs/utils/push/internal/ios.js.map +1 -1
  46. package/dist/commonjs/utils/push/internal/rxSubjects.js +1 -20
  47. package/dist/commonjs/utils/push/internal/rxSubjects.js.map +1 -1
  48. package/dist/commonjs/utils/push/internal/utils.js +17 -1
  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/callingx.js +75 -0
  52. package/dist/commonjs/utils/push/libs/callingx.js.map +1 -0
  53. package/dist/commonjs/utils/push/libs/index.js +8 -19
  54. package/dist/commonjs/utils/push/libs/index.js.map +1 -1
  55. package/dist/commonjs/utils/push/libs/notifee/index.js +0 -19
  56. package/dist/commonjs/utils/push/libs/notifee/index.js.map +1 -1
  57. package/dist/commonjs/utils/push/setupCallingExpEvents.js +97 -0
  58. package/dist/commonjs/utils/push/setupCallingExpEvents.js.map +1 -0
  59. package/dist/commonjs/utils/push/setupIosVoipPushEvents.js +7 -6
  60. package/dist/commonjs/utils/push/setupIosVoipPushEvents.js.map +1 -1
  61. package/dist/commonjs/version.js +1 -1
  62. package/dist/commonjs/version.js.map +1 -1
  63. package/dist/module/components/Call/CallLayout/CallParticipantsGrid.js +3 -1
  64. package/dist/module/components/Call/CallLayout/CallParticipantsGrid.js.map +1 -1
  65. package/dist/module/components/Call/CallLayout/CallParticipantsSpotlight.js +5 -2
  66. package/dist/module/components/Call/CallLayout/CallParticipantsSpotlight.js.map +1 -1
  67. package/dist/module/components/Call/CallParticipantsList/CallParticipantsList.js +6 -3
  68. package/dist/module/components/Call/CallParticipantsList/CallParticipantsList.js.map +1 -1
  69. package/dist/module/components/Participant/FloatingParticipantView/index.js +3 -1
  70. package/dist/module/components/Participant/FloatingParticipantView/index.js.map +1 -1
  71. package/dist/module/components/Participant/ParticipantView/ParticipantView.js +3 -1
  72. package/dist/module/components/Participant/ParticipantView/ParticipantView.js.map +1 -1
  73. package/dist/module/components/Participant/ParticipantView/VideoRenderer/index.js +3 -2
  74. package/dist/module/components/Participant/ParticipantView/VideoRenderer/index.js.map +1 -1
  75. package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js +209 -0
  76. package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
  77. package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
  78. package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
  79. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +66 -99
  80. package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
  81. package/dist/module/index.js +1 -0
  82. package/dist/module/index.js.map +1 -1
  83. package/dist/module/modules/call-manager/CallManager.js +26 -0
  84. package/dist/module/modules/call-manager/CallManager.js.map +1 -1
  85. package/dist/module/providers/StreamCall/index.js +6 -6
  86. package/dist/module/providers/StreamCall/index.js.map +1 -1
  87. package/dist/module/utils/StreamVideoRN/index.js +33 -21
  88. package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
  89. package/dist/module/utils/internal/audioSessionPromise.js +39 -0
  90. package/dist/module/utils/internal/audioSessionPromise.js.map +1 -0
  91. package/dist/module/utils/internal/callingx.js +75 -0
  92. package/dist/module/utils/internal/callingx.js.map +1 -0
  93. package/dist/module/utils/internal/registerSDKGlobals.js +53 -4
  94. package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
  95. package/dist/module/utils/keepCallAliveHeadlessTask.js +42 -0
  96. package/dist/module/utils/keepCallAliveHeadlessTask.js.map +1 -0
  97. package/dist/module/utils/push/android.js +147 -202
  98. package/dist/module/utils/push/android.js.map +1 -1
  99. package/dist/module/utils/push/internal/ios.js +16 -34
  100. package/dist/module/utils/push/internal/ios.js.map +1 -1
  101. package/dist/module/utils/push/internal/rxSubjects.js +0 -19
  102. package/dist/module/utils/push/internal/rxSubjects.js.map +1 -1
  103. package/dist/module/utils/push/internal/utils.js +14 -0
  104. package/dist/module/utils/push/internal/utils.js.map +1 -1
  105. package/dist/module/utils/push/ios.js.map +1 -1
  106. package/dist/module/utils/push/libs/callingx.js +67 -0
  107. package/dist/module/utils/push/libs/callingx.js.map +1 -0
  108. package/dist/module/utils/push/libs/index.js +1 -2
  109. package/dist/module/utils/push/libs/index.js.map +1 -1
  110. package/dist/module/utils/push/libs/notifee/index.js +0 -18
  111. package/dist/module/utils/push/libs/notifee/index.js.map +1 -1
  112. package/dist/module/utils/push/setupCallingExpEvents.js +91 -0
  113. package/dist/module/utils/push/setupCallingExpEvents.js.map +1 -0
  114. package/dist/module/utils/push/setupIosVoipPushEvents.js +7 -6
  115. package/dist/module/utils/push/setupIosVoipPushEvents.js.map +1 -1
  116. package/dist/module/version.js +1 -1
  117. package/dist/module/version.js.map +1 -1
  118. package/dist/typescript/components/Call/CallLayout/CallParticipantsGrid.d.ts +2 -2
  119. package/dist/typescript/components/Call/CallLayout/CallParticipantsGrid.d.ts.map +1 -1
  120. package/dist/typescript/components/Call/CallLayout/CallParticipantsSpotlight.d.ts +2 -2
  121. package/dist/typescript/components/Call/CallLayout/CallParticipantsSpotlight.d.ts.map +1 -1
  122. package/dist/typescript/components/Call/CallParticipantsList/CallParticipantsList.d.ts +6 -1
  123. package/dist/typescript/components/Call/CallParticipantsList/CallParticipantsList.d.ts.map +1 -1
  124. package/dist/typescript/components/Participant/FloatingParticipantView/index.d.ts +2 -2
  125. package/dist/typescript/components/Participant/FloatingParticipantView/index.d.ts.map +1 -1
  126. package/dist/typescript/components/Participant/ParticipantView/ParticipantView.d.ts +6 -1
  127. package/dist/typescript/components/Participant/ParticipantView/ParticipantView.d.ts.map +1 -1
  128. package/dist/typescript/components/Participant/ParticipantView/VideoRenderer/index.d.ts +2 -2
  129. package/dist/typescript/components/Participant/ParticipantView/VideoRenderer/index.d.ts.map +1 -1
  130. package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts +5 -0
  131. package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts.map +1 -0
  132. package/dist/typescript/hooks/push/useIosVoipPushEventsSetupEffect.d.ts.map +1 -1
  133. package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
  134. package/dist/typescript/index.d.ts +1 -0
  135. package/dist/typescript/index.d.ts.map +1 -1
  136. package/dist/typescript/modules/call-manager/CallManager.d.ts +5 -0
  137. package/dist/typescript/modules/call-manager/CallManager.d.ts.map +1 -1
  138. package/dist/typescript/utils/StreamVideoRN/index.d.ts +20 -2
  139. package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
  140. package/dist/typescript/utils/StreamVideoRN/types.d.ts +54 -29
  141. package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
  142. package/dist/typescript/utils/internal/audioSessionPromise.d.ts +16 -0
  143. package/dist/typescript/utils/internal/audioSessionPromise.d.ts.map +1 -0
  144. package/dist/typescript/utils/internal/callingx.d.ts +13 -0
  145. package/dist/typescript/utils/internal/callingx.d.ts.map +1 -0
  146. package/dist/typescript/utils/internal/registerSDKGlobals.d.ts.map +1 -1
  147. package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts +10 -0
  148. package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts.map +1 -0
  149. package/dist/typescript/utils/push/android.d.ts +1 -2
  150. package/dist/typescript/utils/push/android.d.ts.map +1 -1
  151. package/dist/typescript/utils/push/internal/ios.d.ts.map +1 -1
  152. package/dist/typescript/utils/push/internal/rxSubjects.d.ts +0 -12
  153. package/dist/typescript/utils/push/internal/rxSubjects.d.ts.map +1 -1
  154. package/dist/typescript/utils/push/internal/utils.d.ts +4 -0
  155. package/dist/typescript/utils/push/internal/utils.d.ts.map +1 -1
  156. package/dist/typescript/utils/push/ios.d.ts +1 -2
  157. package/dist/typescript/utils/push/ios.d.ts.map +1 -1
  158. package/dist/typescript/utils/push/libs/callingx.d.ts +9 -0
  159. package/dist/typescript/utils/push/libs/callingx.d.ts.map +1 -0
  160. package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts +16 -2
  161. package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts.map +1 -1
  162. package/dist/typescript/utils/push/libs/index.d.ts +1 -2
  163. package/dist/typescript/utils/push/libs/index.d.ts.map +1 -1
  164. package/dist/typescript/utils/push/libs/notifee/index.d.ts +0 -1
  165. package/dist/typescript/utils/push/libs/notifee/index.d.ts.map +1 -1
  166. package/dist/typescript/utils/push/setupCallingExpEvents.d.ts +8 -0
  167. package/dist/typescript/utils/push/setupCallingExpEvents.d.ts.map +1 -0
  168. package/dist/typescript/utils/push/setupIosVoipPushEvents.d.ts.map +1 -1
  169. package/dist/typescript/version.d.ts +1 -1
  170. package/dist/typescript/version.d.ts.map +1 -1
  171. package/expo-config-plugin/dist/withAndroidManifest.js +1 -33
  172. package/expo-config-plugin/dist/withAndroidPermissions.js +2 -7
  173. package/expo-config-plugin/dist/withAppDelegate.js +19 -197
  174. package/expo-config-plugin/dist/withMainActivity.js +1 -1
  175. package/expo-config-plugin/dist/withiOSInfoPlist.js +2 -3
  176. package/ios/StreamInCallManager.m +2 -0
  177. package/ios/StreamInCallManager.swift +20 -5
  178. package/ios/StreamVideoReactNative.h +7 -4
  179. package/ios/StreamVideoReactNative.m +191 -82
  180. package/package.json +10 -15
  181. package/src/components/Call/CallLayout/CallParticipantsGrid.tsx +3 -1
  182. package/src/components/Call/CallLayout/CallParticipantsSpotlight.tsx +4 -1
  183. package/src/components/Call/CallParticipantsList/CallParticipantsList.tsx +8 -0
  184. package/src/components/Participant/FloatingParticipantView/index.tsx +3 -1
  185. package/src/components/Participant/ParticipantView/ParticipantView.tsx +7 -0
  186. package/src/components/Participant/ParticipantView/VideoRenderer/index.tsx +7 -2
  187. package/src/hooks/push/useCallingExpWithCallingStateEffect.ts +307 -0
  188. package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +21 -34
  189. package/src/hooks/useAndroidKeepCallAliveEffect.ts +94 -120
  190. package/src/index.ts +1 -0
  191. package/src/modules/call-manager/CallManager.ts +36 -0
  192. package/src/modules/call-manager/native-module.d.ts +7 -0
  193. package/src/providers/StreamCall/index.tsx +6 -6
  194. package/src/utils/StreamVideoRN/index.ts +40 -30
  195. package/src/utils/StreamVideoRN/types.ts +56 -29
  196. package/src/utils/internal/audioSessionPromise.ts +39 -0
  197. package/src/utils/internal/callingx.ts +108 -0
  198. package/src/utils/internal/registerSDKGlobals.ts +47 -4
  199. package/src/utils/keepCallAliveHeadlessTask.ts +54 -0
  200. package/src/utils/push/android.ts +223 -308
  201. package/src/utils/push/internal/ios.ts +25 -46
  202. package/src/utils/push/internal/rxSubjects.ts +0 -29
  203. package/src/utils/push/internal/utils.ts +25 -0
  204. package/src/utils/push/ios.ts +1 -6
  205. package/src/utils/push/libs/callingx.ts +90 -0
  206. package/src/utils/push/libs/index.ts +1 -2
  207. package/src/utils/push/libs/notifee/index.ts +0 -27
  208. package/src/utils/push/setupCallingExpEvents.ts +117 -0
  209. package/src/utils/push/setupIosVoipPushEvents.ts +11 -7
  210. package/src/version.ts +1 -1
  211. package/CHANGELOG.md +0 -3103
  212. package/android/src/main/java/com/streamvideo/reactnative/util/CallAliveServiceChecker.kt +0 -95
  213. package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -160
  214. package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
  215. package/dist/commonjs/utils/push/libs/callkeep.js +0 -17
  216. package/dist/commonjs/utils/push/libs/callkeep.js.map +0 -1
  217. package/dist/commonjs/utils/push/libs/voipPushNotification.js +0 -17
  218. package/dist/commonjs/utils/push/libs/voipPushNotification.js.map +0 -1
  219. package/dist/commonjs/utils/push/setupIosCallKeepEvents.js +0 -205
  220. package/dist/commonjs/utils/push/setupIosCallKeepEvents.js.map +0 -1
  221. package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -153
  222. package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
  223. package/dist/module/utils/push/libs/callkeep.js +0 -11
  224. package/dist/module/utils/push/libs/callkeep.js.map +0 -1
  225. package/dist/module/utils/push/libs/voipPushNotification.js +0 -11
  226. package/dist/module/utils/push/libs/voipPushNotification.js.map +0 -1
  227. package/dist/module/utils/push/setupIosCallKeepEvents.js +0 -199
  228. package/dist/module/utils/push/setupIosCallKeepEvents.js.map +0 -1
  229. package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts +0 -5
  230. package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts.map +0 -1
  231. package/dist/typescript/utils/push/libs/callkeep.d.ts +0 -3
  232. package/dist/typescript/utils/push/libs/callkeep.d.ts.map +0 -1
  233. package/dist/typescript/utils/push/libs/voipPushNotification.d.ts +0 -3
  234. package/dist/typescript/utils/push/libs/voipPushNotification.d.ts.map +0 -1
  235. package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts +0 -6
  236. package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts.map +0 -1
  237. package/src/hooks/push/useIosCallkeepWithCallingStateEffect.ts +0 -235
  238. package/src/utils/push/libs/callkeep.ts +0 -16
  239. package/src/utils/push/libs/voipPushNotification.ts +0 -17
  240. package/src/utils/push/setupIosCallKeepEvents.ts +0 -252
@@ -4,6 +4,7 @@
4
4
  #import <React/RCTUIManagerUtils.h>
5
5
  #import <UIKit/UIKit.h>
6
6
  #import <CallKit/CallKit.h>
7
+ #import <PushKit/PushKit.h>
7
8
  #import "StreamVideoReactNative.h"
8
9
  #import "WebRTCModule.h"
9
10
  #import "WebRTCModuleOptions.h"
@@ -14,12 +15,8 @@
14
15
  NSNotificationName const kBroadcastStartedNotification = @"iOS_BroadcastStarted";
15
16
  NSNotificationName const kBroadcastStoppedNotification = @"iOS_BroadcastStopped";
16
17
 
17
- static NSMutableDictionary *_incomingCallUUIDsByCallID = nil;
18
- static NSMutableDictionary *_incomingCallCidsByUUID = nil;
19
18
  static dispatch_queue_t _dictionaryQueue = nil;
20
19
 
21
- static BOOL _shouldRejectCallWhenBusy = NO;
22
-
23
20
  void broadcastNotificationCallback(CFNotificationCenterRef center,
24
21
  void *observer,
25
22
  CFStringRef name,
@@ -60,11 +57,198 @@ RCT_EXPORT_MODULE();
60
57
  static dispatch_once_t onceToken;
61
58
  dispatch_once(&onceToken, ^{
62
59
  _dictionaryQueue = dispatch_queue_create("com.stream.video.dictionary", DISPATCH_QUEUE_SERIAL);
63
- _incomingCallUUIDsByCallID = [NSMutableDictionary dictionary];
64
- _incomingCallCidsByUUID = [NSMutableDictionary dictionary];
65
60
  });
66
61
  }
67
62
 
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:fromPushKit: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
+ BOOL fromPushKit = YES;
206
+ void (^completionHandler)(void) = completion;
207
+
208
+ NSMethodSignature *signature = [callingxClass methodSignatureForSelector:selector];
209
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
210
+ [invocation setTarget:callingxClass];
211
+ [invocation setSelector:selector];
212
+ [invocation setArgument:&callCid atIndex:2];
213
+ [invocation setArgument:&createdCallerName atIndex:3];
214
+ [invocation setArgument:&handleType atIndex:4];
215
+ [invocation setArgument:&hasVideo atIndex:5];
216
+ [invocation setArgument:&createdCallerName atIndex:6];
217
+ [invocation setArgument:&supportsHolding atIndex:7];
218
+ [invocation setArgument:&supportsDTMF atIndex:8];
219
+ [invocation setArgument:&supportsGrouping atIndex:9];
220
+ [invocation setArgument:&supportsUngrouping atIndex:10];
221
+ [invocation setArgument:&fromPushKit atIndex:11];
222
+ [invocation setArgument:&streamPayload atIndex:12];
223
+ [invocation setArgument:&completionHandler atIndex:13];
224
+ [invocation invoke];
225
+ }
226
+
227
+ +(void)didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
228
+ Class voipManagerClass = NSClassFromString(@"Callingx.VoipNotificationsManager");
229
+ if (!voipManagerClass) {
230
+ // Fallback: Try the unmangled name (might work depending on Swift version)
231
+ voipManagerClass = NSClassFromString(@"VoipNotificationsManager");
232
+ }
233
+
234
+ if (!voipManagerClass) {
235
+ #if DEBUG
236
+ NSLog(@"[StreamVideoReactNative][didReceiveIncomingPushWithPayload] VoipNotificationsManager not available");
237
+ #endif
238
+ return;
239
+ }
240
+
241
+ SEL selector = @selector(didReceiveIncomingPushWithPayload:forType:);
242
+ if (![voipManagerClass respondsToSelector:selector]) {
243
+ #if DEBUG
244
+ NSLog(@"[StreamVideoReactNative][didReceiveIncomingPushWithPayload] VoipNotificationsManager does not respond to didReceiveIncomingPushWithPayload:forType:");
245
+ #endif
246
+ return;
247
+ }
248
+
249
+ [voipManagerClass didReceiveIncomingPushWithPayload:payload forType:type];
250
+ }
251
+
68
252
  -(instancetype)init {
69
253
  if ((self = [super init])) {
70
254
  _notificationCenter = CFNotificationCenterGetDarwinNotifyCenter();
@@ -191,71 +375,6 @@ RCT_EXPORT_METHOD(currentThermalState:(RCTPromiseResolveBlock)resolve rejecter:(
191
375
  }
192
376
  }
193
377
 
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
-
259
378
  RCT_EXPORT_METHOD(captureRef:(nonnull NSNumber *)reactTag
260
379
  options:(NSDictionary *)options
261
380
  resolver:(RCTPromiseResolveBlock)resolve
@@ -373,17 +492,7 @@ RCT_EXPORT_METHOD(getBatteryState:(RCTPromiseResolveBlock)resolve
373
492
  ];
374
493
  }
375
494
 
376
- +(BOOL)shouldRejectCallWhenBusy {
377
- return _shouldRejectCallWhenBusy;
378
- }
379
-
380
- RCT_EXPORT_METHOD(setShouldRejectCallWhenBusy:(BOOL)shouldReject) {
381
- _shouldRejectCallWhenBusy = shouldReject;
382
- #ifdef DEBUG
383
- NSLog(@"setShouldRejectCallWhenBusy: %@", shouldReject ? @"YES" : @"NO");
384
- #endif
385
- }
386
-
495
+ //current implementation will return any registered calls not only stream calls
387
496
  + (BOOL)hasAnyActiveCall
388
497
  {
389
498
  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.28.3",
3
+ "version": "1.29.0-beta.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/",
@@ -65,6 +65,7 @@
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",
68
69
  "@stream-io/react-native-webrtc": ">=137.1.0",
69
70
  "@stream-io/video-filters-react-native": ">=0.1.0",
70
71
  "expo": ">=47.0.0",
@@ -72,11 +73,9 @@
72
73
  "expo-notifications": "*",
73
74
  "react": ">=17.0.0",
74
75
  "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",
79
- "react-native-voip-push-notification": ">=3.3.1"
78
+ "react-native-svg": ">=13.6.0"
80
79
  },
81
80
  "peerDependenciesMeta": {
82
81
  "@notifee/react-native": {
@@ -94,6 +93,9 @@
94
93
  "@stream-io/noise-cancellation-react-native": {
95
94
  "optional": true
96
95
  },
96
+ "@stream-io/react-native-callingx": {
97
+ "optional": true
98
+ },
97
99
  "@stream-io/video-filters-react-native": {
98
100
  "optional": true
99
101
  },
@@ -106,17 +108,11 @@
106
108
  "expo-notifications": {
107
109
  "optional": true
108
110
  },
109
- "react-native-callkeep": {
110
- "optional": true
111
- },
112
111
  "react-native-gesture-handler": {
113
112
  "optional": true
114
113
  },
115
114
  "react-native-reanimated": {
116
115
  "optional": true
117
- },
118
- "react-native-voip-push-notification": {
119
- "optional": true
120
116
  }
121
117
  },
122
118
  "devDependencies": {
@@ -130,9 +126,10 @@
130
126
  "@react-native-firebase/app": "^23.4.0",
131
127
  "@react-native-firebase/messaging": "^23.4.0",
132
128
  "@react-native/babel-preset": "^0.81.5",
133
- "@stream-io/noise-cancellation-react-native": "^0.5.0",
129
+ "@stream-io/noise-cancellation-react-native": "0.5.0",
130
+ "@stream-io/react-native-callingx": "0.1.0-beta.1",
134
131
  "@stream-io/react-native-webrtc": "137.1.0",
135
- "@stream-io/video-filters-react-native": "^0.10.0",
132
+ "@stream-io/video-filters-react-native": "0.10.0",
136
133
  "@testing-library/jest-native": "^5.4.3",
137
134
  "@testing-library/react-native": "13.3.3",
138
135
  "@tsconfig/node18": "^18.2.4",
@@ -148,11 +145,9 @@
148
145
  "react": "19.1.0",
149
146
  "react-native": "^0.81.5",
150
147
  "react-native-builder-bob": "~0.23",
151
- "react-native-callkeep": "^4.3.16",
152
148
  "react-native-gesture-handler": "^2.28.0",
153
149
  "react-native-reanimated": "~4.1.2",
154
150
  "react-native-svg": "^15.14.0",
155
- "react-native-voip-push-notification": "3.3.3",
156
151
  "react-native-worklets": "^0.5.0",
157
152
  "react-test-renderer": "19.1.0",
158
153
  "rimraf": "^6.0.1",
@@ -167,4 +162,4 @@
167
162
  "typescript"
168
163
  ]
169
164
  }
170
- }
165
+ }
@@ -18,7 +18,7 @@ import { StreamVideoParticipant } from '@stream-io/video-client';
18
18
  */
19
19
  export type CallParticipantsGridProps = ParticipantViewComponentProps &
20
20
  Pick<CallContentProps, 'supportedReactions' | 'CallParticipantsList'> &
21
- Pick<CallParticipantsListComponentProps, 'ParticipantView'> & {
21
+ Pick<CallParticipantsListComponentProps, 'ParticipantView' | 'mirror'> & {
22
22
  /**
23
23
  * Boolean to decide if local participant will be visible in the grid when there is 1:1 call.
24
24
  */
@@ -41,6 +41,7 @@ export const CallParticipantsGrid = ({
41
41
  ParticipantVideoFallback,
42
42
  ParticipantView,
43
43
  VideoRenderer,
44
+ mirror,
44
45
  showLocalParticipant = false,
45
46
  supportedReactions,
46
47
  landscape,
@@ -103,6 +104,7 @@ export const CallParticipantsGrid = ({
103
104
  ParticipantReaction,
104
105
  ParticipantVideoFallback,
105
106
  VideoRenderer,
107
+ mirror,
106
108
  };
107
109
 
108
110
  return (
@@ -27,7 +27,7 @@ export type CallParticipantsSpotlightProps = ParticipantViewComponentProps &
27
27
  CallContentProps,
28
28
  'supportedReactions' | 'CallParticipantsList' | 'ScreenShareOverlay'
29
29
  > &
30
- Pick<CallParticipantsListComponentProps, 'ParticipantView'> & {
30
+ Pick<CallParticipantsListComponentProps, 'ParticipantView' | 'mirror'> & {
31
31
  /**
32
32
  * Check if device is in landscape mode.
33
33
  * This will apply the landscape mode styles to the component.
@@ -49,6 +49,7 @@ export const CallParticipantsSpotlight = ({
49
49
  ScreenShareOverlay,
50
50
  VideoRenderer,
51
51
  supportedReactions,
52
+ mirror,
52
53
  landscape,
53
54
  }: CallParticipantsSpotlightProps) => {
54
55
  const {
@@ -78,6 +79,7 @@ export const CallParticipantsSpotlight = ({
78
79
  const callParticipantsListProps: CallParticipantsListComponentProps = {
79
80
  ...participantViewProps,
80
81
  ParticipantView,
82
+ mirror,
81
83
  };
82
84
 
83
85
  const landscapeStyles: ViewStyle = {
@@ -126,6 +128,7 @@ export const CallParticipantsSpotlight = ({
126
128
  isScreenShareOnSpotlight ? 'screenShareTrack' : 'videoTrack'
127
129
  }
128
130
  supportedReactions={supportedReactions}
131
+ mirror={mirror}
129
132
  {...participantViewProps}
130
133
  />
131
134
  ))}
@@ -43,6 +43,11 @@ export type CallParticipantsListComponentProps =
43
43
  * Component to customize the participant view.
44
44
  */
45
45
  ParticipantView?: React.ComponentType<ParticipantViewProps> | null;
46
+ /**
47
+ * Forces a participant's video to be mirrored or unmirrored. By default, the video track
48
+ * from the local participant is mirrored, and all other videos are not mirrored.
49
+ */
50
+ mirror?: boolean;
46
51
  };
47
52
 
48
53
  /**
@@ -88,6 +93,7 @@ export const CallParticipantsList = ({
88
93
  VideoRenderer,
89
94
  supportedReactions,
90
95
  landscape,
96
+ mirror,
91
97
  }: CallParticipantsListProps) => {
92
98
  const styles = useStyles();
93
99
  const [containerLayout, setContainerLayout] = useState({
@@ -210,6 +216,7 @@ export const CallParticipantsList = ({
210
216
  trackType="videoTrack"
211
217
  isVisible={isVisible}
212
218
  supportedReactions={supportedReactions}
219
+ mirror={mirror}
213
220
  {...participantProps}
214
221
  />
215
222
  )}
@@ -236,6 +243,7 @@ export const CallParticipantsList = ({
236
243
  trackType="videoTrack"
237
244
  key={keyExtractor(participant, index)}
238
245
  supportedReactions={supportedReactions}
246
+ mirror={mirror}
239
247
  {...participantProps}
240
248
  />
241
249
  )
@@ -36,7 +36,7 @@ export type FloatingParticipantViewAlignment =
36
36
  export type FloatingParticipantViewProps = ParticipantViewComponentProps &
37
37
  Pick<CallParticipantsListComponentProps, 'ParticipantView'> &
38
38
  Pick<CallContentProps, 'supportedReactions'> &
39
- Pick<ParticipantViewProps, 'objectFit' | 'videoZOrder'> & {
39
+ Pick<ParticipantViewProps, 'objectFit' | 'videoZOrder' | 'mirror'> & {
40
40
  /**
41
41
  * Determines where the floating participant video will be placed.
42
42
  */
@@ -103,6 +103,7 @@ export const FloatingParticipantView = ({
103
103
  supportedReactions,
104
104
  videoZOrder = 1,
105
105
  objectFit,
106
+ mirror,
106
107
  }: FloatingParticipantViewProps) => {
107
108
  const {
108
109
  theme: {
@@ -195,6 +196,7 @@ export const FloatingParticipantView = ({
195
196
  // (which uses the default: 0)
196
197
  videoZOrder={videoZOrder}
197
198
  objectFit={objectFit}
199
+ mirror={mirror}
198
200
  supportedReactions={supportedReactions}
199
201
  {...participantViewProps}
200
202
  />
@@ -88,6 +88,11 @@ export type ParticipantViewProps = ParticipantViewComponentProps &
88
88
  * In the fashion of https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth and https://www.w3.org/TR/html5/rendering.html#video-object-fit, resembles the CSS style object-fit.
89
89
  */
90
90
  objectFit?: 'contain' | 'cover';
91
+ /**
92
+ * Forces a participant's video to be mirrored or unmirrored. By default, the video track
93
+ * from the local participant is mirrored, and all other videos are not mirrored.
94
+ */
95
+ mirror?: boolean;
91
96
  };
92
97
 
93
98
  /**
@@ -107,6 +112,7 @@ export const ParticipantView = ({
107
112
  ParticipantVideoFallback = DefaultParticipantVideoFallback,
108
113
  objectFit,
109
114
  videoZOrder = 0,
115
+ mirror,
110
116
  supportedReactions,
111
117
  }: ParticipantViewProps) => {
112
118
  const {
@@ -144,6 +150,7 @@ export const ParticipantView = ({
144
150
  ParticipantVideoFallback={ParticipantVideoFallback}
145
151
  objectFit={objectFit}
146
152
  videoZOrder={videoZOrder}
153
+ mirror={mirror}
147
154
  />
148
155
  )}
149
156
  <View
@@ -36,6 +36,7 @@ export type VideoRendererProps = Pick<
36
36
  | 'isVisible'
37
37
  | 'objectFit'
38
38
  | 'videoZOrder'
39
+ | 'mirror'
39
40
  >;
40
41
 
41
42
  /**
@@ -50,6 +51,7 @@ export const VideoRenderer = ({
50
51
  ParticipantVideoFallback = DefaultParticipantVideoFallback,
51
52
  objectFit,
52
53
  videoZOrder = 0,
54
+ mirror: mirrorOverride,
53
55
  }: VideoRendererProps) => {
54
56
  const {
55
57
  theme: { videoRenderer },
@@ -109,8 +111,11 @@ export const VideoRenderer = ({
109
111
  deregisterIosScreenshot,
110
112
  ]);
111
113
 
112
- const mirror =
113
- isLocalParticipant && !isScreenSharing && direction === 'front';
114
+ const mirror = isScreenSharing
115
+ ? false
116
+ : mirrorOverride !== undefined
117
+ ? mirrorOverride
118
+ : isLocalParticipant && direction === 'front';
114
119
 
115
120
  /**
116
121
  * This effect updates the participant's viewportVisibilityState