@stream-io/video-react-native-sdk 1.28.2 → 1.29.0-beta.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/android/src/main/AndroidManifest.xml +8 -1
- package/android/src/main/AndroidManifestNew.xml +11 -0
- package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +42 -5
- package/android/src/main/java/com/streamvideo/reactnative/keepalive/KeepAliveNotification.kt +83 -0
- package/android/src/main/java/com/streamvideo/reactnative/keepalive/StreamCallKeepAliveHeadlessService.kt +134 -0
- package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js +235 -0
- package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +60 -97
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/commonjs/index.js +1 -0
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/modules/call-manager/CallManager.js +20 -0
- 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 +33 -21
- package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/commonjs/utils/internal/registerSDKGlobals.js +47 -3
- package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/commonjs/utils/keepCallAliveHeadlessTask.js +48 -0
- package/dist/commonjs/utils/keepCallAliveHeadlessTask.js.map +1 -0
- package/dist/commonjs/utils/push/android.js +145 -200
- package/dist/commonjs/utils/push/android.js.map +1 -1
- package/dist/commonjs/utils/push/internal/ios.js +16 -34
- package/dist/commonjs/utils/push/internal/ios.js.map +1 -1
- package/dist/commonjs/utils/push/internal/rxSubjects.js +1 -20
- package/dist/commonjs/utils/push/internal/rxSubjects.js.map +1 -1
- package/dist/commonjs/utils/push/internal/utils.js +17 -1
- 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/callingx.js +75 -0
- package/dist/commonjs/utils/push/libs/callingx.js.map +1 -0
- package/dist/commonjs/utils/push/libs/index.js +8 -19
- package/dist/commonjs/utils/push/libs/index.js.map +1 -1
- package/dist/commonjs/utils/push/libs/notifee/index.js +0 -19
- package/dist/commonjs/utils/push/libs/notifee/index.js.map +1 -1
- package/dist/commonjs/utils/push/setupCallingExpEvents.js +75 -0
- package/dist/commonjs/utils/push/setupCallingExpEvents.js.map +1 -0
- package/dist/commonjs/utils/push/setupIosVoipPushEvents.js +7 -6
- package/dist/commonjs/utils/push/setupIosVoipPushEvents.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js +228 -0
- package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +62 -99
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/module/index.js +1 -0
- package/dist/module/index.js.map +1 -1
- package/dist/module/modules/call-manager/CallManager.js +20 -0
- 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 +33 -21
- package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/module/utils/internal/registerSDKGlobals.js +48 -4
- package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/module/utils/keepCallAliveHeadlessTask.js +42 -0
- package/dist/module/utils/keepCallAliveHeadlessTask.js.map +1 -0
- package/dist/module/utils/push/android.js +147 -202
- package/dist/module/utils/push/android.js.map +1 -1
- package/dist/module/utils/push/internal/ios.js +16 -34
- package/dist/module/utils/push/internal/ios.js.map +1 -1
- package/dist/module/utils/push/internal/rxSubjects.js +0 -19
- package/dist/module/utils/push/internal/rxSubjects.js.map +1 -1
- package/dist/module/utils/push/internal/utils.js +14 -0
- 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/callingx.js +67 -0
- package/dist/module/utils/push/libs/callingx.js.map +1 -0
- package/dist/module/utils/push/libs/index.js +1 -2
- package/dist/module/utils/push/libs/index.js.map +1 -1
- package/dist/module/utils/push/libs/notifee/index.js +0 -18
- package/dist/module/utils/push/libs/notifee/index.js.map +1 -1
- package/dist/module/utils/push/setupCallingExpEvents.js +69 -0
- package/dist/module/utils/push/setupCallingExpEvents.js.map +1 -0
- package/dist/module/utils/push/setupIosVoipPushEvents.js +7 -6
- package/dist/module/utils/push/setupIosVoipPushEvents.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts +5 -0
- package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts.map +1 -0
- package/dist/typescript/hooks/push/useIosVoipPushEventsSetupEffect.d.ts.map +1 -1
- package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
- package/dist/typescript/index.d.ts +1 -0
- package/dist/typescript/index.d.ts.map +1 -1
- package/dist/typescript/modules/call-manager/CallManager.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/index.d.ts +20 -2
- package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/types.d.ts +54 -29
- 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/keepCallAliveHeadlessTask.d.ts +10 -0
- package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts.map +1 -0
- package/dist/typescript/utils/push/android.d.ts +1 -2
- 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 +0 -12
- package/dist/typescript/utils/push/internal/rxSubjects.d.ts.map +1 -1
- package/dist/typescript/utils/push/internal/utils.d.ts +4 -0
- package/dist/typescript/utils/push/internal/utils.d.ts.map +1 -1
- package/dist/typescript/utils/push/ios.d.ts +1 -2
- package/dist/typescript/utils/push/ios.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/callingx.d.ts +9 -0
- package/dist/typescript/utils/push/libs/callingx.d.ts.map +1 -0
- package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts +16 -2
- package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/index.d.ts +1 -2
- package/dist/typescript/utils/push/libs/index.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/notifee/index.d.ts +0 -1
- package/dist/typescript/utils/push/libs/notifee/index.d.ts.map +1 -1
- package/dist/typescript/utils/push/setupCallingExpEvents.d.ts +8 -0
- package/dist/typescript/utils/push/setupCallingExpEvents.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/expo-config-plugin/dist/withAndroidManifest.js +1 -33
- package/expo-config-plugin/dist/withAndroidPermissions.js +2 -7
- package/expo-config-plugin/dist/withAppDelegate.js +19 -197
- package/expo-config-plugin/dist/withMainActivity.js +1 -1
- package/expo-config-plugin/dist/withiOSInfoPlist.js +2 -3
- package/ios/StreamInCallManager.swift +4 -0
- package/ios/StreamVideoReactNative.h +7 -4
- package/ios/StreamVideoReactNative.m +191 -82
- package/package.json +12 -17
- package/src/hooks/push/useCallingExpWithCallingStateEffect.ts +361 -0
- package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +21 -34
- package/src/hooks/useAndroidKeepCallAliveEffect.ts +95 -120
- package/src/index.ts +1 -0
- package/src/modules/call-manager/CallManager.ts +30 -0
- package/src/providers/StreamCall/index.tsx +6 -6
- package/src/utils/StreamVideoRN/index.ts +40 -30
- package/src/utils/StreamVideoRN/types.ts +56 -29
- package/src/utils/internal/registerSDKGlobals.ts +42 -4
- package/src/utils/keepCallAliveHeadlessTask.ts +54 -0
- package/src/utils/push/android.ts +223 -308
- package/src/utils/push/internal/ios.ts +25 -46
- package/src/utils/push/internal/rxSubjects.ts +0 -29
- package/src/utils/push/internal/utils.ts +25 -0
- package/src/utils/push/ios.ts +1 -6
- package/src/utils/push/libs/callingx.ts +90 -0
- package/src/utils/push/libs/index.ts +1 -2
- package/src/utils/push/libs/notifee/index.ts +0 -27
- package/src/utils/push/setupCallingExpEvents.ts +100 -0
- package/src/utils/push/setupIosVoipPushEvents.ts +11 -7
- package/src/version.ts +1 -1
- package/CHANGELOG.md +0 -3096
- package/android/src/main/java/com/streamvideo/reactnative/util/CallAliveServiceChecker.kt +0 -95
- package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -160
- package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
- package/dist/commonjs/utils/push/libs/callkeep.js +0 -17
- package/dist/commonjs/utils/push/libs/callkeep.js.map +0 -1
- package/dist/commonjs/utils/push/libs/voipPushNotification.js +0 -17
- package/dist/commonjs/utils/push/libs/voipPushNotification.js.map +0 -1
- package/dist/commonjs/utils/push/setupIosCallKeepEvents.js +0 -205
- package/dist/commonjs/utils/push/setupIosCallKeepEvents.js.map +0 -1
- package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -153
- package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
- package/dist/module/utils/push/libs/callkeep.js +0 -11
- package/dist/module/utils/push/libs/callkeep.js.map +0 -1
- package/dist/module/utils/push/libs/voipPushNotification.js +0 -11
- package/dist/module/utils/push/libs/voipPushNotification.js.map +0 -1
- package/dist/module/utils/push/setupIosCallKeepEvents.js +0 -199
- package/dist/module/utils/push/setupIosCallKeepEvents.js.map +0 -1
- package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts +0 -5
- package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts.map +0 -1
- package/dist/typescript/utils/push/libs/callkeep.d.ts +0 -3
- package/dist/typescript/utils/push/libs/callkeep.d.ts.map +0 -1
- package/dist/typescript/utils/push/libs/voipPushNotification.d.ts +0 -3
- package/dist/typescript/utils/push/libs/voipPushNotification.d.ts.map +0 -1
- package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts +0 -6
- package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts.map +0 -1
- package/src/hooks/push/useIosCallkeepWithCallingStateEffect.ts +0 -235
- package/src/utils/push/libs/callkeep.ts +0 -16
- package/src/utils/push/libs/voipPushNotification.ts +0 -17
- package/src/utils/push/setupIosCallKeepEvents.ts +0 -252
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
package="com.streamvideo.reactnative">
|
|
3
3
|
|
|
4
4
|
<uses-permission android:name="android.permission.INTERNET" />
|
|
5
|
-
<uses-permission android:name="android.permission.DEVICE_POWER" />
|
|
6
5
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
6
|
+
|
|
7
|
+
<application>
|
|
8
|
+
<service
|
|
9
|
+
android:name="com.streamvideo.reactnative.keepalive.StreamCallKeepAliveHeadlessService"
|
|
10
|
+
android:exported="false"
|
|
11
|
+
android:stopWithTask="true"
|
|
12
|
+
android:foregroundServiceType="mediaPlayback|camera|microphone" />
|
|
13
|
+
</application>
|
|
7
14
|
</manifest>
|
|
@@ -1,2 +1,13 @@
|
|
|
1
1
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
|
|
3
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
4
|
+
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
5
|
+
|
|
6
|
+
<application>
|
|
7
|
+
<service
|
|
8
|
+
android:name="com.streamvideo.reactnative.keepalive.StreamCallKeepAliveHeadlessService"
|
|
9
|
+
android:exported="false"
|
|
10
|
+
android:stopWithTask="true"
|
|
11
|
+
android:foregroundServiceType="mediaPlayback|camera|microphone" />
|
|
12
|
+
</application>
|
|
2
13
|
</manifest>
|
|
@@ -15,6 +15,7 @@ import android.os.Build
|
|
|
15
15
|
import android.os.PowerManager
|
|
16
16
|
import android.util.Base64
|
|
17
17
|
import android.util.Log
|
|
18
|
+
import androidx.core.content.ContextCompat
|
|
18
19
|
import com.facebook.react.bridge.Arguments
|
|
19
20
|
import com.facebook.react.bridge.Promise
|
|
20
21
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
@@ -23,8 +24,8 @@ import com.facebook.react.bridge.ReactMethod
|
|
|
23
24
|
import com.facebook.react.bridge.WritableMap
|
|
24
25
|
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
|
|
25
26
|
import com.oney.WebRTCModule.WebRTCModule
|
|
27
|
+
import com.streamvideo.reactnative.keepalive.StreamCallKeepAliveHeadlessService
|
|
26
28
|
import com.streamvideo.reactnative.util.CallAlivePermissionsHelper
|
|
27
|
-
import com.streamvideo.reactnative.util.CallAliveServiceChecker
|
|
28
29
|
import com.streamvideo.reactnative.util.PiPHelper
|
|
29
30
|
import com.streamvideo.reactnative.util.RingtoneUtil
|
|
30
31
|
import com.streamvideo.reactnative.util.YuvFrame
|
|
@@ -115,11 +116,47 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) :
|
|
|
115
116
|
promise.resolve(false)
|
|
116
117
|
return
|
|
117
118
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
// Service is declared in the SDK's own AndroidManifest and merged by default.
|
|
120
|
+
// Permissions are expected to be provided by the app (or via Expo config plugin).
|
|
121
|
+
promise.resolve(true)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@ReactMethod
|
|
126
|
+
fun startKeepCallAliveService(
|
|
127
|
+
callCid: String,
|
|
128
|
+
channelId: String,
|
|
129
|
+
channelName: String,
|
|
130
|
+
title: String,
|
|
131
|
+
body: String,
|
|
132
|
+
smallIconName: String?,
|
|
133
|
+
promise: Promise
|
|
134
|
+
) {
|
|
135
|
+
try {
|
|
136
|
+
val intent = StreamCallKeepAliveHeadlessService.buildStartIntent(
|
|
137
|
+
reactApplicationContext,
|
|
138
|
+
callCid,
|
|
139
|
+
channelId,
|
|
140
|
+
channelName,
|
|
141
|
+
title,
|
|
142
|
+
body,
|
|
143
|
+
smallIconName
|
|
144
|
+
)
|
|
145
|
+
ContextCompat.startForegroundService(reactApplicationContext, intent)
|
|
122
146
|
promise.resolve(true)
|
|
147
|
+
} catch (e: Exception) {
|
|
148
|
+
promise.reject(NAME, "Failed to start keep call alive foreground service", e)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@ReactMethod
|
|
153
|
+
fun stopKeepCallAliveService(promise: Promise) {
|
|
154
|
+
try {
|
|
155
|
+
val intent = StreamCallKeepAliveHeadlessService.buildStopIntent(reactApplicationContext)
|
|
156
|
+
val stopped = reactApplicationContext.stopService(intent)
|
|
157
|
+
promise.resolve(stopped)
|
|
158
|
+
} catch (e: Exception) {
|
|
159
|
+
promise.reject(NAME, "Failed to stop keep call alive foreground service", e)
|
|
123
160
|
}
|
|
124
161
|
}
|
|
125
162
|
|
|
@@ -0,0 +1,83 @@
|
|
|
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
|
+
|
|
@@ -0,0 +1,134 @@
|
|
|
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 androidx.annotation.RequiresApi
|
|
9
|
+
import androidx.core.app.ServiceCompat
|
|
10
|
+
import androidx.core.content.ContextCompat
|
|
11
|
+
import com.facebook.react.HeadlessJsTaskService
|
|
12
|
+
import com.facebook.react.bridge.Arguments
|
|
13
|
+
import com.facebook.react.jstasks.HeadlessJsTaskConfig
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Foreground service that runs a React Native HeadlessJS task to keep a call alive.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
class StreamCallKeepAliveHeadlessService : HeadlessJsTaskService() {
|
|
20
|
+
|
|
21
|
+
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
22
|
+
val safeIntent = intent ?: Intent()
|
|
23
|
+
val channelId = safeIntent.getStringExtra(EXTRA_CHANNEL_ID) ?: DEFAULT_CHANNEL_ID
|
|
24
|
+
val channelName = safeIntent.getStringExtra(EXTRA_CHANNEL_NAME) ?: DEFAULT_CHANNEL_NAME
|
|
25
|
+
val title = safeIntent.getStringExtra(EXTRA_TITLE) ?: DEFAULT_TITLE
|
|
26
|
+
val body = safeIntent.getStringExtra(EXTRA_BODY) ?: DEFAULT_BODY
|
|
27
|
+
val smallIconName = safeIntent.getStringExtra(EXTRA_SMALL_ICON_NAME)
|
|
28
|
+
|
|
29
|
+
KeepAliveNotification.ensureChannel(this, channelId, channelName)
|
|
30
|
+
val notification = KeepAliveNotification.buildOngoingNotification(
|
|
31
|
+
context = this,
|
|
32
|
+
channelId = channelId,
|
|
33
|
+
title = title,
|
|
34
|
+
body = body,
|
|
35
|
+
smallIconName = smallIconName
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
startForegroundCompat(notification)
|
|
39
|
+
|
|
40
|
+
// Ensure HeadlessJS task is started
|
|
41
|
+
return super.onStartCommand(safeIntent, flags, startId)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
override fun getTaskConfig(intent: Intent?): HeadlessJsTaskConfig? {
|
|
45
|
+
val callCid = intent?.getStringExtra(EXTRA_CALL_CID) ?: return null
|
|
46
|
+
val data = Arguments.createMap().apply {
|
|
47
|
+
putString("callCid", callCid)
|
|
48
|
+
}
|
|
49
|
+
// We intentionally allow long-running work (the JS task can return a never-resolving Promise).
|
|
50
|
+
return HeadlessJsTaskConfig(
|
|
51
|
+
TASK_NAME,
|
|
52
|
+
data,
|
|
53
|
+
0, // timeout (0 = no timeout)
|
|
54
|
+
true // allowedInForeground
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
override fun onDestroy() {
|
|
59
|
+
super.onDestroy()
|
|
60
|
+
stopForeground(STOP_FOREGROUND_REMOVE)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@RequiresApi(Build.VERSION_CODES.R)
|
|
64
|
+
private fun computeForegroundServiceTypes(): Int {
|
|
65
|
+
var types = ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
|
|
66
|
+
|
|
67
|
+
val hasCameraPermission =
|
|
68
|
+
ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
|
|
69
|
+
if (hasCameraPermission) {
|
|
70
|
+
types = types or ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
val hasMicrophonePermission =
|
|
74
|
+
ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
|
|
75
|
+
if (hasMicrophonePermission) {
|
|
76
|
+
types = types or ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return types
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private fun startForegroundCompat(notification: android.app.Notification) {
|
|
83
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
84
|
+
val types = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) computeForegroundServiceTypes() else ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
|
|
85
|
+
startForeground(NOTIFICATION_ID, notification, types)
|
|
86
|
+
} else {
|
|
87
|
+
startForeground(NOTIFICATION_ID, notification)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
companion object {
|
|
92
|
+
const val TASK_NAME = "StreamVideoKeepCallAlive"
|
|
93
|
+
|
|
94
|
+
const val EXTRA_CALL_CID = "callCid"
|
|
95
|
+
const val EXTRA_CHANNEL_ID = "channelId"
|
|
96
|
+
const val EXTRA_CHANNEL_NAME = "channelName"
|
|
97
|
+
const val EXTRA_TITLE = "title"
|
|
98
|
+
const val EXTRA_BODY = "body"
|
|
99
|
+
const val EXTRA_SMALL_ICON_NAME = "smallIconName"
|
|
100
|
+
|
|
101
|
+
private const val NOTIFICATION_ID = 6061
|
|
102
|
+
|
|
103
|
+
private const val DEFAULT_CHANNEL_ID = "stream_call_foreground_service"
|
|
104
|
+
private const val DEFAULT_CHANNEL_NAME = "Call in progress"
|
|
105
|
+
private const val DEFAULT_TITLE = "Call in progress"
|
|
106
|
+
private const val DEFAULT_BODY = "Tap to return to the call"
|
|
107
|
+
|
|
108
|
+
fun buildStartIntent(
|
|
109
|
+
context: android.content.Context,
|
|
110
|
+
callCid: String,
|
|
111
|
+
channelId: String,
|
|
112
|
+
channelName: String,
|
|
113
|
+
title: String,
|
|
114
|
+
body: String,
|
|
115
|
+
smallIconName: String?
|
|
116
|
+
): Intent {
|
|
117
|
+
return Intent(context, StreamCallKeepAliveHeadlessService::class.java).apply {
|
|
118
|
+
putExtra(EXTRA_CALL_CID, callCid)
|
|
119
|
+
putExtra(EXTRA_CHANNEL_ID, channelId)
|
|
120
|
+
putExtra(EXTRA_CHANNEL_NAME, channelName)
|
|
121
|
+
putExtra(EXTRA_TITLE, title)
|
|
122
|
+
putExtra(EXTRA_BODY, body)
|
|
123
|
+
if (!smallIconName.isNullOrBlank()) {
|
|
124
|
+
putExtra(EXTRA_SMALL_ICON_NAME, smallIconName)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
fun buildStopIntent(context: android.content.Context): Intent {
|
|
130
|
+
return Intent(context, StreamCallKeepAliveHeadlessService::class.java)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
@@ -0,0 +1,235 @@
|
|
|
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 _callingx = require("../../utils/push/libs/callingx");
|
|
11
|
+
const logger = _videoClient.videoLoggerSystem.getLogger('useCallingExpWithCallingStateEffect');
|
|
12
|
+
|
|
13
|
+
//calling state methods are not exhaustive, so we need to add more methods to cover different cases
|
|
14
|
+
const canAcceptIncomingCall = (prevState, currentState) => {
|
|
15
|
+
if (!prevState && !currentState) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
const isJoined = state => {
|
|
19
|
+
if (!state) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return state === _videoClient.CallingState.JOINING || state === _videoClient.CallingState.JOINED;
|
|
23
|
+
};
|
|
24
|
+
return !isJoined(prevState) && isJoined(currentState) || prevState === _videoClient.CallingState.JOINING && currentState === _videoClient.CallingState.JOINED;
|
|
25
|
+
};
|
|
26
|
+
const canEndCall = (prevState, currentState) => {
|
|
27
|
+
if (!prevState && !currentState) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return (prevState === _videoClient.CallingState.JOINED || prevState === _videoClient.CallingState.JOINING || prevState === _videoClient.CallingState.RINGING || prevState === _videoClient.CallingState.RECONNECTING || prevState === _videoClient.CallingState.MIGRATING || prevState === _videoClient.CallingState.OFFLINE) && (currentState === _videoClient.CallingState.LEFT || currentState === _videoClient.CallingState.RECONNECTING_FAILED || currentState === _videoClient.CallingState.IDLE);
|
|
31
|
+
};
|
|
32
|
+
const canStartCall = (prevState, currentState) => {
|
|
33
|
+
if (!prevState && !currentState) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
return (!prevState || prevState === _videoClient.CallingState.IDLE || prevState === _videoClient.CallingState.UNKNOWN) && (currentState === _videoClient.CallingState.JOINED || currentState === _videoClient.CallingState.JOINING || currentState === _videoClient.CallingState.RINGING);
|
|
37
|
+
};
|
|
38
|
+
function getCallDisplayName(callMembers, participants, currentUserId) {
|
|
39
|
+
if (!callMembers || !participants || !currentUserId) {
|
|
40
|
+
return 'Call';
|
|
41
|
+
}
|
|
42
|
+
let names = [];
|
|
43
|
+
if (callMembers.length > 0) {
|
|
44
|
+
names = callMembers.filter(member => member.user.id !== currentUserId).map(member => member.user.name).filter(name => name !== undefined);
|
|
45
|
+
} else if (participants.length > 0) {
|
|
46
|
+
names = participants.filter(participant => participant.userId !== currentUserId).map(participant => participant.name).filter(Boolean);
|
|
47
|
+
}
|
|
48
|
+
return names.length > 0 ? names.sort().join(', ') : 'Call';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* This hook is used to inform sync call state with CallKit/Telecom (i.e. start call, end call, mute/unmute call).
|
|
53
|
+
*/
|
|
54
|
+
const useCallingExpWithCallingStateEffect = () => {
|
|
55
|
+
const {
|
|
56
|
+
useCallCallingState,
|
|
57
|
+
// useMicrophoneState,
|
|
58
|
+
useParticipants,
|
|
59
|
+
useCallMembers
|
|
60
|
+
} = (0, _videoReactBindings.useCallStateHooks)();
|
|
61
|
+
const activeCall = (0, _videoReactBindings.useCall)();
|
|
62
|
+
const callingState = useCallCallingState();
|
|
63
|
+
// const { isMute, microphone } = useMicrophoneState();
|
|
64
|
+
const callMembers = useCallMembers();
|
|
65
|
+
const participants = useParticipants();
|
|
66
|
+
const prevState = (0, _react.useRef)(undefined);
|
|
67
|
+
const activeCallCid = activeCall?.cid;
|
|
68
|
+
const isIncomingCall = activeCall?.ringing && !activeCall?.isCreatedByMe;
|
|
69
|
+
const isOutcomingCall = activeCall?.ringing && activeCall?.isCreatedByMe;
|
|
70
|
+
const currentUserId = activeCall?.currentUserId;
|
|
71
|
+
const isVideoCall = activeCall?.state.settings?.video?.enabled ?? false;
|
|
72
|
+
const callDisplayName = (0, _react.useMemo)(() => getCallDisplayName(callMembers, participants, currentUserId), [callMembers, participants, currentUserId]);
|
|
73
|
+
(0, _react.useEffect)(() => {
|
|
74
|
+
return () => {
|
|
75
|
+
const callingx = (0, _callingx.getCallingxLibIfAvailable)();
|
|
76
|
+
if (!callingx?.isSetup || !activeCallCid) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const isCallRegistered = callingx.isCallRegistered(activeCallCid);
|
|
80
|
+
if (!isCallRegistered) {
|
|
81
|
+
logger.debug(`No active call cid to end in calling exp: ${activeCallCid} isCallRegistered: ${isCallRegistered}`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
//if incoming stream call was unmounted, we need to end the call in CallKit/Telecom
|
|
85
|
+
logger.debug(`Ending call in calling exp: ${activeCallCid}`);
|
|
86
|
+
callingx.endCallWithReason(activeCallCid, 'local').catch(error => {
|
|
87
|
+
logger.error(`Error ending call in calling exp: ${activeCallCid}`, error);
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
}, [activeCallCid]);
|
|
91
|
+
(0, _react.useEffect)(() => {
|
|
92
|
+
const callingx = (0, _callingx.getCallingxLibIfAvailable)();
|
|
93
|
+
if (!callingx?.isSetup || !activeCallCid || prevState.current === callingState) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//tells if call is registered in CallKit/Telecom
|
|
98
|
+
const isCallRegistered = callingx.isCallRegistered(activeCallCid);
|
|
99
|
+
logger.debug(`useEffect: ${activeCallCid} isCallRegistered: ${isCallRegistered}
|
|
100
|
+
isIncomingCall: ${isIncomingCall} isOutcomingCall: ${isOutcomingCall}
|
|
101
|
+
prevState: ${prevState.current}, currentState: ${callingState}
|
|
102
|
+
isOngoingCallsEnabled: ${callingx.isOngoingCallsEnabled}`);
|
|
103
|
+
if (isIncomingCall && isCallRegistered && canAcceptIncomingCall(prevState.current, callingState)) {
|
|
104
|
+
logger.debug(`Should accept call in callkeep: ${activeCallCid}`);
|
|
105
|
+
callingx.answerIncomingCall(activeCallCid).catch(error => {
|
|
106
|
+
logger.error(`Error answering call in calling exp: ${activeCallCid}`, error);
|
|
107
|
+
});
|
|
108
|
+
} else if ((isOutcomingCall || !isIncomingCall && callingx.isOngoingCallsEnabled) &&
|
|
109
|
+
//we register call in case if is outcoming ringing call or it is non-ringing call and ongoing calls are enabled
|
|
110
|
+
!isCallRegistered && canStartCall(prevState.current, callingState)) {
|
|
111
|
+
logger.debug(`Should register call in callkeep: ${activeCallCid}`);
|
|
112
|
+
//we request start call action from CallKit/Telecom, next step is to make call active when we receive call started event
|
|
113
|
+
callingx.startCall(activeCallCid, activeCallCid, callDisplayName, isVideoCall).catch(error => {
|
|
114
|
+
logger.error(`Error starting call in calling exp: ${activeCallCid}`, error);
|
|
115
|
+
});
|
|
116
|
+
} else if (isCallRegistered && canEndCall(prevState.current, callingState)) {
|
|
117
|
+
//in case call was registered as incoming and state changed to "not joined", we need to end the call and clear rxjs subject
|
|
118
|
+
logger.debug(`Should end call in callkeep: ${activeCallCid}`);
|
|
119
|
+
//TODO: think about sending appropriate reason for end call
|
|
120
|
+
callingx.endCallWithReason(activeCallCid, 'local').catch(error => {
|
|
121
|
+
logger.error(`Error ending call in calling exp: ${activeCallCid}`, error);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
prevState.current = callingState;
|
|
125
|
+
}, [activeCallCid, callingState, callDisplayName, isIncomingCall, isOutcomingCall, isVideoCall]);
|
|
126
|
+
(0, _react.useEffect)(() => {
|
|
127
|
+
const callingx = (0, _callingx.getCallingxLibIfAvailable)();
|
|
128
|
+
if (!callingx?.isSetup || !activeCallCid) {
|
|
129
|
+
logger.debug(`No active call cid to listen to start call action in calling exp: ${activeCallCid} callingx is not setup`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (!isOutcomingCall && !(!isIncomingCall && callingx.isOngoingCallsEnabled)) {
|
|
133
|
+
logger.debug(`Call is not outcoming or ongoing calls are not enabled for non-ringing calls`);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
//listen to start call action from CallKit/Telecom and set the current call active
|
|
138
|
+
const subscription = callingx.addEventListener('didReceiveStartCallAction', ({
|
|
139
|
+
callId
|
|
140
|
+
}) => {
|
|
141
|
+
if (callId === activeCallCid) {
|
|
142
|
+
logger.debug(`Received start call action for call: ${activeCallCid}`);
|
|
143
|
+
callingx.setCurrentCallActive(activeCallCid).catch(error => {
|
|
144
|
+
logger.error(`Error answering call in calling exp: ${activeCallCid}`, error);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
return () => {
|
|
149
|
+
subscription.remove();
|
|
150
|
+
};
|
|
151
|
+
}, [activeCallCid, isOutcomingCall, isIncomingCall]);
|
|
152
|
+
(0, _react.useEffect)(() => {
|
|
153
|
+
const callingx = (0, _callingx.getCallingxLibIfAvailable)();
|
|
154
|
+
if (!callingx?.isSetup || !activeCallCid) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const isCallRegistered = callingx.isCallRegistered(activeCallCid);
|
|
158
|
+
if (!isCallRegistered) {
|
|
159
|
+
logger.debug(`No active call cid to update calling exp: ${activeCallCid} isCallRegistered: ${isCallRegistered}`);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
callingx.updateDisplay(activeCallCid, activeCallCid, callDisplayName);
|
|
163
|
+
}, [activeCallCid, callDisplayName]);
|
|
164
|
+
|
|
165
|
+
// useEffect(() => {
|
|
166
|
+
// const callingx = getCallingxLibIfAvailable();
|
|
167
|
+
// if (!callingx?.isSetup || !activeCallCid) {
|
|
168
|
+
// return;
|
|
169
|
+
// }
|
|
170
|
+
|
|
171
|
+
// const isCallRegistered = callingx.isCallRegistered(activeCallCid);
|
|
172
|
+
// if (!isCallRegistered) {
|
|
173
|
+
// logger.debug(
|
|
174
|
+
// `No active call cid to set muted in calling exp: ${activeCallCid} isCallRegistered: ${isCallRegistered}`,
|
|
175
|
+
// );
|
|
176
|
+
// return;
|
|
177
|
+
// }
|
|
178
|
+
|
|
179
|
+
// callingx.setMutedCall(activeCallCid, isMute);
|
|
180
|
+
// }, [activeCallCid, isMute]);
|
|
181
|
+
|
|
182
|
+
// useEffect(() => {
|
|
183
|
+
// const callingx = getCallingxLibIfAvailable();
|
|
184
|
+
// if (!callingx?.isSetup || !activeCallCid) {
|
|
185
|
+
// return;
|
|
186
|
+
// }
|
|
187
|
+
|
|
188
|
+
// const isCallRegistered = callingx.isCallRegistered(activeCallCid);
|
|
189
|
+
// if (!isCallRegistered) {
|
|
190
|
+
// logger.debug(
|
|
191
|
+
// `No active call cid to set muted in calling exp: ${activeCallCid} isCallRegistered: ${isCallRegistered}`,
|
|
192
|
+
// );
|
|
193
|
+
// return;
|
|
194
|
+
// }
|
|
195
|
+
|
|
196
|
+
// //listen to mic toggle events from CallKit/Telecom and update stream call microphone state
|
|
197
|
+
// const subscription = callingx.addEventListener(
|
|
198
|
+
// 'didPerformSetMutedCallAction',
|
|
199
|
+
// async (event: { callId: string; muted: boolean }) => {
|
|
200
|
+
// const { callId, muted } = event;
|
|
201
|
+
|
|
202
|
+
// if (callId === activeCallCid) {
|
|
203
|
+
// const isCurrentlyMuted =
|
|
204
|
+
// RxUtils.getCurrentValue(microphone.state.status$) === 'disabled';
|
|
205
|
+
// if (isCurrentlyMuted === muted) {
|
|
206
|
+
// logger.debug(
|
|
207
|
+
// `Mic toggle is already in the desired state: ${muted} for call: ${activeCallCid}`,
|
|
208
|
+
// );
|
|
209
|
+
// //this check prevents mic toggle when state change was initiated from client and not from CallKit/Telecom
|
|
210
|
+
// return;
|
|
211
|
+
// }
|
|
212
|
+
|
|
213
|
+
// try {
|
|
214
|
+
// if (muted) {
|
|
215
|
+
// await microphone.disable();
|
|
216
|
+
// } else {
|
|
217
|
+
// await microphone.enable();
|
|
218
|
+
// }
|
|
219
|
+
// } catch (error: unknown) {
|
|
220
|
+
// logger.error(
|
|
221
|
+
// `Error toggling mic in calling exp: ${activeCallCid}`,
|
|
222
|
+
// error,
|
|
223
|
+
// );
|
|
224
|
+
// }
|
|
225
|
+
// }
|
|
226
|
+
// },
|
|
227
|
+
// );
|
|
228
|
+
|
|
229
|
+
// return () => {
|
|
230
|
+
// subscription.remove();
|
|
231
|
+
// };
|
|
232
|
+
// }, [activeCallCid, microphone, isOutcomingCall, isIncomingCall]);
|
|
233
|
+
};
|
|
234
|
+
exports.useCallingExpWithCallingStateEffect = useCallingExpWithCallingStateEffect;
|
|
235
|
+
//# sourceMappingURL=useCallingExpWithCallingStateEffect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_videoClient","require","_videoReactBindings","_react","_callingx","logger","videoLoggerSystem","getLogger","canAcceptIncomingCall","prevState","currentState","isJoined","state","CallingState","JOINING","JOINED","canEndCall","RINGING","RECONNECTING","MIGRATING","OFFLINE","LEFT","RECONNECTING_FAILED","IDLE","canStartCall","UNKNOWN","getCallDisplayName","callMembers","participants","currentUserId","names","length","filter","member","user","id","map","name","undefined","participant","userId","Boolean","sort","join","useCallingExpWithCallingStateEffect","useCallCallingState","useParticipants","useCallMembers","useCallStateHooks","activeCall","useCall","callingState","useRef","activeCallCid","cid","isIncomingCall","ringing","isCreatedByMe","isOutcomingCall","isVideoCall","settings","video","enabled","callDisplayName","useMemo","useEffect","callingx","getCallingxLibIfAvailable","isSetup","isCallRegistered","debug","endCallWithReason","catch","error","current","isOngoingCallsEnabled","answerIncomingCall","startCall","subscription","addEventListener","callId","setCurrentCallActive","remove","updateDisplay","exports"],"sourceRoot":"../../../../src","sources":["hooks/push/useCallingExpWithCallingStateEffect.ts"],"mappings":"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MACxC;IACF;IAEA,MAAMgB,gBAAgB,GAAGH,QAAQ,CAACG,gBAAgB,CAAChB,aAAa,CAAC;IACjE,IAAI,CAACgB,gBAAgB,EAAE;MACrBhE,MAAM,CAACiE,KAAK,CACV,6CAA6CjB,aAAa,sBAAsBgB,gBAAgB,EAClG,CAAC;MACD;IACF;IAEAH,QAAQ,CAACiB,aAAa,CAAC9B,aAAa,EAAEA,aAAa,EAAEU,eAAe,CAAC;EACvE,CAAC,EAAE,CAACV,aAAa,EAAEU,eAAe,CAAC,CAAC;;EAEpC;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;;EAEA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;AACF,CAAC;AAACqB,OAAA,CAAAxC,mCAAA,GAAAA,mCAAA","ignoreList":[]}
|
|
@@ -5,13 +5,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.useIosVoipPushEventsSetupEffect = void 0;
|
|
7
7
|
var _react = require("react");
|
|
8
|
-
var _libs = require("../../utils/push/libs");
|
|
9
8
|
var _reactNative = require("react-native");
|
|
10
9
|
var _utils = require("../../utils");
|
|
11
10
|
var _ios = require("../../utils/push/internal/ios");
|
|
12
11
|
var _videoReactBindings = require("@stream-io/video-react-bindings");
|
|
13
12
|
var _pushLogoutCallback = require("../../utils/internal/pushLogoutCallback");
|
|
14
13
|
var _videoClient = require("@stream-io/video-client");
|
|
14
|
+
var _libs = require("../../utils/push/libs");
|
|
15
15
|
const logger = _videoClient.videoLoggerSystem.getLogger('useIosVoipPushEventsSetupEffect');
|
|
16
16
|
|
|
17
17
|
/* VoipPushNotificationLib has support for only one listener type at a time
|
|
@@ -29,6 +29,7 @@ function setLogoutCallback(client, token, lastVoipTokenRef) {
|
|
|
29
29
|
};
|
|
30
30
|
try {
|
|
31
31
|
await client.removeDevice(token);
|
|
32
|
+
logger.debug('PushLogoutCallback - Removed voip token', token);
|
|
32
33
|
} catch (err) {
|
|
33
34
|
logger.warn('PushLogoutCallback - Failed to remove voip token', err);
|
|
34
35
|
}
|
|
@@ -83,20 +84,10 @@ const useIosVoipPushEventsSetupEffect = () => {
|
|
|
83
84
|
(0, _react.useEffect)(() => {
|
|
84
85
|
const pushConfig = _utils.StreamVideoRN.getConfig().push;
|
|
85
86
|
const pushProviderName = pushConfig?.ios.pushProviderName;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
if (!pushConfig.android.incomingCallChannel) {
|
|
90
|
-
// TODO: remove this check and find a better way once we have telecom integration for android
|
|
91
|
-
logger.debug('android incomingCallChannel is not defined, so skipping the useIosVoipPushEventsSetupEffect');
|
|
87
|
+
const callingx = (0, _libs.getCallingxLibIfAvailable)();
|
|
88
|
+
if (_reactNative.Platform.OS !== 'ios' || !client || !pushProviderName || !callingx) {
|
|
92
89
|
return;
|
|
93
90
|
}
|
|
94
|
-
const voipPushNotification = (0, _libs.getVoipPushNotificationLib)();
|
|
95
|
-
|
|
96
|
-
// even though we do this natively, we have to still register here again
|
|
97
|
-
// natively this will make sure "register" event for JS is sent with the last push token
|
|
98
|
-
// Necessary if client changed before we got the event here or user logged out and logged in again
|
|
99
|
-
voipPushNotification.registerVoipToken();
|
|
100
91
|
const onTokenReceived = token => {
|
|
101
92
|
const userId = client.streamClient._user?.id ?? '';
|
|
102
93
|
if (client.streamClient.anonymous || !token || !userId) {
|
|
@@ -124,27 +115,24 @@ const useIosVoipPushEventsSetupEffect = () => {
|
|
|
124
115
|
});
|
|
125
116
|
};
|
|
126
117
|
// fired when PushKit give us the latest token
|
|
127
|
-
|
|
118
|
+
const voipRegisterListener = callingx.addEventListener('voipNotificationsRegistered', ({
|
|
119
|
+
token
|
|
120
|
+
}) => {
|
|
128
121
|
onTokenReceived(token);
|
|
129
122
|
});
|
|
130
123
|
|
|
131
|
-
// this will
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
} = voipPushEvent;
|
|
141
|
-
if (name === 'RNVoipPushRemoteNotificationsRegisteredEvent') {
|
|
142
|
-
onTokenReceived(data);
|
|
143
|
-
} else if (name === 'RNVoipPushRemoteNotificationReceivedEvent') {
|
|
144
|
-
(0, _ios.onVoipNotificationReceived)(data, pushConfig);
|
|
145
|
-
}
|
|
124
|
+
// this will return events that were fired before js bridge initialized
|
|
125
|
+
callingx.getInitialVoipEvents().forEach(({
|
|
126
|
+
eventName,
|
|
127
|
+
params
|
|
128
|
+
}) => {
|
|
129
|
+
if (eventName === 'voipNotificationsRegistered' && 'token' in params) {
|
|
130
|
+
onTokenReceived(params.token);
|
|
131
|
+
} else if (eventName === 'voipNotificationReceived') {
|
|
132
|
+
(0, _ios.onVoipNotificationReceived)(params, pushConfig);
|
|
146
133
|
}
|
|
147
134
|
});
|
|
135
|
+
callingx.registerVoipToken();
|
|
148
136
|
lastListener.count += 1;
|
|
149
137
|
const currentListenerCount = lastListener.count;
|
|
150
138
|
return () => {
|
|
@@ -154,8 +142,7 @@ const useIosVoipPushEventsSetupEffect = () => {
|
|
|
154
142
|
return;
|
|
155
143
|
}
|
|
156
144
|
logger.debug(`Voip event listeners are removed for user: ${userId}`);
|
|
157
|
-
|
|
158
|
-
voipPushNotification.removeEventListener('register');
|
|
145
|
+
voipRegisterListener.remove();
|
|
159
146
|
};
|
|
160
147
|
}, [client]);
|
|
161
148
|
};
|