@stream-io/video-react-native-sdk 1.31.1-beta.0 → 1.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -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/Participant/ParticipantView/ParticipantLabel.js +2 -6
- package/dist/commonjs/components/Participant/ParticipantView/ParticipantLabel.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 -35
- package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/commonjs/utils/internal/registerSDKGlobals.js +3 -53
- package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/commonjs/utils/push/android.js +202 -135
- 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 +53 -71
- 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/Participant/ParticipantView/ParticipantLabel.js +2 -6
- package/dist/module/components/Participant/ParticipantView/ParticipantLabel.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 -35
- package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/module/utils/internal/registerSDKGlobals.js +3 -53
- package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/module/utils/push/android.js +204 -137
- 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 +50 -67
- 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/Participant/ParticipantView/ParticipantLabel.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 -22
- package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/types.d.ts +25 -59
- package/dist/typescript/utils/StreamVideoRN/types.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 +8 -14
- 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/firebaseMessaging/index.d.ts +2 -16
- package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts.map +1 -1
- 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/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 +16 -11
- package/src/components/Participant/ParticipantView/ParticipantLabel.tsx +2 -7
- 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 -42
- package/src/utils/StreamVideoRN/types.ts +25 -61
- package/src/utils/internal/registerSDKGlobals.ts +4 -52
- package/src/utils/push/android.ts +311 -198
- 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 +64 -108
- 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 -144
- package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js.map +0 -1
- package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js +0 -68
- package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js.map +0 -1
- package/dist/commonjs/utils/internal/callingx/callingx.js +0 -150
- 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 -105
- package/dist/commonjs/utils/push/setupCallingExpEvents.js.map +0 -1
- package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js +0 -137
- package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js.map +0 -1
- package/dist/module/utils/internal/callingx/audioSessionPromise.js +0 -61
- package/dist/module/utils/internal/callingx/audioSessionPromise.js.map +0 -1
- package/dist/module/utils/internal/callingx/callingx.js +0 -140
- 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 -99
- 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/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 -18
- 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 -189
- package/src/utils/internal/callingx/audioSessionPromise.ts +0 -65
- package/src/utils/internal/callingx/callingx.ts +0 -194
- package/src/utils/keepCallAliveHeadlessTask.ts +0 -54
- package/src/utils/push/libs/callingx.ts +0 -89
- package/src/utils/push/setupCallingExpEvents.ts +0 -135
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import {
|
|
2
|
+
pushAcceptedIncomingCallCId$,
|
|
3
|
+
voipCallkeepAcceptedCallOnNativeDialerMap$,
|
|
4
|
+
voipCallkeepCallOnForegroundMap$,
|
|
5
|
+
voipPushNotificationCallCId$,
|
|
6
|
+
} from './internal/rxSubjects';
|
|
7
|
+
import { RxUtils, videoLoggerSystem } from '@stream-io/video-client';
|
|
8
|
+
import { getCallKeepLib, getVoipPushNotificationLib } from './libs';
|
|
9
|
+
import type { StreamVideoConfig } from '../StreamVideoRN/types';
|
|
10
|
+
import {
|
|
11
|
+
clearPushWSEventSubscriptions,
|
|
12
|
+
processCallFromPushInBackground,
|
|
13
|
+
} from './internal/utils';
|
|
14
|
+
import { AppState, NativeModules, Platform } from 'react-native';
|
|
15
|
+
import { RTCAudioSession } from '@stream-io/react-native-webrtc';
|
|
16
|
+
import { setPushLogoutCallback } from '../internal/pushLogoutCallback';
|
|
17
|
+
|
|
18
|
+
type PushConfig = NonNullable<StreamVideoConfig['push']>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* This hook is used to listen to callkeep events and do the necessary actions
|
|
22
|
+
*/
|
|
23
|
+
export function setupIosCallKeepEvents(
|
|
24
|
+
pushConfig: NonNullable<StreamVideoConfig['push']>,
|
|
25
|
+
) {
|
|
26
|
+
if (Platform.OS !== 'ios' || !pushConfig.ios.pushProviderName) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (!pushConfig.android.incomingCallChannel) {
|
|
30
|
+
// TODO: remove this check and find a better way once we have telecom integration for android
|
|
31
|
+
videoLoggerSystem
|
|
32
|
+
.getLogger('setupIosCallKeepEvents')
|
|
33
|
+
.debug(
|
|
34
|
+
'android incomingCallChannel is not defined, so skipping the setupIosCallKeepEvents',
|
|
35
|
+
);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const logger = videoLoggerSystem.getLogger('setupIosCallKeepEvents');
|
|
39
|
+
const callkeep = getCallKeepLib();
|
|
40
|
+
|
|
41
|
+
async function getCallCid(callUUID: string): Promise<string | undefined> {
|
|
42
|
+
try {
|
|
43
|
+
const call_cid =
|
|
44
|
+
await NativeModules.StreamVideoReactNative.getIncomingCallCid(callUUID);
|
|
45
|
+
// in a case that voipPushNotificationCallCId$ is empty (this should not happen as voipPushNotificationCallCId$ is updated in push reception)]
|
|
46
|
+
// update it with this call_cid
|
|
47
|
+
const voipPushNotificationCallCId = RxUtils.getCurrentValue(
|
|
48
|
+
voipPushNotificationCallCId$,
|
|
49
|
+
);
|
|
50
|
+
if (!voipPushNotificationCallCId) {
|
|
51
|
+
logger.debug(
|
|
52
|
+
`voipPushNotificationCallCId$ is empty, updating it with the call_cid: ${call_cid} for callUUID: ${callUUID}`,
|
|
53
|
+
);
|
|
54
|
+
voipPushNotificationCallCId$.next(call_cid);
|
|
55
|
+
}
|
|
56
|
+
return call_cid;
|
|
57
|
+
} catch {
|
|
58
|
+
logger.debug(
|
|
59
|
+
`Error in getting call cid from native module for callUUID: ${callUUID} - probably the call was already processed, so ignoring this callkeep event`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function answerCall(callUUID: string) {
|
|
66
|
+
getCallCid(callUUID).then((call_cid) => {
|
|
67
|
+
logger.debug(`answerCall event with call_cid: ${call_cid}`);
|
|
68
|
+
iosCallkeepAcceptCall(call_cid, callUUID);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function endCall(callUUID: string) {
|
|
73
|
+
getCallCid(callUUID).then((call_cid) => {
|
|
74
|
+
logger.debug(`endCall event with call_cid: ${call_cid}`);
|
|
75
|
+
iosCallkeepRejectCall(call_cid, callUUID, pushConfig!);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* CallKeep / CallKit audio-session events -> WebRTC (iOS)
|
|
81
|
+
*
|
|
82
|
+
* iOS CallKit is the authority that *activates* and *deactivates* the underlying `AVAudioSession`
|
|
83
|
+
* when a call is answered/ended from the system UI (lock screen, Call UI, Bluetooth, etc).
|
|
84
|
+
*
|
|
85
|
+
* WebRTC on iOS wraps `AVAudioSession` with `RTCAudioSession` and its AudioDeviceModule relies on
|
|
86
|
+
* being notified of those lifecycle transitions to correctly start/stop audio I/O and keep its
|
|
87
|
+
* internal activation state consistent (e.g. activation count, playout/recording start).
|
|
88
|
+
*
|
|
89
|
+
* If these callbacks don’t reach WebRTC, answering via the native dialer UI can result in:
|
|
90
|
+
* - no microphone capture / one-way audio
|
|
91
|
+
* - silent playout until the app forces an audio reconfiguration
|
|
92
|
+
* - flaky audio routing (speaker/earpiece/Bluetooth) across subsequent calls
|
|
93
|
+
*
|
|
94
|
+
* We forward CallKeep’s `didActivateAudioSession` / `didDeactivateAudioSession` events to WebRTC’s
|
|
95
|
+
* `RTCAudioSession.audioSessionDidActivate()` / `audioSessionDidDeactivate()` methods.
|
|
96
|
+
*/
|
|
97
|
+
function didActivateAudioSession() {
|
|
98
|
+
logger.debug('didActivateAudioSession');
|
|
99
|
+
RTCAudioSession.audioSessionDidActivate();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function didDeactivateAudioSession() {
|
|
103
|
+
logger.debug('didDeactivateAudioSession');
|
|
104
|
+
RTCAudioSession.audioSessionDidDeactivate();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function didDisplayIncomingCall(callUUID: string, payload: object) {
|
|
108
|
+
const voipPushNotification = getVoipPushNotificationLib();
|
|
109
|
+
// @ts-expect-error - call_cid is not part of RNCallKeepEventPayload
|
|
110
|
+
const call_cid = payload?.call_cid as string | undefined;
|
|
111
|
+
logger.debug(
|
|
112
|
+
`didDisplayIncomingCall event with callUUID: ${callUUID} call_cid: ${call_cid}`,
|
|
113
|
+
);
|
|
114
|
+
if (call_cid) {
|
|
115
|
+
if (AppState.currentState === 'background') {
|
|
116
|
+
processCallFromPushInBackground(
|
|
117
|
+
pushConfig!,
|
|
118
|
+
call_cid,
|
|
119
|
+
'backgroundDelivered',
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
voipCallkeepCallOnForegroundMap$.next({
|
|
123
|
+
uuid: callUUID,
|
|
124
|
+
cid: call_cid,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
voipPushNotification.onVoipNotificationCompleted(callUUID);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const { remove: removeAnswerCall } = callkeep.addEventListener(
|
|
131
|
+
'answerCall',
|
|
132
|
+
({ callUUID }) => {
|
|
133
|
+
answerCall(callUUID);
|
|
134
|
+
},
|
|
135
|
+
);
|
|
136
|
+
const { remove: removeEndCall } = callkeep.addEventListener(
|
|
137
|
+
'endCall',
|
|
138
|
+
({ callUUID }) => {
|
|
139
|
+
endCall(callUUID);
|
|
140
|
+
},
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const { remove: removeDisplayIncomingCall } = callkeep.addEventListener(
|
|
144
|
+
'didDisplayIncomingCall',
|
|
145
|
+
({ callUUID, payload }) => {
|
|
146
|
+
didDisplayIncomingCall(callUUID, payload);
|
|
147
|
+
},
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
const { remove: removeDidActivateAudioSession } = callkeep.addEventListener(
|
|
151
|
+
'didActivateAudioSession',
|
|
152
|
+
() => {
|
|
153
|
+
didActivateAudioSession();
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const { remove: removeDidDeactivateAudioSession } = callkeep.addEventListener(
|
|
158
|
+
'didDeactivateAudioSession',
|
|
159
|
+
() => {
|
|
160
|
+
didDeactivateAudioSession();
|
|
161
|
+
},
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
const { remove: removeDidLoadWithEvents } = callkeep.addEventListener(
|
|
165
|
+
'didLoadWithEvents',
|
|
166
|
+
(events) => {
|
|
167
|
+
if (!events || !Array.isArray(events) || events.length < 1) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
events.forEach((event) => {
|
|
172
|
+
const { name, data } = event;
|
|
173
|
+
if (name === 'RNCallKeepDidDisplayIncomingCall') {
|
|
174
|
+
didDisplayIncomingCall(data.callUUID, data.payload);
|
|
175
|
+
} else if (name === 'RNCallKeepPerformAnswerCallAction') {
|
|
176
|
+
answerCall(data.callUUID);
|
|
177
|
+
} else if (name === 'RNCallKeepPerformEndCallAction') {
|
|
178
|
+
endCall(data.callUUID);
|
|
179
|
+
} else if (name === 'RNCallKeepDidActivateAudioSession') {
|
|
180
|
+
didActivateAudioSession();
|
|
181
|
+
} else if (name === 'RNCallKeepDidDeactivateAudioSession') {
|
|
182
|
+
didDeactivateAudioSession();
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
setPushLogoutCallback(async () => {
|
|
189
|
+
removeAnswerCall();
|
|
190
|
+
removeEndCall();
|
|
191
|
+
removeDisplayIncomingCall();
|
|
192
|
+
removeDidActivateAudioSession();
|
|
193
|
+
removeDidDeactivateAudioSession();
|
|
194
|
+
removeDidLoadWithEvents();
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const iosCallkeepAcceptCall = (
|
|
199
|
+
call_cid: string | undefined,
|
|
200
|
+
callUUIDFromCallkeep: string,
|
|
201
|
+
) => {
|
|
202
|
+
if (!shouldProcessCallFromCallkeep(call_cid, callUUIDFromCallkeep)) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
clearPushWSEventSubscriptions(call_cid);
|
|
206
|
+
// to call end callkeep later if ended in app and not through callkeep
|
|
207
|
+
voipCallkeepAcceptedCallOnNativeDialerMap$.next({
|
|
208
|
+
uuid: callUUIDFromCallkeep,
|
|
209
|
+
cid: call_cid,
|
|
210
|
+
});
|
|
211
|
+
// to process the call in the app
|
|
212
|
+
pushAcceptedIncomingCallCId$.next(call_cid);
|
|
213
|
+
// no need to keep these references anymore
|
|
214
|
+
voipCallkeepCallOnForegroundMap$.next(undefined);
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const iosCallkeepRejectCall = async (
|
|
218
|
+
call_cid: string | undefined,
|
|
219
|
+
callUUIDFromCallkeep: string,
|
|
220
|
+
pushConfig: PushConfig,
|
|
221
|
+
) => {
|
|
222
|
+
if (!shouldProcessCallFromCallkeep(call_cid, callUUIDFromCallkeep)) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
clearPushWSEventSubscriptions(call_cid);
|
|
226
|
+
// remove the references if the call_cid matches
|
|
227
|
+
const voipPushNotificationCallCId = RxUtils.getCurrentValue(
|
|
228
|
+
voipPushNotificationCallCId$,
|
|
229
|
+
);
|
|
230
|
+
if (voipPushNotificationCallCId === call_cid) {
|
|
231
|
+
voipCallkeepAcceptedCallOnNativeDialerMap$.next(undefined);
|
|
232
|
+
voipCallkeepCallOnForegroundMap$.next(undefined);
|
|
233
|
+
voipPushNotificationCallCId$.next(undefined);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
await processCallFromPushInBackground(pushConfig, call_cid, 'decline');
|
|
237
|
+
await NativeModules.StreamVideoReactNative?.removeIncomingCall(call_cid);
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Helper function to determine if the answer/end call event from callkeep must be processed
|
|
242
|
+
* Just checks if we have a valid call_cid and acts as a type guard for call_cid
|
|
243
|
+
*/
|
|
244
|
+
const shouldProcessCallFromCallkeep = (
|
|
245
|
+
call_cid: string | undefined,
|
|
246
|
+
callUUIDFromCallkeep: string,
|
|
247
|
+
): call_cid is string => {
|
|
248
|
+
if (!call_cid || !callUUIDFromCallkeep) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
return true;
|
|
252
|
+
};
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { getVoipPushNotificationLib } from './libs';
|
|
2
2
|
|
|
3
3
|
import { Platform } from 'react-native';
|
|
4
4
|
import { onVoipNotificationReceived } from './internal/ios';
|
|
5
5
|
import { setPushLogoutCallback } from '../internal/pushLogoutCallback';
|
|
6
6
|
import { StreamVideoConfig } from '../StreamVideoRN/types';
|
|
7
7
|
import { videoLoggerSystem } from '@stream-io/video-client';
|
|
8
|
-
import { getCallingxLib } from './libs';
|
|
9
8
|
|
|
10
9
|
export function setupIosVoipPushEvents(
|
|
11
10
|
pushConfig: NonNullable<StreamVideoConfig['push']>,
|
|
@@ -21,19 +20,16 @@ export function setupIosVoipPushEvents(
|
|
|
21
20
|
);
|
|
22
21
|
return;
|
|
23
22
|
}
|
|
23
|
+
const voipPushNotification = getVoipPushNotificationLib();
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
onVoipNotificationReceived(params, pushConfig);
|
|
30
|
-
},
|
|
31
|
-
);
|
|
32
|
-
|
|
25
|
+
logger.debug('notification event listener added');
|
|
26
|
+
voipPushNotification.addEventListener('notification', (notification) => {
|
|
27
|
+
onVoipNotificationReceived(notification, pushConfig);
|
|
28
|
+
});
|
|
33
29
|
setPushLogoutCallback(async () => {
|
|
34
30
|
videoLoggerSystem
|
|
35
31
|
.getLogger('setPushLogoutCallback')
|
|
36
32
|
.debug('notification event listener removed');
|
|
37
|
-
|
|
33
|
+
voipPushNotification.removeEventListener('notification');
|
|
38
34
|
});
|
|
39
35
|
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.31.1
|
|
1
|
+
export const version = '1.31.1';
|
package/android/src/main/java/com/streamvideo/reactnative/keepalive/KeepAliveNotification.kt
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
package com.streamvideo.reactnative.keepalive
|
|
2
|
-
|
|
3
|
-
import android.app.Notification
|
|
4
|
-
import android.app.NotificationChannel
|
|
5
|
-
import android.app.NotificationManager
|
|
6
|
-
import android.app.PendingIntent
|
|
7
|
-
import android.content.Context
|
|
8
|
-
import android.content.Intent
|
|
9
|
-
import android.content.pm.PackageManager
|
|
10
|
-
import android.os.Build
|
|
11
|
-
import androidx.core.app.NotificationCompat
|
|
12
|
-
|
|
13
|
-
internal object KeepAliveNotification {
|
|
14
|
-
private const val DEFAULT_CHANNEL_DESCRIPTION = "Stream call keep-alive"
|
|
15
|
-
|
|
16
|
-
fun ensureChannel(
|
|
17
|
-
context: Context,
|
|
18
|
-
channelId: String,
|
|
19
|
-
channelName: String
|
|
20
|
-
) {
|
|
21
|
-
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
|
|
22
|
-
val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
23
|
-
val existing = manager.getNotificationChannel(channelId)
|
|
24
|
-
if (existing != null) return
|
|
25
|
-
|
|
26
|
-
val channel = NotificationChannel(
|
|
27
|
-
channelId,
|
|
28
|
-
channelName,
|
|
29
|
-
NotificationManager.IMPORTANCE_LOW
|
|
30
|
-
).apply {
|
|
31
|
-
description = DEFAULT_CHANNEL_DESCRIPTION
|
|
32
|
-
setShowBadge(false)
|
|
33
|
-
}
|
|
34
|
-
manager.createNotificationChannel(channel)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
fun buildOngoingNotification(
|
|
38
|
-
context: Context,
|
|
39
|
-
channelId: String,
|
|
40
|
-
title: String,
|
|
41
|
-
body: String,
|
|
42
|
-
smallIconName: String?
|
|
43
|
-
): Notification {
|
|
44
|
-
val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)
|
|
45
|
-
val pendingIntentFlags =
|
|
46
|
-
PendingIntent.FLAG_UPDATE_CURRENT or
|
|
47
|
-
PendingIntent.FLAG_IMMUTABLE
|
|
48
|
-
val contentIntent = if (launchIntent != null) {
|
|
49
|
-
PendingIntent.getActivity(context, 0, launchIntent, pendingIntentFlags)
|
|
50
|
-
} else {
|
|
51
|
-
// Fallback: empty intent to avoid crash if launch activity is missing for some reason
|
|
52
|
-
PendingIntent.getActivity(context, 0, Intent(), pendingIntentFlags)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
val iconResId = resolveSmallIconResId(context, smallIconName)
|
|
56
|
-
return NotificationCompat.Builder(context, channelId)
|
|
57
|
-
.setContentTitle(title)
|
|
58
|
-
.setContentText(body)
|
|
59
|
-
.setOngoing(true)
|
|
60
|
-
.setOnlyAlertOnce(true)
|
|
61
|
-
.setCategory(NotificationCompat.CATEGORY_CALL)
|
|
62
|
-
.setContentIntent(contentIntent)
|
|
63
|
-
.setSmallIcon(iconResId)
|
|
64
|
-
.build()
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private fun resolveSmallIconResId(context: Context, smallIconName: String?): Int {
|
|
68
|
-
val resources = context.resources
|
|
69
|
-
val packageName = context.packageName
|
|
70
|
-
if (!smallIconName.isNullOrBlank()) {
|
|
71
|
-
val id = resources.getIdentifier(smallIconName, "drawable", packageName)
|
|
72
|
-
if (id != 0) return id
|
|
73
|
-
}
|
|
74
|
-
// Default to the app icon
|
|
75
|
-
return try {
|
|
76
|
-
val appInfo = context.packageManager.getApplicationInfo(packageName, 0)
|
|
77
|
-
appInfo.icon
|
|
78
|
-
} catch (_: PackageManager.NameNotFoundException) {
|
|
79
|
-
android.R.drawable.ic_dialog_info
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
package com.streamvideo.reactnative.keepalive
|
|
2
|
-
|
|
3
|
-
import android.Manifest
|
|
4
|
-
import android.content.Intent
|
|
5
|
-
import android.content.pm.PackageManager
|
|
6
|
-
import android.content.pm.ServiceInfo
|
|
7
|
-
import android.os.Build
|
|
8
|
-
import android.util.Log
|
|
9
|
-
import androidx.annotation.RequiresApi
|
|
10
|
-
import androidx.core.app.ServiceCompat
|
|
11
|
-
import androidx.core.content.ContextCompat
|
|
12
|
-
import com.facebook.react.HeadlessJsTaskService
|
|
13
|
-
import com.facebook.react.bridge.Arguments
|
|
14
|
-
import com.facebook.react.jstasks.HeadlessJsTaskConfig
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Foreground service that runs a React Native HeadlessJS task to keep a call alive.
|
|
18
|
-
*
|
|
19
|
-
*/
|
|
20
|
-
class StreamCallKeepAliveHeadlessService : HeadlessJsTaskService() {
|
|
21
|
-
|
|
22
|
-
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
23
|
-
val safeIntent = intent ?: Intent()
|
|
24
|
-
val channelId = safeIntent.getStringExtra(EXTRA_CHANNEL_ID) ?: DEFAULT_CHANNEL_ID
|
|
25
|
-
val channelName = safeIntent.getStringExtra(EXTRA_CHANNEL_NAME) ?: DEFAULT_CHANNEL_NAME
|
|
26
|
-
val title = safeIntent.getStringExtra(EXTRA_TITLE) ?: DEFAULT_TITLE
|
|
27
|
-
val body = safeIntent.getStringExtra(EXTRA_BODY) ?: DEFAULT_BODY
|
|
28
|
-
val smallIconName = safeIntent.getStringExtra(EXTRA_SMALL_ICON_NAME)
|
|
29
|
-
|
|
30
|
-
KeepAliveNotification.ensureChannel(this, channelId, channelName)
|
|
31
|
-
val notification = KeepAliveNotification.buildOngoingNotification(
|
|
32
|
-
context = this,
|
|
33
|
-
channelId = channelId,
|
|
34
|
-
title = title,
|
|
35
|
-
body = body,
|
|
36
|
-
smallIconName = smallIconName
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
startForegroundCompat(notification)
|
|
40
|
-
|
|
41
|
-
// Ensure HeadlessJS task is started
|
|
42
|
-
return super.onStartCommand(safeIntent, flags, startId)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
override fun getTaskConfig(intent: Intent?): HeadlessJsTaskConfig? {
|
|
46
|
-
val callCid = intent?.getStringExtra(EXTRA_CALL_CID) ?: return null
|
|
47
|
-
val data = Arguments.createMap().apply {
|
|
48
|
-
putString("callCid", callCid)
|
|
49
|
-
}
|
|
50
|
-
// We intentionally allow long-running work (the JS task can return a never-resolving Promise).
|
|
51
|
-
return HeadlessJsTaskConfig(
|
|
52
|
-
TASK_NAME,
|
|
53
|
-
data,
|
|
54
|
-
0, // timeout (0 = no timeout)
|
|
55
|
-
true // allowedInForeground
|
|
56
|
-
)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
override fun onDestroy() {
|
|
60
|
-
super.onDestroy()
|
|
61
|
-
stopForeground(STOP_FOREGROUND_REMOVE)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
@RequiresApi(Build.VERSION_CODES.R)
|
|
65
|
-
private fun computeForegroundServiceTypes(): Int {
|
|
66
|
-
var types = ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
|
|
67
|
-
|
|
68
|
-
val hasCameraPermission =
|
|
69
|
-
ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
|
|
70
|
-
if (hasCameraPermission) {
|
|
71
|
-
types = types or ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
val hasMicrophonePermission =
|
|
75
|
-
ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
|
|
76
|
-
if (hasMicrophonePermission) {
|
|
77
|
-
types = types or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return types
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
private fun startForegroundCompat(notification: android.app.Notification) {
|
|
84
|
-
try {
|
|
85
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
86
|
-
val types =
|
|
87
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) computeForegroundServiceTypes()
|
|
88
|
-
else ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
|
|
89
|
-
startForeground(NOTIFICATION_ID, notification, types)
|
|
90
|
-
} else {
|
|
91
|
-
startForeground(NOTIFICATION_ID, notification)
|
|
92
|
-
}
|
|
93
|
-
} catch (e: Exception) {
|
|
94
|
-
// Avoid crashing the app if the system rejects starting a foreground service (e.g.
|
|
95
|
-
// background start restrictions, invalid notification/channel, or permission issues).
|
|
96
|
-
Log.e(
|
|
97
|
-
TAG,
|
|
98
|
-
"startForegroundCompat: Failed to start foreground service: ${e.message}",
|
|
99
|
-
e
|
|
100
|
-
)
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
companion object {
|
|
105
|
-
private const val TAG = "StreamCallKeepAliveHeadlessService"
|
|
106
|
-
|
|
107
|
-
const val TASK_NAME = "StreamVideoKeepCallAlive"
|
|
108
|
-
|
|
109
|
-
const val EXTRA_CALL_CID = "callCid"
|
|
110
|
-
const val EXTRA_CHANNEL_ID = "channelId"
|
|
111
|
-
const val EXTRA_CHANNEL_NAME = "channelName"
|
|
112
|
-
const val EXTRA_TITLE = "title"
|
|
113
|
-
const val EXTRA_BODY = "body"
|
|
114
|
-
const val EXTRA_SMALL_ICON_NAME = "smallIconName"
|
|
115
|
-
|
|
116
|
-
private const val NOTIFICATION_ID = 6061
|
|
117
|
-
|
|
118
|
-
private const val DEFAULT_CHANNEL_ID = "stream_call_foreground_service"
|
|
119
|
-
private const val DEFAULT_CHANNEL_NAME = "Call in progress"
|
|
120
|
-
private const val DEFAULT_TITLE = "Call in progress"
|
|
121
|
-
private const val DEFAULT_BODY = "Tap to return to the call"
|
|
122
|
-
|
|
123
|
-
fun buildStartIntent(
|
|
124
|
-
context: android.content.Context,
|
|
125
|
-
callCid: String,
|
|
126
|
-
channelId: String,
|
|
127
|
-
channelName: String,
|
|
128
|
-
title: String,
|
|
129
|
-
body: String,
|
|
130
|
-
smallIconName: String?
|
|
131
|
-
): Intent {
|
|
132
|
-
return Intent(context, StreamCallKeepAliveHeadlessService::class.java).apply {
|
|
133
|
-
putExtra(EXTRA_CALL_CID, callCid)
|
|
134
|
-
putExtra(EXTRA_CHANNEL_ID, channelId)
|
|
135
|
-
putExtra(EXTRA_CHANNEL_NAME, channelName)
|
|
136
|
-
putExtra(EXTRA_TITLE, title)
|
|
137
|
-
putExtra(EXTRA_BODY, body)
|
|
138
|
-
if (!smallIconName.isNullOrBlank()) {
|
|
139
|
-
putExtra(EXTRA_SMALL_ICON_NAME, smallIconName)
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
fun buildStopIntent(context: android.content.Context): Intent {
|
|
145
|
-
return Intent(context, StreamCallKeepAliveHeadlessService::class.java)
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.useCallingExpWithCallingStateEffect = void 0;
|
|
7
|
-
var _videoClient = require("@stream-io/video-client");
|
|
8
|
-
var _videoReactBindings = require("@stream-io/video-react-bindings");
|
|
9
|
-
var _react = require("react");
|
|
10
|
-
var _operators = require("rxjs/operators");
|
|
11
|
-
var _callingx = require("../../utils/internal/callingx/callingx");
|
|
12
|
-
var _callingx2 = require("../../utils/push/libs/callingx");
|
|
13
|
-
const logger = _videoClient.videoLoggerSystem.getLogger('callingx');
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* This hook is used to inform sync call state with CallKit/Telecom (i.e. start call, end call, mute/unmute call).
|
|
17
|
-
*/
|
|
18
|
-
const useCallingExpWithCallingStateEffect = () => {
|
|
19
|
-
const {
|
|
20
|
-
useMicrophoneState,
|
|
21
|
-
useParticipants,
|
|
22
|
-
useCallMembers
|
|
23
|
-
} = (0, _videoReactBindings.useCallStateHooks)();
|
|
24
|
-
const activeCall = (0, _videoReactBindings.useCall)();
|
|
25
|
-
const {
|
|
26
|
-
isMute,
|
|
27
|
-
microphone
|
|
28
|
-
} = useMicrophoneState();
|
|
29
|
-
const callMembers = useCallMembers();
|
|
30
|
-
const participants = useParticipants();
|
|
31
|
-
const activeCallCid = activeCall?.cid;
|
|
32
|
-
const currentUserId = activeCall?.currentUserId;
|
|
33
|
-
const isIncoming = activeCall?.ringing && !activeCall?.isCreatedByMe || false;
|
|
34
|
-
const callDisplayName = (0, _react.useMemo)(() => (0, _callingx.getCallDisplayName)(callMembers, participants, currentUserId), [callMembers, participants, currentUserId]);
|
|
35
|
-
(0, _react.useEffect)(() => {
|
|
36
|
-
const callingx = (0, _callingx2.getCallingxLibIfAvailable)();
|
|
37
|
-
if (!callingx?.isSetup || !activeCall) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
// need to capture RINGING -> Joining -> Joined state change for the first time
|
|
41
|
-
// and inform callingx that the call is active
|
|
42
|
-
const shouldMakeCallActive = call => {
|
|
43
|
-
// only for outgoing calls or non-ringing ongoing calls in callingx
|
|
44
|
-
// Note: incoming calls are handled by callingx pending states instead
|
|
45
|
-
return call.ringing && call.isCreatedByMe || !call.ringing && callingx.isOngoingCallsEnabled;
|
|
46
|
-
};
|
|
47
|
-
const subscription = activeCall.state.callingState$.pipe((0, _operators.filter)(callingState => shouldMakeCallActive(activeCall) && callingState === _videoClient.CallingState.JOINED && callingx.isCallTracked(activeCall.cid)), (0, _operators.take)(1) // only need to capture the first joined state for outgoing calls
|
|
48
|
-
// then subscription completes and is automatically unsubscribed
|
|
49
|
-
).subscribe(() => {
|
|
50
|
-
callingx.setCurrentCallActive(activeCall.cid);
|
|
51
|
-
});
|
|
52
|
-
return () => {
|
|
53
|
-
subscription.unsubscribe();
|
|
54
|
-
};
|
|
55
|
-
}, [activeCall]);
|
|
56
|
-
(0, _react.useEffect)(() => {
|
|
57
|
-
return () => {
|
|
58
|
-
const callingx = (0, _callingx2.getCallingxLibIfAvailable)();
|
|
59
|
-
if (!callingx?.isSetup || !activeCallCid) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const isCallTracked = callingx.isCallTracked(activeCallCid);
|
|
63
|
-
if (!isCallTracked) {
|
|
64
|
-
logger.debug(`useCallingExpWithCallingStateEffect:No active call cid to end in calling exp: ${activeCallCid} isCallTracked: ${isCallTracked}`);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
//if incoming stream call was unmounted, we need to end the call in CallKit/Telecom
|
|
68
|
-
logger.debug(`useCallingExpWithCallingStateEffect: Ending call in callingx: ${activeCallCid}`);
|
|
69
|
-
callingx.endCallWithReason(activeCallCid, 'local').catch(error => {
|
|
70
|
-
logger.error(`useCallingExpWithCallingStateEffect: Error ending call in callingx: ${activeCallCid}`, error);
|
|
71
|
-
});
|
|
72
|
-
};
|
|
73
|
-
}, [activeCallCid]);
|
|
74
|
-
(0, _react.useEffect)(() => {
|
|
75
|
-
const callingx = (0, _callingx2.getCallingxLibIfAvailable)();
|
|
76
|
-
if (!callingx?.isSetup || !activeCallCid) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
const isCallTracked = callingx.isCallTracked(activeCallCid);
|
|
80
|
-
if (!isCallTracked) {
|
|
81
|
-
logger.debug(`useCallingExpWithCallingStateEffect:No active call cid to update callingx: ${activeCallCid} isCallTracked: ${isCallTracked}`);
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
callingx.updateDisplay(activeCallCid, activeCallCid, callDisplayName, isIncoming);
|
|
85
|
-
}, [activeCallCid, callDisplayName, isIncoming]);
|
|
86
|
-
|
|
87
|
-
// Sync microphone mute state from app → CallKit
|
|
88
|
-
(0, _react.useEffect)(() => {
|
|
89
|
-
const callingx = (0, _callingx2.getCallingxLibIfAvailable)();
|
|
90
|
-
if (!callingx?.isSetup || !activeCallCid) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
const isCallTracked = callingx.isCallTracked(activeCallCid);
|
|
94
|
-
if (!isCallTracked) {
|
|
95
|
-
logger.debug(`useCallingExpWithCallingStateEffect: No active call cid to set muted in calling exp: ${activeCallCid} isCallTracked: ${isCallTracked}`);
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
callingx.setMutedCall(activeCallCid, isMute);
|
|
99
|
-
}, [activeCallCid, isMute]);
|
|
100
|
-
|
|
101
|
-
// Sync mute state from CallKit → app (only for system-initiated mute actions)
|
|
102
|
-
(0, _react.useEffect)(() => {
|
|
103
|
-
const callingx = (0, _callingx2.getCallingxLibIfAvailable)();
|
|
104
|
-
if (!callingx?.isSetup || !activeCallCid) {
|
|
105
|
-
logger.debug(`useCallingExpWithCallingStateEffect: No active call cid to set muted in calling exp: ${activeCallCid} callingx isSetup: ${callingx?.isSetup}`);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Listen to mic toggle events from CallKit/Telecom and update stream call microphone state.
|
|
110
|
-
// Only system-initiated mute actions (e.g. user tapped mute on the native CallKit UI)
|
|
111
|
-
// are sent here — app-initiated actions are filtered out on the native side to prevent
|
|
112
|
-
// the feedback loop: app mutes mic → setMutedCall → CallKit delegate → event to JS → loop.
|
|
113
|
-
const subscription = callingx.addEventListener('didPerformSetMutedCallAction', async event => {
|
|
114
|
-
const {
|
|
115
|
-
callId,
|
|
116
|
-
muted
|
|
117
|
-
} = event;
|
|
118
|
-
const isCallTracked = callingx.isCallTracked(activeCallCid);
|
|
119
|
-
if (!isCallTracked || callId !== activeCallCid) {
|
|
120
|
-
logger.debug(`useCallingExpWithCallingStateEffect: No active call cid to set muted in calling exp: ${activeCallCid} isCallTracked: ${isCallTracked} callId: ${callId}`);
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const isCurrentlyMuted = microphone.state.status === 'disabled';
|
|
124
|
-
if (isCurrentlyMuted === muted) {
|
|
125
|
-
logger.debug(`useCallingExpWithCallingStateEffect: Mic toggle is already in the desired state: ${muted} for call: ${activeCallCid}`);
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
try {
|
|
129
|
-
if (muted) {
|
|
130
|
-
await microphone.disable();
|
|
131
|
-
} else {
|
|
132
|
-
await microphone.enable();
|
|
133
|
-
}
|
|
134
|
-
} catch (error) {
|
|
135
|
-
logger.error(`useCallingExpWithCallingStateEffect: Error toggling mic in calling exp: ${activeCallCid}`, error);
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
return () => {
|
|
139
|
-
subscription.remove();
|
|
140
|
-
};
|
|
141
|
-
}, [activeCallCid, microphone]);
|
|
142
|
-
};
|
|
143
|
-
exports.useCallingExpWithCallingStateEffect = useCallingExpWithCallingStateEffect;
|
|
144
|
-
//# sourceMappingURL=useCallingExpWithCallingStateEffect.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_videoClient","require","_videoReactBindings","_react","_operators","_callingx","_callingx2","logger","videoLoggerSystem","getLogger","useCallingExpWithCallingStateEffect","useMicrophoneState","useParticipants","useCallMembers","useCallStateHooks","activeCall","useCall","isMute","microphone","callMembers","participants","activeCallCid","cid","currentUserId","isIncoming","ringing","isCreatedByMe","callDisplayName","useMemo","getCallDisplayName","useEffect","callingx","getCallingxLibIfAvailable","isSetup","shouldMakeCallActive","call","isOngoingCallsEnabled","subscription","state","callingState$","pipe","filter","callingState","CallingState","JOINED","isCallTracked","take","subscribe","setCurrentCallActive","unsubscribe","debug","endCallWithReason","catch","error","updateDisplay","setMutedCall","addEventListener","event","callId","muted","isCurrentlyMuted","status","disable","enable","remove","exports"],"sourceRoot":"../../../../src","sources":["hooks/push/useCallingExpWithCallingStateEffect.ts"],"mappings":"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","ignoreList":[]}
|