@telnyx/react-voice-commons-sdk 0.1.3 → 0.1.5
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 +21 -0
- package/README.md +9 -23
- package/lib/callkit/callkit-coordinator.d.ts +114 -110
- package/lib/callkit/callkit-coordinator.js +706 -664
- package/lib/callkit/callkit.d.ts +41 -41
- package/lib/callkit/callkit.js +242 -252
- package/lib/callkit/index.js +47 -15
- package/lib/callkit/use-callkit.d.ts +19 -19
- package/lib/callkit/use-callkit.js +310 -270
- package/lib/context/TelnyxVoiceContext.d.ts +9 -9
- package/lib/context/TelnyxVoiceContext.js +13 -10
- package/lib/hooks/use-callkit-coordinator.d.ts +17 -9
- package/lib/hooks/use-callkit-coordinator.js +50 -45
- package/lib/hooks/useAppReadyNotifier.js +15 -13
- package/lib/hooks/useAppStateHandler.d.ts +11 -6
- package/lib/hooks/useAppStateHandler.js +110 -95
- package/lib/index.d.ts +21 -3
- package/lib/index.js +201 -50
- package/lib/internal/CallKitHandler.d.ts +6 -6
- package/lib/internal/CallKitHandler.js +104 -96
- package/lib/internal/callkit-manager.d.ts +57 -57
- package/lib/internal/callkit-manager.js +316 -299
- package/lib/internal/calls/call-state-controller.d.ts +78 -73
- package/lib/internal/calls/call-state-controller.js +326 -265
- package/lib/internal/session/session-manager.d.ts +71 -71
- package/lib/internal/session/session-manager.js +437 -360
- package/lib/internal/user-defaults-helpers.js +39 -49
- package/lib/internal/voice-pn-bridge.d.ts +112 -104
- package/lib/internal/voice-pn-bridge.js +193 -203
- package/lib/models/call-state.d.ts +46 -46
- package/lib/models/call-state.js +74 -70
- package/lib/models/call.d.ts +173 -157
- package/lib/models/call.js +492 -448
- package/lib/models/config.d.ts +18 -11
- package/lib/models/config.js +35 -37
- package/lib/models/connection-state.d.ts +10 -10
- package/lib/models/connection-state.js +16 -16
- package/lib/telnyx-voice-app.d.ts +28 -28
- package/lib/telnyx-voice-app.js +562 -459
- package/lib/telnyx-voip-client.d.ts +174 -167
- package/lib/telnyx-voip-client.js +397 -385
- package/package.json +9 -5
- package/src/telnyx-voice-app.tsx +119 -69
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telnyx/react-voice-commons-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
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",
|
|
@@ -34,7 +34,11 @@
|
|
|
34
34
|
"docs:markdown": "typedoc --options typedoc.markdown.json",
|
|
35
35
|
"docs:all": "npm run docs && npm run docs:markdown",
|
|
36
36
|
"android": "expo run:android",
|
|
37
|
-
"ios": "expo run:ios"
|
|
37
|
+
"ios": "expo run:ios",
|
|
38
|
+
"dev:local": "npm pkg set dependencies.@telnyx/react-native-voice-sdk=file:../package",
|
|
39
|
+
"dev:published": "npm pkg set dependencies.@telnyx/react-native-voice-sdk=^0.3.0",
|
|
40
|
+
"prepublishOnly": "npm run dev:published && npm install --legacy-peer-deps",
|
|
41
|
+
"postpublish": "npm run dev:local && npm install --legacy-peer-deps"
|
|
38
42
|
},
|
|
39
43
|
"keywords": [
|
|
40
44
|
"react-native",
|
|
@@ -60,8 +64,8 @@
|
|
|
60
64
|
"peerDependencies": {
|
|
61
65
|
"@react-native-async-storage/async-storage": "^2.1.0",
|
|
62
66
|
"expo-router": "^5.1.0",
|
|
63
|
-
"react": "19.0.0",
|
|
64
|
-
"react-native": "
|
|
67
|
+
"react": ">=19.0.0 <20.0.0",
|
|
68
|
+
"react-native": ">=0.79.0 <1.0.0",
|
|
65
69
|
"react-native-webrtc": "^124.0.5"
|
|
66
70
|
},
|
|
67
71
|
"peerDependenciesMeta": {
|
|
@@ -83,7 +87,7 @@
|
|
|
83
87
|
},
|
|
84
88
|
"dependencies": {
|
|
85
89
|
"@react-native-community/eslint-config": "^3.2.0",
|
|
86
|
-
"@telnyx/react-native-voice-sdk": "^0.
|
|
90
|
+
"@telnyx/react-native-voice-sdk": "^0.3.0",
|
|
87
91
|
"eventemitter3": "^5.0.1",
|
|
88
92
|
"expo": "~53.0.22",
|
|
89
93
|
"react-native-voip-push-notification": "^3.3.3",
|
package/src/telnyx-voice-app.tsx
CHANGED
|
@@ -289,84 +289,134 @@ const TelnyxVoiceAppComponent: React.FC<TelnyxVoiceAppProps> = ({
|
|
|
289
289
|
try {
|
|
290
290
|
let pushData: Record<string, any> | null = null;
|
|
291
291
|
|
|
292
|
-
// Try to get push data from the native layer using
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
292
|
+
// Try to get push data from the native layer using platform-specific methods
|
|
293
|
+
if (Platform.OS === 'android') {
|
|
294
|
+
try {
|
|
295
|
+
// Import the native bridge module dynamically
|
|
296
|
+
const { NativeModules } = require('react-native');
|
|
297
|
+
const VoicePnBridge = NativeModules.VoicePnBridge;
|
|
298
|
+
|
|
299
|
+
if (VoicePnBridge) {
|
|
300
|
+
log('Checking for pending push actions via VoicePnBridge');
|
|
301
|
+
|
|
302
|
+
// First check for pending call actions (notification button taps like hangup/answer)
|
|
303
|
+
const pendingCallAction = await VoicePnBridge.getPendingCallAction();
|
|
304
|
+
log('Raw pending call action response:', pendingCallAction);
|
|
305
|
+
|
|
306
|
+
if (pendingCallAction && pendingCallAction.action != null) {
|
|
307
|
+
log('Found pending call action:', pendingCallAction);
|
|
308
|
+
|
|
309
|
+
// Handle call actions directly
|
|
310
|
+
if (pendingCallAction.action === 'hangup' && pendingCallAction.callId) {
|
|
311
|
+
log(
|
|
312
|
+
'Processing hangup action from notification for call:',
|
|
313
|
+
pendingCallAction.callId
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
// Find and hangup the call
|
|
317
|
+
const activeCall = voipClient.currentActiveCall;
|
|
318
|
+
if (activeCall && activeCall.callId === pendingCallAction.callId) {
|
|
319
|
+
log('Hanging up active call from notification action');
|
|
320
|
+
try {
|
|
321
|
+
await activeCall.hangup();
|
|
322
|
+
log('Call hung up successfully from notification action');
|
|
323
|
+
} catch (error) {
|
|
324
|
+
log('Error hanging up call from notification action:', error);
|
|
325
|
+
}
|
|
326
|
+
} else {
|
|
327
|
+
log('No matching active call found for hangup action');
|
|
324
328
|
}
|
|
325
|
-
|
|
326
|
-
|
|
329
|
+
|
|
330
|
+
// Clear the pending action
|
|
331
|
+
await VoicePnBridge.clearPendingCallAction();
|
|
332
|
+
return; // Don't process as push data
|
|
327
333
|
}
|
|
334
|
+
}
|
|
328
335
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
336
|
+
// Then check for regular push notification data
|
|
337
|
+
const pendingAction = await VoicePnBridge.getPendingPushAction();
|
|
338
|
+
log('Raw pending action response:', pendingAction);
|
|
339
|
+
|
|
340
|
+
if (pendingAction && pendingAction.action != null && pendingAction.metadata != null) {
|
|
341
|
+
log('Found pending push action:', pendingAction);
|
|
342
|
+
|
|
343
|
+
// Parse the metadata if it's a string
|
|
344
|
+
let metadata = pendingAction.metadata;
|
|
345
|
+
try {
|
|
346
|
+
// First try parsing as JSON
|
|
347
|
+
metadata = JSON.parse(metadata);
|
|
348
|
+
log('Parsed metadata as JSON:', metadata);
|
|
349
|
+
} catch (e) {
|
|
350
|
+
log('JSON parse failed, trying Android key-value format');
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Create push data structure that matches what the VoIP client expects
|
|
354
|
+
pushData = {
|
|
355
|
+
action: pendingAction.action,
|
|
356
|
+
metadata: metadata,
|
|
357
|
+
from_notification: true,
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
// Clear the pending action so it doesn't get processed again
|
|
361
|
+
await VoicePnBridge.clearPendingPushAction();
|
|
362
|
+
log('Cleared pending push action after retrieval');
|
|
363
|
+
} else {
|
|
364
|
+
log('No pending push actions found');
|
|
332
365
|
}
|
|
366
|
+
} else {
|
|
367
|
+
log('VoicePnBridge not available on Android');
|
|
333
368
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
369
|
+
} catch (bridgeError) {
|
|
370
|
+
log('Error accessing VoicePnBridge on Android:', bridgeError);
|
|
371
|
+
}
|
|
372
|
+
} else if (Platform.OS === 'ios') {
|
|
373
|
+
try {
|
|
374
|
+
// Import the native bridge module dynamically (same as Android)
|
|
375
|
+
const { NativeModules } = require('react-native');
|
|
376
|
+
const VoicePnBridge = NativeModules.VoicePnBridge;
|
|
377
|
+
|
|
378
|
+
if (VoicePnBridge) {
|
|
379
|
+
log('Checking for pending VoIP push data via iOS VoicePnBridge');
|
|
380
|
+
|
|
381
|
+
// Check for VoIP push notification data stored by the native push handler
|
|
382
|
+
const pendingVoipPushJson = await VoicePnBridge.getPendingVoipPush();
|
|
383
|
+
log('Raw pending VoIP push response:', pendingVoipPushJson);
|
|
384
|
+
|
|
385
|
+
if (pendingVoipPushJson) {
|
|
386
|
+
try {
|
|
387
|
+
const pendingVoipPush = JSON.parse(pendingVoipPushJson);
|
|
388
|
+
const voipPayload = pendingVoipPush?.payload;
|
|
389
|
+
|
|
390
|
+
if (voipPayload && voipPayload.metadata) {
|
|
391
|
+
log('Found pending VoIP push data:', voipPayload);
|
|
392
|
+
|
|
393
|
+
// Create push data structure that matches what the VoIP client expects
|
|
394
|
+
pushData = {
|
|
395
|
+
action: 'incoming_call',
|
|
396
|
+
metadata: voipPayload.metadata,
|
|
397
|
+
from_notification: true,
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
// Clear the pending VoIP push data so it doesn't get processed again
|
|
401
|
+
await VoicePnBridge.clearPendingVoipPush();
|
|
402
|
+
log('Cleared pending VoIP push data after retrieval');
|
|
403
|
+
} else {
|
|
404
|
+
log('Invalid VoIP push data structure');
|
|
405
|
+
}
|
|
406
|
+
} catch (parseError) {
|
|
407
|
+
log('Error parsing VoIP push JSON:', parseError);
|
|
408
|
+
}
|
|
409
|
+
} else {
|
|
410
|
+
log('No pending VoIP push data found');
|
|
350
411
|
}
|
|
351
|
-
|
|
352
|
-
// Create push data structure that matches what the VoIP client expects
|
|
353
|
-
pushData = {
|
|
354
|
-
action: pendingAction.action,
|
|
355
|
-
metadata: metadata,
|
|
356
|
-
from_notification: true,
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
// Clear the pending action so it doesn't get processed again
|
|
360
|
-
await VoicePnBridge.clearPendingPushAction();
|
|
361
|
-
log('Cleared pending push action after retrieval');
|
|
362
412
|
} else {
|
|
363
|
-
log('
|
|
413
|
+
log('VoicePnBridge not available on iOS');
|
|
364
414
|
}
|
|
365
|
-
}
|
|
366
|
-
log('
|
|
415
|
+
} catch (bridgeError) {
|
|
416
|
+
log('Error accessing VoicePnBridge on iOS:', bridgeError);
|
|
367
417
|
}
|
|
368
|
-
}
|
|
369
|
-
log('
|
|
418
|
+
} else {
|
|
419
|
+
log('Push data check skipped - unsupported platform');
|
|
370
420
|
}
|
|
371
421
|
|
|
372
422
|
// Process the push notification if found
|