@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
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { StyleSheet, View, type ViewStyle } from 'react-native';
|
|
3
|
-
import { useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
4
|
-
import {
|
|
3
|
+
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
4
|
+
import { debounceTime } from 'rxjs';
|
|
5
5
|
import {
|
|
6
6
|
CallParticipantsList as DefaultCallParticipantsList,
|
|
7
7
|
type CallParticipantsListComponentProps,
|
|
@@ -49,19 +49,33 @@ export const CallParticipantsGrid = ({
|
|
|
49
49
|
const {
|
|
50
50
|
theme: { colors, callParticipantsGrid },
|
|
51
51
|
} = useTheme();
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
useParticipants,
|
|
55
|
-
useLocalParticipant,
|
|
56
|
-
useDominantSpeaker,
|
|
57
|
-
} = useCallStateHooks();
|
|
58
|
-
const _remoteParticipants = useRemoteParticipants();
|
|
52
|
+
const call = useCall();
|
|
53
|
+
const { useLocalParticipant, useDominantSpeaker } = useCallStateHooks();
|
|
59
54
|
const localParticipant = useLocalParticipant();
|
|
60
|
-
const _allParticipants = useParticipants();
|
|
61
55
|
const dominantSpeaker = useDominantSpeaker();
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
const [remoteParticipants, setRemoteParticipants] = useState<
|
|
57
|
+
StreamVideoParticipant[]
|
|
58
|
+
>(() => call?.state.remoteParticipants ?? []);
|
|
59
|
+
const [allParticipants, setAllParticipants] = useState<
|
|
60
|
+
StreamVideoParticipant[]
|
|
61
|
+
>(() => call?.state.participants ?? []);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!call) {
|
|
64
|
+
setRemoteParticipants([]);
|
|
65
|
+
setAllParticipants([]);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const sub1 = call.state.remoteParticipants$
|
|
69
|
+
.pipe(debounceTime(300))
|
|
70
|
+
.subscribe(setRemoteParticipants);
|
|
71
|
+
const sub2 = call.state.participants$
|
|
72
|
+
.pipe(debounceTime(300))
|
|
73
|
+
.subscribe(setAllParticipants);
|
|
74
|
+
return () => {
|
|
75
|
+
sub1.unsubscribe();
|
|
76
|
+
sub2.unsubscribe();
|
|
77
|
+
};
|
|
78
|
+
}, [call]);
|
|
65
79
|
const landscapeStyles: ViewStyle = {
|
|
66
80
|
flexDirection: landscape ? 'row' : 'column',
|
|
67
81
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import React, { useMemo } from 'react';
|
|
1
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
hasScreenShare,
|
|
4
|
-
|
|
4
|
+
type StreamVideoParticipant,
|
|
5
5
|
} from '@stream-io/video-client';
|
|
6
|
-
import {
|
|
6
|
+
import { useCall } from '@stream-io/video-react-bindings';
|
|
7
7
|
import { StyleSheet, View, type ViewStyle } from 'react-native';
|
|
8
|
-
import {
|
|
8
|
+
import { debounceTime } from 'rxjs';
|
|
9
9
|
import { ComponentTestIds } from '../../../constants/TestIds';
|
|
10
10
|
import {
|
|
11
11
|
CallParticipantsList as DefaultCallParticipantsList,
|
|
@@ -56,15 +56,24 @@ export const CallParticipantsSpotlight = ({
|
|
|
56
56
|
theme: { callParticipantsSpotlight, variants },
|
|
57
57
|
} = useTheme();
|
|
58
58
|
const styles = useStyles();
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
const call = useCall();
|
|
60
|
+
const [allParticipants, setAllParticipants] = useState<
|
|
61
|
+
StreamVideoParticipant[]
|
|
62
|
+
>(() => call?.state.participants ?? []);
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (!call) {
|
|
65
|
+
setAllParticipants([]);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const sub = call.state.participants$
|
|
69
|
+
.pipe(debounceTime(300))
|
|
70
|
+
.subscribe(setAllParticipants);
|
|
71
|
+
return () => sub.unsubscribe();
|
|
72
|
+
}, [call]);
|
|
64
73
|
const [participantInSpotlight, ...otherParticipants] = allParticipants;
|
|
65
74
|
const isScreenShareOnSpotlight =
|
|
66
75
|
participantInSpotlight && hasScreenShare(participantInSpotlight);
|
|
67
|
-
const isUserAloneInCall =
|
|
76
|
+
const isUserAloneInCall = allParticipants.length === 1;
|
|
68
77
|
|
|
69
78
|
const isInPiP = useIsInPiPMode();
|
|
70
79
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, {
|
|
2
2
|
useCallback,
|
|
3
|
+
useEffect,
|
|
3
4
|
useMemo,
|
|
4
|
-
useReducer,
|
|
5
5
|
useRef,
|
|
6
6
|
useState,
|
|
7
7
|
} from 'react';
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
type StreamVideoParticipantPatches,
|
|
18
18
|
VisibilityState,
|
|
19
19
|
} from '@stream-io/video-client';
|
|
20
|
-
import {
|
|
20
|
+
import { Subject, debounceTime } from 'rxjs';
|
|
21
21
|
import { useCall } from '@stream-io/video-react-bindings';
|
|
22
22
|
import { ComponentTestIds } from '../../../constants/TestIds';
|
|
23
23
|
import {
|
|
@@ -104,9 +104,24 @@ export const CallParticipantsList = ({
|
|
|
104
104
|
// we use a HashSet to track the currently viewable participants
|
|
105
105
|
// and a separate force update state to rerender the component to inform that the HashSet has changed
|
|
106
106
|
// NOTE: we use set instead of array or object for O(1) lookup, add and delete
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
|
|
107
|
+
// Lazy ref init: avoids recreating instances on every render (useRef doesn't support initializer fns)
|
|
108
|
+
const viewableParticipantSessionIds = useRef<Set<string>>(null!);
|
|
109
|
+
if (!viewableParticipantSessionIds.current) {
|
|
110
|
+
viewableParticipantSessionIds.current = new Set();
|
|
111
|
+
}
|
|
112
|
+
const forceUpdate$Ref = useRef<Subject<void>>(null!);
|
|
113
|
+
if (!forceUpdate$Ref.current) {
|
|
114
|
+
forceUpdate$Ref.current = new Subject<void>();
|
|
115
|
+
}
|
|
116
|
+
const forceUpdate$ = forceUpdate$Ref.current;
|
|
117
|
+
const [forceUpdateValue, setForceUpdateValue] = useState(0);
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
const sub = forceUpdate$.pipe(debounceTime(500)).subscribe(() => {
|
|
120
|
+
setForceUpdateValue((v) => v + 1);
|
|
121
|
+
});
|
|
122
|
+
return () => sub.unsubscribe();
|
|
123
|
+
}, [forceUpdate$]);
|
|
124
|
+
const forceUpdate = useCallback(() => forceUpdate$.next(), [forceUpdate$]);
|
|
110
125
|
|
|
111
126
|
// we use a ref to store the active call object
|
|
112
127
|
// so that it can be used in the onViewableItemsChanged callback
|
package/src/hooks/push/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useIosVoipPushEventsSetupEffect } from './useIosVoipPushEventsSetupEffect';
|
|
2
|
+
import { useProcessPushCallEffect } from './useProcessPushCallEffect';
|
|
2
3
|
import { useInitAndroidTokenAndRest } from './useInitAndroidTokenAndRest';
|
|
3
4
|
import { useIosInitRemoteNotifications } from './useIosInitRemoteNotifications';
|
|
4
5
|
import { useProcessPushNonRingingCallEffect } from './useProcessPushNonRingingCallEffect';
|
|
@@ -11,5 +12,6 @@ export const usePushRegisterEffect = () => {
|
|
|
11
12
|
useIosInitRemoteNotifications();
|
|
12
13
|
useIosVoipPushEventsSetupEffect();
|
|
13
14
|
useProcessPushNonRingingCallEffect();
|
|
15
|
+
useProcessPushCallEffect();
|
|
14
16
|
useInitAndroidTokenAndRest();
|
|
15
17
|
};
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CallingState,
|
|
3
|
+
RxUtils,
|
|
4
|
+
videoLoggerSystem,
|
|
5
|
+
} from '@stream-io/video-client';
|
|
6
|
+
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
7
|
+
import { NativeModules, Platform } from 'react-native';
|
|
8
|
+
import { useEffect, useState } from 'react';
|
|
9
|
+
import { StreamVideoRN } from '../../utils';
|
|
10
|
+
import { getCallKeepLib } from '../../utils/push/libs';
|
|
11
|
+
import {
|
|
12
|
+
voipCallkeepAcceptedCallOnNativeDialerMap$,
|
|
13
|
+
voipCallkeepCallOnForegroundMap$,
|
|
14
|
+
voipPushNotificationCallCId$,
|
|
15
|
+
} from '../../utils/push/internal/rxSubjects';
|
|
16
|
+
|
|
17
|
+
const isNonActiveCallingState = (callingState: CallingState) => {
|
|
18
|
+
return (
|
|
19
|
+
callingState === CallingState.IDLE ||
|
|
20
|
+
callingState === CallingState.UNKNOWN ||
|
|
21
|
+
callingState === CallingState.LEFT
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const isAcceptedCallingState = (callingState: CallingState) => {
|
|
26
|
+
return (
|
|
27
|
+
callingState === CallingState.JOINING ||
|
|
28
|
+
callingState === CallingState.JOINED
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const unsubscribeCallkeepEvents = async (activeCallCid: string | undefined) => {
|
|
33
|
+
const voipPushNotificationCallCId = RxUtils.getCurrentValue(
|
|
34
|
+
voipPushNotificationCallCId$,
|
|
35
|
+
);
|
|
36
|
+
if (activeCallCid && activeCallCid === voipPushNotificationCallCId) {
|
|
37
|
+
// callkeep events should not be listened anymore so clear the call cid
|
|
38
|
+
voipPushNotificationCallCId$.next(undefined);
|
|
39
|
+
}
|
|
40
|
+
return await NativeModules.StreamVideoReactNative?.removeIncomingCall(
|
|
41
|
+
activeCallCid,
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const logger = videoLoggerSystem.getLogger(
|
|
46
|
+
'useIosCallkeepWithCallingStateEffect',
|
|
47
|
+
);
|
|
48
|
+
const log = (message: string) => {
|
|
49
|
+
logger.warn(message);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* This hook is used to inform the callkeep library that the call has been joined or ended.
|
|
54
|
+
*/
|
|
55
|
+
export const useIosCallkeepWithCallingStateEffect = () => {
|
|
56
|
+
const activeCall = useCall();
|
|
57
|
+
const { useCallCallingState } = useCallStateHooks();
|
|
58
|
+
const callingState = useCallCallingState();
|
|
59
|
+
const [acceptedForegroundCallkeepMap, setAcceptedForegroundCallkeepMap] =
|
|
60
|
+
useState<{
|
|
61
|
+
uuid: string;
|
|
62
|
+
cid: string;
|
|
63
|
+
}>();
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
return () => {
|
|
67
|
+
const pushConfig = StreamVideoRN.getConfig().push;
|
|
68
|
+
if (
|
|
69
|
+
Platform.OS !== 'ios' ||
|
|
70
|
+
!pushConfig ||
|
|
71
|
+
!pushConfig.ios?.pushProviderName
|
|
72
|
+
) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (!pushConfig.android.incomingCallChannel) {
|
|
76
|
+
// TODO: remove this check and find a better way once we have telecom integration for android
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const callkeep = getCallKeepLib();
|
|
81
|
+
// if the component is unmounted and the callID was not reported to callkeep, then report it now
|
|
82
|
+
if (acceptedForegroundCallkeepMap) {
|
|
83
|
+
log(
|
|
84
|
+
`Ending call in callkeep: ${acceptedForegroundCallkeepMap.cid}, reason: component unmounted and call was present in acceptedForegroundCallkeepMap`,
|
|
85
|
+
);
|
|
86
|
+
unsubscribeCallkeepEvents(acceptedForegroundCallkeepMap.cid).then(() =>
|
|
87
|
+
callkeep.endCall(acceptedForegroundCallkeepMap.uuid),
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}, [acceptedForegroundCallkeepMap]);
|
|
92
|
+
|
|
93
|
+
const activeCallCid = activeCall?.cid;
|
|
94
|
+
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
return () => {
|
|
97
|
+
const pushConfig = StreamVideoRN.getConfig().push;
|
|
98
|
+
if (
|
|
99
|
+
Platform.OS !== 'ios' ||
|
|
100
|
+
!pushConfig ||
|
|
101
|
+
!pushConfig.ios?.pushProviderName ||
|
|
102
|
+
!activeCallCid
|
|
103
|
+
) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (!pushConfig.android.incomingCallChannel) {
|
|
107
|
+
// TODO: remove this check and find a better way once we have telecom integration for android
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const nativeDialerAcceptedCallMap = RxUtils.getCurrentValue(
|
|
111
|
+
voipCallkeepAcceptedCallOnNativeDialerMap$,
|
|
112
|
+
);
|
|
113
|
+
const foregroundIncomingCallkeepMap = RxUtils.getCurrentValue(
|
|
114
|
+
voipCallkeepCallOnForegroundMap$,
|
|
115
|
+
);
|
|
116
|
+
const callkeep = getCallKeepLib();
|
|
117
|
+
if (activeCallCid === nativeDialerAcceptedCallMap?.cid) {
|
|
118
|
+
log(
|
|
119
|
+
`Ending call in callkeep: ${activeCallCid}, reason: activeCallCid changed or was removed and call was present in nativeDialerAcceptedCallMap`,
|
|
120
|
+
);
|
|
121
|
+
unsubscribeCallkeepEvents(activeCallCid).then(() =>
|
|
122
|
+
callkeep.endCall(nativeDialerAcceptedCallMap.uuid),
|
|
123
|
+
);
|
|
124
|
+
// no need to keep this reference anymore
|
|
125
|
+
voipCallkeepAcceptedCallOnNativeDialerMap$.next(undefined);
|
|
126
|
+
} else if (activeCallCid === foregroundIncomingCallkeepMap?.cid) {
|
|
127
|
+
log(
|
|
128
|
+
`Ending call in callkeep: ${activeCallCid}, reason: activeCallCid changed or was removed and call was present in foregroundIncomingCallkeepMap`,
|
|
129
|
+
);
|
|
130
|
+
unsubscribeCallkeepEvents(activeCallCid).then(() =>
|
|
131
|
+
callkeep.endCall(foregroundIncomingCallkeepMap.uuid),
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}, [activeCallCid]);
|
|
136
|
+
|
|
137
|
+
const pushConfig = StreamVideoRN.getConfig().push;
|
|
138
|
+
if (
|
|
139
|
+
Platform.OS !== 'ios' ||
|
|
140
|
+
!pushConfig ||
|
|
141
|
+
!pushConfig.ios.pushProviderName ||
|
|
142
|
+
!activeCallCid
|
|
143
|
+
) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (!pushConfig.android.incomingCallChannel) {
|
|
147
|
+
// TODO: remove this check and find a better way once we have telecom integration for android
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Check if current call is still needed to be accepted in callkeep
|
|
153
|
+
*/
|
|
154
|
+
if (
|
|
155
|
+
isAcceptedCallingState(callingState) &&
|
|
156
|
+
acceptedForegroundCallkeepMap?.cid !== activeCallCid
|
|
157
|
+
) {
|
|
158
|
+
const callkeep = getCallKeepLib();
|
|
159
|
+
// push notification was displayed
|
|
160
|
+
// but the call has been accepted through the app and not through the native dialer
|
|
161
|
+
const foregroundCallkeepMap = RxUtils.getCurrentValue(
|
|
162
|
+
voipCallkeepCallOnForegroundMap$,
|
|
163
|
+
);
|
|
164
|
+
if (foregroundCallkeepMap && foregroundCallkeepMap.cid === activeCallCid) {
|
|
165
|
+
log(
|
|
166
|
+
// @ts-expect-error - types issue
|
|
167
|
+
`Accepting call in callkeep: ${activeCallCid}, reason: callingstate went to ${CallingState[callingState]} and call was present in foregroundCallkeepMap`,
|
|
168
|
+
);
|
|
169
|
+
// no need to keep this reference anymore
|
|
170
|
+
voipCallkeepCallOnForegroundMap$.next(undefined);
|
|
171
|
+
NativeModules.StreamVideoReactNative?.removeIncomingCall(
|
|
172
|
+
activeCallCid,
|
|
173
|
+
).then(() => callkeep.answerIncomingCall(foregroundCallkeepMap.uuid));
|
|
174
|
+
// this call should be accepted in callkeep
|
|
175
|
+
setAcceptedForegroundCallkeepMap(foregroundCallkeepMap);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Check if current call is still needed to be ended in callkeep
|
|
181
|
+
*/
|
|
182
|
+
if (isNonActiveCallingState(callingState)) {
|
|
183
|
+
const callkeep = getCallKeepLib();
|
|
184
|
+
|
|
185
|
+
// this was a previously joined call which had push notification displayed
|
|
186
|
+
// the call was accepted through the app and not through native dialer
|
|
187
|
+
// the call was left using the leave button in the app and not through native dialer
|
|
188
|
+
if (activeCallCid === acceptedForegroundCallkeepMap?.cid) {
|
|
189
|
+
log(
|
|
190
|
+
// @ts-expect-error - types issue
|
|
191
|
+
`Ending call in callkeep: ${activeCallCid}, reason: callingstate went to ${CallingState[callingState]} and call was present in acceptedForegroundCallkeepMap`,
|
|
192
|
+
);
|
|
193
|
+
unsubscribeCallkeepEvents(activeCallCid).then(() =>
|
|
194
|
+
callkeep.endCall(acceptedForegroundCallkeepMap.uuid),
|
|
195
|
+
);
|
|
196
|
+
setAcceptedForegroundCallkeepMap(undefined);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
// this was a call which had push notification displayed but never joined
|
|
200
|
+
// the user rejected in the app and not from native dialer
|
|
201
|
+
const foregroundIncomingCallkeepMap = RxUtils.getCurrentValue(
|
|
202
|
+
voipCallkeepCallOnForegroundMap$,
|
|
203
|
+
);
|
|
204
|
+
if (activeCallCid === foregroundIncomingCallkeepMap?.cid) {
|
|
205
|
+
log(
|
|
206
|
+
// @ts-expect-error - types issue
|
|
207
|
+
`Ending call in callkeep: ${activeCallCid}, reason: callingstate went to ${CallingState[callingState]} and call was present in foregroundIncomingCallkeepMap`,
|
|
208
|
+
);
|
|
209
|
+
unsubscribeCallkeepEvents(activeCallCid).then(() =>
|
|
210
|
+
callkeep.endCall(foregroundIncomingCallkeepMap.uuid),
|
|
211
|
+
);
|
|
212
|
+
// no need to keep this reference anymore
|
|
213
|
+
voipCallkeepCallOnForegroundMap$.next(undefined);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
// this was a previously joined call
|
|
217
|
+
// it was an accepted call from native dialer and not from the app
|
|
218
|
+
// the user left using the leave button in the app
|
|
219
|
+
const nativeDialerAcceptedCallMap = RxUtils.getCurrentValue(
|
|
220
|
+
voipCallkeepAcceptedCallOnNativeDialerMap$,
|
|
221
|
+
);
|
|
222
|
+
if (activeCallCid === nativeDialerAcceptedCallMap?.cid) {
|
|
223
|
+
log(
|
|
224
|
+
// @ts-expect-error - types issue
|
|
225
|
+
`Ending call in callkeep: ${activeCallCid}, reason: callingstate went to ${CallingState[callingState]} and call was present in nativeDialerAcceptedCallMap`,
|
|
226
|
+
);
|
|
227
|
+
unsubscribeCallkeepEvents(activeCallCid).then(() =>
|
|
228
|
+
callkeep.endCall(nativeDialerAcceptedCallMap.uuid),
|
|
229
|
+
);
|
|
230
|
+
// no need to keep this reference anymore
|
|
231
|
+
voipCallkeepAcceptedCallOnNativeDialerMap$.next(undefined);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type MutableRefObject, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { getVoipPushNotificationLib } from '../../utils/push/libs';
|
|
3
|
+
|
|
2
4
|
import { Platform } from 'react-native';
|
|
3
5
|
import { StreamVideoRN } from '../../utils';
|
|
4
6
|
import { onVoipNotificationReceived } from '../../utils/push/internal/ios';
|
|
@@ -8,7 +10,6 @@ import {
|
|
|
8
10
|
} from '@stream-io/video-react-bindings';
|
|
9
11
|
import { setPushLogoutCallback } from '../../utils/internal/pushLogoutCallback';
|
|
10
12
|
import { StreamVideoClient, videoLoggerSystem } from '@stream-io/video-client';
|
|
11
|
-
import { getCallingxLibIfAvailable } from '../../utils/push/libs';
|
|
12
13
|
|
|
13
14
|
const logger = videoLoggerSystem.getLogger('useIosVoipPushEventsSetupEffect');
|
|
14
15
|
|
|
@@ -27,7 +28,6 @@ function setLogoutCallback(
|
|
|
27
28
|
lastVoipTokenRef.current = { token: '', userId: '' };
|
|
28
29
|
try {
|
|
29
30
|
await client.removeDevice(token);
|
|
30
|
-
logger.debug('PushLogoutCallback - Removed voip token', token);
|
|
31
31
|
} catch (err) {
|
|
32
32
|
logger.warn('PushLogoutCallback - Failed to remove voip token', err);
|
|
33
33
|
}
|
|
@@ -89,12 +89,24 @@ export const useIosVoipPushEventsSetupEffect = () => {
|
|
|
89
89
|
useEffect(() => {
|
|
90
90
|
const pushConfig = StreamVideoRN.getConfig().push;
|
|
91
91
|
const pushProviderName = pushConfig?.ios.pushProviderName;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
if (Platform.OS !== 'ios' || !client || !pushProviderName) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (!pushConfig.android.incomingCallChannel) {
|
|
96
|
+
// TODO: remove this check and find a better way once we have telecom integration for android
|
|
97
|
+
logger.debug(
|
|
98
|
+
'android incomingCallChannel is not defined, so skipping the useIosVoipPushEventsSetupEffect',
|
|
99
|
+
);
|
|
95
100
|
return;
|
|
96
101
|
}
|
|
97
102
|
|
|
103
|
+
const voipPushNotification = getVoipPushNotificationLib();
|
|
104
|
+
|
|
105
|
+
// even though we do this natively, we have to still register here again
|
|
106
|
+
// natively this will make sure "register" event for JS is sent with the last push token
|
|
107
|
+
// Necessary if client changed before we got the event here or user logged out and logged in again
|
|
108
|
+
voipPushNotification.registerVoipToken();
|
|
109
|
+
|
|
98
110
|
const onTokenReceived = (token: string) => {
|
|
99
111
|
const userId = client.streamClient._user?.id ?? '';
|
|
100
112
|
if (client.streamClient.anonymous || !token || !userId) {
|
|
@@ -133,24 +145,24 @@ export const useIosVoipPushEventsSetupEffect = () => {
|
|
|
133
145
|
});
|
|
134
146
|
};
|
|
135
147
|
// fired when PushKit give us the latest token
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
onTokenReceived(token);
|
|
140
|
-
},
|
|
141
|
-
);
|
|
148
|
+
voipPushNotification.addEventListener('register', (token) => {
|
|
149
|
+
onTokenReceived(token);
|
|
150
|
+
});
|
|
142
151
|
|
|
143
|
-
// this will
|
|
144
|
-
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
152
|
+
// this will fire when there are events occured before js bridge initialized
|
|
153
|
+
voipPushNotification.addEventListener('didLoadWithEvents', (events) => {
|
|
154
|
+
if (!events || !Array.isArray(events) || events.length < 1) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
for (const voipPushEvent of events) {
|
|
158
|
+
const { name, data } = voipPushEvent;
|
|
159
|
+
if (name === 'RNVoipPushRemoteNotificationsRegisteredEvent') {
|
|
160
|
+
onTokenReceived(data);
|
|
161
|
+
} else if (name === 'RNVoipPushRemoteNotificationReceivedEvent') {
|
|
162
|
+
onVoipNotificationReceived(data, pushConfig);
|
|
163
|
+
}
|
|
149
164
|
}
|
|
150
165
|
});
|
|
151
|
-
|
|
152
|
-
callingx.registerVoipToken();
|
|
153
|
-
|
|
154
166
|
lastListener.count += 1;
|
|
155
167
|
const currentListenerCount = lastListener.count;
|
|
156
168
|
|
|
@@ -163,7 +175,8 @@ export const useIosVoipPushEventsSetupEffect = () => {
|
|
|
163
175
|
return;
|
|
164
176
|
}
|
|
165
177
|
logger.debug(`Voip event listeners are removed for user: ${userId}`);
|
|
166
|
-
|
|
178
|
+
voipPushNotification.removeEventListener('didLoadWithEvents');
|
|
179
|
+
voipPushNotification.removeEventListener('register');
|
|
167
180
|
};
|
|
168
181
|
}, [client]);
|
|
169
182
|
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {
|
|
2
|
+
pushAcceptedIncomingCallCId$,
|
|
3
|
+
pushAndroidBackgroundDeliveredIncomingCallCId$,
|
|
4
|
+
pushRejectedIncomingCallCId$,
|
|
5
|
+
pushTappedIncomingCallCId$,
|
|
6
|
+
} from '../../utils/push/internal/rxSubjects';
|
|
7
|
+
import { useEffect } from 'react';
|
|
8
|
+
import { StreamVideoRN } from '../../utils';
|
|
9
|
+
import {
|
|
10
|
+
useConnectedUser,
|
|
11
|
+
useStreamVideoClient,
|
|
12
|
+
} from '@stream-io/video-react-bindings';
|
|
13
|
+
import { BehaviorSubject } from 'rxjs';
|
|
14
|
+
import { distinctUntilChanged, filter } from 'rxjs/operators';
|
|
15
|
+
import { processCallFromPush } from '../../utils/push/internal/utils';
|
|
16
|
+
import { StreamVideoClient, videoLoggerSystem } from '@stream-io/video-client';
|
|
17
|
+
import type { StreamVideoConfig } from '../../utils/StreamVideoRN/types';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* This hook is used to process the incoming call data via push notifications using the relevant rxjs subjects
|
|
21
|
+
* It either joins or leaves the call based on the user's action.
|
|
22
|
+
* Note: this effect cannot work when push notifications are received when the app is in quit state or in other words when the client is not connected with a websocket.
|
|
23
|
+
* So we essentially run this effect only when the client is connected with a websocket.
|
|
24
|
+
*/
|
|
25
|
+
export const useProcessPushCallEffect = () => {
|
|
26
|
+
const client = useStreamVideoClient();
|
|
27
|
+
const connectedUserId = useConnectedUser()?.id;
|
|
28
|
+
// The Effect to join/reject call automatically when incoming call was received and processed from push notification
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const pushConfig = StreamVideoRN.getConfig().push;
|
|
31
|
+
if (!pushConfig || !client || !connectedUserId) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
videoLoggerSystem
|
|
36
|
+
.getLogger('useProcessPushCallEffect')
|
|
37
|
+
.debug(
|
|
38
|
+
`Adding subscriptions to process incoming call from push notification`,
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// if the user accepts the call from push notification we join the call
|
|
42
|
+
const acceptedCallSubscription = createCallSubscription(
|
|
43
|
+
pushAcceptedIncomingCallCId$,
|
|
44
|
+
client,
|
|
45
|
+
pushConfig,
|
|
46
|
+
'accept',
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// if the user rejects the call from push notification we leave the call
|
|
50
|
+
const declinedCallSubscription = createCallSubscription(
|
|
51
|
+
pushRejectedIncomingCallCId$,
|
|
52
|
+
client,
|
|
53
|
+
pushConfig,
|
|
54
|
+
'decline',
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// if the user taps the call from push notification we do nothing as the only thing is to get the call which adds it to the client
|
|
58
|
+
const pressedCallSubscription = createCallSubscription(
|
|
59
|
+
pushTappedIncomingCallCId$,
|
|
60
|
+
client,
|
|
61
|
+
pushConfig,
|
|
62
|
+
'pressed',
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const backgroundIncomingDeliveredCallSubscription = createCallSubscription(
|
|
66
|
+
pushAndroidBackgroundDeliveredIncomingCallCId$,
|
|
67
|
+
client,
|
|
68
|
+
pushConfig,
|
|
69
|
+
'backgroundDelivered',
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
return () => {
|
|
73
|
+
acceptedCallSubscription.unsubscribe();
|
|
74
|
+
declinedCallSubscription.unsubscribe();
|
|
75
|
+
pressedCallSubscription.unsubscribe();
|
|
76
|
+
backgroundIncomingDeliveredCallSubscription.unsubscribe();
|
|
77
|
+
};
|
|
78
|
+
}, [client, connectedUserId]);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* A type guard to check if the cid is not undefined
|
|
83
|
+
*/
|
|
84
|
+
function cidIsNotUndefined(cid: string | undefined): cid is string {
|
|
85
|
+
return cid !== undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The common logic to create a subscription for the given call cid and action
|
|
90
|
+
*/
|
|
91
|
+
const createCallSubscription = (
|
|
92
|
+
behaviourSubjectWithCallCid: BehaviorSubject<string | undefined>,
|
|
93
|
+
client: StreamVideoClient,
|
|
94
|
+
pushConfig: NonNullable<StreamVideoConfig['push']>,
|
|
95
|
+
action: 'accept' | 'decline' | 'pressed' | 'backgroundDelivered',
|
|
96
|
+
) => {
|
|
97
|
+
return behaviourSubjectWithCallCid
|
|
98
|
+
.pipe(distinctUntilChanged(), filter(cidIsNotUndefined))
|
|
99
|
+
.subscribe(async (callCId) => {
|
|
100
|
+
videoLoggerSystem
|
|
101
|
+
.getLogger('useProcessPushCallEffect')
|
|
102
|
+
.debug(
|
|
103
|
+
`Processing call from push notification with action: ${action} and callCId: ${callCId}`,
|
|
104
|
+
);
|
|
105
|
+
await processCallFromPush(client, callCId, action, pushConfig);
|
|
106
|
+
behaviourSubjectWithCallCid.next(undefined); // remove the current call id to avoid processing again
|
|
107
|
+
});
|
|
108
|
+
};
|