@telnyx/react-voice-commons-sdk 0.4.3 → 1.1.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 +23 -0
- package/README.md +28 -7
- package/android/src/main/java/com/telnyx/react_voice_commons/CallForegroundService.kt +16 -2
- package/android/src/main/java/com/telnyx/react_voice_commons/TelnyxFirebaseMessagingService.kt +16 -2
- package/android/src/main/java/com/telnyx/react_voice_commons/TelnyxNotificationHelper.kt +345 -24
- package/android/src/main/java/com/telnyx/react_voice_commons/VoicePnBridgeModule.kt +74 -1
- package/android/src/main/java/com/telnyx/react_voice_commons/VoicePnManager.kt +36 -1
- package/ios/CallKitBridge.m +20 -1
- package/ios/CallKitBridge.swift +935 -60
- package/ios/README.md +2 -2
- package/ios/VoicePnBridge.m +21 -1
- package/ios/VoicePnBridge.swift +62 -1
- package/lib/callkit/callkit-coordinator.d.ts +39 -3
- package/lib/callkit/callkit-coordinator.js +561 -148
- package/lib/callkit/callkit.d.ts +7 -0
- package/lib/callkit/callkit.js +83 -11
- package/lib/hooks/useAppStateHandler.js +6 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.js +9 -0
- package/lib/internal/CallKitHandler.d.ts +3 -0
- package/lib/internal/CallKitHandler.js +52 -46
- package/lib/internal/calls/call-state-controller.d.ts +39 -1
- package/lib/internal/calls/call-state-controller.js +152 -64
- package/lib/internal/session/session-manager.d.ts +16 -1
- package/lib/internal/session/session-manager.js +229 -58
- package/lib/internal/voice-pn-bridge.d.ts +44 -0
- package/lib/internal/voice-pn-bridge.js +94 -0
- package/lib/models/call.js +35 -0
- package/lib/models/config.d.ts +18 -0
- package/lib/models/config.js +2 -0
- package/lib/telnyx-voice-app.js +85 -43
- package/lib/telnyx-voip-client.d.ts +48 -5
- package/lib/telnyx-voip-client.js +276 -22
- package/package.json +7 -5
- package/src/callkit/callkit-coordinator.ts +642 -160
- package/src/callkit/callkit.ts +110 -12
- package/src/hooks/useAppStateHandler.ts +7 -2
- package/src/index.ts +3 -0
- package/src/internal/CallKitHandler.tsx +60 -55
- package/src/internal/calls/call-state-controller.ts +173 -74
- package/src/internal/session/session-manager.ts +277 -61
- package/src/internal/voice-pn-bridge.ts +111 -0
- package/src/models/call.ts +34 -0
- package/src/models/config.ts +18 -0
- package/src/telnyx-voice-app.tsx +96 -45
- package/src/telnyx-voip-client.ts +260 -24
- package/src/types/telnyx-sdk.d.ts +12 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package com.telnyx.react_voice_commons
|
|
2
2
|
|
|
3
3
|
import android.content.Intent
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.media.AudioManager
|
|
4
6
|
import android.os.Build
|
|
5
7
|
import android.util.Log
|
|
6
8
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
@@ -143,6 +145,7 @@ class VoicePnBridgeModule(reactContext: ReactApplicationContext) : ReactContextB
|
|
|
143
145
|
Log.d(TAG, "showOngoingCallNotification called from React Native")
|
|
144
146
|
|
|
145
147
|
val notificationHelper = TelnyxNotificationHelper(reactApplicationContext)
|
|
148
|
+
notificationHelper.hideIncomingCallNotification()
|
|
146
149
|
notificationHelper.showOngoingCallNotification(
|
|
147
150
|
callerName ?: "Unknown Caller",
|
|
148
151
|
callerNumber ?: "",
|
|
@@ -222,6 +225,76 @@ class VoicePnBridgeModule(reactContext: ReactApplicationContext) : ReactContextB
|
|
|
222
225
|
promise.reject("HIDE_INCOMING_NOTIFICATION_ERROR", e.message, e)
|
|
223
226
|
}
|
|
224
227
|
}
|
|
228
|
+
|
|
229
|
+
@ReactMethod
|
|
230
|
+
fun setIncomingCallRingtone(resourceName: String?, promise: Promise) {
|
|
231
|
+
try {
|
|
232
|
+
val configured = VoicePnManager.setIncomingCallRingtoneResource(
|
|
233
|
+
reactApplicationContext,
|
|
234
|
+
resourceName?.trim()?.takeIf { it.isNotEmpty() }
|
|
235
|
+
)
|
|
236
|
+
// Create the resource-specific channel while JavaScript is available.
|
|
237
|
+
// Android preserves channel settings, and a later FCM push may arrive
|
|
238
|
+
// while the app process is not running.
|
|
239
|
+
TelnyxNotificationHelper(reactApplicationContext)
|
|
240
|
+
promise.resolve(configured)
|
|
241
|
+
} catch (e: Exception) {
|
|
242
|
+
Log.e(TAG, "Error setting incoming call ringtone", e)
|
|
243
|
+
promise.reject("SET_INCOMING_CALL_RINGTONE_ERROR", e.message, e)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
@ReactMethod
|
|
248
|
+
fun setMissedCallNotificationsEnabled(enabled: Boolean, promise: Promise) {
|
|
249
|
+
try {
|
|
250
|
+
val result = VoicePnManager.setMissedCallNotificationsEnabled(
|
|
251
|
+
reactApplicationContext,
|
|
252
|
+
enabled
|
|
253
|
+
)
|
|
254
|
+
promise.resolve(result)
|
|
255
|
+
} catch (e: Exception) {
|
|
256
|
+
Log.e(TAG, "Error setting missed call notifications", e)
|
|
257
|
+
promise.reject("SET_MISSED_CALL_NOTIFICATIONS_ERROR", e.message, e)
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
@ReactMethod
|
|
262
|
+
fun getMissedCallNotificationsEnabled(promise: Promise) {
|
|
263
|
+
try {
|
|
264
|
+
promise.resolve(VoicePnManager.getMissedCallNotificationsEnabled(reactApplicationContext))
|
|
265
|
+
} catch (e: Exception) {
|
|
266
|
+
Log.e(TAG, "Error getting missed call notifications", e)
|
|
267
|
+
promise.reject("GET_MISSED_CALL_NOTIFICATIONS_ERROR", e.message, e)
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
@ReactMethod
|
|
272
|
+
fun setSpeakerEnabled(enabled: Boolean, promise: Promise) {
|
|
273
|
+
try {
|
|
274
|
+
val audioManager = reactApplicationContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
|
275
|
+
// The active call flow owns AudioManager.mode. This bridge only requests the speaker route.
|
|
276
|
+
// Connected Bluetooth or wired accessories may still take precedence over speakerphone.
|
|
277
|
+
audioManager.isSpeakerphoneOn = enabled
|
|
278
|
+
val actualEnabled = audioManager.isSpeakerphoneOn
|
|
279
|
+
|
|
280
|
+
Log.d(TAG, "setSpeakerEnabled called from React Native: requested=$enabled actual=$actualEnabled")
|
|
281
|
+
promise.resolve(actualEnabled)
|
|
282
|
+
} catch (e: Exception) {
|
|
283
|
+
Log.e(TAG, "Error setting speaker route", e)
|
|
284
|
+
promise.reject("SET_SPEAKER_ENABLED_ERROR", e.message, e)
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
@ReactMethod
|
|
289
|
+
fun isSpeakerEnabled(promise: Promise) {
|
|
290
|
+
try {
|
|
291
|
+
val audioManager = reactApplicationContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
|
292
|
+
promise.resolve(audioManager.isSpeakerphoneOn)
|
|
293
|
+
} catch (e: Exception) {
|
|
294
|
+
Log.e(TAG, "Error getting speaker route", e)
|
|
295
|
+
promise.reject("GET_SPEAKER_ENABLED_ERROR", e.message, e)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
225
298
|
|
|
226
299
|
/**
|
|
227
300
|
* Emit call action event to React Native (for immediate notification)
|
|
@@ -245,4 +318,4 @@ class VoicePnBridgeModule(reactContext: ReactApplicationContext) : ReactContextB
|
|
|
245
318
|
Log.e(TAG, "Error emitting call action event", e)
|
|
246
319
|
}
|
|
247
320
|
}
|
|
248
|
-
}
|
|
321
|
+
}
|
|
@@ -8,6 +8,8 @@ object VoicePnManager {
|
|
|
8
8
|
|
|
9
9
|
private const val TAG = "VoicePnManager"
|
|
10
10
|
private const val PREFS_NAME = "telnyx_voice_prefs"
|
|
11
|
+
private const val MISSED_CALL_NOTIFICATIONS_ENABLED = "telnyx_enable_missed_call_notifications"
|
|
12
|
+
private const val INCOMING_CALL_RINGTONE_RESOURCE = "telnyx_incoming_call_ringtone_resource"
|
|
11
13
|
|
|
12
14
|
private fun getSharedPreferences(context: Context): SharedPreferences {
|
|
13
15
|
return context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
|
@@ -78,6 +80,39 @@ object VoicePnManager {
|
|
|
78
80
|
return true
|
|
79
81
|
}
|
|
80
82
|
|
|
83
|
+
fun setMissedCallNotificationsEnabled(context: Context, enabled: Boolean): Boolean {
|
|
84
|
+
Log.d(TAG, "setMissedCallNotificationsEnabled called with: $enabled")
|
|
85
|
+
getSharedPreferences(context)
|
|
86
|
+
.edit()
|
|
87
|
+
.putBoolean(MISSED_CALL_NOTIFICATIONS_ENABLED, enabled)
|
|
88
|
+
.apply()
|
|
89
|
+
return true
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
fun getMissedCallNotificationsEnabled(context: Context): Boolean {
|
|
93
|
+
Log.d(TAG, "getMissedCallNotificationsEnabled called")
|
|
94
|
+
return getSharedPreferences(context)
|
|
95
|
+
.getBoolean(MISSED_CALL_NOTIFICATIONS_ENABLED, true)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
fun setIncomingCallRingtoneResource(context: Context, resourceName: String?): Boolean {
|
|
99
|
+
getSharedPreferences(context)
|
|
100
|
+
.edit()
|
|
101
|
+
.apply {
|
|
102
|
+
if (resourceName.isNullOrBlank()) {
|
|
103
|
+
remove(INCOMING_CALL_RINGTONE_RESOURCE)
|
|
104
|
+
} else {
|
|
105
|
+
putString(INCOMING_CALL_RINGTONE_RESOURCE, resourceName)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
.apply()
|
|
109
|
+
return true
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
fun getIncomingCallRingtoneResource(context: Context): String? {
|
|
113
|
+
return getSharedPreferences(context).getString(INCOMING_CALL_RINGTONE_RESOURCE, null)
|
|
114
|
+
}
|
|
115
|
+
|
|
81
116
|
// PnModule functions
|
|
82
117
|
fun setPendingPushAction(context: Context, action: String, metadata: String) {
|
|
83
118
|
Log.d(TAG, "setPendingPushAction called with action: $action")
|
|
@@ -151,4 +186,4 @@ object VoicePnManager {
|
|
|
151
186
|
editor.apply()
|
|
152
187
|
return true
|
|
153
188
|
}
|
|
154
|
-
}
|
|
189
|
+
}
|
package/ios/CallKitBridge.m
CHANGED
|
@@ -15,6 +15,10 @@ RCT_EXTERN_METHOD(reportIncomingCall:(NSString *)callUUID
|
|
|
15
15
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
16
16
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
17
17
|
|
|
18
|
+
RCT_EXTERN_METHOD(isCallRegistered:(NSString *)callUUID
|
|
19
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
20
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
21
|
+
|
|
18
22
|
RCT_EXTERN_METHOD(answerCall:(NSString *)callUUID
|
|
19
23
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
20
24
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
@@ -23,6 +27,21 @@ RCT_EXTERN_METHOD(endCall:(NSString *)callUUID
|
|
|
23
27
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
24
28
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
25
29
|
|
|
30
|
+
RCT_EXTERN_METHOD(completeHeldCallAction:(NSString *)callUUID
|
|
31
|
+
success:(BOOL)success
|
|
32
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
33
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
34
|
+
|
|
35
|
+
RCT_EXTERN_METHOD(setCallHeld:(NSString *)callUUID
|
|
36
|
+
isOnHold:(BOOL)isOnHold
|
|
37
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
38
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
39
|
+
|
|
40
|
+
RCT_EXTERN_METHOD(swapCalls:(NSString *)activeCallUUID
|
|
41
|
+
heldCallUUID:(NSString *)heldCallUUID
|
|
42
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
43
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
44
|
+
|
|
26
45
|
RCT_EXTERN_METHOD(reportCallConnected:(NSString *)callUUID
|
|
27
46
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
28
47
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
@@ -41,4 +60,4 @@ RCT_EXTERN_METHOD(updateCall:(NSString *)callUUID
|
|
|
41
60
|
RCT_EXTERN_METHOD(getActiveCalls:(RCTPromiseResolveBlock)resolve
|
|
42
61
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
43
62
|
|
|
44
|
-
@end
|
|
63
|
+
@end
|