@vgroup/dialbox 0.2.60 → 0.2.62
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/esm2020/lib/components/call-progress/call-progress.component.mjs +239 -120
- package/fesm2015/vgroup-dialbox.mjs +250 -125
- package/fesm2015/vgroup-dialbox.mjs.map +1 -1
- package/fesm2020/vgroup-dialbox.mjs +238 -119
- package/fesm2020/vgroup-dialbox.mjs.map +1 -1
- package/lib/components/call-progress/call-progress.component.d.ts +3 -1
- package/package.json +1 -1
|
@@ -2110,6 +2110,7 @@ class CallProgressComponent {
|
|
|
2110
2110
|
scope: 'local',
|
|
2111
2111
|
};
|
|
2112
2112
|
const response = await this.initiateCall(payload);
|
|
2113
|
+
this.conferenceId = response?.callauth?.id;
|
|
2113
2114
|
if (response.status == 200) {
|
|
2114
2115
|
const { id: callAuthId, recordCall } = await this.getCallAuthId(response);
|
|
2115
2116
|
this.getUserInformation(callAuthId);
|
|
@@ -2337,118 +2338,114 @@ class CallProgressComponent {
|
|
|
2337
2338
|
this.isAddRemoveParticipant = !this.isAddRemoveParticipant;
|
|
2338
2339
|
this.GetContactsList();
|
|
2339
2340
|
}
|
|
2340
|
-
async callContact(contact) {
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
}
|
|
2449
|
-
this.handleError(error);
|
|
2450
|
-
}
|
|
2451
|
-
}
|
|
2341
|
+
// async callContact(contact: any) {
|
|
2342
|
+
// console.log('Adding contact to call:', contact);
|
|
2343
|
+
// // Check if there's an active call
|
|
2344
|
+
// if (!this.call || this.call.status() !== 'open') {
|
|
2345
|
+
// console.error('No active call to add participant to');
|
|
2346
|
+
// return;
|
|
2347
|
+
// }
|
|
2348
|
+
// // Get the phone number from the contact
|
|
2349
|
+
// const phoneNumber = contact.numbersList && contact.numbersList[0]?.number;
|
|
2350
|
+
// if (!phoneNumber) {
|
|
2351
|
+
// console.error('No phone number found for contact');
|
|
2352
|
+
// return;
|
|
2353
|
+
// }
|
|
2354
|
+
// try {
|
|
2355
|
+
// // Put current call on hold
|
|
2356
|
+
// if (this.call) {
|
|
2357
|
+
// this.heldCall = this.call;
|
|
2358
|
+
// this.isCallOnHold = true;
|
|
2359
|
+
// this.heldCall.mute(true);
|
|
2360
|
+
// console.log('Current call put on hold');
|
|
2361
|
+
// }
|
|
2362
|
+
// // Close contacts panel
|
|
2363
|
+
// this.showContactsPanel = false;
|
|
2364
|
+
// // Prepare new call data
|
|
2365
|
+
// const newCallData = {
|
|
2366
|
+
// phone: phoneNumber,
|
|
2367
|
+
// from: this.callData.from,
|
|
2368
|
+
// extNum: this.callData.extNum,
|
|
2369
|
+
// name: `${contact.firstName} ${contact.middleName || ''} ${contact.lastName || ''}`.trim(),
|
|
2370
|
+
// img: contact.img || 'assets/images/user.jpg',
|
|
2371
|
+
// displayNum: phoneNumber
|
|
2372
|
+
// };
|
|
2373
|
+
// // Initiate new call
|
|
2374
|
+
// this.showRingAnimation = true;
|
|
2375
|
+
// const payload = {
|
|
2376
|
+
// channelId: environment.channelId,
|
|
2377
|
+
// userId: localStorage.getItem('userId'),
|
|
2378
|
+
// to: phoneNumber,
|
|
2379
|
+
// scope: 'local',
|
|
2380
|
+
// fromNumber: this.callData.from
|
|
2381
|
+
// };
|
|
2382
|
+
// const response = await this.initiateCall(payload);
|
|
2383
|
+
// if (response.status == 200) {
|
|
2384
|
+
// const { id: callAuthId, recordCall } = await this.getCallAuthId(response);
|
|
2385
|
+
// this.getUserInformation(callAuthId);
|
|
2386
|
+
// this.recordCall = recordCall;
|
|
2387
|
+
// const tokenData: any = await this.getOutgoingCallToken(callAuthId);
|
|
2388
|
+
// // Connect to new call
|
|
2389
|
+
// const options: any = {
|
|
2390
|
+
// codecPreferences: ['opus', 'pcmu'],
|
|
2391
|
+
// closeProtection: true,
|
|
2392
|
+
// };
|
|
2393
|
+
// // Reuse existing Device if available; otherwise create and register once
|
|
2394
|
+
// if (!this.device) {
|
|
2395
|
+
// this.device = new Device(tokenData.token.value, options);
|
|
2396
|
+
// await this.device.register();
|
|
2397
|
+
// } else {
|
|
2398
|
+
// // Update token if Device supports it and token changed/rotated
|
|
2399
|
+
// try {
|
|
2400
|
+
// if ((this.device as any).updateToken) {
|
|
2401
|
+
// await (this.device as any).updateToken(tokenData.token.value);
|
|
2402
|
+
// }
|
|
2403
|
+
// } catch (e) {
|
|
2404
|
+
// console.warn('Device updateToken failed, proceeding with existing token', e);
|
|
2405
|
+
// }
|
|
2406
|
+
// }
|
|
2407
|
+
// const newCall = await this.device.connect({
|
|
2408
|
+
// params: {
|
|
2409
|
+
// From: this.callData.from,
|
|
2410
|
+
// To: phoneNumber,
|
|
2411
|
+
// Env: environment.abb,
|
|
2412
|
+
// Token: tokenData.token.id,
|
|
2413
|
+
// Ext: this.callData.extNum
|
|
2414
|
+
// },
|
|
2415
|
+
// rtcConstraints: { audio: { deviceId: 'default' } },
|
|
2416
|
+
// });
|
|
2417
|
+
// // Set new call as active
|
|
2418
|
+
// this.call = newCall;
|
|
2419
|
+
// this.callData = newCallData;
|
|
2420
|
+
// // Setup event listeners for new call
|
|
2421
|
+
// this.setupEventListeners();
|
|
2422
|
+
// // Poll call status
|
|
2423
|
+
// this.pollCallStatus(callAuthId);
|
|
2424
|
+
// console.log('New call initiated to:', phoneNumber);
|
|
2425
|
+
// this.cdr.detectChanges();
|
|
2426
|
+
// } else if (response.status == 201) {
|
|
2427
|
+
// swal("Error", response.message.join("<br/>"), "error");
|
|
2428
|
+
// // Restore held call if new call fails
|
|
2429
|
+
// if (this.heldCall) {
|
|
2430
|
+
// this.call = this.heldCall;
|
|
2431
|
+
// this.heldCall = undefined;
|
|
2432
|
+
// this.isCallOnHold = false;
|
|
2433
|
+
// this.call.mute(false);
|
|
2434
|
+
// }
|
|
2435
|
+
// }
|
|
2436
|
+
// } catch (error) {
|
|
2437
|
+
// console.error('Error adding participant:', error);
|
|
2438
|
+
// this.showRingAnimation = false;
|
|
2439
|
+
// // Restore held call on error
|
|
2440
|
+
// if (this.heldCall) {
|
|
2441
|
+
// this.call = this.heldCall;
|
|
2442
|
+
// this.heldCall = undefined;
|
|
2443
|
+
// this.isCallOnHold = false;
|
|
2444
|
+
// this.call.mute(false);
|
|
2445
|
+
// }
|
|
2446
|
+
// this.handleError(error);
|
|
2447
|
+
// }
|
|
2448
|
+
// }
|
|
2452
2449
|
// acceptConcurrentCall(incomingCall: any) {
|
|
2453
2450
|
// if (!incomingCall) return;
|
|
2454
2451
|
// // Put current call on hold instead of disconnecting
|
|
@@ -2471,6 +2468,99 @@ class CallProgressComponent {
|
|
|
2471
2468
|
// this.startTimer();
|
|
2472
2469
|
// this.cdr.detectChanges();
|
|
2473
2470
|
// }
|
|
2471
|
+
async callContact(contact) {
|
|
2472
|
+
console.log("Starting second call:", contact);
|
|
2473
|
+
// Must have active Call A
|
|
2474
|
+
if (!this.call || this.call.status() !== "open") {
|
|
2475
|
+
console.error("No active call to start second call");
|
|
2476
|
+
return;
|
|
2477
|
+
}
|
|
2478
|
+
const phoneNumber = contact?.numbersList?.[0]?.number;
|
|
2479
|
+
if (!phoneNumber) {
|
|
2480
|
+
console.error("No phone number found");
|
|
2481
|
+
return;
|
|
2482
|
+
}
|
|
2483
|
+
try {
|
|
2484
|
+
// ---- HOLD CALL A ----
|
|
2485
|
+
this.heldCall = this.call;
|
|
2486
|
+
this.isCallOnHold = true;
|
|
2487
|
+
this.heldCall.mute(true);
|
|
2488
|
+
console.log("Call A placed on hold");
|
|
2489
|
+
this.showContactsPanel = false;
|
|
2490
|
+
this.showRingAnimation = true;
|
|
2491
|
+
// ---- START CALL B ----
|
|
2492
|
+
await this.startSecondOutboundCall(phoneNumber, contact);
|
|
2493
|
+
this.showRingAnimation = false;
|
|
2494
|
+
console.log("Second call started successfully");
|
|
2495
|
+
}
|
|
2496
|
+
catch (err) {
|
|
2497
|
+
console.error("Error starting second call:", err);
|
|
2498
|
+
// Restore call A
|
|
2499
|
+
if (this.heldCall) {
|
|
2500
|
+
this.call = this.heldCall;
|
|
2501
|
+
this.heldCall = undefined;
|
|
2502
|
+
this.isCallOnHold = false;
|
|
2503
|
+
this.call.mute(false);
|
|
2504
|
+
}
|
|
2505
|
+
this.showRingAnimation = false;
|
|
2506
|
+
swal("Error", "Failed to start second call", "error");
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2509
|
+
async startSecondOutboundCall(phoneNumber, contact) {
|
|
2510
|
+
console.log("Dialing second call to", phoneNumber);
|
|
2511
|
+
// 1️⃣ Prepare data for new call
|
|
2512
|
+
const payload = {
|
|
2513
|
+
channelId: environment.channelId,
|
|
2514
|
+
userId: localStorage.getItem("userId"),
|
|
2515
|
+
to: phoneNumber,
|
|
2516
|
+
scope: "local",
|
|
2517
|
+
fromNumber: this.callData.from
|
|
2518
|
+
};
|
|
2519
|
+
const response = await this.initiateCall(payload);
|
|
2520
|
+
if (response.status !== 200) {
|
|
2521
|
+
throw new Error("Backend failed to initiate call");
|
|
2522
|
+
}
|
|
2523
|
+
const { id: callAuthId, recordCall } = await this.getCallAuthId(response);
|
|
2524
|
+
this.recordCall = recordCall;
|
|
2525
|
+
const tokenData = await this.getOutgoingCallToken(callAuthId);
|
|
2526
|
+
// 2️⃣ Setup Twilio Device (same as your current code)
|
|
2527
|
+
const options = {
|
|
2528
|
+
codecPreferences: ["opus", "pcmu"],
|
|
2529
|
+
closeProtection: true,
|
|
2530
|
+
};
|
|
2531
|
+
if (!this.device) {
|
|
2532
|
+
this.device = new Device(tokenData.token.value, options);
|
|
2533
|
+
await this.device.register();
|
|
2534
|
+
}
|
|
2535
|
+
else if (this.device.updateToken) {
|
|
2536
|
+
await this.device.updateToken(tokenData.token.value);
|
|
2537
|
+
}
|
|
2538
|
+
// 3️⃣ Start NEW CALL B
|
|
2539
|
+
const newCall = await this.device.connect({
|
|
2540
|
+
params: {
|
|
2541
|
+
From: this.callData.from,
|
|
2542
|
+
To: phoneNumber,
|
|
2543
|
+
Env: environment.abb,
|
|
2544
|
+
Token: tokenData.token.id,
|
|
2545
|
+
Ext: this.callData.extNum
|
|
2546
|
+
},
|
|
2547
|
+
rtcConstraints: { audio: { deviceId: "default" } }
|
|
2548
|
+
});
|
|
2549
|
+
// 4️⃣ Set new call B as active call
|
|
2550
|
+
this.call = newCall;
|
|
2551
|
+
// Update call data UI
|
|
2552
|
+
this.callData = {
|
|
2553
|
+
phone: phoneNumber,
|
|
2554
|
+
from: this.callData.from,
|
|
2555
|
+
extNum: this.callData.extNum,
|
|
2556
|
+
name: `${contact.firstName} ${contact.middleName || ""} ${contact.lastName || ""}`.trim(),
|
|
2557
|
+
img: contact.img || "assets/images/user.jpg",
|
|
2558
|
+
displayNum: phoneNumber
|
|
2559
|
+
};
|
|
2560
|
+
this.setupEventListeners();
|
|
2561
|
+
this.pollCallStatus(callAuthId);
|
|
2562
|
+
console.log("Call B is now active");
|
|
2563
|
+
}
|
|
2474
2564
|
acceptConcurrentCall(incomingCall) {
|
|
2475
2565
|
if (!incomingCall)
|
|
2476
2566
|
return;
|
|
@@ -2528,14 +2618,43 @@ class CallProgressComponent {
|
|
|
2528
2618
|
console.log('Updated callData:', this.callData);
|
|
2529
2619
|
this.cdr.detectChanges();
|
|
2530
2620
|
}
|
|
2531
|
-
mergeCalls() {
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2621
|
+
// mergeCalls() {
|
|
2622
|
+
// // Merge functionality - unmute both calls for conference
|
|
2623
|
+
// if (this.heldCall && this.call) {
|
|
2624
|
+
// this.heldCall.mute(false);
|
|
2625
|
+
// this.call.mute(false);
|
|
2626
|
+
// this.isCallOnHold = false;
|
|
2627
|
+
// this.isConference = true;
|
|
2628
|
+
// this.cdr.detectChanges();
|
|
2629
|
+
// }
|
|
2630
|
+
// }
|
|
2631
|
+
async mergeCalls() {
|
|
2632
|
+
if (!this.conferenceId) {
|
|
2633
|
+
swal("Error", "Unable to merge: conference ID missing", "error");
|
|
2634
|
+
return;
|
|
2635
|
+
}
|
|
2636
|
+
if (!this.callData?.phone) {
|
|
2637
|
+
swal("Error", "Second call number is missing", "error");
|
|
2638
|
+
return;
|
|
2639
|
+
}
|
|
2640
|
+
try {
|
|
2641
|
+
this.showRingAnimation = true;
|
|
2642
|
+
const payload = {
|
|
2643
|
+
from: this.callData.from,
|
|
2644
|
+
route: "OUTGOING",
|
|
2645
|
+
participantNumber: this.callData.phone,
|
|
2646
|
+
conferenceId: this.conferenceId
|
|
2647
|
+
};
|
|
2648
|
+
console.log("Calling addParticipant API:", payload);
|
|
2649
|
+
await this.addParticipantToCall(payload);
|
|
2650
|
+
this.showRingAnimation = false;
|
|
2537
2651
|
this.isConference = true;
|
|
2538
|
-
|
|
2652
|
+
swal("Success", "Calls have been merged", "success");
|
|
2653
|
+
}
|
|
2654
|
+
catch (error) {
|
|
2655
|
+
console.error("Merge failed:", error);
|
|
2656
|
+
this.showRingAnimation = false;
|
|
2657
|
+
swal("Error", "Failed to merge calls", "error");
|
|
2539
2658
|
}
|
|
2540
2659
|
}
|
|
2541
2660
|
endHeldCall() {
|