@stream-io/react-native-callingx 0.1.1 → 0.3.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 +17 -0
- package/README.md +25 -0
- package/android/src/main/java/io/getstream/rn/callingx/CallService.kt +7 -0
- package/android/src/main/java/io/getstream/rn/callingx/CallingxModuleImpl.kt +11 -5
- package/android/src/main/java/io/getstream/rn/callingx/StreamMessagingHelper.kt +84 -0
- package/android/src/main/java/io/getstream/rn/callingx/StreamMessagingService.kt +3 -19
- package/android/src/main/java/io/getstream/rn/callingx/repo/TelecomCallRepository.kt +7 -0
- package/android/src/main/java/io/getstream/rn/callingx/utils/LifecycleListener.kt +42 -0
- package/android/src/main/java/io/getstream/rn/callingx/utils/SettingsStore.kt +11 -0
- package/dist/module/CallingxModule.js +20 -5
- package/dist/module/CallingxModule.js.map +1 -1
- package/dist/module/spec/NativeCallingx.js.map +1 -1
- package/dist/module/utils/constants.js +7 -2
- package/dist/module/utils/constants.js.map +1 -1
- package/dist/typescript/src/CallingxModule.d.ts +2 -1
- package/dist/typescript/src/CallingxModule.d.ts.map +1 -1
- package/dist/typescript/src/spec/NativeCallingx.d.ts +3 -0
- package/dist/typescript/src/spec/NativeCallingx.d.ts.map +1 -1
- package/dist/typescript/src/types.d.ts +36 -5
- package/dist/typescript/src/types.d.ts.map +1 -1
- package/dist/typescript/src/utils/constants.d.ts +1 -1
- package/dist/typescript/src/utils/constants.d.ts.map +1 -1
- package/ios/AudioSessionManager.swift +39 -12
- package/ios/Callingx.mm +25 -3
- package/ios/CallingxImpl.swift +11 -0
- package/ios/Settings.swift +7 -0
- package/package.json +2 -2
- package/src/CallingxModule.ts +26 -3
- package/src/spec/NativeCallingx.ts +4 -0
- package/src/types.ts +40 -5
- package/src/utils/constants.ts +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [0.3.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/react-native-callingx-0.2.0...@stream-io/react-native-callingx-0.3.0) (2026-05-25)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- added option to skip ringing notification in foreground ([#2213](https://github.com/GetStream/stream-video-js/issues/2213)) ([8b43986](https://github.com/GetStream/stream-video-js/commit/8b43986c89d510c75668967fde46d7cb75f1636f))
|
|
10
|
+
- made messaging service extendable ([#2244](https://github.com/GetStream/stream-video-js/issues/2244)) ([c6278fa](https://github.com/GetStream/stream-video-js/commit/c6278fa8f5aafe6ea6c550ce61db74e4f358f121))
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- missing callingx iOS default audio route selection ([#2251](https://github.com/GetStream/stream-video-js/issues/2251)) ([067ebf4](https://github.com/GetStream/stream-video-js/commit/067ebf4a223d3f346fdb5edaa682272f3354af6b)), closes [#2219](https://github.com/GetStream/stream-video-js/issues/2219)
|
|
15
|
+
|
|
16
|
+
## [0.2.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/react-native-callingx-0.1.1...@stream-io/react-native-callingx-0.2.0) (2026-05-08)
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
- ongoing calls adjustments ([#2209](https://github.com/GetStream/stream-video-js/issues/2209)) ([16e2331](https://github.com/GetStream/stream-video-js/commit/16e23319bb352d5b28a6a67c5fa97dbdf757ba1a))
|
|
21
|
+
|
|
5
22
|
## [0.1.1](https://github.com/GetStream/stream-video-js/compare/@stream-io/react-native-callingx-0.1.0...@stream-io/react-native-callingx-0.1.1) (2026-04-09)
|
|
6
23
|
|
|
7
24
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -76,6 +76,31 @@ VoIP events:
|
|
|
76
76
|
- `voipNotificationsRegistered`
|
|
77
77
|
- `voipNotificationReceived`
|
|
78
78
|
|
|
79
|
+
## Skip CallKit when the app is in the foreground (iOS 26.4+)
|
|
80
|
+
|
|
81
|
+
Set `skipIncomingPushInForeground: true` in `setup()` to hide CallKit for
|
|
82
|
+
ringing pushes that arrive while the user is already inside your app. The
|
|
83
|
+
push is still delivered to JS via `voipNotificationReceived`, so the app
|
|
84
|
+
must show its own ringing UI. Background pushes are unaffected.
|
|
85
|
+
|
|
86
|
+
Requires iOS 26.4+ (no-op on older versions). Also add this delegate to your
|
|
87
|
+
`AppDelegate.swift`:
|
|
88
|
+
|
|
89
|
+
```swift title="AppDelegate.swift"
|
|
90
|
+
private func pushRegistry(
|
|
91
|
+
_ registry: PKPushRegistry,
|
|
92
|
+
didReceiveIncomingVoIPPushWith payload: PKPushPayload,
|
|
93
|
+
metadata: AnyObject,
|
|
94
|
+
withCompletionHandler completion: @escaping () -> Void
|
|
95
|
+
) {
|
|
96
|
+
StreamVideoReactNative.didReceiveIncomingVoIPPush(
|
|
97
|
+
payload,
|
|
98
|
+
metadata: metadata,
|
|
99
|
+
completionHandler: completion
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
79
104
|
## Notes
|
|
80
105
|
|
|
81
106
|
- Import from `@stream-io/react-native-callingx`.
|
|
@@ -24,6 +24,7 @@ import io.getstream.rn.callingx.notifications.NotificationsConfig
|
|
|
24
24
|
import io.getstream.rn.callingx.repo.CallRepository
|
|
25
25
|
import io.getstream.rn.callingx.repo.CallRepositoryFactory
|
|
26
26
|
import io.getstream.rn.callingx.utils.SettingsStore
|
|
27
|
+
import kotlinx.coroutines.CancellationException
|
|
27
28
|
import kotlinx.coroutines.CoroutineScope
|
|
28
29
|
import kotlinx.coroutines.SupervisorJob
|
|
29
30
|
import kotlinx.coroutines.cancel
|
|
@@ -503,6 +504,12 @@ class CallService : Service(), CallRepository.Listener {
|
|
|
503
504
|
callInfo.isVideo,
|
|
504
505
|
callInfo.displayOptions,
|
|
505
506
|
)
|
|
507
|
+
} catch (e: CancellationException) {
|
|
508
|
+
// Swallow cancellation: nothing runs after this catch, and nobody awaits this launch.
|
|
509
|
+
debugLog(
|
|
510
|
+
TAG,
|
|
511
|
+
"[service] registerCall: Registration canceled for ${callInfo.callId} during teardown"
|
|
512
|
+
)
|
|
506
513
|
} catch (e: Exception) {
|
|
507
514
|
Log.e(TAG, "[service] registerCall: Error registering call: ${e.message}")
|
|
508
515
|
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
package io.getstream.rn.callingx
|
|
2
2
|
|
|
3
|
-
import android.content.BroadcastReceiver
|
|
4
|
-
import android.content.Context
|
|
5
3
|
import android.content.Intent
|
|
6
|
-
import android.content.IntentFilter
|
|
7
|
-
import android.os.Build
|
|
8
4
|
import android.os.Bundle
|
|
9
5
|
import android.telecom.DisconnectCause
|
|
10
6
|
import android.util.Log
|
|
11
7
|
import androidx.core.content.ContextCompat
|
|
12
8
|
import androidx.core.net.toUri
|
|
13
9
|
import com.facebook.react.bridge.Arguments
|
|
14
|
-
import com.facebook.react.bridge.LifecycleEventListener
|
|
15
10
|
import com.facebook.react.bridge.Promise
|
|
16
11
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
17
12
|
import com.facebook.react.bridge.ReadableMap
|
|
@@ -22,6 +17,7 @@ import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
|
22
17
|
import io.getstream.rn.callingx.model.CallAction
|
|
23
18
|
import io.getstream.rn.callingx.notifications.NotificationChannelsManager
|
|
24
19
|
import io.getstream.rn.callingx.notifications.NotificationsConfig
|
|
20
|
+
import io.getstream.rn.callingx.utils.LifecycleListener
|
|
25
21
|
import io.getstream.rn.callingx.utils.SettingsStore
|
|
26
22
|
|
|
27
23
|
class CallingxModuleImpl(
|
|
@@ -68,11 +64,13 @@ class CallingxModuleImpl(
|
|
|
68
64
|
|
|
69
65
|
fun initialize() {
|
|
70
66
|
debugLog(TAG, "[module] initialize: Initializing module")
|
|
67
|
+
LifecycleListener.register(reactApplicationContext)
|
|
71
68
|
}
|
|
72
69
|
|
|
73
70
|
fun invalidate() {
|
|
74
71
|
debugLog(TAG, "[module] invalidate: Invalidating module")
|
|
75
72
|
|
|
73
|
+
LifecycleListener.unregister()
|
|
76
74
|
CallRegistrationStore.clearAll()
|
|
77
75
|
CallEventBus.unsubscribe(this)
|
|
78
76
|
|
|
@@ -106,6 +104,14 @@ class CallingxModuleImpl(
|
|
|
106
104
|
)
|
|
107
105
|
}
|
|
108
106
|
|
|
107
|
+
val skipIncomingPushInForeground =
|
|
108
|
+
options.hasKey("skipIncomingPushInForeground") &&
|
|
109
|
+
options.getBoolean("skipIncomingPushInForeground")
|
|
110
|
+
SettingsStore.setSkipIncomingPushInForeground(
|
|
111
|
+
reactApplicationContext,
|
|
112
|
+
skipIncomingPushInForeground,
|
|
113
|
+
)
|
|
114
|
+
|
|
109
115
|
isModuleInitialized = true
|
|
110
116
|
}
|
|
111
117
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
package io.getstream.rn.callingx
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import com.google.firebase.messaging.RemoteMessage
|
|
5
|
+
import io.getstream.rn.callingx.utils.LifecycleListener
|
|
6
|
+
import io.getstream.rn.callingx.utils.SettingsStore
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Public entry point for consumer apps that host their own [com.google.firebase.messaging.FirebaseMessagingService].
|
|
11
|
+
*
|
|
12
|
+
* To opt out of the default [StreamMessagingService] registration, add to the app manifest:
|
|
13
|
+
* ```
|
|
14
|
+
* <service
|
|
15
|
+
* android:name="io.getstream.rn.callingx.StreamMessagingService"
|
|
16
|
+
* tools:node="remove" />
|
|
17
|
+
* ```
|
|
18
|
+
* then invoke [handleMessage] from the app's own messaging service:
|
|
19
|
+
* ```
|
|
20
|
+
* class AppMessagingService : ReactNativeFirebaseMessagingService() {
|
|
21
|
+
* override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
|
22
|
+
* // pass remote message to React Native Firebase JS background handler
|
|
23
|
+
* super.onMessageReceived(remoteMessage)
|
|
24
|
+
*
|
|
25
|
+
* // Optional gate — provided for finer control over the forwarding flow.
|
|
26
|
+
* // `handleMessage` is also safe to call unconditionally; it no-ops for
|
|
27
|
+
* // payloads that aren't a Stream `call.ring`.
|
|
28
|
+
* if (StreamMessagingHelper.isStreamCallRing(remoteMessage)) {
|
|
29
|
+
* StreamMessagingHelper.handleMessage(applicationContext, remoteMessage)
|
|
30
|
+
* } else {
|
|
31
|
+
* // forward to other push SDKs
|
|
32
|
+
* }
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
object StreamMessagingHelper {
|
|
38
|
+
|
|
39
|
+
private const val TAG = "[Callingx] StreamMessagingHelper"
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns `true` if [remoteMessage] is a Stream Video incoming `call.ring` push.
|
|
43
|
+
* Useful when you want to short-circuit other SDK forwarders for Stream pushes.
|
|
44
|
+
*/
|
|
45
|
+
@JvmStatic
|
|
46
|
+
fun isStreamCallRing(remoteMessage: RemoteMessage): Boolean {
|
|
47
|
+
val data = remoteMessage.data
|
|
48
|
+
return data["sender"] == "stream.video" && data["type"] == "call.ring"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Handles a Stream Video `call.ring` payload by starting the incoming call flow.
|
|
53
|
+
* No-op for any other payload, so it is safe to call unconditionally from a host
|
|
54
|
+
* messaging service.
|
|
55
|
+
*/
|
|
56
|
+
@JvmStatic
|
|
57
|
+
fun handleMessage(context: Context, remoteMessage: RemoteMessage) {
|
|
58
|
+
val data = remoteMessage.data
|
|
59
|
+
|
|
60
|
+
if (!isStreamCallRing(remoteMessage)) {
|
|
61
|
+
debugLog(TAG, "sender or type is not supported, skipping CallService start")
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
val callCid = data["call_cid"]
|
|
66
|
+
if (callCid.isNullOrEmpty()) {
|
|
67
|
+
debugLog(TAG, "missing call_cid for call.ring, skipping CallService start")
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (
|
|
72
|
+
SettingsStore.shouldSkipIncomingPushInForeground(context) &&
|
|
73
|
+
LifecycleListener.isInForeground
|
|
74
|
+
) {
|
|
75
|
+
debugLog(
|
|
76
|
+
TAG,
|
|
77
|
+
"app is in foreground and skipIncomingPushInForeground=true, letting JS handle call.ring — skipping CallService start",
|
|
78
|
+
)
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
CallService.startIncomingCallFromPush(context.applicationContext, data)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -14,32 +14,16 @@ import io.invertase.firebase.messaging.ReactNativeFirebaseMessagingService
|
|
|
14
14
|
* the merged manifest so this service is the single FCM handler
|
|
15
15
|
*/
|
|
16
16
|
@SuppressLint("MissingFirebaseInstanceTokenRefresh")
|
|
17
|
-
class StreamMessagingService : ReactNativeFirebaseMessagingService() {
|
|
17
|
+
open class StreamMessagingService : ReactNativeFirebaseMessagingService() {
|
|
18
18
|
|
|
19
19
|
companion object {
|
|
20
20
|
const val TAG = "[Callingx] StreamMessagingService"
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
|
24
|
-
|
|
25
|
-
debugLog(TAG, "onMessageReceived data = $data")
|
|
24
|
+
debugLog(TAG, "onMessageReceived data=${remoteMessage.data}")
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
data["sender"] == "stream.video" && data["type"] == "call.ring"
|
|
29
|
-
|
|
30
|
-
if (isSupportedStreamVideoCallRing) {
|
|
31
|
-
val callCid = data["call_cid"]
|
|
32
|
-
if (callCid.isNullOrEmpty()) {
|
|
33
|
-
debugLog(
|
|
34
|
-
TAG,
|
|
35
|
-
"missing call_cid for call.ring, skipping CallService start",
|
|
36
|
-
)
|
|
37
|
-
} else {
|
|
38
|
-
CallService.startIncomingCallFromPush(applicationContext, data)
|
|
39
|
-
}
|
|
40
|
-
} else {
|
|
41
|
-
debugLog(TAG, "sender or type is not supported, skipping CallService start")
|
|
42
|
-
}
|
|
26
|
+
StreamMessagingHelper.handleMessage(applicationContext, remoteMessage)
|
|
43
27
|
|
|
44
28
|
// Let React Native Firebase continue its normal processing so
|
|
45
29
|
// setBackgroundMessageHandler() still runs in JS.
|
|
@@ -14,6 +14,7 @@ import androidx.core.telecom.CallsManager
|
|
|
14
14
|
import io.getstream.rn.callingx.debugLog
|
|
15
15
|
import io.getstream.rn.callingx.model.Call
|
|
16
16
|
import io.getstream.rn.callingx.model.CallAction
|
|
17
|
+
import kotlinx.coroutines.CancellationException
|
|
17
18
|
import kotlinx.coroutines.Job
|
|
18
19
|
import kotlinx.coroutines.cancel
|
|
19
20
|
import kotlinx.coroutines.channels.Channel
|
|
@@ -213,6 +214,12 @@ class TelecomCallRepository(context: Context) : CallRepository(context) {
|
|
|
213
214
|
TAG,
|
|
214
215
|
"[repository] registerCall: Call $callId scope ended normally"
|
|
215
216
|
)
|
|
217
|
+
} catch (e: CancellationException) {
|
|
218
|
+
debugLog(
|
|
219
|
+
TAG,
|
|
220
|
+
"[repository] registerCall: Registration canceled for $callId during teardown"
|
|
221
|
+
)
|
|
222
|
+
throw e
|
|
216
223
|
} catch (e: Exception) {
|
|
217
224
|
Log.e(TAG, "[repository] registerCall: Error registering call $callId", e)
|
|
218
225
|
throw e
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
package io.getstream.rn.callingx.utils
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.LifecycleEventListener
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
|
+
import com.facebook.react.common.LifecycleState
|
|
6
|
+
|
|
7
|
+
object LifecycleListener : LifecycleEventListener {
|
|
8
|
+
|
|
9
|
+
@Volatile
|
|
10
|
+
var isInForeground: Boolean = false
|
|
11
|
+
private set
|
|
12
|
+
|
|
13
|
+
private var registered: Boolean = false
|
|
14
|
+
private var currentContext: ReactApplicationContext? = null
|
|
15
|
+
|
|
16
|
+
fun register(context: ReactApplicationContext) {
|
|
17
|
+
if (registered) return
|
|
18
|
+
registered = true
|
|
19
|
+
currentContext = context
|
|
20
|
+
context.addLifecycleEventListener(this)
|
|
21
|
+
isInForeground = context.lifecycleState == LifecycleState.RESUMED
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
fun unregister() {
|
|
25
|
+
currentContext?.removeLifecycleEventListener(this)
|
|
26
|
+
currentContext = null
|
|
27
|
+
registered = false
|
|
28
|
+
isInForeground = false
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
override fun onHostResume() {
|
|
32
|
+
isInForeground = true
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override fun onHostPause() {
|
|
36
|
+
isInForeground = false
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
override fun onHostDestroy() {
|
|
40
|
+
isInForeground = false
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -9,6 +9,7 @@ object SettingsStore {
|
|
|
9
9
|
private const val KEY_REJECT_CALL_WHEN_BUSY = "reject_call_when_busy"
|
|
10
10
|
private const val KEY_OPTIMISTIC_ACCEPTING_TEXT = "optimistic_accepting_text"
|
|
11
11
|
private const val KEY_OPTIMISTIC_REJECTING_TEXT = "optimistic_rejecting_text"
|
|
12
|
+
private const val KEY_SKIP_INCOMING_PUSH_IN_FOREGROUND = "skip_incoming_push_in_foreground"
|
|
12
13
|
|
|
13
14
|
private const val DEFAULT_OPTIMISTIC_ACCEPTING_TEXT = "Connecting..."
|
|
14
15
|
private const val DEFAULT_OPTIMISTIC_REJECTING_TEXT = "Declining..."
|
|
@@ -48,4 +49,14 @@ object SettingsStore {
|
|
|
48
49
|
val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
|
49
50
|
return prefs.getString(KEY_OPTIMISTIC_REJECTING_TEXT, DEFAULT_OPTIMISTIC_REJECTING_TEXT) ?: DEFAULT_OPTIMISTIC_REJECTING_TEXT
|
|
50
51
|
}
|
|
52
|
+
|
|
53
|
+
fun setSkipIncomingPushInForeground(context: Context, skip: Boolean) {
|
|
54
|
+
val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
|
55
|
+
prefs.edit { putBoolean(KEY_SKIP_INCOMING_PUSH_IN_FOREGROUND, skip) }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fun shouldSkipIncomingPushInForeground(context: Context): Boolean {
|
|
59
|
+
val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
|
60
|
+
return prefs.getBoolean(KEY_SKIP_INCOMING_PUSH_IN_FOREGROUND, false)
|
|
61
|
+
}
|
|
51
62
|
}
|
|
@@ -8,7 +8,10 @@ import { androidEndCallReasonMap, defaultAndroidOptions, defaultiOSOptions, iosE
|
|
|
8
8
|
import { isVoipEvent } from "./utils/utils.js";
|
|
9
9
|
class CallingxModule {
|
|
10
10
|
_isSetup = false;
|
|
11
|
-
_isOngoingCallsEnabled =
|
|
11
|
+
_isOngoingCallsEnabled = {
|
|
12
|
+
android: false,
|
|
13
|
+
ios: false
|
|
14
|
+
};
|
|
12
15
|
_isHeadlessTaskRegistered = false;
|
|
13
16
|
titleTransformer = memberName => memberName;
|
|
14
17
|
eventManager = new EventManager();
|
|
@@ -20,7 +23,7 @@ class CallingxModule {
|
|
|
20
23
|
return NativeCallingModule.canPostNotifications();
|
|
21
24
|
}
|
|
22
25
|
get isOngoingCallsEnabled() {
|
|
23
|
-
return this._isOngoingCallsEnabled;
|
|
26
|
+
return Platform.OS === 'ios' ? this._isOngoingCallsEnabled.ios : this._isOngoingCallsEnabled.android;
|
|
24
27
|
}
|
|
25
28
|
get isSetup() {
|
|
26
29
|
return this._isSetup;
|
|
@@ -29,20 +32,27 @@ class CallingxModule {
|
|
|
29
32
|
if (this._isSetup) {
|
|
30
33
|
return;
|
|
31
34
|
}
|
|
32
|
-
this._isOngoingCallsEnabled =
|
|
35
|
+
this._isOngoingCallsEnabled = {
|
|
36
|
+
android: options.android?.enableOngoingCalls ?? false,
|
|
37
|
+
ios: options.ios?.enableOngoingCalls ?? false
|
|
38
|
+
};
|
|
33
39
|
this.setShouldRejectCallWhenBusy(options.shouldRejectCallWhenBusy ?? false);
|
|
34
40
|
if (Platform.OS === 'ios') {
|
|
35
41
|
NativeCallingModule.setupiOS({
|
|
36
42
|
...defaultiOSOptions,
|
|
37
43
|
...options.ios
|
|
38
44
|
});
|
|
45
|
+
if (options.ios?.defaultDeviceEndpointType) {
|
|
46
|
+
NativeCallingModule.setDefaultAudioDeviceEndpointType(options.ios.defaultDeviceEndpointType);
|
|
47
|
+
}
|
|
39
48
|
}
|
|
40
49
|
if (Platform.OS === 'android') {
|
|
41
50
|
const {
|
|
42
51
|
titleTransformer,
|
|
43
52
|
incomingChannel,
|
|
44
53
|
ongoingChannel,
|
|
45
|
-
notificationTexts
|
|
54
|
+
notificationTexts,
|
|
55
|
+
skipIncomingPushInForeground = false
|
|
46
56
|
} = options.android ?? {};
|
|
47
57
|
this.titleTransformer = titleTransformer ?? (memberName => memberName);
|
|
48
58
|
const notificationsConfig = {
|
|
@@ -54,7 +64,8 @@ class CallingxModule {
|
|
|
54
64
|
...defaultAndroidOptions.ongoingChannel,
|
|
55
65
|
...(ongoingChannel ?? {})
|
|
56
66
|
},
|
|
57
|
-
notificationTexts
|
|
67
|
+
notificationTexts,
|
|
68
|
+
skipIncomingPushInForeground
|
|
58
69
|
};
|
|
59
70
|
if (notificationsConfig.incomingChannel.id === notificationsConfig.ongoingChannel.id) {
|
|
60
71
|
throw new Error('Incoming and outgoing channel IDs cannot be the same');
|
|
@@ -67,6 +78,10 @@ class CallingxModule {
|
|
|
67
78
|
setShouldRejectCallWhenBusy(shouldReject) {
|
|
68
79
|
NativeCallingModule.setShouldRejectCallWhenBusy(shouldReject);
|
|
69
80
|
}
|
|
81
|
+
setDefaultAudioDeviceEndpointType(endpointType) {
|
|
82
|
+
if (Platform.OS !== 'ios') return;
|
|
83
|
+
NativeCallingModule.setDefaultAudioDeviceEndpointType(endpointType);
|
|
84
|
+
}
|
|
70
85
|
getInitialEvents() {
|
|
71
86
|
return NativeCallingModule.getInitialEvents();
|
|
72
87
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Platform","NativeCallingModule","HEADLESS_TASK_NAME","registerHeadlessTask","setHeadlessTask","EventManager","androidEndCallReasonMap","defaultAndroidOptions","defaultiOSOptions","iosEndCallReasonMap","isVoipEvent","CallingxModule","_isSetup","_isOngoingCallsEnabled","_isHeadlessTaskRegistered","titleTransformer","memberName","eventManager","voipEventManager","canPostNotifications","OS","isOngoingCallsEnabled","isSetup","setup","options","enableOngoingCalls","setShouldRejectCallWhenBusy","shouldRejectCallWhenBusy","setupiOS","
|
|
1
|
+
{"version":3,"names":["Platform","NativeCallingModule","HEADLESS_TASK_NAME","registerHeadlessTask","setHeadlessTask","EventManager","androidEndCallReasonMap","defaultAndroidOptions","defaultiOSOptions","iosEndCallReasonMap","isVoipEvent","CallingxModule","_isSetup","_isOngoingCallsEnabled","android","ios","_isHeadlessTaskRegistered","titleTransformer","memberName","eventManager","voipEventManager","canPostNotifications","OS","isOngoingCallsEnabled","isSetup","setup","options","enableOngoingCalls","setShouldRejectCallWhenBusy","shouldRejectCallWhenBusy","setupiOS","defaultDeviceEndpointType","setDefaultAudioDeviceEndpointType","incomingChannel","ongoingChannel","notificationTexts","skipIncomingPushInForeground","notificationsConfig","id","Error","setupAndroid","shouldReject","endpointType","getInitialEvents","getInitialVoipEvents","setCurrentCallActive","callId","displayIncomingCall","phoneNumber","callerName","hasVideo","displayOptions","displayTitle","answerIncomingCall","startCall","updateDisplay","incoming","endCallWithReason","reason","reasons","endCall","isCallTracked","hasRegisteredCall","setMutedCall","isMuted","setOnHoldCall","isOnHold","registerBackgroundTask","taskProvider","stopTask","stopBackgroundTask","taskData","registerBackgroundTaskAvailable","startBackgroundTask","fulfillAnswerCallAction","didFail","fulfillEndCallAction","registerVoipToken","stopService","addEventListener","eventName","callback","manager","addListener","remove","removeListener","log","message","level","module"],"sourceRoot":"../../src","sources":["CallingxModule.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","NativeModules","isTurboModuleEnabled","CallingxModule","getEnforcing","Callingx"],"sourceRoot":"../../../src","sources":["spec/NativeCallingx.ts"],"mappings":";;AAAA,SACEA,mBAAmB,EACnBC,aAAa,QAER,cAAc;;AAErB;;AAEA,SAASC,oBAAoB,QAAQ,mBAAgB;
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","NativeModules","isTurboModuleEnabled","CallingxModule","getEnforcing","Callingx"],"sourceRoot":"../../../src","sources":["spec/NativeCallingx.ts"],"mappings":";;AAAA,SACEA,mBAAmB,EACnBC,aAAa,QAER,cAAc;;AAErB;;AAEA,SAASC,oBAAoB,QAAQ,mBAAgB;AAoLrD,MAAMC,cAAoB,GAAGD,oBAAoB,GAC7CF,mBAAmB,CAACI,YAAY,CAAO,UAAU,CAAC,GACjDH,aAAa,CAACI,QAAiB;AAEpC,eAAeF,cAAc","ignoreList":[]}
|
|
@@ -8,7 +8,11 @@ export const defaultiOSOptions = {
|
|
|
8
8
|
sound: '',
|
|
9
9
|
imageName: '',
|
|
10
10
|
callsHistory: false,
|
|
11
|
-
displayCallTimeout: 60000
|
|
11
|
+
displayCallTimeout: 60000,
|
|
12
|
+
// 1 minute
|
|
13
|
+
enableOngoingCalls: false,
|
|
14
|
+
skipIncomingPushInForeground: false,
|
|
15
|
+
defaultDeviceEndpointType: 'speaker'
|
|
12
16
|
};
|
|
13
17
|
export const defaultAndroidOptions = {
|
|
14
18
|
incomingChannel: {
|
|
@@ -20,7 +24,8 @@ export const defaultAndroidOptions = {
|
|
|
20
24
|
ongoingChannel: {
|
|
21
25
|
id: 'stream_ongoing_calls_channel',
|
|
22
26
|
name: 'Ongoing calls'
|
|
23
|
-
}
|
|
27
|
+
},
|
|
28
|
+
enableOngoingCalls: false
|
|
24
29
|
};
|
|
25
30
|
|
|
26
31
|
// iOS: maps to CXCallEndedReason raw values.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["defaultiOSOptions","supportsVideo","maximumCallsPerCallGroup","maximumCallGroups","handleType","sound","imageName","callsHistory","displayCallTimeout","defaultAndroidOptions","incomingChannel","id","name","vibration","ongoingChannel","iosEndCallReasonMap","local","remote","rejected","busy","answeredElsewhere","missed","error","canceled","restricted","unknown","androidEndCallReasonMap"],"sourceRoot":"../../../src","sources":["utils/constants.ts"],"mappings":";;AAOA,OAAO,MAAMA,iBAA+C,GAAG;EAC7DC,aAAa,EAAE,IAAI;EACnBC,wBAAwB,EAAE,CAAC;EAC3BC,iBAAiB,EAAE,CAAC;EACpBC,UAAU,EAAE,SAAS;EACrBC,KAAK,EAAE,EAAE;EACTC,SAAS,EAAE,EAAE;EACbC,YAAY,EAAE,KAAK;EACnBC,kBAAkB,EAAE,KAAK,
|
|
1
|
+
{"version":3,"names":["defaultiOSOptions","supportsVideo","maximumCallsPerCallGroup","maximumCallGroups","handleType","sound","imageName","callsHistory","displayCallTimeout","enableOngoingCalls","skipIncomingPushInForeground","defaultDeviceEndpointType","defaultAndroidOptions","incomingChannel","id","name","vibration","ongoingChannel","iosEndCallReasonMap","local","remote","rejected","busy","answeredElsewhere","missed","error","canceled","restricted","unknown","androidEndCallReasonMap"],"sourceRoot":"../../../src","sources":["utils/constants.ts"],"mappings":";;AAOA,OAAO,MAAMA,iBAA+C,GAAG;EAC7DC,aAAa,EAAE,IAAI;EACnBC,wBAAwB,EAAE,CAAC;EAC3BC,iBAAiB,EAAE,CAAC;EACpBC,UAAU,EAAE,SAAS;EACrBC,KAAK,EAAE,EAAE;EACTC,SAAS,EAAE,EAAE;EACbC,YAAY,EAAE,KAAK;EACnBC,kBAAkB,EAAE,KAAK;EAAE;EAC3BC,kBAAkB,EAAE,KAAK;EACzBC,4BAA4B,EAAE,KAAK;EACnCC,yBAAyB,EAAE;AAC7B,CAAC;AAED,OAAO,MAAMC,qBAGZ,GAAG;EACFC,eAAe,EAAE;IACfC,EAAE,EAAE,+BAA+B;IACnCC,IAAI,EAAE,gBAAgB;IACtBV,KAAK,EAAE,EAAE;IACTW,SAAS,EAAE;EACb,CAAC;EACDC,cAAc,EAAE;IACdH,EAAE,EAAE,8BAA8B;IAClCC,IAAI,EAAE;EACR,CAAC;EACDN,kBAAkB,EAAE;AACtB,CAAC;;AAED;AACA;AACA;AACA,OAAO,MAAMS,mBAAkD,GAAG;EAChEC,KAAK,EAAE,CAAC,CAAC;EAAE;EACXC,MAAM,EAAE,CAAC;EAAE;EACXC,QAAQ,EAAE,CAAC;EAAE;EACbC,IAAI,EAAE,CAAC;EAAE;EACTC,iBAAiB,EAAE,CAAC;EAAE;EACtBC,MAAM,EAAE,CAAC;EAAE;EACXC,KAAK,EAAE,CAAC;EAAE;EACVC,QAAQ,EAAE,CAAC;EAAE;EACbC,UAAU,EAAE,CAAC;EAAE;EACfC,OAAO,EAAE,CAAC,CAAE;AACd,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,uBAAsD,GAAG;EACpEV,KAAK,EAAE,CAAC;EAAE;EACVC,MAAM,EAAE,CAAC;EAAE;EACXC,QAAQ,EAAE,CAAC;EAAE;EACbC,IAAI,EAAE,CAAC;EAAE;EACTC,iBAAiB,EAAE,CAAC;EAAE;EACtBC,MAAM,EAAE,CAAC;EAAE;EACXC,KAAK,EAAE,CAAC;EAAE;EACVC,QAAQ,EAAE,CAAC;EAAE;EACbC,UAAU,EAAE,CAAC;EAAE;EACfC,OAAO,EAAE,CAAC,CAAE;AACd,CAAC","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ManagableTask } from './utils/headlessTask';
|
|
2
2
|
import type { EventListener } from './EventManager';
|
|
3
|
-
import { type ICallingxModule, type EndCallReason, type EventData, type EventName, type EventParams, type CallingExpOptions, type VoipEventName, type VoipEventParams, type VoipEventData } from './types';
|
|
3
|
+
import { type ICallingxModule, type EndCallReason, type EventData, type EventName, type EventParams, type CallingExpOptions, type DefaultDeviceEndpointType, type VoipEventName, type VoipEventParams, type VoipEventData } from './types';
|
|
4
4
|
declare class CallingxModule implements ICallingxModule {
|
|
5
5
|
private _isSetup;
|
|
6
6
|
private _isOngoingCallsEnabled;
|
|
@@ -13,6 +13,7 @@ declare class CallingxModule implements ICallingxModule {
|
|
|
13
13
|
get isSetup(): boolean;
|
|
14
14
|
setup(options: CallingExpOptions): void;
|
|
15
15
|
setShouldRejectCallWhenBusy(shouldReject: boolean): void;
|
|
16
|
+
setDefaultAudioDeviceEndpointType(endpointType: DefaultDeviceEndpointType): void;
|
|
16
17
|
getInitialEvents(): EventData[];
|
|
17
18
|
getInitialVoipEvents(): VoipEventData[];
|
|
18
19
|
setCurrentCallActive(callId: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CallingxModule.d.ts","sourceRoot":"","sources":["../../../src/CallingxModule.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,SAAS,CAAC;AASjB,cAAM,cAAe,YAAW,eAAe;IAC7C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"CallingxModule.d.ts","sourceRoot":"","sources":["../../../src/CallingxModule.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ export interface Spec extends TurboModule {
|
|
|
10
10
|
imageName: string | null;
|
|
11
11
|
callsHistory: boolean;
|
|
12
12
|
displayCallTimeout: number;
|
|
13
|
+
skipIncomingPushInForeground: boolean;
|
|
13
14
|
}): void;
|
|
14
15
|
setupAndroid(options: {
|
|
15
16
|
incomingChannel: {
|
|
@@ -26,8 +27,10 @@ export interface Spec extends TurboModule {
|
|
|
26
27
|
accepting?: string;
|
|
27
28
|
rejecting?: string;
|
|
28
29
|
};
|
|
30
|
+
skipIncomingPushInForeground: boolean;
|
|
29
31
|
}): void;
|
|
30
32
|
setShouldRejectCallWhenBusy(shouldReject: boolean): void;
|
|
33
|
+
setDefaultAudioDeviceEndpointType(endpointType: string): void;
|
|
31
34
|
canPostNotifications(): boolean;
|
|
32
35
|
getInitialEvents(): Array<{
|
|
33
36
|
eventName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeCallingx.d.ts","sourceRoot":"","sources":["../../../../src/spec/NativeCallingx.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AAG9E,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,QAAQ,CAAC,OAAO,EAAE;QAChB,aAAa,EAAE,OAAO,CAAC;QACvB,wBAAwB,EAAE,MAAM,CAAC;QACjC,iBAAiB,EAAE,MAAM,CAAC;QAC1B,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,YAAY,EAAE,OAAO,CAAC;QACtB,kBAAkB,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeCallingx.d.ts","sourceRoot":"","sources":["../../../../src/spec/NativeCallingx.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { EventListener } from './EventManager';
|
|
2
2
|
import type { ManagableTask } from './utils/headlessTask';
|
|
3
|
+
export type DefaultDeviceEndpointType = 'speaker' | 'earpiece';
|
|
3
4
|
export interface ICallingxModule {
|
|
4
5
|
/**
|
|
5
6
|
* Whether the module can post call notifications. Android only. iOS always returns true.
|
|
@@ -28,6 +29,11 @@ export interface ICallingxModule {
|
|
|
28
29
|
* @param shouldReject - Whether to reject calls when the user is busy.
|
|
29
30
|
*/
|
|
30
31
|
setShouldRejectCallWhenBusy(shouldReject: boolean): void;
|
|
32
|
+
/**
|
|
33
|
+
* Set the default audio endpoint for CallKit-managed calls (iOS only; no-op on Android).
|
|
34
|
+
* Sticky preference applied next time CallKit activates the session.
|
|
35
|
+
*/
|
|
36
|
+
setDefaultAudioDeviceEndpointType(endpointType: DefaultDeviceEndpointType): void;
|
|
31
37
|
/**
|
|
32
38
|
* Get the initial events. This method is used to get the initial events from the app launch.
|
|
33
39
|
* The events are queued and can be retrieved after the module is setup.
|
|
@@ -145,6 +151,25 @@ export type InternalIOSOptions = {
|
|
|
145
151
|
* @default 60000 (1 minute)
|
|
146
152
|
*/
|
|
147
153
|
displayCallTimeout?: number;
|
|
154
|
+
/**
|
|
155
|
+
* Whether to enable ongoing calls.
|
|
156
|
+
* @default false
|
|
157
|
+
*/
|
|
158
|
+
enableOngoingCalls?: boolean;
|
|
159
|
+
/**
|
|
160
|
+
* When true, ringing pushes that arrive while the app is in the foreground
|
|
161
|
+
* are not shown by CallKit. The push is still delivered to JS via
|
|
162
|
+
* `voipNotificationReceived`, so the app must show its own ringing UI.
|
|
163
|
+
* Background pushes are unaffected. Requires iOS 26.4+; no-op on older
|
|
164
|
+
* versions.
|
|
165
|
+
* @default false
|
|
166
|
+
*/
|
|
167
|
+
skipIncomingPushInForeground?: boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Default audio endpoint when CallKit activates the session.
|
|
170
|
+
* `'earpiece'` omits `.defaultToSpeaker` for voice-only call UX.
|
|
171
|
+
*/
|
|
172
|
+
defaultDeviceEndpointType?: DefaultDeviceEndpointType;
|
|
148
173
|
};
|
|
149
174
|
type iOSOptions = Omit<InternalIOSOptions, 'maximumCallsPerCallGroup' | 'maximumCallGroups' | 'handleType'>;
|
|
150
175
|
export type InternalAndroidOptions = {
|
|
@@ -182,6 +207,17 @@ export type InternalAndroidOptions = {
|
|
|
182
207
|
*/
|
|
183
208
|
rejecting?: string;
|
|
184
209
|
};
|
|
210
|
+
/**
|
|
211
|
+
* Whether to enable ongoing calls.
|
|
212
|
+
* @default false
|
|
213
|
+
*/
|
|
214
|
+
enableOngoingCalls?: boolean;
|
|
215
|
+
/**
|
|
216
|
+
* When true, incoming call push notifications (call.ring) will not be displayed
|
|
217
|
+
* as a notification when the app is in the foreground.
|
|
218
|
+
* @default false
|
|
219
|
+
*/
|
|
220
|
+
skipIncomingPushInForeground?: boolean;
|
|
185
221
|
};
|
|
186
222
|
type AndroidOptions = InternalAndroidOptions & NotificationTransformers;
|
|
187
223
|
export type NotificationTransformers = {
|
|
@@ -190,11 +226,6 @@ export type NotificationTransformers = {
|
|
|
190
226
|
export type CallingExpOptions = {
|
|
191
227
|
ios?: iOSOptions;
|
|
192
228
|
android?: AndroidOptions;
|
|
193
|
-
/**
|
|
194
|
-
* Whether to enable ongoing calls.
|
|
195
|
-
* @default false
|
|
196
|
-
*/
|
|
197
|
-
enableOngoingCalls?: boolean;
|
|
198
229
|
/**
|
|
199
230
|
* Whether to reject calls when the user is busy.
|
|
200
231
|
* @default false
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B;;;;;;;;OAQG;IACH,IAAI,oBAAoB,IAAI,OAAO,CAAC;IACpC,IAAI,qBAAqB,IAAI,OAAO,CAAC;IACrC,IAAI,OAAO,IAAI,OAAO,CAAC;IAEvB;;;;;;;OAOG;IACH,KAAK,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC;;;;OAIG;IACH,2BAA2B,CAAC,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { InternalAndroidOptions, InternalIOSOptions, EndCallReason } from '../types';
|
|
2
2
|
import type { DeepRequired } from './types';
|
|
3
3
|
export declare const defaultiOSOptions: Required<InternalIOSOptions>;
|
|
4
|
-
export declare const defaultAndroidOptions: Omit<DeepRequired<InternalAndroidOptions>, 'notificationTexts'>;
|
|
4
|
+
export declare const defaultAndroidOptions: Omit<DeepRequired<InternalAndroidOptions>, 'notificationTexts' | 'skipIncomingPushInForeground'>;
|
|
5
5
|
export declare const iosEndCallReasonMap: Record<EndCallReason, number>;
|
|
6
6
|
export declare const androidEndCallReasonMap: Record<EndCallReason, number>;
|
|
7
7
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/utils/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACd,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/utils/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACd,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,kBAAkB,CAY1D,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,IAAI,CACtC,YAAY,CAAC,sBAAsB,CAAC,EACpC,mBAAmB,GAAG,8BAA8B,CAarD,CAAC;AAKF,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAW7D,CAAC;AAeF,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAWjE,CAAC"}
|
|
@@ -2,39 +2,66 @@ import Foundation
|
|
|
2
2
|
import AVFoundation
|
|
3
3
|
import stream_react_native_webrtc
|
|
4
4
|
|
|
5
|
+
enum DefaultAudioDevice {
|
|
6
|
+
case speaker
|
|
7
|
+
case earpiece
|
|
8
|
+
}
|
|
9
|
+
|
|
5
10
|
@objcMembers public class AudioSessionManager: NSObject {
|
|
6
11
|
|
|
12
|
+
private static let stateQueue = DispatchQueue(label: "io.getstream.callingx.audioSessionManager")
|
|
13
|
+
private static var defaultAudioDevice: DefaultAudioDevice = .speaker
|
|
14
|
+
private static var configuredInCurrentActivationCycle: Bool = false
|
|
15
|
+
|
|
16
|
+
public static func setDefaultAudioDeviceEndpointType(_ endpointType: String) {
|
|
17
|
+
let next: DefaultAudioDevice = endpointType.lowercased() == "earpiece" ? .earpiece : .speaker
|
|
18
|
+
stateQueue.async { defaultAudioDevice = next }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public static func reapplyForDidActivateIfNeeded() {
|
|
22
|
+
if stateQueue.sync(execute: { configuredInCurrentActivationCycle }) { return }
|
|
23
|
+
createAudioSessionIfNeeded()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public static func resetActivationCycle() {
|
|
27
|
+
stateQueue.async { configuredInCurrentActivationCycle = false }
|
|
28
|
+
}
|
|
29
|
+
|
|
7
30
|
public static func createAudioSessionIfNeeded() {
|
|
8
|
-
|
|
9
|
-
NSLog("%@","[Callingx][createAudioSessionIfNeeded] Creating audio session")
|
|
10
|
-
#endif
|
|
31
|
+
let currentDevice = stateQueue.sync { defaultAudioDevice }
|
|
11
32
|
|
|
12
|
-
|
|
33
|
+
// XCode 16 and older don't expose .allowBluetoothHFP
|
|
34
|
+
// https://forums.swift.org/t/xcode-26-avaudiosession-categoryoptions-allowbluetooth-deprecated/80956
|
|
13
35
|
#if compiler(>=6.2) // For Xcode 26.0+
|
|
14
|
-
|
|
36
|
+
let bluetoothOption: AVAudioSession.CategoryOptions = .allowBluetoothHFP
|
|
15
37
|
#else
|
|
16
|
-
|
|
38
|
+
let bluetoothOption: AVAudioSession.CategoryOptions = .allowBluetooth
|
|
17
39
|
#endif
|
|
18
|
-
let mode: AVAudioSession.Mode = .voiceChat
|
|
19
40
|
|
|
20
|
-
|
|
21
|
-
|
|
41
|
+
var categoryOptions: AVAudioSession.CategoryOptions = [bluetoothOption, .allowBluetoothA2DP]
|
|
42
|
+
if currentDevice == .speaker {
|
|
43
|
+
categoryOptions.insert(.defaultToSpeaker)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// webRTC() singleton hardcodes sampleRate=48000 / ioBufferDuration=0.02 — keep those.
|
|
22
47
|
let rtcConfig = RTCAudioSessionConfiguration.webRTC()
|
|
23
48
|
rtcConfig.category = AVAudioSession.Category.playAndRecord.rawValue
|
|
24
|
-
rtcConfig.mode =
|
|
49
|
+
rtcConfig.mode = AVAudioSession.Mode.voiceChat.rawValue
|
|
25
50
|
rtcConfig.categoryOptions = categoryOptions
|
|
26
51
|
RTCAudioSessionConfiguration.setWebRTC(rtcConfig)
|
|
27
52
|
|
|
28
|
-
// Apply settings via RTCAudioSession (with lock) to keep WebRTC internal state consistent
|
|
29
53
|
let rtcSession = RTCAudioSession.sharedInstance()
|
|
30
54
|
rtcSession.lockForConfiguration()
|
|
31
55
|
defer { rtcSession.unlockForConfiguration() }
|
|
32
56
|
|
|
33
57
|
do {
|
|
34
58
|
try rtcSession.setConfiguration(rtcConfig)
|
|
59
|
+
// Set inside do{} so a failure leaves the flag false and the next
|
|
60
|
+
// didActivate reapply auto-recovers.
|
|
61
|
+
stateQueue.async { configuredInCurrentActivationCycle = true }
|
|
35
62
|
} catch {
|
|
36
63
|
#if DEBUG
|
|
37
|
-
NSLog("%@","[Callingx][createAudioSessionIfNeeded] Error
|
|
64
|
+
NSLog("%@","[Callingx][createAudioSessionIfNeeded] Error: \(error)")
|
|
38
65
|
#endif
|
|
39
66
|
}
|
|
40
67
|
}
|
package/ios/Callingx.mm
CHANGED
|
@@ -28,6 +28,10 @@
|
|
|
28
28
|
@property (nonatomic, strong) CXCallController *callKeepCallController;
|
|
29
29
|
@property (nonatomic, strong) CXProvider *callKeepProvider;
|
|
30
30
|
|
|
31
|
+
// Returns the persisted `skipIncomingPushInForeground` setting.
|
|
32
|
+
// Dispatched from StreamVideoReactNative via runtime lookup.
|
|
33
|
+
+ (BOOL)shouldSkipIncomingPushInForeground;
|
|
34
|
+
|
|
31
35
|
@end
|
|
32
36
|
|
|
33
37
|
@implementation Callingx {
|
|
@@ -93,6 +97,10 @@ RCT_EXPORT_MODULE(Callingx)
|
|
|
93
97
|
return [CallingxImpl canRegisterCall];
|
|
94
98
|
}
|
|
95
99
|
|
|
100
|
+
+ (BOOL)shouldSkipIncomingPushInForeground {
|
|
101
|
+
return [Settings getSkipIncomingPushInForeground];
|
|
102
|
+
}
|
|
103
|
+
|
|
96
104
|
+ (void)endCall:(NSString *)callId reason:(int)reason {
|
|
97
105
|
[CallingxImpl endCall:callId reason:reason];
|
|
98
106
|
}
|
|
@@ -175,9 +183,10 @@ RCT_EXPORT_MODULE(Callingx)
|
|
|
175
183
|
@"ringtoneSound" : options.sound(),
|
|
176
184
|
@"imageName" : options.imageName(),
|
|
177
185
|
@"includesCallsInRecents" : @(options.callsHistory()),
|
|
178
|
-
@"displayCallTimeout" : @(options.displayCallTimeout())
|
|
186
|
+
@"displayCallTimeout" : @(options.displayCallTimeout()),
|
|
187
|
+
@"skipIncomingPushInForeground" : @(options.skipIncomingPushInForeground())
|
|
179
188
|
};
|
|
180
|
-
|
|
189
|
+
|
|
181
190
|
[self _setupiOSWithOptions:optionsDict];
|
|
182
191
|
}
|
|
183
192
|
#else
|
|
@@ -190,7 +199,8 @@ RCT_EXPORT_METHOD(setupiOS:(NSDictionary *)options) {
|
|
|
190
199
|
@"ringtoneSound" : options[@"sound"] ?: @"",
|
|
191
200
|
@"imageName" : options[@"imageName"] ?: @"",
|
|
192
201
|
@"includesCallsInRecents" : options[@"callsHistory"] ?: @(NO),
|
|
193
|
-
@"displayCallTimeout" : options[@"displayCallTimeout"] ?: @(0)
|
|
202
|
+
@"displayCallTimeout" : options[@"displayCallTimeout"] ?: @(0),
|
|
203
|
+
@"skipIncomingPushInForeground" : options[@"skipIncomingPushInForeground"] ?: @(NO)
|
|
194
204
|
};
|
|
195
205
|
|
|
196
206
|
[self _setupiOSWithOptions:optionsDict];
|
|
@@ -237,6 +247,18 @@ RCT_EXPORT_METHOD(setShouldRejectCallWhenBusy:(BOOL)shouldReject) {
|
|
|
237
247
|
}
|
|
238
248
|
#endif
|
|
239
249
|
|
|
250
|
+
#pragma mark - setDefaultAudioDeviceEndpointType
|
|
251
|
+
|
|
252
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
253
|
+
- (void)setDefaultAudioDeviceEndpointType:(NSString *)endpointType {
|
|
254
|
+
[_moduleImpl setDefaultAudioDeviceEndpointType:endpointType];
|
|
255
|
+
}
|
|
256
|
+
#else
|
|
257
|
+
RCT_EXPORT_METHOD(setDefaultAudioDeviceEndpointType:(NSString *)endpointType) {
|
|
258
|
+
[_moduleImpl setDefaultAudioDeviceEndpointType:endpointType];
|
|
259
|
+
}
|
|
260
|
+
#endif
|
|
261
|
+
|
|
240
262
|
#pragma mark - getInitialEvents
|
|
241
263
|
|
|
242
264
|
#ifdef RCT_NEW_ARCH_ENABLED
|
package/ios/CallingxImpl.swift
CHANGED
|
@@ -827,6 +827,10 @@ import stream_react_native_webrtc
|
|
|
827
827
|
// When CallKit activates the AVAudioSession, inform WebRTC as well.
|
|
828
828
|
RTCAudioSession.sharedInstance().audioSessionDidActivate(audioSession)
|
|
829
829
|
|
|
830
|
+
// No-op on the first didActivate per call (CXAction.perform already configured);
|
|
831
|
+
// only fires for interruption recovery / unhold cycles. See Apple Forums 749202.
|
|
832
|
+
AudioSessionManager.reapplyForDidActivateIfNeeded()
|
|
833
|
+
|
|
830
834
|
// Enable wake lock to keep the device awake during the call
|
|
831
835
|
DispatchQueue.main.async {
|
|
832
836
|
UIApplication.shared.isIdleTimerDisabled = true
|
|
@@ -843,6 +847,7 @@ import stream_react_native_webrtc
|
|
|
843
847
|
// When CallKit deactivates the AVAudioSession, inform WebRTC as well.
|
|
844
848
|
RTCAudioSession.sharedInstance().audioSessionDidDeactivate(audioSession)
|
|
845
849
|
getAudioDeviceModule()?.reset()
|
|
850
|
+
AudioSessionManager.resetActivationCycle()
|
|
846
851
|
|
|
847
852
|
// Disable wake lock when the call ends
|
|
848
853
|
DispatchQueue.main.async {
|
|
@@ -932,6 +937,12 @@ import stream_react_native_webrtc
|
|
|
932
937
|
}
|
|
933
938
|
}
|
|
934
939
|
|
|
940
|
+
// MARK: - Audio Configuration
|
|
941
|
+
|
|
942
|
+
@objc public func setDefaultAudioDeviceEndpointType(_ endpointType: String) {
|
|
943
|
+
AudioSessionManager.setDefaultAudioDeviceEndpointType(endpointType)
|
|
944
|
+
}
|
|
945
|
+
|
|
935
946
|
// MARK: - Helper Methods
|
|
936
947
|
private func elapsedMilliseconds(since start: DispatchTime) -> Int {
|
|
937
948
|
let nowNs = DispatchTime.now().uptimeNanoseconds
|
package/ios/Settings.swift
CHANGED
|
@@ -37,6 +37,13 @@ import UIKit
|
|
|
37
37
|
setSettings(["shouldRejectCallWhenBusy": shouldReject])
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
public static func getSkipIncomingPushInForeground() -> Bool {
|
|
41
|
+
guard let skip = getSettings()["skipIncomingPushInForeground"] as? Bool else {
|
|
42
|
+
return false
|
|
43
|
+
}
|
|
44
|
+
return skip
|
|
45
|
+
}
|
|
46
|
+
|
|
40
47
|
public static func getProviderConfiguration() -> CXProviderConfiguration {
|
|
41
48
|
#if DEBUG
|
|
42
49
|
NSLog("%@","[Settings][getProviderConfiguration]")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-io/react-native-callingx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "CallKit and Telecom API capabilities for React Native",
|
|
5
5
|
"main": "./dist/module/index.js",
|
|
6
6
|
"module": "./dist/module/index.js",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@react-native-community/cli": "20.0.1",
|
|
63
63
|
"@react-native/babel-preset": "^0.81.5",
|
|
64
|
-
"@stream-io/react-native-webrtc": "137.
|
|
64
|
+
"@stream-io/react-native-webrtc": "137.2.0",
|
|
65
65
|
"@types/react": "^19.1.0",
|
|
66
66
|
"del-cli": "^6.0.0",
|
|
67
67
|
"react": "19.1.0",
|
package/src/CallingxModule.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
type EventName,
|
|
17
17
|
type EventParams,
|
|
18
18
|
type CallingExpOptions,
|
|
19
|
+
type DefaultDeviceEndpointType,
|
|
19
20
|
type VoipEventName,
|
|
20
21
|
type VoipEventParams,
|
|
21
22
|
type VoipEventData,
|
|
@@ -30,7 +31,10 @@ import { isVoipEvent } from './utils/utils';
|
|
|
30
31
|
|
|
31
32
|
class CallingxModule implements ICallingxModule {
|
|
32
33
|
private _isSetup = false;
|
|
33
|
-
private _isOngoingCallsEnabled =
|
|
34
|
+
private _isOngoingCallsEnabled = {
|
|
35
|
+
android: false,
|
|
36
|
+
ios: false,
|
|
37
|
+
};
|
|
34
38
|
private _isHeadlessTaskRegistered = false;
|
|
35
39
|
|
|
36
40
|
private titleTransformer: (memberName: string, incoming: boolean) => string =
|
|
@@ -50,7 +54,9 @@ class CallingxModule implements ICallingxModule {
|
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
get isOngoingCallsEnabled(): boolean {
|
|
53
|
-
return
|
|
57
|
+
return Platform.OS === 'ios'
|
|
58
|
+
? this._isOngoingCallsEnabled.ios
|
|
59
|
+
: this._isOngoingCallsEnabled.android;
|
|
54
60
|
}
|
|
55
61
|
|
|
56
62
|
get isSetup(): boolean {
|
|
@@ -62,11 +68,19 @@ class CallingxModule implements ICallingxModule {
|
|
|
62
68
|
return;
|
|
63
69
|
}
|
|
64
70
|
|
|
65
|
-
this._isOngoingCallsEnabled =
|
|
71
|
+
this._isOngoingCallsEnabled = {
|
|
72
|
+
android: options.android?.enableOngoingCalls ?? false,
|
|
73
|
+
ios: options.ios?.enableOngoingCalls ?? false,
|
|
74
|
+
};
|
|
66
75
|
this.setShouldRejectCallWhenBusy(options.shouldRejectCallWhenBusy ?? false);
|
|
67
76
|
|
|
68
77
|
if (Platform.OS === 'ios') {
|
|
69
78
|
NativeCallingModule.setupiOS({ ...defaultiOSOptions, ...options.ios });
|
|
79
|
+
if (options.ios?.defaultDeviceEndpointType) {
|
|
80
|
+
NativeCallingModule.setDefaultAudioDeviceEndpointType(
|
|
81
|
+
options.ios.defaultDeviceEndpointType,
|
|
82
|
+
);
|
|
83
|
+
}
|
|
70
84
|
}
|
|
71
85
|
|
|
72
86
|
if (Platform.OS === 'android') {
|
|
@@ -75,6 +89,7 @@ class CallingxModule implements ICallingxModule {
|
|
|
75
89
|
incomingChannel,
|
|
76
90
|
ongoingChannel,
|
|
77
91
|
notificationTexts,
|
|
92
|
+
skipIncomingPushInForeground = false,
|
|
78
93
|
} = options.android ?? {};
|
|
79
94
|
|
|
80
95
|
this.titleTransformer =
|
|
@@ -90,6 +105,7 @@ class CallingxModule implements ICallingxModule {
|
|
|
90
105
|
...(ongoingChannel ?? {}),
|
|
91
106
|
},
|
|
92
107
|
notificationTexts,
|
|
108
|
+
skipIncomingPushInForeground,
|
|
93
109
|
};
|
|
94
110
|
|
|
95
111
|
if (
|
|
@@ -111,6 +127,13 @@ class CallingxModule implements ICallingxModule {
|
|
|
111
127
|
NativeCallingModule.setShouldRejectCallWhenBusy(shouldReject);
|
|
112
128
|
}
|
|
113
129
|
|
|
130
|
+
setDefaultAudioDeviceEndpointType(
|
|
131
|
+
endpointType: DefaultDeviceEndpointType,
|
|
132
|
+
): void {
|
|
133
|
+
if (Platform.OS !== 'ios') return;
|
|
134
|
+
NativeCallingModule.setDefaultAudioDeviceEndpointType(endpointType);
|
|
135
|
+
}
|
|
136
|
+
|
|
114
137
|
getInitialEvents(): EventData[] {
|
|
115
138
|
return NativeCallingModule.getInitialEvents() as EventData[];
|
|
116
139
|
}
|
|
@@ -18,6 +18,7 @@ export interface Spec extends TurboModule {
|
|
|
18
18
|
imageName: string | null;
|
|
19
19
|
callsHistory: boolean;
|
|
20
20
|
displayCallTimeout: number;
|
|
21
|
+
skipIncomingPushInForeground: boolean;
|
|
21
22
|
}): void;
|
|
22
23
|
|
|
23
24
|
setupAndroid(options: {
|
|
@@ -35,10 +36,13 @@ export interface Spec extends TurboModule {
|
|
|
35
36
|
accepting?: string;
|
|
36
37
|
rejecting?: string;
|
|
37
38
|
};
|
|
39
|
+
skipIncomingPushInForeground: boolean;
|
|
38
40
|
}): void;
|
|
39
41
|
|
|
40
42
|
setShouldRejectCallWhenBusy(shouldReject: boolean): void;
|
|
41
43
|
|
|
44
|
+
setDefaultAudioDeviceEndpointType(endpointType: string): void;
|
|
45
|
+
|
|
42
46
|
canPostNotifications(): boolean;
|
|
43
47
|
|
|
44
48
|
getInitialEvents(): Array<{
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { EventListener } from './EventManager';
|
|
2
2
|
import type { ManagableTask } from './utils/headlessTask';
|
|
3
3
|
|
|
4
|
+
export type DefaultDeviceEndpointType = 'speaker' | 'earpiece';
|
|
5
|
+
|
|
4
6
|
export interface ICallingxModule {
|
|
5
7
|
/**
|
|
6
8
|
* Whether the module can post call notifications. Android only. iOS always returns true.
|
|
@@ -30,6 +32,14 @@ export interface ICallingxModule {
|
|
|
30
32
|
* @param shouldReject - Whether to reject calls when the user is busy.
|
|
31
33
|
*/
|
|
32
34
|
setShouldRejectCallWhenBusy(shouldReject: boolean): void;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Set the default audio endpoint for CallKit-managed calls (iOS only; no-op on Android).
|
|
38
|
+
* Sticky preference applied next time CallKit activates the session.
|
|
39
|
+
*/
|
|
40
|
+
setDefaultAudioDeviceEndpointType(
|
|
41
|
+
endpointType: DefaultDeviceEndpointType,
|
|
42
|
+
): void;
|
|
33
43
|
/**
|
|
34
44
|
* Get the initial events. This method is used to get the initial events from the app launch.
|
|
35
45
|
* The events are queued and can be retrieved after the module is setup.
|
|
@@ -189,6 +199,25 @@ export type InternalIOSOptions = {
|
|
|
189
199
|
* @default 60000 (1 minute)
|
|
190
200
|
*/
|
|
191
201
|
displayCallTimeout?: number;
|
|
202
|
+
/**
|
|
203
|
+
* Whether to enable ongoing calls.
|
|
204
|
+
* @default false
|
|
205
|
+
*/
|
|
206
|
+
enableOngoingCalls?: boolean;
|
|
207
|
+
/**
|
|
208
|
+
* When true, ringing pushes that arrive while the app is in the foreground
|
|
209
|
+
* are not shown by CallKit. The push is still delivered to JS via
|
|
210
|
+
* `voipNotificationReceived`, so the app must show its own ringing UI.
|
|
211
|
+
* Background pushes are unaffected. Requires iOS 26.4+; no-op on older
|
|
212
|
+
* versions.
|
|
213
|
+
* @default false
|
|
214
|
+
*/
|
|
215
|
+
skipIncomingPushInForeground?: boolean;
|
|
216
|
+
/**
|
|
217
|
+
* Default audio endpoint when CallKit activates the session.
|
|
218
|
+
* `'earpiece'` omits `.defaultToSpeaker` for voice-only call UX.
|
|
219
|
+
*/
|
|
220
|
+
defaultDeviceEndpointType?: DefaultDeviceEndpointType;
|
|
192
221
|
};
|
|
193
222
|
type iOSOptions = Omit<
|
|
194
223
|
InternalIOSOptions,
|
|
@@ -230,6 +259,17 @@ export type InternalAndroidOptions = {
|
|
|
230
259
|
*/
|
|
231
260
|
rejecting?: string;
|
|
232
261
|
};
|
|
262
|
+
/**
|
|
263
|
+
* Whether to enable ongoing calls.
|
|
264
|
+
* @default false
|
|
265
|
+
*/
|
|
266
|
+
enableOngoingCalls?: boolean;
|
|
267
|
+
/**
|
|
268
|
+
* When true, incoming call push notifications (call.ring) will not be displayed
|
|
269
|
+
* as a notification when the app is in the foreground.
|
|
270
|
+
* @default false
|
|
271
|
+
*/
|
|
272
|
+
skipIncomingPushInForeground?: boolean;
|
|
233
273
|
};
|
|
234
274
|
type AndroidOptions = InternalAndroidOptions & NotificationTransformers;
|
|
235
275
|
|
|
@@ -240,11 +280,6 @@ export type NotificationTransformers = {
|
|
|
240
280
|
export type CallingExpOptions = {
|
|
241
281
|
ios?: iOSOptions;
|
|
242
282
|
android?: AndroidOptions;
|
|
243
|
-
/**
|
|
244
|
-
* Whether to enable ongoing calls.
|
|
245
|
-
* @default false
|
|
246
|
-
*/
|
|
247
|
-
enableOngoingCalls?: boolean;
|
|
248
283
|
/**
|
|
249
284
|
* Whether to reject calls when the user is busy.
|
|
250
285
|
* @default false
|
package/src/utils/constants.ts
CHANGED
|
@@ -14,11 +14,14 @@ export const defaultiOSOptions: Required<InternalIOSOptions> = {
|
|
|
14
14
|
imageName: '',
|
|
15
15
|
callsHistory: false,
|
|
16
16
|
displayCallTimeout: 60000, // 1 minute
|
|
17
|
+
enableOngoingCalls: false,
|
|
18
|
+
skipIncomingPushInForeground: false,
|
|
19
|
+
defaultDeviceEndpointType: 'speaker',
|
|
17
20
|
};
|
|
18
21
|
|
|
19
22
|
export const defaultAndroidOptions: Omit<
|
|
20
23
|
DeepRequired<InternalAndroidOptions>,
|
|
21
|
-
'notificationTexts'
|
|
24
|
+
'notificationTexts' | 'skipIncomingPushInForeground'
|
|
22
25
|
> = {
|
|
23
26
|
incomingChannel: {
|
|
24
27
|
id: 'stream_incoming_calls_channel',
|
|
@@ -30,6 +33,7 @@ export const defaultAndroidOptions: Omit<
|
|
|
30
33
|
id: 'stream_ongoing_calls_channel',
|
|
31
34
|
name: 'Ongoing calls',
|
|
32
35
|
},
|
|
36
|
+
enableOngoingCalls: false,
|
|
33
37
|
};
|
|
34
38
|
|
|
35
39
|
// iOS: maps to CXCallEndedReason raw values.
|