@telnyx/react-voice-commons-sdk 1.0.0 → 1.1.1
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/TelnyxNotificationHelper.kt +345 -24
- package/android/src/main/java/com/telnyx/react_voice_commons/VoicePnBridgeModule.kt +19 -0
- package/android/src/main/java/com/telnyx/react_voice_commons/VoicePnManager.kt +19 -0
- package/ios/CallKitBridge.m +27 -1
- package/ios/CallKitBridge.swift +640 -125
- package/ios/README.md +2 -2
- package/ios/VoicePnBridge.m +6 -0
- package/ios/VoicePnBridge.swift +15 -0
- 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/internal/CallKitHandler.d.ts +3 -0
- package/lib/internal/CallKitHandler.js +52 -46
- package/lib/internal/calls/call-state-controller.d.ts +33 -1
- package/lib/internal/calls/call-state-controller.js +100 -28
- package/lib/internal/session/session-manager.d.ts +15 -1
- package/lib/internal/session/session-manager.js +214 -62
- package/lib/internal/voice-pn-bridge.d.ts +18 -0
- package/lib/internal/voice-pn-bridge.js +39 -0
- package/lib/models/call.js +35 -0
- package/lib/models/config.d.ts +10 -0
- package/lib/models/config.js +2 -0
- package/lib/telnyx-voice-app.js +85 -43
- package/lib/telnyx-voip-client.d.ts +46 -5
- package/lib/telnyx-voip-client.js +238 -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/internal/CallKitHandler.tsx +60 -55
- package/src/internal/calls/call-state-controller.ts +112 -29
- package/src/internal/session/session-manager.ts +260 -65
- package/src/internal/voice-pn-bridge.ts +47 -0
- package/src/models/call.ts +34 -0
- package/src/models/config.ts +10 -0
- package/src/telnyx-voice-app.tsx +96 -45
- package/src/telnyx-voip-client.ts +216 -24
- package/src/types/telnyx-sdk.d.ts +2 -1
|
@@ -1,9 +1,62 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
var __createBinding =
|
|
3
|
+
(this && this.__createBinding) ||
|
|
4
|
+
(Object.create
|
|
5
|
+
? function (o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function () {
|
|
12
|
+
return m[k];
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}
|
|
18
|
+
: function (o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
});
|
|
22
|
+
var __setModuleDefault =
|
|
23
|
+
(this && this.__setModuleDefault) ||
|
|
24
|
+
(Object.create
|
|
25
|
+
? function (o, v) {
|
|
26
|
+
Object.defineProperty(o, 'default', { enumerable: true, value: v });
|
|
27
|
+
}
|
|
28
|
+
: function (o, v) {
|
|
29
|
+
o['default'] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar =
|
|
32
|
+
(this && this.__importStar) ||
|
|
33
|
+
(function () {
|
|
34
|
+
var ownKeys = function (o) {
|
|
35
|
+
ownKeys =
|
|
36
|
+
Object.getOwnPropertyNames ||
|
|
37
|
+
function (o) {
|
|
38
|
+
var ar = [];
|
|
39
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
40
|
+
return ar;
|
|
41
|
+
};
|
|
42
|
+
return ownKeys(o);
|
|
43
|
+
};
|
|
44
|
+
return function (mod) {
|
|
45
|
+
if (mod && mod.__esModule) return mod;
|
|
46
|
+
var result = {};
|
|
47
|
+
if (mod != null)
|
|
48
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++)
|
|
49
|
+
if (k[i] !== 'default') __createBinding(result, mod, k[i]);
|
|
50
|
+
__setModuleDefault(result, mod);
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
})();
|
|
2
54
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3
55
|
exports.TelnyxVoipClient = void 0;
|
|
4
56
|
exports.createTelnyxVoipClient = createTelnyxVoipClient;
|
|
5
57
|
exports.destroyTelnyxVoipClient = destroyTelnyxVoipClient;
|
|
6
58
|
exports.createBackgroundTelnyxVoipClient = createBackgroundTelnyxVoipClient;
|
|
59
|
+
const react_native_1 = require('react-native');
|
|
7
60
|
const connection_state_1 = require('./models/connection-state');
|
|
8
61
|
const call_state_1 = require('./models/call-state');
|
|
9
62
|
const config_1 = require('./models/config');
|
|
@@ -11,7 +64,9 @@ const session_manager_1 = require('./internal/session/session-manager');
|
|
|
11
64
|
const call_state_controller_1 = require('./internal/calls/call-state-controller');
|
|
12
65
|
const voice_pn_bridge_1 = require('./internal/voice-pn-bridge');
|
|
13
66
|
const USE_TRICKLE_ICE_STORAGE_KEY = '@use_trickle_ice';
|
|
67
|
+
const PUSH_WHEN_ACTIVE_STORAGE_KEY = '@push_when_active';
|
|
14
68
|
const MISSED_CALL_NOTIFICATIONS_STORAGE_KEY = '@enable_missed_call_notifications';
|
|
69
|
+
const LEGACY_CALLKIT_ANSWER_KEY = '__legacy_callkit_answer__';
|
|
15
70
|
/**
|
|
16
71
|
* The main public interface for the react-voice-commons module.
|
|
17
72
|
*
|
|
@@ -50,6 +105,7 @@ class TelnyxVoipClient {
|
|
|
50
105
|
* @param options Configuration options for the client
|
|
51
106
|
*/
|
|
52
107
|
constructor(options = {}) {
|
|
108
|
+
this._pendingCallKitAnswers = new Map();
|
|
53
109
|
this._disposed = false;
|
|
54
110
|
this._options = {
|
|
55
111
|
enableAppStateManagement: true,
|
|
@@ -67,6 +123,7 @@ class TelnyxVoipClient {
|
|
|
67
123
|
console.log(
|
|
68
124
|
'🔧 TelnyxVoipClient: Client ready, initializing call state controller listeners'
|
|
69
125
|
);
|
|
126
|
+
this._flushPendingCallKitAnswers();
|
|
70
127
|
this._callStateController.initializeClientListeners();
|
|
71
128
|
});
|
|
72
129
|
// Clear any tracked calls when the session disconnects, so ghosts
|
|
@@ -157,6 +214,66 @@ class TelnyxVoipClient {
|
|
|
157
214
|
getCall(callId) {
|
|
158
215
|
return this._callStateController.getCall(callId);
|
|
159
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Explicitly set the active call for multi-call scenarios.
|
|
219
|
+
* @param callId The ID of the call to mark as active
|
|
220
|
+
*/
|
|
221
|
+
setActiveCall(callId) {
|
|
222
|
+
this._throwIfDisposed();
|
|
223
|
+
this._callStateController.setActiveCall(callId);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Clear the explicitly selected active call and return to default selection.
|
|
227
|
+
*/
|
|
228
|
+
clearActiveCall() {
|
|
229
|
+
this._throwIfDisposed();
|
|
230
|
+
this._callStateController.clearActiveCall();
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Swap the current active call with a held call.
|
|
234
|
+
* On iOS this is coordinated through CallKit so native and SDK state stay aligned.
|
|
235
|
+
*
|
|
236
|
+
* @param targetCallId ID of the held call to make active
|
|
237
|
+
*/
|
|
238
|
+
async swapCalls(targetCallId) {
|
|
239
|
+
this._throwIfDisposed();
|
|
240
|
+
const activeCall = this.currentActiveCall;
|
|
241
|
+
const heldCall = this.getCall(targetCallId);
|
|
242
|
+
if (!activeCall || !heldCall || activeCall.callId === heldCall.callId) {
|
|
243
|
+
throw new Error('An active call and a different held call are required to swap calls');
|
|
244
|
+
}
|
|
245
|
+
if (activeCall.currentState !== call_state_1.TelnyxCallState.ACTIVE) {
|
|
246
|
+
throw new Error(`Cannot swap active call in state: ${activeCall.currentState}`);
|
|
247
|
+
}
|
|
248
|
+
if (heldCall.currentState !== call_state_1.TelnyxCallState.HELD) {
|
|
249
|
+
throw new Error(`Cannot swap target call in state: ${heldCall.currentState}`);
|
|
250
|
+
}
|
|
251
|
+
if (react_native_1.Platform.OS === 'ios') {
|
|
252
|
+
const { callKitCoordinator } = await Promise.resolve().then(() =>
|
|
253
|
+
__importStar(require('./callkit/callkit-coordinator'))
|
|
254
|
+
);
|
|
255
|
+
if (callKitCoordinator.isAvailable()) {
|
|
256
|
+
const success = await callKitCoordinator.swapCallsFromUI(
|
|
257
|
+
activeCall.telnyxCall,
|
|
258
|
+
heldCall.telnyxCall
|
|
259
|
+
);
|
|
260
|
+
if (!success) {
|
|
261
|
+
throw new Error('CallKit failed to swap calls');
|
|
262
|
+
}
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
await activeCall.hold();
|
|
267
|
+
try {
|
|
268
|
+
await heldCall.resume();
|
|
269
|
+
this.setActiveCall(heldCall.callId);
|
|
270
|
+
} catch (error) {
|
|
271
|
+
await activeCall.resume().catch((resumeError) => {
|
|
272
|
+
console.error('Failed to restore active call after swap failure', resumeError);
|
|
273
|
+
});
|
|
274
|
+
throw error;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
160
277
|
/**
|
|
161
278
|
* Current session ID (UUID) for this connection.
|
|
162
279
|
*/
|
|
@@ -188,10 +305,11 @@ class TelnyxVoipClient {
|
|
|
188
305
|
if (this._options.debug) {
|
|
189
306
|
console.log('TelnyxVoipClient: Logging in with credentials for user:', config.sipUser);
|
|
190
307
|
}
|
|
191
|
-
const loginConfig = {
|
|
308
|
+
const loginConfig = await this._withNativeVoipPushToken({
|
|
192
309
|
...config,
|
|
193
310
|
useTrickleIce: config.useTrickleIce ?? this._options.useTrickleIce,
|
|
194
|
-
};
|
|
311
|
+
});
|
|
312
|
+
await voice_pn_bridge_1.VoicePnBridge.setIncomingCallRingtone(loginConfig.incomingCallRingtone);
|
|
195
313
|
// Store credentials for future reconnection
|
|
196
314
|
await this._storeCredentials(loginConfig);
|
|
197
315
|
await this._sessionManager.connectWithCredential(loginConfig);
|
|
@@ -214,10 +332,11 @@ class TelnyxVoipClient {
|
|
|
214
332
|
if (this._options.debug) {
|
|
215
333
|
console.log('TelnyxVoipClient: Logging in with token');
|
|
216
334
|
}
|
|
217
|
-
const loginConfig = {
|
|
335
|
+
const loginConfig = await this._withNativeVoipPushToken({
|
|
218
336
|
...config,
|
|
219
337
|
useTrickleIce: config.useTrickleIce ?? this._options.useTrickleIce,
|
|
220
|
-
};
|
|
338
|
+
});
|
|
339
|
+
await voice_pn_bridge_1.VoicePnBridge.setIncomingCallRingtone(loginConfig.incomingCallRingtone);
|
|
221
340
|
// Store token for future reconnection
|
|
222
341
|
await this._storeToken(loginConfig);
|
|
223
342
|
await this._sessionManager.connectWithToken(loginConfig);
|
|
@@ -258,19 +377,30 @@ class TelnyxVoipClient {
|
|
|
258
377
|
const storedCredentialToken = await AsyncStorage.getItem('@credential_token');
|
|
259
378
|
const storedPushToken = await AsyncStorage.getItem('@push_token');
|
|
260
379
|
const storedUseTrickleIce = await AsyncStorage.getItem(USE_TRICKLE_ICE_STORAGE_KEY);
|
|
380
|
+
const storedPushWhenActive = await AsyncStorage.getItem(PUSH_WHEN_ACTIVE_STORAGE_KEY);
|
|
261
381
|
const storedMissedCallNotifications = await AsyncStorage.getItem(
|
|
262
382
|
MISSED_CALL_NOTIFICATIONS_STORAGE_KEY
|
|
263
383
|
);
|
|
264
384
|
const useTrickleIce =
|
|
265
385
|
storedUseTrickleIce === null ? this._options.useTrickleIce : storedUseTrickleIce === 'true';
|
|
386
|
+
const pushWhenActive = storedPushWhenActive === 'true';
|
|
266
387
|
const enableMissedCallNotifications = storedMissedCallNotifications === 'true';
|
|
388
|
+
const nativePushToken =
|
|
389
|
+
react_native_1.Platform.OS === 'ios'
|
|
390
|
+
? (await voice_pn_bridge_1.VoicePnBridge.getVoipToken())?.trim()
|
|
391
|
+
: null;
|
|
392
|
+
const pushNotificationDeviceToken = nativePushToken || storedPushToken;
|
|
393
|
+
if (nativePushToken && nativePushToken !== storedPushToken) {
|
|
394
|
+
await AsyncStorage.setItem('@push_token', nativePushToken);
|
|
395
|
+
}
|
|
267
396
|
// Check if we have credential-based authentication data
|
|
268
397
|
if (storedUsername && storedPassword) {
|
|
269
398
|
// Create credential config from stored data
|
|
270
399
|
const { createCredentialConfig } = require('./models/config');
|
|
271
400
|
const config = createCredentialConfig(storedUsername, storedPassword, {
|
|
272
|
-
pushNotificationDeviceToken
|
|
401
|
+
pushNotificationDeviceToken,
|
|
273
402
|
useTrickleIce,
|
|
403
|
+
pushWhenActive,
|
|
274
404
|
enableMissedCallNotifications,
|
|
275
405
|
});
|
|
276
406
|
if (this._options.debug) {
|
|
@@ -287,8 +417,9 @@ class TelnyxVoipClient {
|
|
|
287
417
|
// Create token config from stored data
|
|
288
418
|
const { createTokenConfig } = require('./models/config');
|
|
289
419
|
const config = createTokenConfig(storedCredentialToken, {
|
|
290
|
-
pushNotificationDeviceToken
|
|
420
|
+
pushNotificationDeviceToken,
|
|
291
421
|
useTrickleIce,
|
|
422
|
+
pushWhenActive,
|
|
292
423
|
enableMissedCallNotifications,
|
|
293
424
|
});
|
|
294
425
|
if (this._options.debug) {
|
|
@@ -403,38 +534,60 @@ class TelnyxVoipClient {
|
|
|
403
534
|
* This should be called when the user answers from CallKit before the socket connection is established
|
|
404
535
|
* @param customHeaders Optional custom headers to include with the answer
|
|
405
536
|
*/
|
|
406
|
-
queueAnswerFromCallKit(customHeaders = {}) {
|
|
537
|
+
queueAnswerFromCallKit(callKitUUIDOrHeaders, customHeaders = {}) {
|
|
407
538
|
this._throwIfDisposed();
|
|
408
539
|
if (this._options.debug) {
|
|
409
|
-
console.log('TelnyxVoipClient: Queuing answer action from CallKit',
|
|
540
|
+
console.log('TelnyxVoipClient: Queuing answer action from CallKit', {
|
|
541
|
+
callKitUUIDOrHeaders,
|
|
542
|
+
customHeaders,
|
|
543
|
+
});
|
|
410
544
|
}
|
|
411
545
|
const telnyxClient = this._sessionManager.telnyxClient;
|
|
412
546
|
if (telnyxClient && typeof telnyxClient.queueAnswerFromCallKit === 'function') {
|
|
413
|
-
telnyxClient.queueAnswerFromCallKit(customHeaders);
|
|
547
|
+
telnyxClient.queueAnswerFromCallKit(callKitUUIDOrHeaders, customHeaders);
|
|
414
548
|
} else {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
549
|
+
const normalizedUUID =
|
|
550
|
+
typeof callKitUUIDOrHeaders === 'string' ? callKitUUIDOrHeaders.toLowerCase() : undefined;
|
|
551
|
+
const actionKey = normalizedUUID ?? LEGACY_CALLKIT_ANSWER_KEY;
|
|
552
|
+
let retainedUUIDOrHeaders = normalizedUUID;
|
|
553
|
+
if (callKitUUIDOrHeaders && typeof callKitUUIDOrHeaders !== 'string') {
|
|
554
|
+
retainedUUIDOrHeaders = { ...callKitUUIDOrHeaders };
|
|
555
|
+
}
|
|
556
|
+
this._pendingCallKitAnswers.set(actionKey, {
|
|
557
|
+
callKitUUIDOrHeaders: retainedUUIDOrHeaders,
|
|
558
|
+
customHeaders: { ...customHeaders },
|
|
559
|
+
});
|
|
418
560
|
}
|
|
419
561
|
}
|
|
420
562
|
/**
|
|
421
563
|
* Queue an end action for when the call invite arrives (for CallKit integration)
|
|
422
564
|
* This should be called when the user ends from CallKit before the socket connection is established
|
|
423
565
|
*/
|
|
424
|
-
queueEndFromCallKit() {
|
|
566
|
+
queueEndFromCallKit(callKitUUID) {
|
|
425
567
|
this._throwIfDisposed();
|
|
426
568
|
if (this._options.debug) {
|
|
427
569
|
console.log('TelnyxVoipClient: Queuing end action from CallKit');
|
|
428
570
|
}
|
|
429
571
|
const telnyxClient = this._sessionManager.telnyxClient;
|
|
430
572
|
if (telnyxClient && typeof telnyxClient.queueEndFromCallKit === 'function') {
|
|
431
|
-
telnyxClient.queueEndFromCallKit();
|
|
573
|
+
telnyxClient.queueEndFromCallKit(callKitUUID);
|
|
432
574
|
} else {
|
|
433
575
|
console.warn(
|
|
434
576
|
'TelnyxVoipClient: TelnyxRTC client not available or method not found for queueEndFromCallKit'
|
|
435
577
|
);
|
|
436
578
|
}
|
|
437
579
|
}
|
|
580
|
+
/**
|
|
581
|
+
* Associate the next push-delivered INVITE with its app-facing CallKit UUID.
|
|
582
|
+
* The underlying signaling call ID remains unchanged.
|
|
583
|
+
* @internal
|
|
584
|
+
*/
|
|
585
|
+
setPushNotificationCallKitUUID(callKitUUID) {
|
|
586
|
+
const telnyxClient = this._sessionManager.telnyxClient;
|
|
587
|
+
if (telnyxClient && typeof telnyxClient.setPushNotificationCallKitUUID === 'function') {
|
|
588
|
+
telnyxClient.setPushNotificationCallKitUUID(callKitUUID);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
438
591
|
// ========== Lifecycle Methods ==========
|
|
439
592
|
/**
|
|
440
593
|
* Dispose of the client and clean up all resources.
|
|
@@ -443,18 +596,72 @@ class TelnyxVoipClient {
|
|
|
443
596
|
* This is particularly important for background clients that should be
|
|
444
597
|
* disposed after handling push notifications.
|
|
445
598
|
*/
|
|
446
|
-
dispose() {
|
|
447
|
-
if (this.
|
|
448
|
-
return;
|
|
599
|
+
async dispose() {
|
|
600
|
+
if (this._disposePromise) {
|
|
601
|
+
return this._disposePromise;
|
|
449
602
|
}
|
|
450
603
|
if (this._options.debug) {
|
|
451
604
|
console.log('TelnyxVoipClient: Disposing client');
|
|
452
605
|
}
|
|
453
606
|
this._disposed = true;
|
|
454
|
-
this.
|
|
455
|
-
|
|
607
|
+
this._disposePromise = (async () => {
|
|
608
|
+
try {
|
|
609
|
+
await this._sessionManager.dispose();
|
|
610
|
+
} finally {
|
|
611
|
+
this._pendingCallKitAnswers.clear();
|
|
612
|
+
this._callStateController.dispose();
|
|
613
|
+
}
|
|
614
|
+
})();
|
|
615
|
+
return this._disposePromise;
|
|
456
616
|
}
|
|
457
617
|
// ========== Private Methods ==========
|
|
618
|
+
/**
|
|
619
|
+
* Forward answers captured during cold start as soon as SessionManager has
|
|
620
|
+
* created the TelnyxRTC instance. SessionManager invokes its ready callback
|
|
621
|
+
* before connect(), so the UUID-keyed action is present when the INVITE
|
|
622
|
+
* arrives.
|
|
623
|
+
*/
|
|
624
|
+
_flushPendingCallKitAnswers() {
|
|
625
|
+
const telnyxClient = this._sessionManager.telnyxClient;
|
|
626
|
+
if (!telnyxClient || typeof telnyxClient.queueAnswerFromCallKit !== 'function') {
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
for (const [actionKey, pendingAnswer] of this._pendingCallKitAnswers) {
|
|
630
|
+
try {
|
|
631
|
+
telnyxClient.queueAnswerFromCallKit(
|
|
632
|
+
pendingAnswer.callKitUUIDOrHeaders,
|
|
633
|
+
pendingAnswer.customHeaders
|
|
634
|
+
);
|
|
635
|
+
this._pendingCallKitAnswers.delete(actionKey);
|
|
636
|
+
} catch (error) {
|
|
637
|
+
console.error('TelnyxVoipClient: Failed to restore pending CallKit answer', {
|
|
638
|
+
actionKey,
|
|
639
|
+
error,
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Prefer an explicitly supplied token, otherwise hydrate it from PushKit's
|
|
646
|
+
* native storage. PushKit registration starts in AppDelegate before React
|
|
647
|
+
* mounts, so this removes the race between the JS token event and login.
|
|
648
|
+
*/
|
|
649
|
+
async _withNativeVoipPushToken(config) {
|
|
650
|
+
if (react_native_1.Platform.OS !== 'ios' || config.pushNotificationDeviceToken?.trim()) {
|
|
651
|
+
return config;
|
|
652
|
+
}
|
|
653
|
+
const nativePushToken = (await voice_pn_bridge_1.VoicePnBridge.getVoipToken())?.trim();
|
|
654
|
+
if (!nativePushToken) {
|
|
655
|
+
return config;
|
|
656
|
+
}
|
|
657
|
+
if (this._options.debug) {
|
|
658
|
+
console.log('TelnyxVoipClient: Using PushKit token from native storage');
|
|
659
|
+
}
|
|
660
|
+
return {
|
|
661
|
+
...config,
|
|
662
|
+
pushNotificationDeviceToken: nativePushToken,
|
|
663
|
+
};
|
|
664
|
+
}
|
|
458
665
|
/**
|
|
459
666
|
* Store credential configuration for automatic reconnection
|
|
460
667
|
*/
|
|
@@ -467,6 +674,10 @@ class TelnyxVoipClient {
|
|
|
467
674
|
USE_TRICKLE_ICE_STORAGE_KEY,
|
|
468
675
|
String(config.useTrickleIce ?? false)
|
|
469
676
|
);
|
|
677
|
+
await AsyncStorage.setItem(
|
|
678
|
+
PUSH_WHEN_ACTIVE_STORAGE_KEY,
|
|
679
|
+
String(config.pushWhenActive ?? false)
|
|
680
|
+
);
|
|
470
681
|
await AsyncStorage.setItem(
|
|
471
682
|
MISSED_CALL_NOTIFICATIONS_STORAGE_KEY,
|
|
472
683
|
String(config.enableMissedCallNotifications ?? false)
|
|
@@ -497,6 +708,10 @@ class TelnyxVoipClient {
|
|
|
497
708
|
USE_TRICKLE_ICE_STORAGE_KEY,
|
|
498
709
|
String(config.useTrickleIce ?? false)
|
|
499
710
|
);
|
|
711
|
+
await AsyncStorage.setItem(
|
|
712
|
+
PUSH_WHEN_ACTIVE_STORAGE_KEY,
|
|
713
|
+
String(config.pushWhenActive ?? false)
|
|
714
|
+
);
|
|
500
715
|
await AsyncStorage.setItem(
|
|
501
716
|
MISSED_CALL_NOTIFICATIONS_STORAGE_KEY,
|
|
502
717
|
String(config.enableMissedCallNotifications ?? false)
|
|
@@ -549,10 +764,11 @@ function createTelnyxVoipClient(options) {
|
|
|
549
764
|
* Disposes the current singleton so that a subsequent call to
|
|
550
765
|
* `createTelnyxVoipClient()` will create a fresh instance.
|
|
551
766
|
*/
|
|
552
|
-
function destroyTelnyxVoipClient() {
|
|
553
|
-
|
|
554
|
-
|
|
767
|
+
async function destroyTelnyxVoipClient() {
|
|
768
|
+
const sharedInstance = _sharedInstance;
|
|
769
|
+
if (sharedInstance) {
|
|
555
770
|
_sharedInstance = null;
|
|
771
|
+
await sharedInstance.dispose();
|
|
556
772
|
}
|
|
557
773
|
}
|
|
558
774
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telnyx/react-voice-commons-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "A high-level, state-agnostic, drop-in module for the Telnyx React Native SDK that simplifies WebRTC voice calling integration",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dev": "tsc --watch",
|
|
31
31
|
"test": "jest",
|
|
32
32
|
"test:watch": "jest --watch",
|
|
33
|
-
"lint": "eslint src --ext .ts,.tsx",
|
|
33
|
+
"lint": "ESLINT_USE_FLAT_CONFIG=false eslint src --ext .ts,.tsx",
|
|
34
34
|
"clean": "rm -rf lib",
|
|
35
35
|
"docs": "typedoc",
|
|
36
36
|
"docs:watch": "typedoc --watch",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
},
|
|
87
87
|
"dependencies": {
|
|
88
88
|
"@react-native-community/eslint-config": "^3.2.0",
|
|
89
|
-
"@telnyx/react-native-voice-sdk": ">=1.
|
|
89
|
+
"@telnyx/react-native-voice-sdk": ">=1.1.0",
|
|
90
90
|
"eventemitter3": "^5.0.1",
|
|
91
91
|
"expo": "~53.0.22",
|
|
92
92
|
"react-native-url-polyfill": "^3.0.0",
|
|
@@ -98,11 +98,13 @@
|
|
|
98
98
|
"@types/jest": "^29.5.0",
|
|
99
99
|
"@types/react": "~19.0.14",
|
|
100
100
|
"@types/react-native": "^0.72.8",
|
|
101
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
102
|
-
"@typescript-eslint/parser": "^
|
|
101
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
102
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
103
103
|
"eslint": "^8.0.0",
|
|
104
|
+
"expo-router": "^5.1.0",
|
|
104
105
|
"jest": "^29.5.0",
|
|
105
106
|
"prettier": "^3.0.0",
|
|
107
|
+
"react": "^19.0.0",
|
|
106
108
|
"ts-jest": "^29.1.0",
|
|
107
109
|
"typedoc": "^0.28.14",
|
|
108
110
|
"typedoc-plugin-markdown": "^4.9.0",
|