@stream-io/video-react-native-sdk 1.9.22 → 1.9.24
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 +16 -0
- package/dist/commonjs/hooks/push/useIosCallKeepEventsSetupEffect.js +5 -0
- package/dist/commonjs/hooks/push/useIosCallKeepEventsSetupEffect.js.map +1 -1
- package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js +16 -0
- package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +1 -1
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js +61 -26
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/commonjs/hooks/push/useProcessPushCallEffect.js +3 -0
- package/dist/commonjs/hooks/push/useProcessPushCallEffect.js.map +1 -1
- package/dist/commonjs/hooks/push/useProcessPushNonRingingCallEffect.js +2 -0
- package/dist/commonjs/hooks/push/useProcessPushNonRingingCallEffect.js.map +1 -1
- package/dist/commonjs/utils/push/android.js +37 -4
- package/dist/commonjs/utils/push/android.js.map +1 -1
- package/dist/commonjs/utils/push/internal/utils.js +4 -1
- package/dist/commonjs/utils/push/internal/utils.js.map +1 -1
- package/dist/commonjs/utils/push/ios.js +32 -8
- package/dist/commonjs/utils/push/ios.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/module/hooks/push/useIosCallKeepEventsSetupEffect.js +6 -1
- package/dist/module/hooks/push/useIosCallKeepEventsSetupEffect.js.map +1 -1
- package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js +17 -1
- package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +1 -1
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js +63 -28
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/module/hooks/push/useProcessPushCallEffect.js +3 -0
- package/dist/module/hooks/push/useProcessPushCallEffect.js.map +1 -1
- package/dist/module/hooks/push/useProcessPushNonRingingCallEffect.js +2 -0
- package/dist/module/hooks/push/useProcessPushNonRingingCallEffect.js.map +1 -1
- package/dist/module/utils/push/android.js +37 -4
- package/dist/module/utils/push/android.js.map +1 -1
- package/dist/module/utils/push/internal/utils.js +4 -1
- package/dist/module/utils/push/internal/utils.js.map +1 -1
- package/dist/module/utils/push/ios.js +32 -8
- package/dist/module/utils/push/ios.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/hooks/push/useIosCallKeepEventsSetupEffect.d.ts.map +1 -1
- package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts.map +1 -1
- package/dist/typescript/hooks/push/useIosVoipPushEventsSetupEffect.d.ts.map +1 -1
- package/dist/typescript/hooks/push/useProcessPushCallEffect.d.ts.map +1 -1
- package/dist/typescript/hooks/push/useProcessPushNonRingingCallEffect.d.ts.map +1 -1
- package/dist/typescript/utils/push/android.d.ts.map +1 -1
- package/dist/typescript/utils/push/internal/utils.d.ts.map +1 -1
- package/dist/typescript/utils/push/ios.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/package.json +5 -5
- package/src/hooks/push/useIosCallKeepEventsSetupEffect.ts +9 -1
- package/src/hooks/push/useIosCallkeepWithCallingStateEffect.ts +35 -1
- package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +103 -22
- package/src/hooks/push/useProcessPushCallEffect.ts +10 -1
- package/src/hooks/push/useProcessPushNonRingingCallEffect.ts +5 -0
- package/src/utils/push/android.ts +90 -4
- package/src/utils/push/internal/utils.ts +13 -1
- package/src/utils/push/ios.ts +68 -5
- package/src/version.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-io/video-react-native-sdk",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.24",
|
|
4
4
|
"packageManager": "yarn@3.2.4",
|
|
5
5
|
"main": "dist/commonjs/index.js",
|
|
6
6
|
"module": "dist/module/index.js",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"!**/.*"
|
|
47
47
|
],
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@stream-io/video-client": "1.16.
|
|
50
|
-
"@stream-io/video-react-bindings": "1.4.
|
|
49
|
+
"@stream-io/video-client": "1.16.3",
|
|
50
|
+
"@stream-io/video-react-bindings": "1.4.11",
|
|
51
51
|
"intl-pluralrules": "2.0.1",
|
|
52
52
|
"lodash.merge": "^4.6.2",
|
|
53
53
|
"react-native-url-polyfill": "1.3.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@react-native-community/push-notification-ios": ">=1.11.0",
|
|
61
61
|
"@react-native-firebase/app": ">=17.5.0",
|
|
62
62
|
"@react-native-firebase/messaging": ">=17.5.0",
|
|
63
|
-
"@stream-io/react-native-webrtc": ">=125.0.
|
|
63
|
+
"@stream-io/react-native-webrtc": ">=125.0.4",
|
|
64
64
|
"@stream-io/video-filters-react-native": ">=0.1.0",
|
|
65
65
|
"expo": ">=47.0.0",
|
|
66
66
|
"expo-build-properties": "*",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"@react-native-firebase/app": "19.2.2",
|
|
122
122
|
"@react-native-firebase/messaging": "19.2.2",
|
|
123
123
|
"@react-native/eslint-config": "^0.74.84",
|
|
124
|
-
"@stream-io/react-native-webrtc": "125.0.
|
|
124
|
+
"@stream-io/react-native-webrtc": "^125.0.4",
|
|
125
125
|
"@stream-io/video-filters-react-native": "^0.2.6",
|
|
126
126
|
"@testing-library/jest-native": "^5.4.2",
|
|
127
127
|
"@testing-library/react-native": "^12.1.2",
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
voipCallkeepCallOnForegroundMap$,
|
|
4
4
|
voipPushNotificationCallCId$,
|
|
5
5
|
} from '../../utils/push/internal/rxSubjects';
|
|
6
|
-
import { RxUtils } from '@stream-io/video-client';
|
|
6
|
+
import { getLogger, RxUtils } from '@stream-io/video-client';
|
|
7
7
|
import { getCallKeepLib } from '../../utils/push/libs';
|
|
8
8
|
import { StreamVideoRN } from '../../utils/StreamVideoRN';
|
|
9
9
|
import type { StreamVideoConfig } from '../../utils/StreamVideoRN/types';
|
|
@@ -19,6 +19,8 @@ import { Platform } from 'react-native';
|
|
|
19
19
|
|
|
20
20
|
type PushConfig = NonNullable<StreamVideoConfig['push']>;
|
|
21
21
|
|
|
22
|
+
const logger = getLogger(['useIosCallKeepEventsSetupEffect']);
|
|
23
|
+
|
|
22
24
|
/**
|
|
23
25
|
* This hook is used to listen to callkeep events and do the necessary actions
|
|
24
26
|
*/
|
|
@@ -34,6 +36,7 @@ export const useIosCallKeepEventsSetupEffect = () => {
|
|
|
34
36
|
'answerCall',
|
|
35
37
|
({ callUUID }) => {
|
|
36
38
|
const call_cid = RxUtils.getCurrentValue(voipPushNotificationCallCId$);
|
|
39
|
+
logger('debug', `answerCall event with call_cid: ${call_cid}`);
|
|
37
40
|
iosCallkeepAcceptCall(call_cid, callUUID);
|
|
38
41
|
}
|
|
39
42
|
);
|
|
@@ -41,6 +44,7 @@ export const useIosCallKeepEventsSetupEffect = () => {
|
|
|
41
44
|
'endCall',
|
|
42
45
|
({ callUUID }) => {
|
|
43
46
|
const call_cid = RxUtils.getCurrentValue(voipPushNotificationCallCId$);
|
|
47
|
+
logger('debug', `endCall event with call_cid: ${call_cid}`);
|
|
44
48
|
iosCallkeepRejectCall(call_cid, callUUID, pushConfig);
|
|
45
49
|
}
|
|
46
50
|
);
|
|
@@ -55,6 +59,10 @@ export const useIosCallKeepEventsSetupEffect = () => {
|
|
|
55
59
|
if (!call_cid) {
|
|
56
60
|
return;
|
|
57
61
|
}
|
|
62
|
+
logger(
|
|
63
|
+
'debug',
|
|
64
|
+
`didDisplayIncomingCall event with call_cid: ${call_cid}`
|
|
65
|
+
);
|
|
58
66
|
voipCallkeepCallOnForegroundMap$.next({
|
|
59
67
|
uuid: callUUID,
|
|
60
68
|
cid: call_cid,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CallingState, RxUtils } from '@stream-io/video-client';
|
|
1
|
+
import { CallingState, getLogger, RxUtils } from '@stream-io/video-client';
|
|
2
2
|
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
3
3
|
import { Platform } from 'react-native';
|
|
4
4
|
import { useEffect, useState } from 'react';
|
|
@@ -35,6 +35,8 @@ const unsubscribeCallkeepEvents = (activeCallCid: string | undefined) => {
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
+
const logger = getLogger(['useIosCallkeepWithCallingStateEffect']);
|
|
39
|
+
|
|
38
40
|
/**
|
|
39
41
|
* This hook is used to inform the callkeep library that the call has been joined or ended.
|
|
40
42
|
*/
|
|
@@ -57,6 +59,10 @@ export const useIosCallkeepWithCallingStateEffect = () => {
|
|
|
57
59
|
const callkeep = getCallKeepLib();
|
|
58
60
|
// if the component is unmounted and the callID was not reported to callkeep, then report it now
|
|
59
61
|
if (acceptedForegroundCallkeepMap) {
|
|
62
|
+
logger(
|
|
63
|
+
'debug',
|
|
64
|
+
`Ending call in callkeep: ${acceptedForegroundCallkeepMap.cid}, reason: component unmounted and call was present in acceptedForegroundCallkeepMap`
|
|
65
|
+
);
|
|
60
66
|
unsubscribeCallkeepEvents(acceptedForegroundCallkeepMap.cid);
|
|
61
67
|
// this call should be ended in callkeep
|
|
62
68
|
callkeep.endCall(acceptedForegroundCallkeepMap.uuid);
|
|
@@ -80,11 +86,19 @@ export const useIosCallkeepWithCallingStateEffect = () => {
|
|
|
80
86
|
);
|
|
81
87
|
const callkeep = getCallKeepLib();
|
|
82
88
|
if (activeCallCid === nativeDialerAcceptedCallMap?.cid) {
|
|
89
|
+
logger(
|
|
90
|
+
'debug',
|
|
91
|
+
`Ending call in callkeep: ${activeCallCid}, reason: activeCallCid changed or was removed and call was present in nativeDialerAcceptedCallMap`
|
|
92
|
+
);
|
|
83
93
|
unsubscribeCallkeepEvents(activeCallCid);
|
|
84
94
|
callkeep.endCall(nativeDialerAcceptedCallMap.uuid);
|
|
85
95
|
// no need to keep this reference anymore
|
|
86
96
|
voipCallkeepAcceptedCallOnNativeDialerMap$.next(undefined);
|
|
87
97
|
} else if (activeCallCid === foregroundIncomingCallkeepMap?.cid) {
|
|
98
|
+
logger(
|
|
99
|
+
'debug',
|
|
100
|
+
`Ending call in callkeep: ${activeCallCid}, reason: activeCallCid changed or was removed and call was present in foregroundIncomingCallkeepMap`
|
|
101
|
+
);
|
|
88
102
|
unsubscribeCallkeepEvents(activeCallCid);
|
|
89
103
|
callkeep.endCall(foregroundIncomingCallkeepMap.uuid);
|
|
90
104
|
// no need to keep this reference anymore
|
|
@@ -112,6 +126,11 @@ export const useIosCallkeepWithCallingStateEffect = () => {
|
|
|
112
126
|
voipCallkeepCallOnForegroundMap$
|
|
113
127
|
);
|
|
114
128
|
if (foregroundCallkeepMap && foregroundCallkeepMap.cid === activeCallCid) {
|
|
129
|
+
logger(
|
|
130
|
+
'debug',
|
|
131
|
+
// @ts-ignore
|
|
132
|
+
`Accepting call in callkeep: ${activeCallCid}, reason: callingstate went to ${CallingState[callingState]} and call was present in foregroundCallkeepMap`
|
|
133
|
+
);
|
|
115
134
|
// this call should be accepted in callkeep
|
|
116
135
|
callkeep.answerIncomingCall(foregroundCallkeepMap.uuid);
|
|
117
136
|
// no need to keep this reference anymore
|
|
@@ -131,6 +150,11 @@ export const useIosCallkeepWithCallingStateEffect = () => {
|
|
|
131
150
|
// the call was accepted through the app and not through native dialer
|
|
132
151
|
// the call was left using the leave button in the app and not through native dialer
|
|
133
152
|
if (activeCallCid === acceptedForegroundCallkeepMap?.cid) {
|
|
153
|
+
logger(
|
|
154
|
+
'debug',
|
|
155
|
+
// @ts-ignore
|
|
156
|
+
`Ending call in callkeep: ${activeCallCid}, reason: callingstate went to ${CallingState[callingState]} and call was present in acceptedForegroundCallkeepMap`
|
|
157
|
+
);
|
|
134
158
|
callkeep.endCall(acceptedForegroundCallkeepMap.uuid);
|
|
135
159
|
setAcceptedForegroundCallkeepMap(undefined);
|
|
136
160
|
return;
|
|
@@ -141,6 +165,11 @@ export const useIosCallkeepWithCallingStateEffect = () => {
|
|
|
141
165
|
voipCallkeepCallOnForegroundMap$
|
|
142
166
|
);
|
|
143
167
|
if (activeCallCid === foregroundIncomingCallkeepMap?.cid) {
|
|
168
|
+
logger(
|
|
169
|
+
'debug',
|
|
170
|
+
// @ts-ignore
|
|
171
|
+
`Ending call in callkeep: ${activeCallCid}, reason: callingstate went to ${CallingState[callingState]} and call was present in foregroundIncomingCallkeepMap`
|
|
172
|
+
);
|
|
144
173
|
callkeep.endCall(foregroundIncomingCallkeepMap.uuid);
|
|
145
174
|
// no need to keep this reference anymore
|
|
146
175
|
voipCallkeepCallOnForegroundMap$.next(undefined);
|
|
@@ -153,6 +182,11 @@ export const useIosCallkeepWithCallingStateEffect = () => {
|
|
|
153
182
|
voipCallkeepAcceptedCallOnNativeDialerMap$
|
|
154
183
|
);
|
|
155
184
|
if (activeCallCid === nativeDialerAcceptedCallMap?.cid) {
|
|
185
|
+
logger(
|
|
186
|
+
'debug',
|
|
187
|
+
// @ts-ignore
|
|
188
|
+
`Ending call in callkeep: ${activeCallCid}, reason: callingstate went to ${CallingState[callingState]} and call was present in nativeDialerAcceptedCallMap`
|
|
189
|
+
);
|
|
156
190
|
callkeep.endCall(nativeDialerAcceptedCallMap.uuid);
|
|
157
191
|
// no need to keep this reference anymore
|
|
158
192
|
voipCallkeepAcceptedCallOnNativeDialerMap$.next(undefined);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
1
|
+
import { MutableRefObject, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
getCallKeepLib,
|
|
4
4
|
getVoipPushNotificationLib,
|
|
@@ -6,7 +6,10 @@ import {
|
|
|
6
6
|
|
|
7
7
|
import { AppState, Platform } from 'react-native';
|
|
8
8
|
import { StreamVideoRN } from '../../utils';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
useConnectedUser,
|
|
11
|
+
useStreamVideoClient,
|
|
12
|
+
} from '@stream-io/video-react-bindings';
|
|
10
13
|
import { setPushLogoutCallback } from '../../utils/internal/pushLogoutCallback';
|
|
11
14
|
import { NativeModules } from 'react-native';
|
|
12
15
|
import {
|
|
@@ -17,9 +20,28 @@ import {
|
|
|
17
20
|
pushUnsubscriptionCallbacks$,
|
|
18
21
|
voipPushNotificationCallCId$,
|
|
19
22
|
} from '../../utils/push/internal/rxSubjects';
|
|
20
|
-
import { RxUtils, getLogger } from '@stream-io/video-client';
|
|
23
|
+
import { RxUtils, StreamVideoClient, getLogger } from '@stream-io/video-client';
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
const logger = getLogger(['useIosVoipPushEventsSetupEffect']);
|
|
26
|
+
|
|
27
|
+
function setLogoutCallback(
|
|
28
|
+
client: StreamVideoClient,
|
|
29
|
+
token: string,
|
|
30
|
+
lastVoipTokenRef: MutableRefObject<{ token: string; userId: string }>
|
|
31
|
+
) {
|
|
32
|
+
setPushLogoutCallback(async () => {
|
|
33
|
+
lastVoipTokenRef.current = { token: '', userId: '' };
|
|
34
|
+
try {
|
|
35
|
+
await client.removeDevice(token);
|
|
36
|
+
} catch (err) {
|
|
37
|
+
logger(
|
|
38
|
+
'warn',
|
|
39
|
+
'PushLogoutCallback - Failed to remove voip token from stream',
|
|
40
|
+
err
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
23
45
|
|
|
24
46
|
/**
|
|
25
47
|
* This hook is used to do the initial setup of listeners
|
|
@@ -27,6 +49,45 @@ let lastVoipToken = { token: '', userId: '' };
|
|
|
27
49
|
*/
|
|
28
50
|
export const useIosVoipPushEventsSetupEffect = () => {
|
|
29
51
|
const client = useStreamVideoClient();
|
|
52
|
+
const connectedUserId = useConnectedUser()?.id;
|
|
53
|
+
const lastVoipTokenRef = useRef({ token: '', userId: '' });
|
|
54
|
+
const [unsentToken, setUnsentToken] = useState<string>();
|
|
55
|
+
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
const pushConfig = StreamVideoRN.getConfig().push;
|
|
58
|
+
// we need to wait for user to be connected before we can send the push token
|
|
59
|
+
if (
|
|
60
|
+
!pushConfig?.ios.pushProviderName ||
|
|
61
|
+
!client ||
|
|
62
|
+
!connectedUserId ||
|
|
63
|
+
!unsentToken
|
|
64
|
+
) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
logger(
|
|
68
|
+
'debug',
|
|
69
|
+
'Sending unsent voip token to stream as user logged in after token was received, token: ' +
|
|
70
|
+
unsentToken
|
|
71
|
+
);
|
|
72
|
+
client
|
|
73
|
+
.addVoipDevice(unsentToken, 'apn', pushConfig.ios.pushProviderName)
|
|
74
|
+
.then(() => {
|
|
75
|
+
setLogoutCallback(client, unsentToken, lastVoipTokenRef);
|
|
76
|
+
logger(
|
|
77
|
+
'debug',
|
|
78
|
+
'Sent unsent voip token to stream - token: ' + unsentToken
|
|
79
|
+
);
|
|
80
|
+
lastVoipTokenRef.current = {
|
|
81
|
+
token: unsentToken,
|
|
82
|
+
userId: connectedUserId,
|
|
83
|
+
};
|
|
84
|
+
setUnsentToken(undefined);
|
|
85
|
+
})
|
|
86
|
+
.catch((error) => {
|
|
87
|
+
logger('warn', 'Error in sending unsent voip token to stream', error);
|
|
88
|
+
});
|
|
89
|
+
}, [client, connectedUserId, unsentToken]);
|
|
90
|
+
|
|
30
91
|
useEffect(() => {
|
|
31
92
|
const pushConfig = StreamVideoRN.getConfig().push;
|
|
32
93
|
if (Platform.OS !== 'ios' || !pushConfig || !client) {
|
|
@@ -35,28 +96,34 @@ export const useIosVoipPushEventsSetupEffect = () => {
|
|
|
35
96
|
const voipPushNotification = getVoipPushNotificationLib();
|
|
36
97
|
const onTokenReceived = (token: string) => {
|
|
37
98
|
const userId = client.streamClient._user?.id ?? '';
|
|
99
|
+
if (!userId) {
|
|
100
|
+
setUnsentToken(token);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const lastVoipToken = lastVoipTokenRef.current;
|
|
38
104
|
if (lastVoipToken.token === token && lastVoipToken.userId === userId) {
|
|
105
|
+
logger(
|
|
106
|
+
'debug',
|
|
107
|
+
`Skipped sending voip token to stream as it is same as last token - token: ${token}, userId: ${userId}`
|
|
108
|
+
);
|
|
39
109
|
return;
|
|
40
110
|
}
|
|
41
|
-
lastVoipToken = { token, userId };
|
|
42
111
|
const push_provider_name = pushConfig.ios.pushProviderName;
|
|
43
112
|
if (!push_provider_name) {
|
|
44
113
|
return;
|
|
45
114
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
});
|
|
115
|
+
logger('debug', 'Sending voip token to stream, token: ' + token);
|
|
116
|
+
client
|
|
117
|
+
.addVoipDevice(token, 'apn', push_provider_name)
|
|
118
|
+
.then(() => {
|
|
119
|
+
logger('debug', 'Sent voip token to stream, token: ' + token);
|
|
120
|
+
setLogoutCallback(client, token, lastVoipTokenRef);
|
|
121
|
+
lastVoipTokenRef.current = { token, userId };
|
|
122
|
+
})
|
|
123
|
+
.catch((err) => {
|
|
124
|
+
setUnsentToken(token);
|
|
125
|
+
logger('warn', 'Failed to send voip token to stream', err);
|
|
126
|
+
});
|
|
60
127
|
};
|
|
61
128
|
// fired when PushKit give us the latest token
|
|
62
129
|
voipPushNotification.addEventListener('register', (token) => {
|
|
@@ -145,7 +212,6 @@ const onNotificationReceived = async (notification: any) => {
|
|
|
145
212
|
call_cid
|
|
146
213
|
);
|
|
147
214
|
} catch (error) {
|
|
148
|
-
const logger = getLogger(['useIosVoipPushEventsSetupEffect']);
|
|
149
215
|
logger('error', 'Error in getting call uuid from native module', error);
|
|
150
216
|
}
|
|
151
217
|
if (!uuid) {
|
|
@@ -161,6 +227,10 @@ const onNotificationReceived = async (notification: any) => {
|
|
|
161
227
|
);
|
|
162
228
|
if (mustEndCall) {
|
|
163
229
|
const callkeep = getCallKeepLib();
|
|
230
|
+
logger(
|
|
231
|
+
'debug',
|
|
232
|
+
`callkeep.reportEndCallWithUUID for uuid: ${uuid}, call_cid: ${call_cid}, reason: ${callkeepReason}`
|
|
233
|
+
);
|
|
164
234
|
callkeep.reportEndCallWithUUID(uuid, callkeepReason);
|
|
165
235
|
return true;
|
|
166
236
|
}
|
|
@@ -170,13 +240,24 @@ const onNotificationReceived = async (notification: any) => {
|
|
|
170
240
|
const canListenToWS = () =>
|
|
171
241
|
canAddPushWSSubscriptionsRef.current && AppState.currentState !== 'active';
|
|
172
242
|
if (!closed && canListenToWS()) {
|
|
173
|
-
const unsubscribe = callFromPush.on('all', () => {
|
|
174
|
-
|
|
243
|
+
const unsubscribe = callFromPush.on('all', (event) => {
|
|
244
|
+
const _canListenToWS = canListenToWS();
|
|
245
|
+
if (!_canListenToWS) {
|
|
246
|
+
logger(
|
|
247
|
+
'debug',
|
|
248
|
+
`unsubscribe due to event callCid: ${call_cid} canListenToWS: ${_canListenToWS}`,
|
|
249
|
+
event
|
|
250
|
+
);
|
|
175
251
|
unsubscribe();
|
|
176
252
|
return;
|
|
177
253
|
}
|
|
178
254
|
const _closed = closeCallIfNecessary();
|
|
179
255
|
if (_closed) {
|
|
256
|
+
logger(
|
|
257
|
+
'debug',
|
|
258
|
+
`unsubscribe due to event callCid: ${call_cid} canListenToWS: ${_canListenToWS} shouldCallBeClosed: ${_closed}`,
|
|
259
|
+
event
|
|
260
|
+
);
|
|
180
261
|
unsubscribe();
|
|
181
262
|
}
|
|
182
263
|
});
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { BehaviorSubject } from 'rxjs';
|
|
14
14
|
import { filter, distinctUntilChanged } from 'rxjs/operators';
|
|
15
15
|
import { processCallFromPush } from '../../utils/push/internal/utils';
|
|
16
|
-
import { StreamVideoClient } from '@stream-io/video-client';
|
|
16
|
+
import { getLogger, StreamVideoClient } from '@stream-io/video-client';
|
|
17
17
|
import type { StreamVideoConfig } from '../../utils/StreamVideoRN/types';
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -32,6 +32,11 @@ export const useProcessPushCallEffect = () => {
|
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
getLogger(['useProcessPushCallEffect'])(
|
|
36
|
+
'debug',
|
|
37
|
+
`Adding subscriptions to process incoming call from push notification`
|
|
38
|
+
);
|
|
39
|
+
|
|
35
40
|
// if the user accepts the call from push notification we join the call
|
|
36
41
|
const acceptedCallSubscription = createCallSubscription(
|
|
37
42
|
pushAcceptedIncomingCallCId$,
|
|
@@ -91,6 +96,10 @@ const createCallSubscription = (
|
|
|
91
96
|
return behaviourSubjectWithCallCid
|
|
92
97
|
.pipe(filter(cidIsNotUndefined), distinctUntilChanged())
|
|
93
98
|
.subscribe(async (callCId) => {
|
|
99
|
+
getLogger(['useProcessPushCallEffect'])(
|
|
100
|
+
'debug',
|
|
101
|
+
`Processing call from push notification with action: ${action} and callCId: ${callCId}`
|
|
102
|
+
);
|
|
94
103
|
await processCallFromPush(client, callCId, action, pushConfig);
|
|
95
104
|
behaviourSubjectWithCallCid.next(undefined); // remove the current call id to avoid processing again
|
|
96
105
|
});
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from '@stream-io/video-react-bindings';
|
|
8
8
|
import { filter } from 'rxjs/operators';
|
|
9
9
|
import { processNonIncomingCallFromPush } from '../../utils/push/internal/utils';
|
|
10
|
+
import { getLogger } from '@stream-io/video-client';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* This hook is used to process the non ringing call data via push notifications using the relevant rxjs subject
|
|
@@ -26,6 +27,10 @@ export const useProcessPushNonRingingCallEffect = () => {
|
|
|
26
27
|
const subscription = pushNonRingingCallData$
|
|
27
28
|
.pipe(filter(NotUndefined))
|
|
28
29
|
.subscribe(async ({ cid, type }) => {
|
|
30
|
+
getLogger(['useProcessPushNonRingingCallEffect'])(
|
|
31
|
+
'debug',
|
|
32
|
+
`processNonIncomingCallFromPush with callCId: ${cid} and type: ${type}`
|
|
33
|
+
);
|
|
29
34
|
await processNonIncomingCallFromPush(client, cid, type);
|
|
30
35
|
pushNonRingingCallData$.next(undefined); // remove the current data to avoid processing again
|
|
31
36
|
});
|
|
@@ -64,12 +64,20 @@ export async function initAndroidPushToken(
|
|
|
64
64
|
lastFirebaseToken.token === token &&
|
|
65
65
|
lastFirebaseToken.userId === userId
|
|
66
66
|
) {
|
|
67
|
+
getLogger(['initAndroidPushToken'])(
|
|
68
|
+
'debug',
|
|
69
|
+
`Skipping setting the same token again for userId: ${userId} and token: ${token}`
|
|
70
|
+
);
|
|
67
71
|
return;
|
|
68
72
|
}
|
|
69
73
|
lastFirebaseToken = { token, userId };
|
|
70
74
|
setPushLogoutCallback(async () => {
|
|
71
75
|
lastFirebaseToken = { token: '', userId: '' };
|
|
72
76
|
try {
|
|
77
|
+
getLogger(['initAndroidPushToken'])(
|
|
78
|
+
'debug',
|
|
79
|
+
`Logout removeDeviceToken: ${token}`
|
|
80
|
+
);
|
|
73
81
|
await client.removeDevice(token);
|
|
74
82
|
} catch (err) {
|
|
75
83
|
const logger = getLogger(['initAndroidPushToken']);
|
|
@@ -159,18 +167,44 @@ export const firebaseDataHandler = async (
|
|
|
159
167
|
return new Promise(async () => {
|
|
160
168
|
const client = await pushConfig.createStreamVideoClient();
|
|
161
169
|
if (!client) {
|
|
170
|
+
getLogger(['firebaseMessagingOnMessageHandler'])(
|
|
171
|
+
'debug',
|
|
172
|
+
`Closing fg service as there is no client to create from push config`
|
|
173
|
+
);
|
|
162
174
|
notifee.stopForegroundService();
|
|
163
175
|
return;
|
|
164
176
|
}
|
|
165
177
|
const callFromPush = await client.onRingingCall(call_cid);
|
|
166
|
-
|
|
178
|
+
let _shouldCallBeClosed = shouldCallBeClosed(callFromPush);
|
|
179
|
+
if (_shouldCallBeClosed) {
|
|
180
|
+
getLogger(['firebaseMessagingOnMessageHandler'])(
|
|
181
|
+
'debug',
|
|
182
|
+
`Closing fg service callCid: ${call_cid} shouldCallBeClosed: ${_shouldCallBeClosed}`
|
|
183
|
+
);
|
|
167
184
|
notifee.stopForegroundService();
|
|
168
185
|
return;
|
|
169
186
|
}
|
|
170
187
|
const unsubscribeFunctions: Array<() => void> = [];
|
|
171
188
|
// check if service needs to be closed if accept/decline event was done on another device
|
|
172
|
-
const unsubscribe = callFromPush.on('all', () => {
|
|
173
|
-
|
|
189
|
+
const unsubscribe = callFromPush.on('all', (event) => {
|
|
190
|
+
const _canListenToWS = canListenToWS();
|
|
191
|
+
if (!_canListenToWS) {
|
|
192
|
+
getLogger(['firebaseMessagingOnMessageHandler'])(
|
|
193
|
+
'debug',
|
|
194
|
+
`Closing fg service from event callCid: ${call_cid} canListenToWS: ${_canListenToWS}`,
|
|
195
|
+
{ event }
|
|
196
|
+
);
|
|
197
|
+
unsubscribeFunctions.forEach((fn) => fn());
|
|
198
|
+
notifee.stopForegroundService();
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
_shouldCallBeClosed = shouldCallBeClosed(callFromPush);
|
|
202
|
+
if (_shouldCallBeClosed) {
|
|
203
|
+
getLogger(['firebaseMessagingOnMessageHandler'])(
|
|
204
|
+
'debug',
|
|
205
|
+
`Closing fg service from event callCid: ${call_cid} canListenToWS: ${_canListenToWS} shouldCallBeClosed: ${_shouldCallBeClosed}`,
|
|
206
|
+
{ event }
|
|
207
|
+
);
|
|
174
208
|
unsubscribeFunctions.forEach((fn) => fn());
|
|
175
209
|
notifee.stopForegroundService();
|
|
176
210
|
}
|
|
@@ -221,6 +255,14 @@ export const firebaseDataHandler = async (
|
|
|
221
255
|
const { getTitle, getBody } = incomingCallNotificationTextGetters;
|
|
222
256
|
const createdUserName = data.created_by_display_name as string;
|
|
223
257
|
|
|
258
|
+
const title = getTitle(createdUserName);
|
|
259
|
+
const body = getBody(createdUserName);
|
|
260
|
+
|
|
261
|
+
getLogger(['firebaseMessagingOnMessageHandler'])(
|
|
262
|
+
'debug',
|
|
263
|
+
`Displaying incoming call notification with callCid: ${call_cid} title: ${title} body: ${body} asForegroundService: ${asForegroundService}`
|
|
264
|
+
);
|
|
265
|
+
|
|
224
266
|
const channelId = incomingCallChannel.id;
|
|
225
267
|
await notifee.displayNotification({
|
|
226
268
|
id: call_cid,
|
|
@@ -276,6 +318,10 @@ export const firebaseDataHandler = async (
|
|
|
276
318
|
const callFromPush = await client.onRingingCall(call_cid);
|
|
277
319
|
|
|
278
320
|
if (shouldCallBeClosed(callFromPush)) {
|
|
321
|
+
getLogger(['firebaseMessagingOnMessageHandler'])(
|
|
322
|
+
'debug',
|
|
323
|
+
`Removing incoming call notification immediately with callCid: ${call_cid} as it should be closed`
|
|
324
|
+
);
|
|
279
325
|
notifee.cancelDisplayedNotification(call_cid);
|
|
280
326
|
}
|
|
281
327
|
} else {
|
|
@@ -288,7 +334,7 @@ export const firebaseDataHandler = async (
|
|
|
288
334
|
if (!callChannel || !callNotificationTextGetters) {
|
|
289
335
|
const logger = getLogger(['firebaseMessagingOnMessageHandler']);
|
|
290
336
|
logger(
|
|
291
|
-
'
|
|
337
|
+
'debug',
|
|
292
338
|
"Can't show call notification as either or both callChannel and callNotificationTextGetters is not provided"
|
|
293
339
|
);
|
|
294
340
|
return;
|
|
@@ -299,6 +345,14 @@ export const firebaseDataHandler = async (
|
|
|
299
345
|
const createdUserName = data.created_by_display_name as string;
|
|
300
346
|
// we can safely cast to string because the data is from "stream.video"
|
|
301
347
|
const type = data.type as NonRingingPushEvent;
|
|
348
|
+
|
|
349
|
+
const title = getTitle(type, createdUserName);
|
|
350
|
+
const body = getBody(type, createdUserName);
|
|
351
|
+
|
|
352
|
+
getLogger(['firebaseMessagingOnMessageHandler'])(
|
|
353
|
+
'debug',
|
|
354
|
+
`Displaying NonRingingPushEvent ${type} notification with title: ${title} body: ${body}`
|
|
355
|
+
);
|
|
302
356
|
await notifee.displayNotification({
|
|
303
357
|
title: getTitle(type, createdUserName),
|
|
304
358
|
body: getBody(type, createdUserName),
|
|
@@ -369,25 +423,53 @@ export const onAndroidNotifeeEvent = async ({
|
|
|
369
423
|
mustDecline ||
|
|
370
424
|
type === notifeeLib.EventType.ACTION_PRESS
|
|
371
425
|
) {
|
|
426
|
+
getLogger(['onAndroidNotifeeEvent'])(
|
|
427
|
+
'debug',
|
|
428
|
+
`clearPushWSEventSubscriptions for callCId: ${call_cid} mustAccept: ${mustAccept} mustDecline: ${mustDecline}`
|
|
429
|
+
);
|
|
372
430
|
clearPushWSEventSubscriptions();
|
|
373
431
|
notifee.stopForegroundService();
|
|
374
432
|
}
|
|
375
433
|
|
|
376
434
|
if (mustAccept) {
|
|
435
|
+
getLogger(['onAndroidNotifeeEvent'])(
|
|
436
|
+
'debug',
|
|
437
|
+
`pushAcceptedIncomingCallCId$ added with callCId: ${call_cid}`
|
|
438
|
+
);
|
|
377
439
|
pushAcceptedIncomingCallCId$.next(call_cid);
|
|
378
440
|
// NOTE: accept will be handled by the app with rxjs observers as the app will go to foreground always
|
|
379
441
|
} else if (mustDecline) {
|
|
442
|
+
getLogger(['onAndroidNotifeeEvent'])(
|
|
443
|
+
'debug',
|
|
444
|
+
`pushRejectedIncomingCallCId$ added with callCId: ${call_cid}`
|
|
445
|
+
);
|
|
380
446
|
pushRejectedIncomingCallCId$.next(call_cid);
|
|
381
447
|
if (hasObservers) {
|
|
382
448
|
// if we had observers we can return here as the observers will handle the call as the app is in the foreground state
|
|
449
|
+
getLogger(['onAndroidNotifeeEvent'])(
|
|
450
|
+
'debug',
|
|
451
|
+
`Skipped processCallFromPushInBackground for Declining call with callCId: ${call_cid} as the app is in the foreground state`
|
|
452
|
+
);
|
|
383
453
|
return;
|
|
384
454
|
}
|
|
455
|
+
getLogger(['onAndroidNotifeeEvent'])(
|
|
456
|
+
'debug',
|
|
457
|
+
`start processCallFromPushInBackground - Declining call with callCId: ${call_cid}`
|
|
458
|
+
);
|
|
385
459
|
await processCallFromPushInBackground(pushConfig, call_cid, 'decline');
|
|
386
460
|
} else {
|
|
387
461
|
if (type === notifeeLib.EventType.PRESS) {
|
|
462
|
+
getLogger(['onAndroidNotifeeEvent'])(
|
|
463
|
+
'debug',
|
|
464
|
+
`pushTappedIncomingCallCId$ added with callCId: ${call_cid}`
|
|
465
|
+
);
|
|
388
466
|
pushTappedIncomingCallCId$.next(call_cid);
|
|
389
467
|
// pressed state will be handled by the app with rxjs observers as the app will go to foreground always
|
|
390
468
|
} else if (isBackground && type === notifeeLib.EventType.DELIVERED) {
|
|
469
|
+
getLogger(['onAndroidNotifeeEvent'])(
|
|
470
|
+
'debug',
|
|
471
|
+
`pushAndroidBackgroundDeliveredIncomingCallCId$ added with callCId: ${call_cid}`
|
|
472
|
+
);
|
|
391
473
|
pushAndroidBackgroundDeliveredIncomingCallCId$.next(call_cid);
|
|
392
474
|
// background delivered state will be handled by the app with rxjs observers as processing needs to happen only when app is opened
|
|
393
475
|
}
|
|
@@ -395,6 +477,10 @@ export const onAndroidNotifeeEvent = async ({
|
|
|
395
477
|
} else {
|
|
396
478
|
const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
|
|
397
479
|
if (type === notifeeLib.EventType.PRESS) {
|
|
480
|
+
getLogger(['onAndroidNotifeeEvent'])(
|
|
481
|
+
'debug',
|
|
482
|
+
`onTapNonRingingCallNotification with callCId: ${call_cid}`
|
|
483
|
+
);
|
|
398
484
|
pushConfig.onTapNonRingingCallNotification?.(
|
|
399
485
|
call_cid,
|
|
400
486
|
data.type as NonRingingPushEvent
|
|
@@ -57,6 +57,10 @@ export const shouldCallBeEnded = (
|
|
|
57
57
|
callkeepReason = 4;
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
+
getLogger(['shouldCallBeEnded'])(
|
|
61
|
+
'debug',
|
|
62
|
+
`callCid: ${callFromPush.cid} mustEndCall: ${mustEndCall} callkeepReason: ${callkeepReason}`
|
|
63
|
+
);
|
|
60
64
|
return { mustEndCall, callkeepReason };
|
|
61
65
|
};
|
|
62
66
|
|
|
@@ -111,16 +115,24 @@ export const processCallFromPush = async (
|
|
|
111
115
|
if (pushConfig.publishOptions) {
|
|
112
116
|
callFromPush.updatePublishOptions(pushConfig.publishOptions);
|
|
113
117
|
}
|
|
118
|
+
getLogger(['processCallFromPush'])(
|
|
119
|
+
'debug',
|
|
120
|
+
`joining call from push notification with callCid: ${callFromPush.cid}`
|
|
121
|
+
);
|
|
114
122
|
await callFromPush.join();
|
|
115
123
|
} else if (action === 'decline') {
|
|
116
124
|
const canReject =
|
|
117
125
|
callFromPush.state.callingState === CallingState.RINGING;
|
|
126
|
+
getLogger(['processCallFromPush'])(
|
|
127
|
+
'debug',
|
|
128
|
+
`declining call from push notification with callCid: ${callFromPush.cid} reject: ${canReject}`
|
|
129
|
+
);
|
|
118
130
|
await callFromPush.leave({ reject: canReject, reason: 'decline' });
|
|
119
131
|
}
|
|
120
132
|
} catch (e) {
|
|
121
133
|
const logger = getLogger(['processCallFromPush']);
|
|
122
134
|
logger(
|
|
123
|
-
'
|
|
135
|
+
'warn',
|
|
124
136
|
`failed to process ${action} call from push notification`,
|
|
125
137
|
e
|
|
126
138
|
);
|