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