@stream-io/video-react-native-sdk 1.36.1 → 1.37.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.
- package/CHANGELOG.md +27 -0
- package/dist/commonjs/components/Call/CallContent/CallContent.js +1 -2
- package/dist/commonjs/components/Call/CallContent/CallContent.js.map +1 -1
- package/dist/commonjs/components/Call/Lobby/Lobby.js +1 -1
- package/dist/commonjs/components/Call/Lobby/Lobby.js.map +1 -1
- package/dist/commonjs/components/Participant/FloatingParticipantView/index.js +1 -2
- package/dist/commonjs/components/Participant/FloatingParticipantView/index.js.map +1 -1
- package/dist/commonjs/components/Participant/ParticipantView/ParticipantVideoFallback.js +2 -3
- package/dist/commonjs/components/Participant/ParticipantView/ParticipantVideoFallback.js.map +1 -1
- package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer/index.js +2 -10
- package/dist/commonjs/components/Participant/ParticipantView/VideoRenderer/index.js.map +1 -1
- package/dist/commonjs/utils/internal/callingx/callingx.js +16 -36
- package/dist/commonjs/utils/internal/callingx/callingx.js.map +1 -1
- package/dist/commonjs/utils/push/internal/ios.js +4 -3
- package/dist/commonjs/utils/push/internal/ios.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/module/components/Call/CallContent/CallContent.js +1 -2
- package/dist/module/components/Call/CallContent/CallContent.js.map +1 -1
- package/dist/module/components/Call/Lobby/Lobby.js +1 -1
- package/dist/module/components/Call/Lobby/Lobby.js.map +1 -1
- package/dist/module/components/Participant/FloatingParticipantView/index.js +1 -2
- package/dist/module/components/Participant/FloatingParticipantView/index.js.map +1 -1
- package/dist/module/components/Participant/ParticipantView/ParticipantVideoFallback.js +2 -3
- package/dist/module/components/Participant/ParticipantView/ParticipantVideoFallback.js.map +1 -1
- package/dist/module/components/Participant/ParticipantView/VideoRenderer/index.js +2 -10
- package/dist/module/components/Participant/ParticipantView/VideoRenderer/index.js.map +1 -1
- package/dist/module/utils/internal/callingx/callingx.js +17 -37
- package/dist/module/utils/internal/callingx/callingx.js.map +1 -1
- package/dist/module/utils/push/internal/ios.js +4 -3
- package/dist/module/utils/push/internal/ios.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/components/Call/CallContent/CallContent.d.ts.map +1 -1
- package/dist/typescript/components/Participant/FloatingParticipantView/index.d.ts.map +1 -1
- package/dist/typescript/components/Participant/ParticipantView/ParticipantVideoFallback.d.ts.map +1 -1
- package/dist/typescript/utils/internal/callingx/callingx.d.ts.map +1 -1
- package/dist/typescript/utils/push/internal/ios.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/expo-config-plugin/dist/withAppDelegate.js +14 -177
- package/ios/RTCViewPip.swift +6 -6
- package/ios/RTCViewPipManager.swift +47 -10
- package/ios/StreamInCallManager.swift +2 -6
- package/ios/StreamVideoReactNative.h +5 -18
- package/ios/StreamVideoReactNative.m +2 -296
- package/package.json +28 -27
- package/src/components/Call/CallContent/CallContent.tsx +5 -2
- package/src/components/Call/Lobby/Lobby.tsx +1 -1
- package/src/components/Participant/FloatingParticipantView/index.tsx +1 -1
- package/src/components/Participant/ParticipantView/ParticipantVideoFallback.tsx +1 -1
- package/src/components/Participant/ParticipantView/VideoRenderer/index.tsx +2 -11
- package/src/utils/internal/callingx/callingx.ts +17 -42
- package/src/utils/push/internal/ios.ts +4 -3
- package/src/version.ts +1 -1
|
@@ -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"
|
|
@@ -25,8 +24,6 @@
|
|
|
25
24
|
NSNotificationName const kBroadcastStartedNotification = @"iOS_BroadcastStarted";
|
|
26
25
|
NSNotificationName const kBroadcastStoppedNotification = @"iOS_BroadcastStopped";
|
|
27
26
|
|
|
28
|
-
static NSString *const DEFAULT_DISPLAY_NAME = @"Unknown Caller";
|
|
29
|
-
|
|
30
27
|
static dispatch_queue_t _dictionaryQueue = nil;
|
|
31
28
|
|
|
32
29
|
void broadcastNotificationCallback(CFNotificationCenterRef center,
|
|
@@ -49,9 +46,6 @@ void broadcastNotificationCallback(CFNotificationCenterRef center,
|
|
|
49
46
|
AVAudioPlayer *_busyTonePlayer; // Instance variable
|
|
50
47
|
}
|
|
51
48
|
|
|
52
|
-
// necessary for addUIBlock usage https://github.com/facebook/react-native/issues/50800#issuecomment-2823327307
|
|
53
|
-
@synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED;
|
|
54
|
-
|
|
55
49
|
RCT_EXPORT_MODULE();
|
|
56
50
|
|
|
57
51
|
+(BOOL)requiresMainQueueSetup {
|
|
@@ -72,77 +66,6 @@ RCT_EXPORT_MODULE();
|
|
|
72
66
|
});
|
|
73
67
|
}
|
|
74
68
|
|
|
75
|
-
+(BOOL)canRegisterCall {
|
|
76
|
-
Class callingxClass = NSClassFromString(@"Callingx");
|
|
77
|
-
if (!callingxClass) {
|
|
78
|
-
#if DEBUG
|
|
79
|
-
NSLog(@"[StreamVideoReactNative][canRegisterCall] Callingx not available");
|
|
80
|
-
#endif
|
|
81
|
-
return YES;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
SEL selector = @selector(canRegisterCall);
|
|
85
|
-
if (![callingxClass respondsToSelector:selector]) {
|
|
86
|
-
#if DEBUG
|
|
87
|
-
NSLog(@"[StreamVideoReactNative][canRegisterCall] Callingx does not respond to canRegisterCall selector");
|
|
88
|
-
#endif
|
|
89
|
-
return YES;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
NSMethodSignature *signature = [callingxClass methodSignatureForSelector:selector];
|
|
93
|
-
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
|
94
|
-
[invocation setTarget:callingxClass];
|
|
95
|
-
[invocation setSelector:selector];
|
|
96
|
-
[invocation invoke];
|
|
97
|
-
|
|
98
|
-
BOOL canRegister = NO;
|
|
99
|
-
[invocation getReturnValue:&canRegister];
|
|
100
|
-
|
|
101
|
-
#if DEBUG
|
|
102
|
-
NSLog(@"[StreamVideoReactNative][canRegisterCall] canRegisterCall = %@", canRegister ? @"YES" : @"NO");
|
|
103
|
-
#endif
|
|
104
|
-
|
|
105
|
-
return canRegister;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
+(BOOL)shouldSkipIncomingPushInForeground {
|
|
109
|
-
Class callingxClass = NSClassFromString(@"Callingx");
|
|
110
|
-
if (!callingxClass) {
|
|
111
|
-
return NO;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
SEL selector = @selector(shouldSkipIncomingPushInForeground);
|
|
115
|
-
if (![callingxClass respondsToSelector:selector]) {
|
|
116
|
-
return NO;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
NSMethodSignature *signature = [callingxClass methodSignatureForSelector:selector];
|
|
120
|
-
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
|
121
|
-
[invocation setTarget:callingxClass];
|
|
122
|
-
[invocation setSelector:selector];
|
|
123
|
-
[invocation invoke];
|
|
124
|
-
|
|
125
|
-
BOOL shouldSkip = NO;
|
|
126
|
-
[invocation getReturnValue:&shouldSkip];
|
|
127
|
-
return shouldSkip;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
+(BOOL)isAppInForeground {
|
|
131
|
-
// applicationState must be read on the main thread (PushKit delivers on
|
|
132
|
-
// main, so the common path skips dispatch). Treat Inactive as foreground:
|
|
133
|
-
// covers brief transitions and system overlays.
|
|
134
|
-
__block UIApplicationState state = UIApplicationStateActive;
|
|
135
|
-
void (^readState)(void) = ^{
|
|
136
|
-
state = [UIApplication sharedApplication].applicationState;
|
|
137
|
-
};
|
|
138
|
-
if ([NSThread isMainThread]) {
|
|
139
|
-
readState();
|
|
140
|
-
} else {
|
|
141
|
-
dispatch_sync(dispatch_get_main_queue(), readState);
|
|
142
|
-
}
|
|
143
|
-
return state != UIApplicationStateBackground;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
69
|
+(void)voipRegistration {
|
|
147
70
|
Class voipManagerClass = NSClassFromString(@"Callingx.VoipNotificationsManager");
|
|
148
71
|
if (!voipManagerClass) {
|
|
@@ -168,223 +91,6 @@ RCT_EXPORT_MODULE();
|
|
|
168
91
|
[voipManagerClass voipRegistration];
|
|
169
92
|
}
|
|
170
93
|
|
|
171
|
-
+(void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
|
|
172
|
-
Class voipManagerClass = NSClassFromString(@"Callingx.VoipNotificationsManager");
|
|
173
|
-
if (!voipManagerClass) {
|
|
174
|
-
// Fallback: Try the unmangled name (might work depending on Swift version)
|
|
175
|
-
voipManagerClass = NSClassFromString(@"VoipNotificationsManager");
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (!voipManagerClass) {
|
|
179
|
-
#if DEBUG
|
|
180
|
-
NSLog(@"[StreamVideoReactNative][didUpdatePushCredentials] VoipNotificationsManager not available");
|
|
181
|
-
#endif
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
SEL selector = @selector(didUpdatePushCredentials:forType:);
|
|
186
|
-
if (![voipManagerClass respondsToSelector:selector]) {
|
|
187
|
-
#if DEBUG
|
|
188
|
-
NSLog(@"[StreamVideoReactNative][didUpdatePushCredentials] VoipNotificationsManager does not respond to didUpdatePushCredentials:forType:");
|
|
189
|
-
#endif
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
[voipManagerClass didUpdatePushCredentials:credentials forType:type];
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
+(void)didReceiveIncomingPush:(PKPushPayload *)payload forType:(NSString *)type completionHandler: (void (^_Nullable)(void)) completion {
|
|
197
|
-
NSDictionary *streamPayload = payload.dictionaryPayload[@"stream"];
|
|
198
|
-
if (!streamPayload) {
|
|
199
|
-
#if DEBUG
|
|
200
|
-
NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Stream payload not found");
|
|
201
|
-
#endif
|
|
202
|
-
if (completion) {
|
|
203
|
-
completion();
|
|
204
|
-
}
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
NSString *callCid = streamPayload[@"call_cid"];
|
|
209
|
-
if (!callCid) {
|
|
210
|
-
#if DEBUG
|
|
211
|
-
NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Missing required field: call_cid");
|
|
212
|
-
#endif
|
|
213
|
-
if (completion) {
|
|
214
|
-
completion();
|
|
215
|
-
}
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (![StreamVideoReactNative canRegisterCall]) {
|
|
220
|
-
if (completion) {
|
|
221
|
-
completion();
|
|
222
|
-
}
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
[StreamVideoReactNative reportNewIncomingCall:streamPayload forType:type completionHandler:completion];
|
|
227
|
-
[StreamVideoReactNative didReceiveIncomingPushWithPayload:payload forType:type];
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
+(void)didReceiveIncomingVoIPPush:(PKPushPayload *)payload
|
|
231
|
-
metadata:(id _Nullable)metadata
|
|
232
|
-
completionHandler:(void (^_Nullable)(void))completion {
|
|
233
|
-
NSDictionary *streamPayload = payload.dictionaryPayload[@"stream"];
|
|
234
|
-
if (!streamPayload) {
|
|
235
|
-
#if DEBUG
|
|
236
|
-
NSLog(@"[StreamVideoReactNative][didReceiveIncomingVoIPPush] Stream payload not found");
|
|
237
|
-
#endif
|
|
238
|
-
if (completion) {
|
|
239
|
-
completion();
|
|
240
|
-
}
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
NSString *callCid = streamPayload[@"call_cid"];
|
|
245
|
-
if (!callCid) {
|
|
246
|
-
#if DEBUG
|
|
247
|
-
NSLog(@"[StreamVideoReactNative][didReceiveIncomingVoIPPush] Missing required field: call_cid");
|
|
248
|
-
#endif
|
|
249
|
-
if (completion) {
|
|
250
|
-
completion();
|
|
251
|
-
}
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
NSString *type = @"PKPushTypeVoIP";
|
|
256
|
-
BOOL mustReport = readMustReportFromMetadata(metadata);
|
|
257
|
-
|
|
258
|
-
// Both skip paths require mustReport == NO; skipping while YES risks
|
|
259
|
-
// PushKit terminating the app.
|
|
260
|
-
if (!mustReport && ![StreamVideoReactNative canRegisterCall]) {
|
|
261
|
-
// Busy reject: drop without forwarding to JS.
|
|
262
|
-
if (completion) {
|
|
263
|
-
completion();
|
|
264
|
-
}
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (!mustReport &&
|
|
269
|
-
[StreamVideoReactNative shouldSkipIncomingPushInForeground] &&
|
|
270
|
-
[StreamVideoReactNative isAppInForeground]) {
|
|
271
|
-
// Foreground skip: hide CallKit, let JS render the ringing UI.
|
|
272
|
-
[StreamVideoReactNative didReceiveIncomingPushWithPayload:payload forType:type];
|
|
273
|
-
if (completion) {
|
|
274
|
-
completion();
|
|
275
|
-
}
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
[StreamVideoReactNative reportNewIncomingCall:streamPayload forType:type completionHandler:completion];
|
|
280
|
-
[StreamVideoReactNative didReceiveIncomingPushWithPayload:payload forType:type];
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// Reads `PKVoIPPushMetadata.mustReport` via runtime dispatch. Fail-safe:
|
|
284
|
-
// returns YES on any uncertainty (nil, missing property, wrong return type)
|
|
285
|
-
// so unknown metadata never causes CallKit to be skipped.
|
|
286
|
-
static BOOL readMustReportFromMetadata(id _Nullable metadata) {
|
|
287
|
-
SEL selector = @selector(mustReport);
|
|
288
|
-
if (!metadata || ![metadata respondsToSelector:selector]) {
|
|
289
|
-
return YES;
|
|
290
|
-
}
|
|
291
|
-
NSMethodSignature *signature = [metadata methodSignatureForSelector:selector];
|
|
292
|
-
if (!signature || signature.methodReturnLength != sizeof(BOOL)) {
|
|
293
|
-
return YES;
|
|
294
|
-
}
|
|
295
|
-
// BOOL encodes as "c" (legacy ABIs) or "B" (modern). Reject anything else
|
|
296
|
-
// so getReturnValue: never reads garbage from an object-returning selector.
|
|
297
|
-
const char *returnType = signature.methodReturnType;
|
|
298
|
-
if (!returnType ||
|
|
299
|
-
(strcmp(returnType, @encode(BOOL)) != 0 &&
|
|
300
|
-
strcmp(returnType, @encode(bool)) != 0)) {
|
|
301
|
-
return YES;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
|
305
|
-
[invocation setTarget:metadata];
|
|
306
|
-
[invocation setSelector:selector];
|
|
307
|
-
[invocation invoke];
|
|
308
|
-
|
|
309
|
-
BOOL mustReport = NO;
|
|
310
|
-
[invocation getReturnValue:&mustReport];
|
|
311
|
-
return mustReport;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
+(void)reportNewIncomingCall:(NSDictionary *)streamPayload forType:(NSString *)type completionHandler: (void (^_Nullable)(void)) completion {
|
|
315
|
-
Class callingxClass = NSClassFromString(@"Callingx");
|
|
316
|
-
if (!callingxClass) {
|
|
317
|
-
NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Callingx not available");
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
SEL selector = @selector(reportNewIncomingCall:handle:handleType:hasVideo:localizedCallerName:supportsHolding:supportsDTMF:supportsGrouping:supportsUngrouping:payload:withCompletionHandler:);
|
|
322
|
-
if (![callingxClass respondsToSelector:selector]) {
|
|
323
|
-
#if DEBUG
|
|
324
|
-
NSLog(@"[StreamVideoReactNative][didReceiveIncomingPush] Callingx does not respond to selector");
|
|
325
|
-
#endif
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
NSString *callCid = streamPayload[@"call_cid"];
|
|
330
|
-
NSString *callDisplayName = streamPayload[@"call_display_name"];
|
|
331
|
-
NSString *createdByDisplayName = streamPayload[@"created_by_display_name"];
|
|
332
|
-
NSString *createdCallerName = callDisplayName.length > 0 ? callDisplayName : createdByDisplayName;
|
|
333
|
-
NSString *localizedCallerName = createdCallerName.length > 0 ? createdCallerName : DEFAULT_DISPLAY_NAME;
|
|
334
|
-
NSString *createdById = streamPayload[@"created_by_id"];
|
|
335
|
-
NSString *handle = createdById.length > 0 ? createdById : localizedCallerName;
|
|
336
|
-
NSString *videoIncluded = streamPayload[@"video"];
|
|
337
|
-
BOOL hasVideo = [videoIncluded isEqualToString:@"false"] ? NO : YES;
|
|
338
|
-
NSString *handleType = @"generic";
|
|
339
|
-
BOOL supportsHolding = NO;
|
|
340
|
-
BOOL supportsDTMF = NO;
|
|
341
|
-
BOOL supportsGrouping = NO;
|
|
342
|
-
BOOL supportsUngrouping = NO;
|
|
343
|
-
void (^completionHandler)(void) = completion;
|
|
344
|
-
|
|
345
|
-
NSMethodSignature *signature = [callingxClass methodSignatureForSelector:selector];
|
|
346
|
-
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
|
347
|
-
[invocation setTarget:callingxClass];
|
|
348
|
-
[invocation setSelector:selector];
|
|
349
|
-
[invocation setArgument:&callCid atIndex:2];
|
|
350
|
-
[invocation setArgument:&handle atIndex:3];
|
|
351
|
-
[invocation setArgument:&handleType atIndex:4];
|
|
352
|
-
[invocation setArgument:&hasVideo atIndex:5];
|
|
353
|
-
[invocation setArgument:&localizedCallerName atIndex:6];
|
|
354
|
-
[invocation setArgument:&supportsHolding atIndex:7];
|
|
355
|
-
[invocation setArgument:&supportsDTMF atIndex:8];
|
|
356
|
-
[invocation setArgument:&supportsGrouping atIndex:9];
|
|
357
|
-
[invocation setArgument:&supportsUngrouping atIndex:10];
|
|
358
|
-
[invocation setArgument:&streamPayload atIndex:11];
|
|
359
|
-
[invocation setArgument:&completionHandler atIndex:12];
|
|
360
|
-
[invocation invoke];
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
+(void)didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
|
|
364
|
-
Class voipManagerClass = NSClassFromString(@"Callingx.VoipNotificationsManager");
|
|
365
|
-
if (!voipManagerClass) {
|
|
366
|
-
// Fallback: Try the unmangled name (might work depending on Swift version)
|
|
367
|
-
voipManagerClass = NSClassFromString(@"VoipNotificationsManager");
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
if (!voipManagerClass) {
|
|
371
|
-
#if DEBUG
|
|
372
|
-
NSLog(@"[StreamVideoReactNative][didReceiveIncomingPushWithPayload] VoipNotificationsManager not available");
|
|
373
|
-
#endif
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
SEL selector = @selector(didReceiveIncomingPushWithPayload:forType:);
|
|
378
|
-
if (![voipManagerClass respondsToSelector:selector]) {
|
|
379
|
-
#if DEBUG
|
|
380
|
-
NSLog(@"[StreamVideoReactNative][didReceiveIncomingPushWithPayload] VoipNotificationsManager does not respond to didReceiveIncomingPushWithPayload:forType:");
|
|
381
|
-
#endif
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
[voipManagerClass didReceiveIncomingPushWithPayload:payload forType:type];
|
|
386
|
-
}
|
|
387
|
-
|
|
388
94
|
-(instancetype)init {
|
|
389
95
|
if ((self = [super init])) {
|
|
390
96
|
_notificationCenter = CFNotificationCenterGetDarwinNotifyCenter();
|
|
@@ -924,7 +630,7 @@ RCT_EXPORT_METHOD(stopInAppScreenCapture:(RCTPromiseResolveBlock)resolve
|
|
|
924
630
|
RCT_EXPORT_METHOD(startScreenShareAudioMixing:(RCTPromiseResolveBlock)resolve
|
|
925
631
|
reject:(RCTPromiseRejectBlock)reject)
|
|
926
632
|
{
|
|
927
|
-
WebRTCModule *webrtcModule = [self.
|
|
633
|
+
WebRTCModule *webrtcModule = [self.moduleRegistry moduleForName:"WebRTCModule"];
|
|
928
634
|
WebRTCModuleOptions *options = [WebRTCModuleOptions sharedInstance];
|
|
929
635
|
|
|
930
636
|
ScreenShareAudioMixer *mixer = webrtcModule.audioDeviceModule.screenShareAudioMixer;
|
|
@@ -955,7 +661,7 @@ RCT_EXPORT_METHOD(startScreenShareAudioMixing:(RCTPromiseResolveBlock)resolve
|
|
|
955
661
|
RCT_EXPORT_METHOD(stopScreenShareAudioMixing:(RCTPromiseResolveBlock)resolve
|
|
956
662
|
reject:(RCTPromiseRejectBlock)reject)
|
|
957
663
|
{
|
|
958
|
-
WebRTCModule *webrtcModule = [self.
|
|
664
|
+
WebRTCModule *webrtcModule = [self.moduleRegistry moduleForName:"WebRTCModule"];
|
|
959
665
|
WebRTCModuleOptions *options = [WebRTCModuleOptions sharedInstance];
|
|
960
666
|
|
|
961
667
|
// Stop feeding audio to the mixer
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-io/video-react-native-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.37.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.
|
|
54
|
-
"@stream-io/video-react-bindings": "1.16.
|
|
53
|
+
"@stream-io/video-client": "1.52.0",
|
|
54
|
+
"@stream-io/video-react-bindings": "1.16.2",
|
|
55
55
|
"intl-pluralrules": "2.0.1",
|
|
56
56
|
"react-native-url-polyfill": "^3.0.0",
|
|
57
57
|
"rxjs": "~7.8.2",
|
|
@@ -107,38 +107,39 @@
|
|
|
107
107
|
}
|
|
108
108
|
},
|
|
109
109
|
"devDependencies": {
|
|
110
|
-
"@babel/core": "^7.
|
|
111
|
-
"@expo/config-plugins": "
|
|
112
|
-
"@expo/config-types": "^
|
|
113
|
-
"@expo/plist": "^0.
|
|
114
|
-
"@react-native-community/netinfo": "
|
|
115
|
-
"@react-native-firebase/app": "^
|
|
116
|
-
"@react-native-firebase/messaging": "^
|
|
117
|
-
"@react-native/babel-preset": "0.
|
|
110
|
+
"@babel/core": "^7.29.7",
|
|
111
|
+
"@expo/config-plugins": "56.0.8",
|
|
112
|
+
"@expo/config-types": "^56.0.5",
|
|
113
|
+
"@expo/plist": "^0.7.0",
|
|
114
|
+
"@react-native-community/netinfo": "12.0.1",
|
|
115
|
+
"@react-native-firebase/app": "^24.0.0",
|
|
116
|
+
"@react-native-firebase/messaging": "^24.0.0",
|
|
117
|
+
"@react-native/babel-preset": "0.85.3",
|
|
118
|
+
"@react-native/metro-config": "0.85.3",
|
|
118
119
|
"@stream-io/noise-cancellation-react-native": "^0.7.0",
|
|
119
|
-
"@stream-io/react-native-callingx": "^0.
|
|
120
|
+
"@stream-io/react-native-callingx": "^0.4.0",
|
|
120
121
|
"@stream-io/react-native-webrtc": "137.2.0",
|
|
121
|
-
"@stream-io/video-filters-react-native": "^0.12.
|
|
122
|
+
"@stream-io/video-filters-react-native": "^0.12.4",
|
|
122
123
|
"@testing-library/jest-native": "^5.4.3",
|
|
123
124
|
"@testing-library/react-native": "13.3.3",
|
|
124
|
-
"@tsconfig/node18": "^18.2.
|
|
125
|
+
"@tsconfig/node18": "^18.2.6",
|
|
125
126
|
"@types/jest": "^29.5.14",
|
|
126
|
-
"@types/react": "~19.
|
|
127
|
+
"@types/react": "~19.2.15",
|
|
127
128
|
"@types/react-test-renderer": "^19.1.0",
|
|
128
|
-
"expo": "~
|
|
129
|
-
"expo-build-properties": "
|
|
130
|
-
"expo-module-scripts": "^
|
|
131
|
-
"expo-notifications": "~0.
|
|
129
|
+
"expo": "~56.0.8",
|
|
130
|
+
"expo-build-properties": "~56.0.16",
|
|
131
|
+
"expo-module-scripts": "^56.0.3",
|
|
132
|
+
"expo-notifications": "~56.0.15",
|
|
132
133
|
"jest": "^29.7.0",
|
|
133
|
-
"react": "19.
|
|
134
|
-
"react-native": "0.
|
|
134
|
+
"react": "19.2.3",
|
|
135
|
+
"react-native": "0.85.3",
|
|
135
136
|
"react-native-builder-bob": "~0.23",
|
|
136
|
-
"react-native-gesture-handler": "
|
|
137
|
-
"react-native-reanimated": "
|
|
138
|
-
"react-native-svg": "
|
|
139
|
-
"react-native-worklets": "
|
|
140
|
-
"react-test-renderer": "19.
|
|
141
|
-
"rimraf": "^6.
|
|
137
|
+
"react-native-gesture-handler": "~2.31.2",
|
|
138
|
+
"react-native-reanimated": "4.3.1",
|
|
139
|
+
"react-native-svg": "15.15.5",
|
|
140
|
+
"react-native-worklets": "0.8.3",
|
|
141
|
+
"react-test-renderer": "19.2.3",
|
|
142
|
+
"rimraf": "^6.1.3",
|
|
142
143
|
"typescript": "^5.9.3"
|
|
143
144
|
},
|
|
144
145
|
"react-native-builder-bob": {
|
|
@@ -257,7 +257,11 @@ export const CallContent = ({
|
|
|
257
257
|
<View style={[styles.container, landscapeStyles, callContent.container]}>
|
|
258
258
|
<View style={[styles.content, callContent.callParticipantsContainer]}>
|
|
259
259
|
<View
|
|
260
|
-
style={[
|
|
260
|
+
style={[
|
|
261
|
+
StyleSheet.absoluteFill,
|
|
262
|
+
styles.view,
|
|
263
|
+
callContent.topContainer,
|
|
264
|
+
]}
|
|
261
265
|
// "box-none" disallows the container view to be not take up touches
|
|
262
266
|
// and allows only the top and floating view (its child views) to take up the touches
|
|
263
267
|
pointerEvents="box-none"
|
|
@@ -310,7 +314,6 @@ const useStyles = () => {
|
|
|
310
314
|
},
|
|
311
315
|
content: { flex: 1 },
|
|
312
316
|
view: {
|
|
313
|
-
...StyleSheet.absoluteFillObject,
|
|
314
317
|
zIndex: Z_INDEX.IN_FRONT,
|
|
315
318
|
},
|
|
316
319
|
}),
|
|
@@ -99,7 +99,7 @@ export const Lobby = ({
|
|
|
99
99
|
mirror={true}
|
|
100
100
|
streamURL={localVideoStream.toURL()}
|
|
101
101
|
objectFit="cover"
|
|
102
|
-
style={StyleSheet.
|
|
102
|
+
style={StyleSheet.absoluteFill}
|
|
103
103
|
/>
|
|
104
104
|
) : (
|
|
105
105
|
<View style={[styles.avatarContainer, lobby.avatarContainer]}>
|
|
@@ -74,6 +74,7 @@ const DefaultLocalParticipantViewVideoFallback = () => {
|
|
|
74
74
|
return (
|
|
75
75
|
<View
|
|
76
76
|
style={[
|
|
77
|
+
StyleSheet.absoluteFill,
|
|
77
78
|
styles.videoFallback,
|
|
78
79
|
{ backgroundColor: colors.sheetSecondary },
|
|
79
80
|
floatingParticipantsView.videoFallback,
|
|
@@ -224,7 +225,6 @@ const styles = StyleSheet.create({
|
|
|
224
225
|
elevation: 4,
|
|
225
226
|
},
|
|
226
227
|
videoFallback: {
|
|
227
|
-
...StyleSheet.absoluteFillObject,
|
|
228
228
|
alignItems: 'center',
|
|
229
229
|
justifyContent: 'center',
|
|
230
230
|
},
|
|
@@ -28,6 +28,7 @@ export const ParticipantVideoFallback = ({
|
|
|
28
28
|
return (
|
|
29
29
|
<View
|
|
30
30
|
style={[
|
|
31
|
+
StyleSheet.absoluteFill,
|
|
31
32
|
styles.container,
|
|
32
33
|
{ backgroundColor: colors.sheetTertiary },
|
|
33
34
|
participantVideoFallback.container,
|
|
@@ -61,6 +62,5 @@ const styles = StyleSheet.create({
|
|
|
61
62
|
container: {
|
|
62
63
|
alignItems: 'center',
|
|
63
64
|
justifyContent: 'center',
|
|
64
|
-
...StyleSheet.absoluteFillObject,
|
|
65
65
|
},
|
|
66
66
|
});
|
|
@@ -194,7 +194,7 @@ export const VideoRenderer = ({
|
|
|
194
194
|
return (
|
|
195
195
|
<View
|
|
196
196
|
onLayout={onLayout}
|
|
197
|
-
style={[
|
|
197
|
+
style={[StyleSheet.absoluteFill, videoRenderer.container]}
|
|
198
198
|
>
|
|
199
199
|
{call && !isLocalParticipant && (
|
|
200
200
|
<TrackSubscriber
|
|
@@ -209,7 +209,7 @@ export const VideoRenderer = ({
|
|
|
209
209
|
videoStreamToRender &&
|
|
210
210
|
(objectFit || isVideoDimensionsValid) ? (
|
|
211
211
|
<RTCView
|
|
212
|
-
style={[
|
|
212
|
+
style={[StyleSheet.absoluteFill, videoRenderer.videoStream]}
|
|
213
213
|
streamURL={videoStreamToRender.toURL()}
|
|
214
214
|
mirror={mirror}
|
|
215
215
|
ref={viewRef}
|
|
@@ -229,12 +229,3 @@ export const VideoRenderer = ({
|
|
|
229
229
|
</View>
|
|
230
230
|
);
|
|
231
231
|
};
|
|
232
|
-
|
|
233
|
-
const styles = StyleSheet.create({
|
|
234
|
-
container: {
|
|
235
|
-
...StyleSheet.absoluteFillObject,
|
|
236
|
-
},
|
|
237
|
-
videoStream: {
|
|
238
|
-
...StyleSheet.absoluteFillObject,
|
|
239
|
-
},
|
|
240
|
-
});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Internal utils for callingx library usage from video-client.
|
|
3
3
|
* See @./registerSDKGlobals.ts for more usage details.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { Platform } from 'react-native';
|
|
6
6
|
import type { EndCallReason } from '@stream-io/react-native-callingx';
|
|
7
7
|
import { getCallingxLibIfAvailable } from '../../push/libs/callingx';
|
|
8
8
|
import { waitForAudioSessionActivation } from './audioSessionPromise';
|
|
@@ -12,17 +12,8 @@ import type {
|
|
|
12
12
|
StreamVideoParticipant,
|
|
13
13
|
} from '@stream-io/video-client';
|
|
14
14
|
import { CallingState, videoLoggerSystem } from '@stream-io/video-client';
|
|
15
|
-
import { StreamVideoRN } from '../../StreamVideoRN';
|
|
16
|
-
const CallingxModule = getCallingxLibIfAvailable();
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
if (Platform.OS === 'android') {
|
|
20
|
-
const nativeModule = NativeModules.StreamVideoAppLifecycle;
|
|
21
|
-
const state = await nativeModule.getCurrentAppState();
|
|
22
|
-
return state === 'active';
|
|
23
|
-
}
|
|
24
|
-
return AppState.currentState !== 'background';
|
|
25
|
-
}
|
|
16
|
+
const CallingxModule = getCallingxLibIfAvailable();
|
|
26
17
|
|
|
27
18
|
/**
|
|
28
19
|
* Gets the call display name. To be used for display in native call screen.
|
|
@@ -148,19 +139,7 @@ export async function joinCallingxCall(call: Call, activeCalls: Call[]) {
|
|
|
148
139
|
}
|
|
149
140
|
} else if (isIncomingCall) {
|
|
150
141
|
logger.debug(`joinCallingxCall: Joining incoming call ${call.cid}`);
|
|
151
|
-
|
|
152
|
-
if (Platform.OS === 'ios') {
|
|
153
|
-
skipIncomingPushInForeground =
|
|
154
|
-
StreamVideoRN.getConfig().push?.ios?.skipIncomingPushInForeground ??
|
|
155
|
-
false;
|
|
156
|
-
} else {
|
|
157
|
-
skipIncomingPushInForeground =
|
|
158
|
-
StreamVideoRN.getConfig().push?.android?.skipIncomingPushInForeground ??
|
|
159
|
-
false;
|
|
160
|
-
}
|
|
161
|
-
const shouldSkipDisplayIncoming = skipIncomingPushInForeground
|
|
162
|
-
? await isAppInForeground()
|
|
163
|
-
: false;
|
|
142
|
+
|
|
164
143
|
try {
|
|
165
144
|
// Leave any existing active ringing calls before joining a new ringing call
|
|
166
145
|
const activeCallsToLeave = activeCalls.filter(
|
|
@@ -177,29 +156,25 @@ export async function joinCallingxCall(call: Call, activeCalls: Call[]) {
|
|
|
177
156
|
logger.error(`failed to leave active call ${activeCall.cid}`, e);
|
|
178
157
|
});
|
|
179
158
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
callDisplayName, // display name for display in call screen
|
|
191
|
-
call.state.settings?.video?.enabled ?? false, // is video call?
|
|
192
|
-
);
|
|
159
|
+
// Awaits native CallKit/Telecom registration before answering.
|
|
160
|
+
// Safe to call even if the call is already registered (e.g. from VoIP push) --
|
|
161
|
+
// iOS early-returns with no error, Android sends the registered broadcast.
|
|
162
|
+
const callDisplayName = getCallDisplayNameFromCall(call);
|
|
163
|
+
await CallingxModule.displayIncomingCall(
|
|
164
|
+
call.cid, // unique id for call
|
|
165
|
+
call.state.createdBy?.id ?? callDisplayName, // handle for native call UI (prefer createdBy user id, fallback to call display name)
|
|
166
|
+
callDisplayName, // display name for display in call screen
|
|
167
|
+
call.state.settings?.video?.enabled ?? false, // is video call?
|
|
168
|
+
);
|
|
193
169
|
|
|
194
|
-
|
|
170
|
+
await CallingxModule.answerIncomingCall(call.cid);
|
|
195
171
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
172
|
+
if (Platform.OS === 'ios') {
|
|
173
|
+
await waitForAudioSessionActivation();
|
|
199
174
|
}
|
|
200
175
|
} catch (error) {
|
|
201
176
|
logger.error(
|
|
202
|
-
`Error joining incoming call in callingx: ${call.cid}
|
|
177
|
+
`Error joining incoming call in callingx: ${call.cid}`,
|
|
203
178
|
error,
|
|
204
179
|
);
|
|
205
180
|
}
|
|
@@ -48,10 +48,9 @@ export const onVoipNotificationReceived = async (
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
const callingx = getCallingxLib();
|
|
51
|
-
if (
|
|
52
|
-
//same call_cid is already tracked, so we skip the notification
|
|
51
|
+
if (pushUnsubscriptionCallbacks.has(call_cid)) {
|
|
53
52
|
logger.debug(
|
|
54
|
-
`the same call_cid ${call_cid} is already
|
|
53
|
+
`the same call_cid ${call_cid} is already being watched, skipping the call.ring notification`,
|
|
55
54
|
);
|
|
56
55
|
return;
|
|
57
56
|
}
|
|
@@ -91,6 +90,7 @@ export const onVoipNotificationReceived = async (
|
|
|
91
90
|
event,
|
|
92
91
|
);
|
|
93
92
|
unsubscribe();
|
|
93
|
+
pushUnsubscriptionCallbacks.delete(call_cid);
|
|
94
94
|
return;
|
|
95
95
|
}
|
|
96
96
|
const _closed = closeCallIfNecessary();
|
|
@@ -100,6 +100,7 @@ export const onVoipNotificationReceived = async (
|
|
|
100
100
|
event,
|
|
101
101
|
);
|
|
102
102
|
unsubscribe();
|
|
103
|
+
pushUnsubscriptionCallbacks.delete(call_cid);
|
|
103
104
|
}
|
|
104
105
|
});
|
|
105
106
|
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.
|
|
1
|
+
export const version = '1.37.0';
|