@telnyx/react-voice-commons-sdk 0.4.3 → 1.0.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/java/com/telnyx/react_voice_commons/TelnyxFirebaseMessagingService.kt +16 -2
- package/android/src/main/java/com/telnyx/react_voice_commons/VoicePnBridgeModule.kt +55 -1
- package/android/src/main/java/com/telnyx/react_voice_commons/VoicePnManager.kt +17 -1
- package/ios/CallKitBridge.swift +426 -0
- package/ios/VoicePnBridge.m +15 -1
- package/ios/VoicePnBridge.swift +47 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +9 -0
- package/lib/internal/calls/call-state-controller.d.ts +6 -0
- package/lib/internal/calls/call-state-controller.js +52 -36
- package/lib/internal/session/session-manager.d.ts +1 -0
- package/lib/internal/session/session-manager.js +19 -0
- package/lib/internal/voice-pn-bridge.d.ts +26 -0
- package/lib/internal/voice-pn-bridge.js +55 -0
- package/lib/models/config.d.ts +8 -0
- package/lib/telnyx-voip-client.d.ts +2 -0
- package/lib/telnyx-voip-client.js +42 -4
- package/package.json +2 -2
- package/src/index.ts +3 -0
- package/src/internal/calls/call-state-controller.ts +61 -45
- package/src/internal/session/session-manager.ts +21 -0
- package/src/internal/voice-pn-bridge.ts +64 -0
- package/src/models/config.ts +8 -0
- package/src/telnyx-voip-client.ts +48 -4
- package/src/types/telnyx-sdk.d.ts +10 -0
|
@@ -17,6 +17,7 @@ export class CallStateController {
|
|
|
17
17
|
private readonly _calls = new BehaviorSubject<Call[]>([]);
|
|
18
18
|
private readonly _callMap = new Map<string, Call>();
|
|
19
19
|
private _disposed = false;
|
|
20
|
+
private _listenerClient?: TelnyxRTC;
|
|
20
21
|
|
|
21
22
|
// Callbacks for waiting for invite logic (used for push notifications)
|
|
22
23
|
private _isWaitingForInvite?: () => boolean;
|
|
@@ -155,6 +156,9 @@ export class CallStateController {
|
|
|
155
156
|
callerIdName: callerName,
|
|
156
157
|
callerIdNumber: callerNumber,
|
|
157
158
|
customHeaders,
|
|
159
|
+
peerConnectionOptions: {
|
|
160
|
+
useTrickleIce: this._sessionManager.useTrickleIce,
|
|
161
|
+
},
|
|
158
162
|
};
|
|
159
163
|
const telnyxCall = await this._sessionManager.telnyxClient.newCall(callOptions);
|
|
160
164
|
|
|
@@ -225,6 +229,7 @@ export class CallStateController {
|
|
|
225
229
|
}
|
|
226
230
|
|
|
227
231
|
this._disposed = true;
|
|
232
|
+
this._removeClientListeners();
|
|
228
233
|
|
|
229
234
|
// Dispose of all calls
|
|
230
235
|
this.currentCalls.forEach((call) => call.dispose());
|
|
@@ -241,40 +246,28 @@ export class CallStateController {
|
|
|
241
246
|
private _setupClientListeners(): void {
|
|
242
247
|
console.log('CallStateController: Setting up client listeners...');
|
|
243
248
|
|
|
244
|
-
|
|
249
|
+
const telnyxClient = this._sessionManager.telnyxClient;
|
|
250
|
+
|
|
251
|
+
if (!telnyxClient) {
|
|
245
252
|
console.log('CallStateController: No telnyxClient available yet, skipping listener setup');
|
|
246
253
|
return;
|
|
247
254
|
}
|
|
248
255
|
|
|
256
|
+
this._removeClientListeners();
|
|
257
|
+
this._listenerClient = telnyxClient;
|
|
258
|
+
|
|
249
259
|
console.log('CallStateController: TelnyxClient found, setting up incoming call listener');
|
|
250
|
-
console.log(
|
|
251
|
-
'CallStateController: Client instance:',
|
|
252
|
-
this._sessionManager.telnyxClient.constructor.name
|
|
253
|
-
);
|
|
260
|
+
console.log('CallStateController: Client instance:', telnyxClient.constructor.name);
|
|
254
261
|
|
|
255
262
|
// Listen for incoming calls
|
|
256
|
-
|
|
257
|
-
'telnyx.call.incoming',
|
|
258
|
-
(telnyxCall: TelnyxCall, msg: any) => {
|
|
259
|
-
console.log('CallStateController: Incoming call received:', telnyxCall.callId);
|
|
260
|
-
this._handleIncomingCall(telnyxCall, msg, false);
|
|
261
|
-
}
|
|
262
|
-
);
|
|
263
|
+
telnyxClient.on('telnyx.call.incoming', this._handleTelnyxIncomingCall);
|
|
263
264
|
|
|
264
265
|
// Listen for reattached calls (after network reconnection)
|
|
265
|
-
|
|
266
|
-
'telnyx.call.reattached',
|
|
267
|
-
(telnyxCall: TelnyxCall, msg: any) => {
|
|
268
|
-
console.log('CallStateController: Reattached call received:', telnyxCall.callId);
|
|
269
|
-
this._handleIncomingCall(telnyxCall, msg, true);
|
|
270
|
-
}
|
|
271
|
-
);
|
|
266
|
+
telnyxClient.on('telnyx.call.reattached', this._handleTelnyxReattachedCall);
|
|
272
267
|
|
|
273
268
|
// Verify listeners are set up
|
|
274
|
-
const incomingListeners =
|
|
275
|
-
|
|
276
|
-
const reattachedListeners =
|
|
277
|
-
this._sessionManager.telnyxClient.listenerCount('telnyx.call.reattached');
|
|
269
|
+
const incomingListeners = telnyxClient.listenerCount('telnyx.call.incoming');
|
|
270
|
+
const reattachedListeners = telnyxClient.listenerCount('telnyx.call.reattached');
|
|
278
271
|
console.log(
|
|
279
272
|
'CallStateController: Listeners registered - incoming:',
|
|
280
273
|
incomingListeners,
|
|
@@ -283,34 +276,57 @@ export class CallStateController {
|
|
|
283
276
|
);
|
|
284
277
|
|
|
285
278
|
// Listen for call state changes from the TelnyxRTC client (multi-call support)
|
|
286
|
-
|
|
287
|
-
'telnyx.call.stateChanged',
|
|
288
|
-
(telnyxCall: TelnyxCall, state: string) => {
|
|
289
|
-
console.log(
|
|
290
|
-
'CallStateController: Call state changed from TelnyxRTC:',
|
|
291
|
-
telnyxCall.callId,
|
|
292
|
-
state
|
|
293
|
-
);
|
|
294
|
-
// Find our wrapper call and update if needed
|
|
295
|
-
const call = this.findCallByTelnyxCall(telnyxCall);
|
|
296
|
-
if (call) {
|
|
297
|
-
console.log(
|
|
298
|
-
'CallStateController: Found wrapper call, state sync handled by Call subscription'
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
);
|
|
279
|
+
telnyxClient.on('telnyx.call.stateChanged', this._handleTelnyxCallStateChanged);
|
|
303
280
|
|
|
304
281
|
// Listen for call removal events from TelnyxRTC (multi-call support)
|
|
305
|
-
|
|
306
|
-
console.log('CallStateController: Call removed from TelnyxRTC:', callId);
|
|
307
|
-
// The call cleanup is already handled by our call state subscription
|
|
308
|
-
// This event is informational for logging/debugging
|
|
309
|
-
});
|
|
282
|
+
telnyxClient.on('telnyx.call.removed', this._handleTelnyxCallRemoved);
|
|
310
283
|
|
|
311
284
|
console.log('CallStateController: Client listeners set up successfully');
|
|
312
285
|
}
|
|
313
286
|
|
|
287
|
+
private _removeClientListeners(): void {
|
|
288
|
+
if (!this._listenerClient) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
this._listenerClient.off('telnyx.call.incoming', this._handleTelnyxIncomingCall);
|
|
293
|
+
this._listenerClient.off('telnyx.call.reattached', this._handleTelnyxReattachedCall);
|
|
294
|
+
this._listenerClient.off('telnyx.call.stateChanged', this._handleTelnyxCallStateChanged);
|
|
295
|
+
this._listenerClient.off('telnyx.call.removed', this._handleTelnyxCallRemoved);
|
|
296
|
+
this._listenerClient = undefined;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
private _handleTelnyxIncomingCall = (telnyxCall: TelnyxCall, msg: any): void => {
|
|
300
|
+
console.log('CallStateController: Incoming call received:', telnyxCall.callId);
|
|
301
|
+
this._handleIncomingCall(telnyxCall, msg, false);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
private _handleTelnyxReattachedCall = (telnyxCall: TelnyxCall, msg: any): void => {
|
|
305
|
+
console.log('CallStateController: Reattached call received:', telnyxCall.callId);
|
|
306
|
+
this._handleIncomingCall(telnyxCall, msg, true);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
private _handleTelnyxCallStateChanged = (telnyxCall: TelnyxCall, state: string): void => {
|
|
310
|
+
console.log(
|
|
311
|
+
'CallStateController: Call state changed from TelnyxRTC:',
|
|
312
|
+
telnyxCall.callId,
|
|
313
|
+
state
|
|
314
|
+
);
|
|
315
|
+
// Find our wrapper call and update if needed
|
|
316
|
+
const call = this.findCallByTelnyxCall(telnyxCall);
|
|
317
|
+
if (call) {
|
|
318
|
+
console.log(
|
|
319
|
+
'CallStateController: Found wrapper call, state sync handled by Call subscription'
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
private _handleTelnyxCallRemoved = (callId: string): void => {
|
|
325
|
+
console.log('CallStateController: Call removed from TelnyxRTC:', callId);
|
|
326
|
+
// The call cleanup is already handled by our call state subscription.
|
|
327
|
+
// This event is informational for logging/debugging.
|
|
328
|
+
};
|
|
329
|
+
|
|
314
330
|
/**
|
|
315
331
|
* Handle incoming call or reattached call
|
|
316
332
|
*/
|
|
@@ -11,6 +11,9 @@ import {
|
|
|
11
11
|
isTokenConfig,
|
|
12
12
|
} from '../../models/config';
|
|
13
13
|
|
|
14
|
+
const USE_TRICKLE_ICE_STORAGE_KEY = '@use_trickle_ice';
|
|
15
|
+
const MISSED_CALL_NOTIFICATIONS_STORAGE_KEY = '@enable_missed_call_notifications';
|
|
16
|
+
|
|
14
17
|
/**
|
|
15
18
|
* Manages the connection lifecycle to the Telnyx platform.
|
|
16
19
|
*
|
|
@@ -75,6 +78,10 @@ export class SessionManager {
|
|
|
75
78
|
return this._telnyxClient;
|
|
76
79
|
}
|
|
77
80
|
|
|
81
|
+
get useTrickleIce(): boolean {
|
|
82
|
+
return Boolean(this._currentConfig?.useTrickleIce);
|
|
83
|
+
}
|
|
84
|
+
|
|
78
85
|
/**
|
|
79
86
|
* Connect using credential authentication
|
|
80
87
|
*/
|
|
@@ -210,6 +217,12 @@ export class SessionManager {
|
|
|
210
217
|
const storedPassword = await AsyncStorage.getItem('@telnyx_password');
|
|
211
218
|
const storedCredentialToken = await AsyncStorage.getItem('@credential_token');
|
|
212
219
|
const storedPushToken = await AsyncStorage.getItem('@push_token');
|
|
220
|
+
const storedUseTrickleIce = await AsyncStorage.getItem(USE_TRICKLE_ICE_STORAGE_KEY);
|
|
221
|
+
const storedMissedCallNotifications = await AsyncStorage.getItem(
|
|
222
|
+
MISSED_CALL_NOTIFICATIONS_STORAGE_KEY
|
|
223
|
+
);
|
|
224
|
+
const useTrickleIce = storedUseTrickleIce === 'true';
|
|
225
|
+
const enableMissedCallNotifications = storedMissedCallNotifications === 'true';
|
|
213
226
|
|
|
214
227
|
// Check if we have credential-based authentication data
|
|
215
228
|
if (storedUsername && storedPassword) {
|
|
@@ -217,6 +230,8 @@ export class SessionManager {
|
|
|
217
230
|
const { createCredentialConfig } = require('../../models/config');
|
|
218
231
|
this._currentConfig = createCredentialConfig(storedUsername, storedPassword, {
|
|
219
232
|
pushNotificationDeviceToken: storedPushToken,
|
|
233
|
+
useTrickleIce,
|
|
234
|
+
enableMissedCallNotifications,
|
|
220
235
|
});
|
|
221
236
|
}
|
|
222
237
|
// Check if we have token-based authentication data
|
|
@@ -225,6 +240,8 @@ export class SessionManager {
|
|
|
225
240
|
const { createTokenConfig } = require('../../models/config');
|
|
226
241
|
this._currentConfig = createTokenConfig(storedCredentialToken, {
|
|
227
242
|
pushNotificationDeviceToken: storedPushToken,
|
|
243
|
+
useTrickleIce,
|
|
244
|
+
enableMissedCallNotifications,
|
|
228
245
|
});
|
|
229
246
|
}
|
|
230
247
|
|
|
@@ -353,6 +370,8 @@ export class SessionManager {
|
|
|
353
370
|
logLevel: this._currentConfig.debug ? 'debug' : 'warn',
|
|
354
371
|
debug: this._currentConfig.debug ?? false,
|
|
355
372
|
pushNotificationDeviceToken: this._currentConfig.pushNotificationDeviceToken,
|
|
373
|
+
enableMissedCallNotifications: this._currentConfig.enableMissedCallNotifications ?? false,
|
|
374
|
+
useTrickleIce: this._currentConfig.useTrickleIce,
|
|
356
375
|
enableCallReports: this._currentConfig.enableCallReports,
|
|
357
376
|
callReportInterval: this._currentConfig.callReportInterval,
|
|
358
377
|
callReportLogLevel: this._currentConfig.callReportLogLevel,
|
|
@@ -371,6 +390,8 @@ export class SessionManager {
|
|
|
371
390
|
logLevel: this._currentConfig.debug ? 'debug' : 'warn',
|
|
372
391
|
debug: this._currentConfig.debug ?? false,
|
|
373
392
|
pushNotificationDeviceToken: this._currentConfig.pushNotificationDeviceToken,
|
|
393
|
+
enableMissedCallNotifications: this._currentConfig.enableMissedCallNotifications ?? false,
|
|
394
|
+
useTrickleIce: this._currentConfig.useTrickleIce,
|
|
374
395
|
enableCallReports: this._currentConfig.enableCallReports,
|
|
375
396
|
callReportInterval: this._currentConfig.callReportInterval,
|
|
376
397
|
callReportLogLevel: this._currentConfig.callReportLogLevel,
|
|
@@ -38,6 +38,10 @@ export interface VoicePnBridgeInterface {
|
|
|
38
38
|
clearPendingVoipPush(): Promise<boolean>;
|
|
39
39
|
getPendingVoipAction(): Promise<string | null>;
|
|
40
40
|
clearPendingVoipAction(): Promise<boolean>;
|
|
41
|
+
setMissedCallNotificationsEnabled(enabled: boolean): Promise<boolean>;
|
|
42
|
+
getMissedCallNotificationsEnabled(): Promise<boolean>;
|
|
43
|
+
setSpeakerEnabled(enabled: boolean): Promise<boolean>;
|
|
44
|
+
isSpeakerEnabled(): Promise<boolean>;
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
const NativeBridge: VoicePnBridgeInterface = NativeModules.VoicePnBridge;
|
|
@@ -244,6 +248,66 @@ export class VoicePnBridge {
|
|
|
244
248
|
}
|
|
245
249
|
}
|
|
246
250
|
|
|
251
|
+
/**
|
|
252
|
+
* Enable or disable local missed call notifications on iOS.
|
|
253
|
+
* Missed-call VoIP pushes are still handled through CallKit either way.
|
|
254
|
+
*/
|
|
255
|
+
static async setMissedCallNotificationsEnabled(enabled: boolean): Promise<boolean> {
|
|
256
|
+
try {
|
|
257
|
+
return await NativeBridge.setMissedCallNotificationsEnabled(enabled);
|
|
258
|
+
} catch (error) {
|
|
259
|
+
console.error('VoicePnBridge: Error setting missed call notifications:', error);
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Returns true by default, matching the sample-app behavior for missed calls.
|
|
266
|
+
*/
|
|
267
|
+
static async getMissedCallNotificationsEnabled(): Promise<boolean> {
|
|
268
|
+
try {
|
|
269
|
+
return await NativeBridge.getMissedCallNotificationsEnabled();
|
|
270
|
+
} catch (error) {
|
|
271
|
+
console.error('VoicePnBridge: Error getting missed call notifications setting:', error);
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Route call audio through the loudspeaker when enabled, or back to the
|
|
278
|
+
* platform default voice route when disabled.
|
|
279
|
+
*/
|
|
280
|
+
static async setSpeakerEnabled(enabled: boolean): Promise<boolean> {
|
|
281
|
+
try {
|
|
282
|
+
return await NativeBridge.setSpeakerEnabled(enabled);
|
|
283
|
+
} catch (error) {
|
|
284
|
+
console.error('VoicePnBridge: Error setting speaker route:', error);
|
|
285
|
+
throw error;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Returns whether the current audio route is using the loudspeaker.
|
|
291
|
+
*/
|
|
292
|
+
static async isSpeakerEnabled(): Promise<boolean> {
|
|
293
|
+
try {
|
|
294
|
+
return await NativeBridge.isSpeakerEnabled();
|
|
295
|
+
} catch (error) {
|
|
296
|
+
console.error('VoicePnBridge: Error getting speaker route:', error);
|
|
297
|
+
throw error;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Toggle between loudspeaker and the platform default voice route.
|
|
303
|
+
*/
|
|
304
|
+
static async toggleSpeaker(): Promise<boolean> {
|
|
305
|
+
// This is intentionally read-then-write because route changes can also come from
|
|
306
|
+
// the OS, Bluetooth, wired accessories, or the active call session.
|
|
307
|
+
const enabled = await VoicePnBridge.isSpeakerEnabled();
|
|
308
|
+
return VoicePnBridge.setSpeakerEnabled(!enabled);
|
|
309
|
+
}
|
|
310
|
+
|
|
247
311
|
/**
|
|
248
312
|
* Android → React Native: Listen for immediate call action events from notification buttons
|
|
249
313
|
* Use this for active calls where immediate response is needed (e.g., ending ongoing calls)
|
package/src/models/config.ts
CHANGED
|
@@ -7,6 +7,10 @@ export interface CredentialConfig {
|
|
|
7
7
|
sipPassword: string;
|
|
8
8
|
debug?: boolean;
|
|
9
9
|
pushNotificationDeviceToken?: string;
|
|
10
|
+
/** Enable native missed call push notifications. Default: false */
|
|
11
|
+
enableMissedCallNotifications?: boolean;
|
|
12
|
+
/** Enable Trickle ICE. Default: false */
|
|
13
|
+
useTrickleIce?: boolean;
|
|
10
14
|
/** Enable automatic call quality reporting. Default: true */
|
|
11
15
|
enableCallReports?: boolean;
|
|
12
16
|
/** Stats collection interval in seconds. Default: 5 */
|
|
@@ -25,6 +29,10 @@ export interface TokenConfig {
|
|
|
25
29
|
token: string;
|
|
26
30
|
debug?: boolean;
|
|
27
31
|
pushNotificationDeviceToken?: string;
|
|
32
|
+
/** Enable native missed call push notifications. Default: false */
|
|
33
|
+
enableMissedCallNotifications?: boolean;
|
|
34
|
+
/** Enable Trickle ICE. Default: false */
|
|
35
|
+
useTrickleIce?: boolean;
|
|
28
36
|
/** Enable automatic call quality reporting. Default: true */
|
|
29
37
|
enableCallReports?: boolean;
|
|
30
38
|
/** Stats collection interval in seconds. Default: 5 */
|
|
@@ -7,6 +7,9 @@ import { SessionManager } from './internal/session/session-manager';
|
|
|
7
7
|
import { CallStateController } from './internal/calls/call-state-controller';
|
|
8
8
|
import { VoicePnBridge } from './internal/voice-pn-bridge';
|
|
9
9
|
|
|
10
|
+
const USE_TRICKLE_ICE_STORAGE_KEY = '@use_trickle_ice';
|
|
11
|
+
const MISSED_CALL_NOTIFICATIONS_STORAGE_KEY = '@enable_missed_call_notifications';
|
|
12
|
+
|
|
10
13
|
/**
|
|
11
14
|
* Configuration options for TelnyxVoipClient
|
|
12
15
|
*/
|
|
@@ -16,6 +19,9 @@ export interface TelnyxVoipClientOptions {
|
|
|
16
19
|
|
|
17
20
|
/** Enable debug logging */
|
|
18
21
|
debug?: boolean;
|
|
22
|
+
|
|
23
|
+
/** Enable Trickle ICE for calls created by this client */
|
|
24
|
+
useTrickleIce?: boolean;
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
/**
|
|
@@ -67,6 +73,7 @@ export class TelnyxVoipClient {
|
|
|
67
73
|
this._options = {
|
|
68
74
|
enableAppStateManagement: true,
|
|
69
75
|
debug: false,
|
|
76
|
+
useTrickleIce: false,
|
|
70
77
|
...options,
|
|
71
78
|
};
|
|
72
79
|
|
|
@@ -218,10 +225,15 @@ export class TelnyxVoipClient {
|
|
|
218
225
|
console.log('TelnyxVoipClient: Logging in with credentials for user:', config.sipUser);
|
|
219
226
|
}
|
|
220
227
|
|
|
228
|
+
const loginConfig = {
|
|
229
|
+
...config,
|
|
230
|
+
useTrickleIce: config.useTrickleIce ?? this._options.useTrickleIce,
|
|
231
|
+
};
|
|
232
|
+
|
|
221
233
|
// Store credentials for future reconnection
|
|
222
|
-
await this._storeCredentials(
|
|
234
|
+
await this._storeCredentials(loginConfig);
|
|
223
235
|
|
|
224
|
-
await this._sessionManager.connectWithCredential(
|
|
236
|
+
await this._sessionManager.connectWithCredential(loginConfig);
|
|
225
237
|
}
|
|
226
238
|
|
|
227
239
|
/**
|
|
@@ -245,10 +257,15 @@ export class TelnyxVoipClient {
|
|
|
245
257
|
console.log('TelnyxVoipClient: Logging in with token');
|
|
246
258
|
}
|
|
247
259
|
|
|
260
|
+
const loginConfig = {
|
|
261
|
+
...config,
|
|
262
|
+
useTrickleIce: config.useTrickleIce ?? this._options.useTrickleIce,
|
|
263
|
+
};
|
|
264
|
+
|
|
248
265
|
// Store token for future reconnection
|
|
249
|
-
await this._storeToken(
|
|
266
|
+
await this._storeToken(loginConfig);
|
|
250
267
|
|
|
251
|
-
await this._sessionManager.connectWithToken(
|
|
268
|
+
await this._sessionManager.connectWithToken(loginConfig);
|
|
252
269
|
}
|
|
253
270
|
|
|
254
271
|
/**
|
|
@@ -292,6 +309,13 @@ export class TelnyxVoipClient {
|
|
|
292
309
|
const storedPassword = await AsyncStorage.getItem('@telnyx_password');
|
|
293
310
|
const storedCredentialToken = await AsyncStorage.getItem('@credential_token');
|
|
294
311
|
const storedPushToken = await AsyncStorage.getItem('@push_token');
|
|
312
|
+
const storedUseTrickleIce = await AsyncStorage.getItem(USE_TRICKLE_ICE_STORAGE_KEY);
|
|
313
|
+
const storedMissedCallNotifications = await AsyncStorage.getItem(
|
|
314
|
+
MISSED_CALL_NOTIFICATIONS_STORAGE_KEY
|
|
315
|
+
);
|
|
316
|
+
const useTrickleIce =
|
|
317
|
+
storedUseTrickleIce === null ? this._options.useTrickleIce : storedUseTrickleIce === 'true';
|
|
318
|
+
const enableMissedCallNotifications = storedMissedCallNotifications === 'true';
|
|
295
319
|
|
|
296
320
|
// Check if we have credential-based authentication data
|
|
297
321
|
if (storedUsername && storedPassword) {
|
|
@@ -299,6 +323,8 @@ export class TelnyxVoipClient {
|
|
|
299
323
|
const { createCredentialConfig } = require('./models/config');
|
|
300
324
|
const config = createCredentialConfig(storedUsername, storedPassword, {
|
|
301
325
|
pushNotificationDeviceToken: storedPushToken,
|
|
326
|
+
useTrickleIce,
|
|
327
|
+
enableMissedCallNotifications,
|
|
302
328
|
});
|
|
303
329
|
|
|
304
330
|
if (this._options.debug) {
|
|
@@ -318,6 +344,8 @@ export class TelnyxVoipClient {
|
|
|
318
344
|
const { createTokenConfig } = require('./models/config');
|
|
319
345
|
const config = createTokenConfig(storedCredentialToken, {
|
|
320
346
|
pushNotificationDeviceToken: storedPushToken,
|
|
347
|
+
useTrickleIce,
|
|
348
|
+
enableMissedCallNotifications,
|
|
321
349
|
});
|
|
322
350
|
|
|
323
351
|
if (this._options.debug) {
|
|
@@ -528,6 +556,14 @@ export class TelnyxVoipClient {
|
|
|
528
556
|
|
|
529
557
|
await AsyncStorage.setItem('@telnyx_username', config.sipUser);
|
|
530
558
|
await AsyncStorage.setItem('@telnyx_password', config.sipPassword);
|
|
559
|
+
await AsyncStorage.setItem(
|
|
560
|
+
USE_TRICKLE_ICE_STORAGE_KEY,
|
|
561
|
+
String(config.useTrickleIce ?? false)
|
|
562
|
+
);
|
|
563
|
+
await AsyncStorage.setItem(
|
|
564
|
+
MISSED_CALL_NOTIFICATIONS_STORAGE_KEY,
|
|
565
|
+
String(config.enableMissedCallNotifications ?? false)
|
|
566
|
+
);
|
|
531
567
|
|
|
532
568
|
if (config.pushNotificationDeviceToken) {
|
|
533
569
|
await AsyncStorage.setItem('@push_token', config.pushNotificationDeviceToken);
|
|
@@ -555,6 +591,14 @@ export class TelnyxVoipClient {
|
|
|
555
591
|
const AsyncStorage = require('@react-native-async-storage/async-storage').default;
|
|
556
592
|
|
|
557
593
|
await AsyncStorage.setItem('@credential_token', config.token);
|
|
594
|
+
await AsyncStorage.setItem(
|
|
595
|
+
USE_TRICKLE_ICE_STORAGE_KEY,
|
|
596
|
+
String(config.useTrickleIce ?? false)
|
|
597
|
+
);
|
|
598
|
+
await AsyncStorage.setItem(
|
|
599
|
+
MISSED_CALL_NOTIFICATIONS_STORAGE_KEY,
|
|
600
|
+
String(config.enableMissedCallNotifications ?? false)
|
|
601
|
+
);
|
|
558
602
|
|
|
559
603
|
if (config.pushNotificationDeviceToken) {
|
|
560
604
|
await AsyncStorage.setItem('@push_token', config.pushNotificationDeviceToken);
|
|
@@ -14,6 +14,14 @@ declare module '@telnyx/react-native-voice-sdk' {
|
|
|
14
14
|
destinationNumber?: string;
|
|
15
15
|
audio?: boolean;
|
|
16
16
|
video?: boolean;
|
|
17
|
+
peerConnectionOptions?: {
|
|
18
|
+
prefetchIceCandidates?: boolean;
|
|
19
|
+
useTrickleIce?: boolean;
|
|
20
|
+
iceServers?: any[];
|
|
21
|
+
iceTransportPolicy?: string;
|
|
22
|
+
bundlePolicy?: string;
|
|
23
|
+
rtcpMuxPolicy?: string;
|
|
24
|
+
};
|
|
17
25
|
}
|
|
18
26
|
|
|
19
27
|
export interface ClientOptions {
|
|
@@ -26,6 +34,8 @@ declare module '@telnyx/react-native-voice-sdk' {
|
|
|
26
34
|
debug?: boolean;
|
|
27
35
|
logLevel?: string;
|
|
28
36
|
pushNotificationDeviceToken?: string;
|
|
37
|
+
enableMissedCallNotifications?: boolean;
|
|
38
|
+
useTrickleIce?: boolean;
|
|
29
39
|
enableCallReports?: boolean;
|
|
30
40
|
callReportInterval?: number;
|
|
31
41
|
callReportLogLevel?: string;
|