@telnyx/react-voice-commons-sdk 0.1.0 → 0.1.2
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/README.md +483 -0
- package/TelnyxVoiceCommons.podspec +31 -31
- package/ios/CallKitBridge.m +43 -43
- package/ios/CallKitBridge.swift +879 -879
- package/ios/VoicePnBridge.m +30 -30
- package/ios/VoicePnBridge.swift +86 -86
- package/lib/callkit/callkit-coordinator.d.ts +117 -113
- package/lib/callkit/callkit-coordinator.js +727 -681
- 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 +86 -81
- package/lib/internal/calls/call-state-controller.js +307 -269
- package/lib/internal/session/session-manager.d.ts +75 -75
- package/lib/internal/session/session-manager.js +424 -350
- package/lib/internal/user-defaults-helpers.js +39 -49
- package/lib/internal/voice-pn-bridge.d.ts +11 -11
- package/lib/internal/voice-pn-bridge.js +3 -3
- package/lib/models/call-state.d.ts +44 -44
- package/lib/models/call-state.js +68 -66
- package/lib/models/call.d.ts +133 -133
- package/lib/models/call.js +382 -354
- 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 +482 -424
- package/lib/telnyx-voip-client.d.ts +167 -155
- package/lib/telnyx-voip-client.js +392 -331
- package/package.json +1 -1
- package/src/telnyx-voip-client.ts +64 -0
package/lib/models/call.js
CHANGED
|
@@ -1,43 +1,62 @@
|
|
|
1
|
-
|
|
2
|
-
var __createBinding =
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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;
|
|
24
41
|
};
|
|
25
|
-
|
|
42
|
+
return ownKeys(o);
|
|
26
43
|
};
|
|
27
44
|
return function (mod) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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;
|
|
33
52
|
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports,
|
|
53
|
+
})();
|
|
54
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
36
55
|
exports.Call = void 0;
|
|
37
|
-
const rxjs_1 = require(
|
|
38
|
-
const operators_1 = require(
|
|
39
|
-
const call_state_1 = require(
|
|
40
|
-
const react_native_1 = require(
|
|
56
|
+
const rxjs_1 = require('rxjs');
|
|
57
|
+
const operators_1 = require('rxjs/operators');
|
|
58
|
+
const call_state_1 = require('./call-state');
|
|
59
|
+
const react_native_1 = require('react-native');
|
|
41
60
|
/**
|
|
42
61
|
* Represents a call with reactive state streams.
|
|
43
62
|
*
|
|
@@ -46,327 +65,336 @@ const react_native_1 = require("react-native");
|
|
|
46
65
|
* integrate with any state management solution.
|
|
47
66
|
*/
|
|
48
67
|
class Call {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
68
|
+
constructor(_telnyxCall, _callId, _destination, _isIncoming) {
|
|
69
|
+
this._telnyxCall = _telnyxCall;
|
|
70
|
+
this._callId = _callId;
|
|
71
|
+
this._destination = _destination;
|
|
72
|
+
this._isIncoming = _isIncoming;
|
|
73
|
+
this._callState = new rxjs_1.BehaviorSubject(call_state_1.TelnyxCallState.RINGING);
|
|
74
|
+
this._isMuted = new rxjs_1.BehaviorSubject(false);
|
|
75
|
+
this._isHeld = new rxjs_1.BehaviorSubject(false);
|
|
76
|
+
this._duration = new rxjs_1.BehaviorSubject(0);
|
|
77
|
+
this._setupCallListeners();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Unique identifier for this call
|
|
81
|
+
*/
|
|
82
|
+
get callId() {
|
|
83
|
+
return this._callId;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The destination number or SIP URI
|
|
87
|
+
*/
|
|
88
|
+
get destination() {
|
|
89
|
+
return this._destination;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Whether this is an incoming call
|
|
93
|
+
*/
|
|
94
|
+
get isIncoming() {
|
|
95
|
+
return this._isIncoming;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Whether this is an outgoing call
|
|
99
|
+
*/
|
|
100
|
+
get isOutgoing() {
|
|
101
|
+
return !this._isIncoming;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Current call state (synchronous access)
|
|
105
|
+
*/
|
|
106
|
+
get currentState() {
|
|
107
|
+
return this._callState.value;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Current mute state (synchronous access)
|
|
111
|
+
*/
|
|
112
|
+
get currentIsMuted() {
|
|
113
|
+
return this._isMuted.value;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Current hold state (synchronous access)
|
|
117
|
+
*/
|
|
118
|
+
get currentIsHeld() {
|
|
119
|
+
return this._isHeld.value;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Current call duration in seconds (synchronous access)
|
|
123
|
+
*/
|
|
124
|
+
get currentDuration() {
|
|
125
|
+
return this._duration.value;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get the underlying Telnyx Call object (for internal use)
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
131
|
+
get telnyxCall() {
|
|
132
|
+
return this._telnyxCall;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Observable stream of call state changes
|
|
136
|
+
*/
|
|
137
|
+
get callState$() {
|
|
138
|
+
return this._callState.asObservable().pipe((0, operators_1.distinctUntilChanged)());
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Observable stream of mute state changes
|
|
142
|
+
*/
|
|
143
|
+
get isMuted$() {
|
|
144
|
+
return this._isMuted.asObservable().pipe((0, operators_1.distinctUntilChanged)());
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Observable stream of hold state changes
|
|
148
|
+
*/
|
|
149
|
+
get isHeld$() {
|
|
150
|
+
return this._isHeld.asObservable().pipe((0, operators_1.distinctUntilChanged)());
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Observable stream of call duration changes (in seconds)
|
|
154
|
+
*/
|
|
155
|
+
get duration$() {
|
|
156
|
+
return this._duration.asObservable().pipe((0, operators_1.distinctUntilChanged)());
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Observable that emits true when the call can be answered
|
|
160
|
+
*/
|
|
161
|
+
get canAnswer$() {
|
|
162
|
+
return this.callState$.pipe(
|
|
163
|
+
(0, operators_1.map)((state) => call_state_1.CallStateHelpers.canAnswer(state)),
|
|
164
|
+
(0, operators_1.distinctUntilChanged)()
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Observable that emits true when the call can be hung up
|
|
169
|
+
*/
|
|
170
|
+
get canHangup$() {
|
|
171
|
+
return this.callState$.pipe(
|
|
172
|
+
(0, operators_1.map)((state) => call_state_1.CallStateHelpers.canHangup(state)),
|
|
173
|
+
(0, operators_1.distinctUntilChanged)()
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Observable that emits true when the call can be put on hold
|
|
178
|
+
*/
|
|
179
|
+
get canHold$() {
|
|
180
|
+
return this.callState$.pipe(
|
|
181
|
+
(0, operators_1.map)((state) => call_state_1.CallStateHelpers.canHold(state)),
|
|
182
|
+
(0, operators_1.distinctUntilChanged)()
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Observable that emits true when the call can be resumed from hold
|
|
187
|
+
*/
|
|
188
|
+
get canResume$() {
|
|
189
|
+
return this.callState$.pipe(
|
|
190
|
+
(0, operators_1.map)((state) => call_state_1.CallStateHelpers.canResume(state)),
|
|
191
|
+
(0, operators_1.distinctUntilChanged)()
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Answer the incoming call
|
|
196
|
+
*/
|
|
197
|
+
async answer() {
|
|
198
|
+
if (!call_state_1.CallStateHelpers.canAnswer(this.currentState)) {
|
|
199
|
+
throw new Error(`Cannot answer call in state: ${this.currentState}`);
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
// On iOS, use CallKit coordinator for proper audio session handling
|
|
203
|
+
if (react_native_1.Platform.OS === 'ios') {
|
|
204
|
+
const { callKitCoordinator } = await Promise.resolve().then(() =>
|
|
205
|
+
__importStar(require('../callkit/callkit-coordinator'))
|
|
206
|
+
);
|
|
207
|
+
if (callKitCoordinator.isAvailable()) {
|
|
208
|
+
console.log('Call: Using CallKit coordinator to answer call (iOS)');
|
|
209
|
+
await callKitCoordinator.answerCallFromUI(this._telnyxCall);
|
|
210
|
+
return;
|
|
184
211
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
throw error;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Put the call on hold
|
|
217
|
-
*/
|
|
218
|
-
async hold() {
|
|
219
|
-
if (!call_state_1.CallStateHelpers.canHold(this.currentState)) {
|
|
220
|
-
throw new Error(`Cannot hold call in state: ${this.currentState}`);
|
|
212
|
+
}
|
|
213
|
+
// Fallback for Android or when CallKit is not available
|
|
214
|
+
console.log('Call: Setting state to CONNECTING before answering');
|
|
215
|
+
this._callState.next(call_state_1.TelnyxCallState.CONNECTING);
|
|
216
|
+
await this._telnyxCall.answer();
|
|
217
|
+
} catch (error) {
|
|
218
|
+
console.error('Failed to answer call:', error);
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Hang up the call
|
|
224
|
+
*/
|
|
225
|
+
async hangup() {
|
|
226
|
+
if (!call_state_1.CallStateHelpers.canHangup(this.currentState)) {
|
|
227
|
+
throw new Error(`Cannot hang up call in state: ${this.currentState}`);
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
// On iOS, use CallKit coordinator for proper CallKit cleanup
|
|
231
|
+
if (react_native_1.Platform.OS === 'ios') {
|
|
232
|
+
const { callKitCoordinator } = await Promise.resolve().then(() =>
|
|
233
|
+
__importStar(require('../callkit/callkit-coordinator'))
|
|
234
|
+
);
|
|
235
|
+
if (callKitCoordinator.isAvailable()) {
|
|
236
|
+
console.log('Call: Using CallKit coordinator to end call (iOS)');
|
|
237
|
+
await callKitCoordinator.endCallFromUI(this._telnyxCall);
|
|
238
|
+
return;
|
|
221
239
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
240
|
+
}
|
|
241
|
+
// Fallback for Android or when CallKit is not available
|
|
242
|
+
await this._telnyxCall.hangup();
|
|
243
|
+
} catch (error) {
|
|
244
|
+
console.error('Failed to hang up call:', error);
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Put the call on hold
|
|
250
|
+
*/
|
|
251
|
+
async hold() {
|
|
252
|
+
if (!call_state_1.CallStateHelpers.canHold(this.currentState)) {
|
|
253
|
+
throw new Error(`Cannot hold call in state: ${this.currentState}`);
|
|
254
|
+
}
|
|
255
|
+
try {
|
|
256
|
+
await this._telnyxCall.hold();
|
|
257
|
+
} catch (error) {
|
|
258
|
+
console.error('Failed to hold call:', error);
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Resume the call from hold
|
|
264
|
+
*/
|
|
265
|
+
async resume() {
|
|
266
|
+
if (!call_state_1.CallStateHelpers.canResume(this.currentState)) {
|
|
267
|
+
throw new Error(`Cannot resume call in state: ${this.currentState}`);
|
|
268
|
+
}
|
|
269
|
+
try {
|
|
270
|
+
await this._telnyxCall.unhold();
|
|
271
|
+
} catch (error) {
|
|
272
|
+
console.error('Failed to resume call:', error);
|
|
273
|
+
throw error;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Mute the call
|
|
278
|
+
*/
|
|
279
|
+
async mute() {
|
|
280
|
+
if (!call_state_1.CallStateHelpers.canToggleMute(this.currentState)) {
|
|
281
|
+
throw new Error(`Cannot mute call in state: ${this.currentState}`);
|
|
282
|
+
}
|
|
283
|
+
try {
|
|
284
|
+
this._telnyxCall.mute();
|
|
285
|
+
this._isMuted.next(true);
|
|
286
|
+
} catch (error) {
|
|
287
|
+
console.error('Failed to mute call:', error);
|
|
288
|
+
throw error;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Unmute the call
|
|
293
|
+
*/
|
|
294
|
+
async unmute() {
|
|
295
|
+
if (!call_state_1.CallStateHelpers.canToggleMute(this.currentState)) {
|
|
296
|
+
throw new Error(`Cannot unmute call in state: ${this.currentState}`);
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
this._telnyxCall.unmute();
|
|
300
|
+
this._isMuted.next(false);
|
|
301
|
+
} catch (error) {
|
|
302
|
+
console.error('Failed to unmute call:', error);
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Toggle mute state
|
|
308
|
+
*/
|
|
309
|
+
async toggleMute() {
|
|
310
|
+
if (this.currentIsMuted) {
|
|
311
|
+
await this.unmute();
|
|
312
|
+
} else {
|
|
313
|
+
await this.mute();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Set the call to connecting state (used for push notification calls when answered via CallKit)
|
|
318
|
+
* @internal
|
|
319
|
+
*/
|
|
320
|
+
setConnecting() {
|
|
321
|
+
console.log('Call: Setting state to CONNECTING for push notification answer');
|
|
322
|
+
this._callState.next(call_state_1.TelnyxCallState.CONNECTING);
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Clean up resources when the call is disposed
|
|
326
|
+
*/
|
|
327
|
+
dispose() {
|
|
328
|
+
this._stopDurationTimer();
|
|
329
|
+
this._callState.complete();
|
|
330
|
+
this._isMuted.complete();
|
|
331
|
+
this._isHeld.complete();
|
|
332
|
+
this._duration.complete();
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Set up listeners for the underlying Telnyx call
|
|
336
|
+
*/
|
|
337
|
+
_setupCallListeners() {
|
|
338
|
+
// Map Telnyx call states to our simplified states
|
|
339
|
+
this._telnyxCall.on('telnyx.call.state', (call, state) => {
|
|
340
|
+
const telnyxState = this._mapToTelnyxCallState(state);
|
|
341
|
+
this._callState.next(telnyxState);
|
|
342
|
+
// Start duration timer when call becomes active
|
|
343
|
+
if (telnyxState === call_state_1.TelnyxCallState.ACTIVE && !this._startTime) {
|
|
344
|
+
this._startDurationTimer();
|
|
345
|
+
}
|
|
346
|
+
// Stop duration timer when call ends
|
|
347
|
+
if (call_state_1.CallStateHelpers.isTerminated(telnyxState)) {
|
|
300
348
|
this._stopDurationTimer();
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
* Start the duration timer
|
|
352
|
-
*/
|
|
353
|
-
_startDurationTimer() {
|
|
354
|
-
this._startTime = new Date();
|
|
355
|
-
this._durationTimer = setInterval(() => {
|
|
356
|
-
if (this._startTime) {
|
|
357
|
-
const duration = Math.floor((Date.now() - this._startTime.getTime()) / 1000);
|
|
358
|
-
this._duration.next(duration);
|
|
359
|
-
}
|
|
360
|
-
}, 1000);
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Stop the duration timer
|
|
364
|
-
*/
|
|
365
|
-
_stopDurationTimer() {
|
|
366
|
-
if (this._durationTimer) {
|
|
367
|
-
clearInterval(this._durationTimer);
|
|
368
|
-
this._durationTimer = undefined;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Map Telnyx SDK call states to our simplified call states
|
|
354
|
+
*/
|
|
355
|
+
_mapToTelnyxCallState(telnyxState) {
|
|
356
|
+
// This mapping will depend on the actual Telnyx SDK call states
|
|
357
|
+
// For now, using a basic mapping - this should be updated based on actual SDK
|
|
358
|
+
switch (telnyxState) {
|
|
359
|
+
case 'ringing':
|
|
360
|
+
case 'new':
|
|
361
|
+
return call_state_1.TelnyxCallState.RINGING;
|
|
362
|
+
case 'active':
|
|
363
|
+
case 'answered':
|
|
364
|
+
return call_state_1.TelnyxCallState.ACTIVE;
|
|
365
|
+
case 'held':
|
|
366
|
+
return call_state_1.TelnyxCallState.HELD;
|
|
367
|
+
case 'ended':
|
|
368
|
+
case 'hangup':
|
|
369
|
+
return call_state_1.TelnyxCallState.ENDED;
|
|
370
|
+
case 'failed':
|
|
371
|
+
case 'rejected':
|
|
372
|
+
return call_state_1.TelnyxCallState.FAILED;
|
|
373
|
+
default:
|
|
374
|
+
console.warn(`Unknown call state: ${telnyxState}`);
|
|
375
|
+
return call_state_1.TelnyxCallState.RINGING;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Start the duration timer
|
|
380
|
+
*/
|
|
381
|
+
_startDurationTimer() {
|
|
382
|
+
this._startTime = new Date();
|
|
383
|
+
this._durationTimer = setInterval(() => {
|
|
384
|
+
if (this._startTime) {
|
|
385
|
+
const duration = Math.floor((Date.now() - this._startTime.getTime()) / 1000);
|
|
386
|
+
this._duration.next(duration);
|
|
387
|
+
}
|
|
388
|
+
}, 1000);
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Stop the duration timer
|
|
392
|
+
*/
|
|
393
|
+
_stopDurationTimer() {
|
|
394
|
+
if (this._durationTimer) {
|
|
395
|
+
clearInterval(this._durationTimer);
|
|
396
|
+
this._durationTimer = undefined;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
371
399
|
}
|
|
372
400
|
exports.Call = Call;
|