@stream-io/video-react-native-sdk 0.9.7 → 0.10.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 +11 -0
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +21 -18
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/commonjs/utils/push/android.js +36 -29
- package/dist/commonjs/utils/push/android.js.map +1 -1
- package/dist/commonjs/utils/push/ios.js +3 -5
- package/dist/commonjs/utils/push/ios.js.map +1 -1
- package/dist/commonjs/utils/push/libs/index.js +11 -0
- package/dist/commonjs/utils/push/libs/index.js.map +1 -1
- package/dist/commonjs/utils/push/libs/notifee.js +27 -0
- package/dist/commonjs/utils/push/libs/notifee.js.map +1 -0
- package/dist/commonjs/version.js +1 -1
- package/dist/commonjs/version.js.map +1 -1
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +15 -10
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/module/utils/push/android.js +20 -11
- package/dist/module/utils/push/android.js.map +1 -1
- package/dist/module/utils/push/ios.js +4 -4
- package/dist/module/utils/push/ios.js.map +1 -1
- package/dist/module/utils/push/libs/index.js +1 -0
- package/dist/module/utils/push/libs/index.js.map +1 -1
- package/dist/module/utils/push/libs/notifee.js +20 -0
- package/dist/module/utils/push/libs/notifee.js.map +1 -0
- package/dist/module/version.js +1 -1
- package/dist/module/version.js.map +1 -1
- package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/types.d.ts +1 -1
- package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
- package/dist/typescript/utils/push/android.d.ts.map +1 -1
- package/dist/typescript/utils/push/ios.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/index.d.ts +1 -0
- package/dist/typescript/utils/push/libs/index.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/notifee.d.ts +4 -0
- package/dist/typescript/utils/push/libs/notifee.d.ts.map +1 -0
- package/dist/typescript/version.d.ts +1 -1
- package/dist/typescript/version.d.ts.map +1 -1
- package/expo-config-plugin/dist/withAndroidManifest.js +27 -32
- package/expo-config-plugin/dist/withAndroidPermissions.js +12 -11
- package/expo-config-plugin/dist/withMainActivity.js +13 -18
- package/package.json +5 -2
- package/src/hooks/useAndroidKeepCallAliveEffect.ts +29 -17
- package/src/utils/StreamVideoRN/types.ts +1 -1
- package/src/utils/push/android.ts +32 -13
- package/src/utils/push/ios.ts +9 -4
- package/src/utils/push/libs/index.ts +1 -0
- package/src/utils/push/libs/notifee.ts +33 -0
- package/src/version.ts +1 -1
|
@@ -9,25 +9,20 @@ const addNewLinesToMainActivity_1 = __importDefault(require("./common/addNewLine
|
|
|
9
9
|
const withStreamVideoReactNativeSDKMainActivity = (configuration, props) => {
|
|
10
10
|
return (0, config_plugins_1.withMainActivity)(configuration, (config) => {
|
|
11
11
|
const isMainActivityJava = config.modResults.language === 'java';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
config.modResults.contents = addOnUserLeaveHint(config.modResults.contents, isMainActivityJava);
|
|
24
|
-
}
|
|
25
|
-
if (props?.enableScreenshare) {
|
|
26
|
-
config.modResults.contents = addInsideOnCreate(config.modResults.contents, isMainActivityJava);
|
|
27
|
-
}
|
|
12
|
+
config.modResults.contents = (0, codeMod_1.addImports)(config.modResults.contents, [
|
|
13
|
+
'com.streamvideo.reactnative.StreamVideoReactNative',
|
|
14
|
+
'android.os.Build',
|
|
15
|
+
'android.util.Rational',
|
|
16
|
+
'androidx.lifecycle.Lifecycle',
|
|
17
|
+
'android.app.PictureInPictureParams',
|
|
18
|
+
'com.oney.WebRTCModule.WebRTCModuleOptions',
|
|
19
|
+
], isMainActivityJava);
|
|
20
|
+
config.modResults.contents = addOnPictureInPictureModeChanged(config.modResults.contents, isMainActivityJava);
|
|
21
|
+
if (props?.androidPictureInPicture?.enableAutomaticEnter) {
|
|
22
|
+
config.modResults.contents = addOnUserLeaveHint(config.modResults.contents, isMainActivityJava);
|
|
28
23
|
}
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
if (props?.enableScreenshare) {
|
|
25
|
+
config.modResults.contents = addInsideOnCreate(config.modResults.contents, isMainActivityJava);
|
|
31
26
|
}
|
|
32
27
|
return config;
|
|
33
28
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-io/video-react-native-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"packageManager": "yarn@3.2.4",
|
|
5
5
|
"main": "dist/commonjs/index.js",
|
|
6
6
|
"module": "dist/module/index.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"build:expo-plugin": "rimraf expo-config-plugin/dist && tsc --project expo-config-plugin/tsconfig.json",
|
|
18
18
|
"build": "yarn clean && yarn copy-version && bob build && yarn build:expo-plugin",
|
|
19
19
|
"test:expo-plugin": "jest expo-config-plugin --coverage",
|
|
20
|
-
"test": "jest --coverage && yarn test:expo-plugin",
|
|
20
|
+
"test": "yarn copy-version && jest --coverage && yarn test:expo-plugin",
|
|
21
21
|
"copy-version": "echo \"export const version = '$npm_package_version';\" > ./src/version.ts"
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
@@ -75,6 +75,9 @@
|
|
|
75
75
|
"react-native-voip-push-notification": ">=3.3.1"
|
|
76
76
|
},
|
|
77
77
|
"peerDependenciesMeta": {
|
|
78
|
+
"@notifee/react-native": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
78
81
|
"@react-native-community/push-notification-ios": {
|
|
79
82
|
"optional": true
|
|
80
83
|
},
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
2
2
|
import { useEffect, useRef } from 'react';
|
|
3
|
-
import notifee, { AuthorizationStatus } from '@notifee/react-native';
|
|
4
3
|
import { StreamVideoRN } from '../utils';
|
|
5
4
|
import { Platform } from 'react-native';
|
|
6
5
|
import { CallingState, getLogger } from '@stream-io/video-client';
|
|
6
|
+
import { getNotifeeLibNoThrowForKeepCallAlive } from '../utils/push/libs/notifee';
|
|
7
7
|
|
|
8
8
|
const isAndroid7OrBelow = Platform.OS === 'android' && Platform.Version < 26;
|
|
9
9
|
|
|
10
|
+
const notifeeLib = isAndroid7OrBelow
|
|
11
|
+
? getNotifeeLibNoThrowForKeepCallAlive()
|
|
12
|
+
: undefined;
|
|
13
|
+
|
|
10
14
|
function setForegroundService() {
|
|
11
15
|
if (!isAndroid7OrBelow) return;
|
|
12
|
-
|
|
16
|
+
notifeeLib?.default.registerForegroundService(() => {
|
|
13
17
|
return new Promise(() => {
|
|
14
18
|
const logger = getLogger(['setForegroundService method']);
|
|
15
19
|
logger('info', 'Foreground service running for call in progress');
|
|
@@ -23,8 +27,11 @@ async function startForegroundService(call_cid: string) {
|
|
|
23
27
|
const { title, body } = foregroundServiceConfig.android.notificationTexts;
|
|
24
28
|
|
|
25
29
|
// request for notification permission and then start the foreground service
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
if (!notifeeLib) return;
|
|
31
|
+
const settings = await notifeeLib.default.getNotificationSettings();
|
|
32
|
+
if (
|
|
33
|
+
settings.authorizationStatus !== notifeeLib.AuthorizationStatus.AUTHORIZED
|
|
34
|
+
) {
|
|
28
35
|
const logger = getLogger(['startForegroundService']);
|
|
29
36
|
logger(
|
|
30
37
|
'info',
|
|
@@ -32,7 +39,7 @@ async function startForegroundService(call_cid: string) {
|
|
|
32
39
|
);
|
|
33
40
|
return;
|
|
34
41
|
}
|
|
35
|
-
await
|
|
42
|
+
await notifeeLib.default.displayNotification({
|
|
36
43
|
id: call_cid,
|
|
37
44
|
title,
|
|
38
45
|
body,
|
|
@@ -69,6 +76,7 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
69
76
|
const callingState = useCallCallingState();
|
|
70
77
|
|
|
71
78
|
useEffect((): (() => void) | undefined => {
|
|
79
|
+
if (!notifeeLib) return;
|
|
72
80
|
if (Platform.OS === 'ios' || !activeCallCid) {
|
|
73
81
|
return;
|
|
74
82
|
}
|
|
@@ -79,6 +87,7 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
79
87
|
if (foregroundServiceStartedRef.current) {
|
|
80
88
|
return;
|
|
81
89
|
}
|
|
90
|
+
const notifee = notifeeLib.default;
|
|
82
91
|
notifee.getDisplayedNotifications().then((displayedNotifications) => {
|
|
83
92
|
const activeCallNotification = displayedNotifications.find(
|
|
84
93
|
(notification) => notification.id === activeCallCid
|
|
@@ -99,7 +108,7 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
99
108
|
// cancel any notifee displayed notification when the call has transitioned out of ringing
|
|
100
109
|
return () => {
|
|
101
110
|
// cancels the non fg service notifications
|
|
102
|
-
|
|
111
|
+
notifeeLib.default.cancelDisplayedNotification(activeCallCid);
|
|
103
112
|
};
|
|
104
113
|
} else if (
|
|
105
114
|
callingState === CallingState.IDLE ||
|
|
@@ -107,18 +116,20 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
107
116
|
) {
|
|
108
117
|
if (foregroundServiceStartedRef.current) {
|
|
109
118
|
// stop foreground service when the call is not active
|
|
110
|
-
|
|
119
|
+
notifeeLib.default.stopForegroundService();
|
|
111
120
|
foregroundServiceStartedRef.current = false;
|
|
112
121
|
} else {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
notifeeLib.default
|
|
123
|
+
.getDisplayedNotifications()
|
|
124
|
+
.then((displayedNotifications) => {
|
|
125
|
+
const activeCallNotification = displayedNotifications.find(
|
|
126
|
+
(notification) => notification.id === activeCallCid
|
|
127
|
+
);
|
|
128
|
+
if (activeCallNotification) {
|
|
129
|
+
// this means that we have a incoming call notification shown as foreground service and we must stop it
|
|
130
|
+
notifeeLib.default.stopForegroundService();
|
|
131
|
+
}
|
|
132
|
+
});
|
|
122
133
|
}
|
|
123
134
|
}
|
|
124
135
|
}, [activeCallCid, callingState]);
|
|
@@ -127,7 +138,8 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
127
138
|
return () => {
|
|
128
139
|
// stop foreground service when this effect is unmounted
|
|
129
140
|
if (foregroundServiceStartedRef.current) {
|
|
130
|
-
|
|
141
|
+
if (!notifeeLib) return;
|
|
142
|
+
notifeeLib.default.stopForegroundService();
|
|
131
143
|
foregroundServiceStartedRef.current = false;
|
|
132
144
|
}
|
|
133
145
|
};
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import notifee, {
|
|
2
|
-
EventType,
|
|
3
|
-
Event,
|
|
4
|
-
AndroidCategory,
|
|
5
|
-
} from '@notifee/react-native';
|
|
6
1
|
import { FirebaseMessagingTypes } from '@react-native-firebase/messaging';
|
|
7
2
|
import {
|
|
8
3
|
Call,
|
|
@@ -20,6 +15,8 @@ import {
|
|
|
20
15
|
getFirebaseMessagingLibNoThrow,
|
|
21
16
|
getExpoNotificationsLib,
|
|
22
17
|
getExpoTaskManagerLib,
|
|
18
|
+
getNotifeeLibThrowIfNotInstalledForPush,
|
|
19
|
+
NotifeeLib,
|
|
23
20
|
} from './libs';
|
|
24
21
|
import {
|
|
25
22
|
pushAcceptedIncomingCallCId$,
|
|
@@ -43,6 +40,14 @@ const DECLINE_CALL_ACTION_ID = 'decline';
|
|
|
43
40
|
|
|
44
41
|
type PushConfig = NonNullable<StreamVideoConfig['push']>;
|
|
45
42
|
|
|
43
|
+
type onBackgroundEventFunctionParams = Parameters<
|
|
44
|
+
NotifeeLib['default']['onBackgroundEvent']
|
|
45
|
+
>[0];
|
|
46
|
+
|
|
47
|
+
type Event = Parameters<onBackgroundEventFunctionParams>[0];
|
|
48
|
+
|
|
49
|
+
// EventType = NotifeeLib['EventType'];
|
|
50
|
+
|
|
46
51
|
/** Setup Firebase push message handler **/
|
|
47
52
|
export function setupFirebaseHandlerAndroid(pushConfig: PushConfig) {
|
|
48
53
|
if (Platform.OS !== 'android') {
|
|
@@ -114,6 +119,8 @@ export function setupFirebaseHandlerAndroid(pushConfig: PushConfig) {
|
|
|
114
119
|
}
|
|
115
120
|
|
|
116
121
|
// the notification tap handlers are always registered with notifee for both expo and non-expo in android
|
|
122
|
+
const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
|
|
123
|
+
const notifee = notifeeLib.default;
|
|
117
124
|
notifee.onBackgroundEvent(async (event) => {
|
|
118
125
|
await onNotifeeEvent(event, pushConfig, true);
|
|
119
126
|
});
|
|
@@ -208,6 +215,9 @@ const firebaseMessagingOnMessageHandler = async (
|
|
|
208
215
|
AppState.currentState !== 'active';
|
|
209
216
|
const asForegroundService = canListenToWS();
|
|
210
217
|
|
|
218
|
+
const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
|
|
219
|
+
const notifee = notifeeLib.default;
|
|
220
|
+
|
|
211
221
|
if (asForegroundService) {
|
|
212
222
|
// Listen to call events from WS through fg service
|
|
213
223
|
// note: this will replace the current empty fg service runner
|
|
@@ -291,7 +301,7 @@ const firebaseMessagingOnMessageHandler = async (
|
|
|
291
301
|
},
|
|
292
302
|
},
|
|
293
303
|
],
|
|
294
|
-
category: AndroidCategory.CALL,
|
|
304
|
+
category: notifeeLib.AndroidCategory.CALL,
|
|
295
305
|
fullScreenAction: {
|
|
296
306
|
id: 'stream_ringing_incoming_call',
|
|
297
307
|
},
|
|
@@ -316,6 +326,8 @@ const firebaseMessagingOnMessageHandler = async (
|
|
|
316
326
|
return;
|
|
317
327
|
}
|
|
318
328
|
} else {
|
|
329
|
+
const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
|
|
330
|
+
const notifee = notifeeLib.default;
|
|
319
331
|
// the other types are call.live_started and call.notification
|
|
320
332
|
const callChannel = pushConfig.android.callChannel;
|
|
321
333
|
const callNotificationTextGetters =
|
|
@@ -376,18 +388,24 @@ const onNotifeeEvent = async (
|
|
|
376
388
|
pushAcceptedIncomingCallCId$.observed &&
|
|
377
389
|
pushRejectedIncomingCallCId$.observed;
|
|
378
390
|
|
|
391
|
+
const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
|
|
392
|
+
const notifee = notifeeLib.default;
|
|
379
393
|
// Check if we need to decline the call
|
|
380
394
|
const didPressDecline =
|
|
381
|
-
type === EventType.ACTION_PRESS &&
|
|
395
|
+
type === notifeeLib.EventType.ACTION_PRESS &&
|
|
382
396
|
pressAction?.id === DECLINE_CALL_ACTION_ID;
|
|
383
|
-
const didDismiss = type === EventType.DISMISSED;
|
|
397
|
+
const didDismiss = type === notifeeLib.EventType.DISMISSED;
|
|
384
398
|
const mustDecline = didPressDecline || didDismiss;
|
|
385
399
|
// Check if we need to accept the call
|
|
386
400
|
const mustAccept =
|
|
387
|
-
type === EventType.ACTION_PRESS &&
|
|
401
|
+
type === notifeeLib.EventType.ACTION_PRESS &&
|
|
388
402
|
pressAction?.id === ACCEPT_CALL_ACTION_ID;
|
|
389
403
|
|
|
390
|
-
if (
|
|
404
|
+
if (
|
|
405
|
+
mustAccept ||
|
|
406
|
+
mustDecline ||
|
|
407
|
+
type === notifeeLib.EventType.ACTION_PRESS
|
|
408
|
+
) {
|
|
391
409
|
clearPushWSEventSubscriptions();
|
|
392
410
|
notifee.stopForegroundService();
|
|
393
411
|
}
|
|
@@ -403,16 +421,17 @@ const onNotifeeEvent = async (
|
|
|
403
421
|
}
|
|
404
422
|
await processCallFromPushInBackground(pushConfig, call_cid, 'decline');
|
|
405
423
|
} else {
|
|
406
|
-
if (type === EventType.PRESS) {
|
|
424
|
+
if (type === notifeeLib.EventType.PRESS) {
|
|
407
425
|
pushTappedIncomingCallCId$.next(call_cid);
|
|
408
426
|
// pressed state will be handled by the app with rxjs observers as the app will go to foreground always
|
|
409
|
-
} else if (isBackground && type === EventType.DELIVERED) {
|
|
427
|
+
} else if (isBackground && type === notifeeLib.EventType.DELIVERED) {
|
|
410
428
|
pushAndroidBackgroundDeliveredIncomingCallCId$.next(call_cid);
|
|
411
429
|
// background delivered state will be handled by the app with rxjs observers as processing needs to happen only when app is opened
|
|
412
430
|
}
|
|
413
431
|
}
|
|
414
432
|
} else {
|
|
415
|
-
|
|
433
|
+
const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
|
|
434
|
+
if (type === notifeeLib.EventType.PRESS) {
|
|
416
435
|
pushTappedIncomingCallCId$.next(call_cid);
|
|
417
436
|
pushConfig.onTapNonRingingCallNotification?.(
|
|
418
437
|
call_cid,
|
package/src/utils/push/ios.ts
CHANGED
|
@@ -14,10 +14,13 @@ import {
|
|
|
14
14
|
clearPushWSEventSubscriptions,
|
|
15
15
|
processCallFromPushInBackground,
|
|
16
16
|
} from './utils';
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
getExpoNotificationsLib,
|
|
19
|
+
getNotifeeLibThrowIfNotInstalledForPush,
|
|
20
|
+
getPushNotificationIosLib,
|
|
21
|
+
} from './libs';
|
|
18
22
|
import { StreamVideoClient, getLogger } from '@stream-io/video-client';
|
|
19
23
|
import { setPushLogoutCallback } from '../internal/pushLogoutCallback';
|
|
20
|
-
import notifee, { EventType } from '@notifee/react-native';
|
|
21
24
|
|
|
22
25
|
type PushConfig = NonNullable<StreamVideoConfig['push']>;
|
|
23
26
|
|
|
@@ -96,8 +99,10 @@ export const setupRemoteNotificationsHandleriOS = (pushConfig: PushConfig) => {
|
|
|
96
99
|
if (Platform.OS !== 'ios') {
|
|
97
100
|
return;
|
|
98
101
|
}
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
const notifeeLib = getNotifeeLibThrowIfNotInstalledForPush();
|
|
103
|
+
|
|
104
|
+
notifeeLib.default.onForegroundEvent(({ type, detail }) => {
|
|
105
|
+
if (type === notifeeLib.EventType.PRESS) {
|
|
101
106
|
const streamPayload = detail.notification?.data?.stream as
|
|
102
107
|
| StreamPayload
|
|
103
108
|
| undefined;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { getLogger } from '../../..';
|
|
2
|
+
|
|
3
|
+
export type NotifeeLib = typeof import('@notifee/react-native');
|
|
4
|
+
|
|
5
|
+
let notifeeLib: NotifeeLib | undefined;
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
notifeeLib = require('@notifee/react-native');
|
|
9
|
+
} catch (_e) {}
|
|
10
|
+
|
|
11
|
+
const INSTALLATION_INSTRUCTION =
|
|
12
|
+
'Please see https://notifee.app/react-native/docs/installation for installation instructions';
|
|
13
|
+
|
|
14
|
+
export function getNotifeeLibThrowIfNotInstalledForPush() {
|
|
15
|
+
if (!notifeeLib) {
|
|
16
|
+
throw Error(
|
|
17
|
+
'@notifee/react-native is not installed. It is required for implementing push notifications. ' +
|
|
18
|
+
INSTALLATION_INSTRUCTION
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
return notifeeLib;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function getNotifeeLibNoThrowForKeepCallAlive() {
|
|
25
|
+
if (!notifeeLib) {
|
|
26
|
+
const logger = getLogger(['getNotifeeLibNoThrow']);
|
|
27
|
+
logger(
|
|
28
|
+
'info',
|
|
29
|
+
`${'@notifee/react-native library not installed. It is required to keep call alive in the background for Android < 26. '}${INSTALLATION_INSTRUCTION}`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
return notifeeLib;
|
|
33
|
+
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '0.
|
|
1
|
+
export const version = '0.10.0';
|