@vgroup/dialbox 0.8.18 → 0.8.20

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.
@@ -63,23 +63,23 @@ const keypad = [
63
63
  ];
64
64
 
65
65
  const environment = {
66
- abb: "d",
66
+ abb: "t",
67
67
  production: false,
68
68
  secureCookies: true,
69
- feUrl: 'https://dev.vgroupinc.com:91/',
70
- apiUrl: 'https://dev-api-t10.vgroupinc.com/dev_softphone_p91',
71
- websocketUrl: 'wss://dev-api-t10.vgroupinc.com/dev_softphone_p91/',
69
+ feUrl: 'https://test.vgroupinc.com:91/',
70
+ apiUrl: 'https://apis.vgroupinc.com/test_softphone',
71
+ websocketUrl: 'wss://apis.vgroupinc.com/test_softphone/',
72
72
  captchaKey: "6LfpOmEaAAAAAGsI6JXlMzOl3b7rW4YmYXFDjldD",
73
- stripePublishableKey: "pk_test_51K6aTuBiNVV2TMlQfmBWY8jziwiDo0IZ3TrqWPqth1m32cpMAAg5Qpi2AlSMDEAX6hCZRBXoTzBB1uQQLc8B4tco00q2SgG6zO",
73
+ stripePublishableKey: "pk_test_51NbMVaA3guus6fhlTuCV5ycFTIJmwgN38dDUf9pNPfM319x5CkLbV6EbTQaZiNOrRsfR16RWLE8hQmR0eZFTBqTy00Wlsug4qS",
74
74
  sessionTimeout: 15,
75
75
  deviceType: "web",
76
76
  appVersion: "2.3",
77
77
  channelId: '61481b12e138eb7dc3007579',
78
78
  c2c_support_point_id: '60424735f74ac306c1bfa900',
79
- c2c_support_channel_id: '677f67f3be93ab507fbbfdfc',
79
+ c2c_support_channel_id: '677f6726be93ab507fbbfdf0',
80
80
  c2c_point_url: 'https://app.contexttocall.com/assets/cdn/c2c.js',
81
- c2c_call_label_id: 'ye2XFLfOHCr12GFVRzPh',
82
- c2c_email_label_id: 'mvjVgOP2VCiYsVovQqdq',
81
+ c2c_call_label_id: '6NU5fKE2mGTyXDC3yhmK',
82
+ c2c_email_label_id: 'YPMamj8RvsGORVvqXWyc',
83
83
  radarAPIKey: 'prj_live_sk_569b6f639edde6120a26f703511c61aaecd3f7ef',
84
84
  firebase: {
85
85
  apiKey: "AIzaSyCA8LSPrqlDq_thk26LhBQexAQeY6pkU5Y",
@@ -93,7 +93,7 @@ const environment = {
93
93
  },
94
94
  perspectiveApiKey: 'AIzaSyClf32lvLH4QOy-vOnzLzwSNntKIgapH8s',
95
95
  keycloakURL: 'https://test-keycloak.vgroupinc.com/',
96
- keycloakRealm: 'vgroup-dev',
96
+ keycloakRealm: 'vgroup-test',
97
97
  keycloakClientId: 'c2c-softphone-app'
98
98
  };
99
99
 
@@ -1467,6 +1467,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
1467
1467
  }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: IpAddressService }]; } });
1468
1468
 
1469
1469
  class TwilioService {
1470
+ requestSpecialCallConfirm(message, inCallScreen) {
1471
+ this.resolveSpecialCallConfirm(false); // close any stale confirmation
1472
+ this.isAwaitingSpecialCallConfirm = true;
1473
+ return new Promise((resolve) => {
1474
+ this.specialCallConfirmResolver = resolve;
1475
+ this.specialCallConfirm = { message, inCallScreen };
1476
+ });
1477
+ }
1478
+ resolveSpecialCallConfirm(isConfirmed) {
1479
+ const resolve = this.specialCallConfirmResolver;
1480
+ this.specialCallConfirmResolver = null;
1481
+ this.specialCallConfirm = null;
1482
+ if (isConfirmed) {
1483
+ // Twilio has not connected yet – keep the call screen alive until call-progress reports the
1484
+ // client leg is connected (releaseSpecialCallGuard), with a safety timeout.
1485
+ this.holdCallScreenGuard(20000);
1486
+ }
1487
+ else {
1488
+ this.releaseSpecialCallGuard();
1489
+ }
1490
+ resolve === null || resolve === void 0 ? void 0 : resolve(isConfirmed);
1491
+ }
1492
+ // Keep the call screen alive while an outgoing call is set up. The safety timeout only covers
1493
+ // API/Twilio waits — requestSpecialCallConfirm() clears it so the charges modal can stay open indefinitely.
1494
+ holdCallScreenGuard(timeoutMs = 30000) {
1495
+ clearTimeout(this.specialCallGuardTimer);
1496
+ this.isAwaitingSpecialCallConfirm = true;
1497
+ this.specialCallGuardTimer = setTimeout(() => this.releaseSpecialCallGuard(), timeoutMs);
1498
+ }
1499
+ releaseSpecialCallGuard() {
1500
+ clearTimeout(this.specialCallGuardTimer);
1501
+ this.isAwaitingSpecialCallConfirm = false;
1502
+ }
1470
1503
  constructor(http, extensionService) {
1471
1504
  this.http = http;
1472
1505
  this.extensionService = extensionService;
@@ -1494,12 +1527,23 @@ class TwilioService {
1494
1527
  // CRITICAL: Track all accepted Call objects (mirrors iOS acceptedCallList)
1495
1528
  // Used to guard device re-initialization so active calls are never torn down
1496
1529
  this.acceptedCallList = [];
1530
+ // True while an outgoing call is being set up (initiate API → special call charges modal → Twilio
1531
+ // client leg connected). Socket ticks are empty during this window, so dialbox must not treat them as idle.
1532
+ this.isAwaitingSpecialCallConfirm = false;
1533
+ // Special call charges modal state. inCallScreen: true → rendered by call-progress (a call screen is open),
1534
+ // false → rendered by dialbox over the "Connecting..." loader (first call, call screen not rendered yet)
1535
+ this.specialCallConfirm = null;
1536
+ this.specialCallConfirmResolver = null;
1497
1537
  this.primaryHasCall = false;
1498
1538
  this.spareDevice = null;
1499
1539
  this.spareDeviceReady = false;
1500
1540
  this.pendingIncomingDevices = new Map();
1501
1541
  this.extraDevices = new Map();
1502
1542
  this.incomingCallsMap = new Map();
1543
+ // BE issues incoming-call access tokens with a 1h30m TTL. Ask Twilio to fire
1544
+ // 'tokenWillExpire' 5 minutes before that (SDK default is only 10s) so a slow
1545
+ // network / backgrounded tab still has time to fetch and apply a fresh token.
1546
+ this.TOKEN_REFRESH_MS = 5 * 60 * 1000;
1503
1547
  this.tokenRefreshInProgress = false;
1504
1548
  this.recoveryAttempts = 0;
1505
1549
  this.recoveryTimer = null;
@@ -1588,7 +1632,7 @@ class TwilioService {
1588
1632
  console.error('No Twilio token available');
1589
1633
  return;
1590
1634
  }
1591
- const device = new Device(this.incomingCallToken, { allowIncomingWhileBusy: true });
1635
+ const device = new Device(this.incomingCallToken, { allowIncomingWhileBusy: true, tokenRefreshMs: this.TOKEN_REFRESH_MS });
1592
1636
  this.device = device;
1593
1637
  device.on('registered', () => {
1594
1638
  console.log('Twilio Device registered successfully');
@@ -1602,7 +1646,7 @@ class TwilioService {
1602
1646
  }
1603
1647
  this.prepareDevice2ForIncomingCall();
1604
1648
  });
1605
- // Twilio fires this ~3 minutes before the access token expires. Swap in a
1649
+ // Twilio fires this TOKEN_REFRESH_MS before the access token expires. Swap in a
1606
1650
  // fresh one via updateToken() so the signaling connection never has to drop
1607
1651
  // in the first place (this is the main cause of "idle for a while, BE still
1608
1652
  // notifies but Twilio incoming event never fires").
@@ -1694,17 +1738,27 @@ class TwilioService {
1694
1738
  this.tokenRefreshInProgress = true;
1695
1739
  this.extensionService.getIncomingCallToken(this.deviceId || localStorage.getItem('deviceId')).subscribe({
1696
1740
  next: (data) => {
1697
- var _a;
1698
1741
  this.tokenRefreshInProgress = false;
1699
1742
  this.incomingCallToken = data.token;
1700
1743
  localStorage.setItem('in-token', data.token);
1701
1744
  this.tokenInitialized = true;
1702
- try {
1703
- (_a = this.device) === null || _a === void 0 ? void 0 : _a.updateToken(this.incomingCallToken);
1704
- }
1705
- catch (err) {
1706
- console.error('Failed to apply refreshed Twilio token:', err);
1707
- }
1745
+ // Every live Device was created from the same token, so they all expire
1746
+ // together — refresh the spare/pending/concurrent ones too, otherwise the
1747
+ // spare silently dies after 1h30m idle and concurrent calls never ring.
1748
+ const apply = (dev) => {
1749
+ if (!dev)
1750
+ return;
1751
+ try {
1752
+ dev.updateToken(this.incomingCallToken);
1753
+ }
1754
+ catch (err) {
1755
+ console.error('Failed to apply refreshed Twilio token:', err);
1756
+ }
1757
+ };
1758
+ apply(this.device);
1759
+ apply(this.spareDevice);
1760
+ this.pendingIncomingDevices.forEach(apply);
1761
+ this.extraDevices.forEach(apply);
1708
1762
  },
1709
1763
  error: (err) => {
1710
1764
  this.tokenRefreshInProgress = false;
@@ -1922,8 +1976,13 @@ class TwilioService {
1922
1976
  console.warn('prepareSpareDevice: no token available');
1923
1977
  return;
1924
1978
  }
1925
- const spare = new Device(this.incomingCallToken, { allowIncomingWhileBusy: true });
1979
+ const spare = new Device(this.incomingCallToken, { allowIncomingWhileBusy: true, tokenRefreshMs: this.TOKEN_REFRESH_MS });
1926
1980
  spare._ownsAcceptedCall = false;
1981
+ // Fallback in case the primary device is gone/replaced: the spare can trigger
1982
+ // the shared refresh itself (refreshDeviceToken dedupes concurrent requests).
1983
+ spare.on('tokenWillExpire', () => {
1984
+ this.refreshDeviceToken();
1985
+ });
1927
1986
  spare.on('registered', () => {
1928
1987
  var _a;
1929
1988
  this.spareDeviceReady = true;
@@ -2311,6 +2370,9 @@ class CallProgressComponent {
2311
2370
  this.isHoldBtnDisable = false;
2312
2371
  this.C2ConfoList = {};
2313
2372
  this.lastActiveConferenceId = null;
2373
+ // Conferences flagged as specialCall (from initiate response / socket) – adding participants is not allowed
2374
+ this.specialCallConferenceIds = new Set();
2375
+ this.isComponentDestroyed = false;
2314
2376
  this.pendingAutoUnhold = false;
2315
2377
  this.pendingMuteParticipants = new Set();
2316
2378
  this.intendedMuteStates = new Map();
@@ -2381,6 +2443,7 @@ class CallProgressComponent {
2381
2443
  this.newIncomingCallsList.forEach((callInfo, i) => {
2382
2444
  var _a, _b, _c;
2383
2445
  this.conferenceId = i == 0 ? this.newIncomingCallsList[i].conferenceId : this.conferenceId;
2446
+ this.updateSpecialCallFlag(callInfo === null || callInfo === void 0 ? void 0 : callInfo.conferenceId, callInfo === null || callInfo === void 0 ? void 0 : callInfo.specialCall);
2384
2447
  let ourNumberInfo = (_a = this.newIncomingCallsList[i]) === null || _a === void 0 ? void 0 : _a.participants.find((resData) => { var _a; return ((this.deviceNumberList.includes(resData === null || resData === void 0 ? void 0 : resData.from) && (resData === null || resData === void 0 ? void 0 : resData.direction) == 'outgoing-call' && (resData === null || resData === void 0 ? void 0 : resData.client)) || (this.deviceNumberList.includes(resData === null || resData === void 0 ? void 0 : resData.to) && (resData === null || resData === void 0 ? void 0 : resData.direction) == 'incoming-call' && (!(resData === null || resData === void 0 ? void 0 : resData.businessNumber) || ((resData === null || resData === void 0 ? void 0 : resData.businessNumber) && ((_a = callInfo === null || callInfo === void 0 ? void 0 : callInfo.participants) === null || _a === void 0 ? void 0 : _a.length) == 1)))) && !(resData === null || resData === void 0 ? void 0 : resData.isLeft); });
2385
2448
  if (!this.pendingMuteUpdate) {
2386
2449
  this.isMute = !(ourNumberInfo === null || ourNumberInfo === void 0 ? void 0 : ourNumberInfo.isHold) ? ourNumberInfo === null || ourNumberInfo === void 0 ? void 0 : ourNumberInfo.isMute : this.isMute;
@@ -2755,8 +2818,7 @@ class CallProgressComponent {
2755
2818
  Env: environment.abb,
2756
2819
  Token: rejoinParticipentInfo.id,
2757
2820
  Ext: rejoinParticipentInfo.extNum,
2758
- conferenceId: rejoinParticipentInfo === null || rejoinParticipentInfo === void 0 ? void 0 : rejoinParticipentInfo.conferenceId,
2759
- Name: rejoinParticipentInfo.toName || ''
2821
+ conferenceId: rejoinParticipentInfo === null || rejoinParticipentInfo === void 0 ? void 0 : rejoinParticipentInfo.conferenceId
2760
2822
  },
2761
2823
  rtcConstraints: { audio: { deviceId: 'default' } },
2762
2824
  });
@@ -2936,7 +2998,7 @@ class CallProgressComponent {
2936
2998
  });
2937
2999
  }
2938
3000
  startCall(callData, isNewConference) {
2939
- var _a, _b;
3001
+ var _a, _b, _c, _d, _e;
2940
3002
  return __awaiter(this, void 0, void 0, function* () {
2941
3003
  try {
2942
3004
  if (!((_a = this.currentCallList) === null || _a === void 0 ? void 0 : _a.length)) {
@@ -2985,8 +3047,13 @@ class CallProgressComponent {
2985
3047
  toName: (callData === null || callData === void 0 ? void 0 : callData.name) || '',
2986
3048
  userId: this.userId || (callData === null || callData === void 0 ? void 0 : callData.userId)
2987
3049
  };
3050
+ // Socket ticks don't include our client leg until Twilio connects, so without this guard an
3051
+ // empty tick during initiateCall() resets dialbox and destroys this component mid-setup
3052
+ // (e.g. while the special call charges modal is about to open).
3053
+ this.twilioService.holdCallScreenGuard();
2988
3054
  const response = yield this.initiateCall(payload);
2989
3055
  if (this.isCallCancelled) {
3056
+ this.twilioService.releaseSpecialCallGuard();
2990
3057
  this.unholdPendingConference();
2991
3058
  this.isCallCancelled = false;
2992
3059
  return false;
@@ -2994,6 +3061,15 @@ class CallProgressComponent {
2994
3061
  this.conferenceId = (_b = response === null || response === void 0 ? void 0 : response.callauth) === null || _b === void 0 ? void 0 : _b.id;
2995
3062
  this.isCallCancelled = false;
2996
3063
  if ((response === null || response === void 0 ? void 0 : response.status) == 200) {
3064
+ if ((_c = response === null || response === void 0 ? void 0 : response.callauth) === null || _c === void 0 ? void 0 : _c.specialCall) {
3065
+ this.updateSpecialCallFlag((_d = response === null || response === void 0 ? void 0 : response.callauth) === null || _d === void 0 ? void 0 : _d.id, true);
3066
+ const isConfirmed = yield this.confirmSpecialCallCharges(response);
3067
+ if (!isConfirmed || this.isCallCancelled) {
3068
+ this.isCallCancelled = false;
3069
+ this.cancelSpecialCall((_e = response === null || response === void 0 ? void 0 : response.callauth) === null || _e === void 0 ? void 0 : _e.id, isNewConference);
3070
+ return false;
3071
+ }
3072
+ }
2997
3073
  this.pendingNewCallHeldParticipant = null;
2998
3074
  const { id: callAuthId, recordCall, tokenData } = yield this.getCallAuthId(response);
2999
3075
  this.recordCall = recordCall; // Store the recordCall value
@@ -3001,9 +3077,11 @@ class CallProgressComponent {
3001
3077
  yield this.pollCallStatus(callAuthId);
3002
3078
  console.log('Call initiated successfully:', response);
3003
3079
  (() => __awaiter(this, void 0, void 0, function* () {
3004
- var _c, _d, _e, _f;
3080
+ var _f, _g, _h, _j;
3005
3081
  try {
3006
3082
  const clientSid = yield this.waitForClientCallSid(isNewConference);
3083
+ // Client leg connected (or gave up) – socket idle handling can run normally again
3084
+ this.twilioService.releaseSpecialCallGuard();
3007
3085
  if (!clientSid) {
3008
3086
  console.error('CallSid not available within 10 seconds, skipping addClientParticipant');
3009
3087
  this.isNewCallLoader = false;
@@ -3025,7 +3103,7 @@ class CallProgressComponent {
3025
3103
  from: callData === null || callData === void 0 ? void 0 : callData.from,
3026
3104
  route: "OUTGOING",
3027
3105
  participantNumber: callData === null || callData === void 0 ? void 0 : callData.phone,
3028
- conferenceId: (_c = response === null || response === void 0 ? void 0 : response.callauth) === null || _c === void 0 ? void 0 : _c.id,
3106
+ conferenceId: (_f = response === null || response === void 0 ? void 0 : response.callauth) === null || _f === void 0 ? void 0 : _f.id,
3029
3107
  userId: this.userId || localStorage.getItem('userId'),
3030
3108
  proxy: '',
3031
3109
  countrycode: '',
@@ -3039,18 +3117,21 @@ class CallProgressComponent {
3039
3117
  from: callData === null || callData === void 0 ? void 0 : callData.from,
3040
3118
  route: "OUTGOING",
3041
3119
  participantNumber: callData === null || callData === void 0 ? void 0 : callData.phone,
3042
- conferenceId: (_d = response === null || response === void 0 ? void 0 : response.callauth) === null || _d === void 0 ? void 0 : _d.id,
3120
+ conferenceId: (_g = response === null || response === void 0 ? void 0 : response.callauth) === null || _g === void 0 ? void 0 : _g.id,
3043
3121
  userId: this.userId || localStorage.getItem('userId'),
3044
3122
  proxy: '',
3045
3123
  countrycode: '',
3046
3124
  deviceId: this.deviceId,
3047
- });
3125
+ }).catch((err) => err === null || err === void 0 ? void 0 : err.error);
3126
+ if (this.isAddParticipantFailed(this.addRes)) {
3127
+ this.showAddParticipantError(this.addRes);
3128
+ }
3048
3129
  this.isNewCallLoader = false;
3049
3130
  if (isNewConference) {
3050
- this.conferenceCallIDForParticipantList = (_e = response === null || response === void 0 ? void 0 : response.callauth) === null || _e === void 0 ? void 0 : _e.id;
3131
+ this.conferenceCallIDForParticipantList = (_h = response === null || response === void 0 ? void 0 : response.callauth) === null || _h === void 0 ? void 0 : _h.id;
3051
3132
  }
3052
3133
  this.isNewAddedCall = false;
3053
- if (((_f = this.newIncomingCallsList) === null || _f === void 0 ? void 0 : _f.length) > 1) {
3134
+ if (((_j = this.newIncomingCallsList) === null || _j === void 0 ? void 0 : _j.length) > 1) {
3054
3135
  this.extensionService.isLoadershow.next(false);
3055
3136
  this.isLoadershown.emit(false);
3056
3137
  }
@@ -3065,6 +3146,7 @@ class CallProgressComponent {
3065
3146
  // Poll the status for 30-45 seconds
3066
3147
  }
3067
3148
  else if (response.status == 201) {
3149
+ this.twilioService.releaseSpecialCallGuard();
3068
3150
  this.extensionService.isLoadershow.next(false);
3069
3151
  this.isLoadershown.emit(false);
3070
3152
  this.isNewAddedCall = false;
@@ -3081,6 +3163,8 @@ class CallProgressComponent {
3081
3163
  }
3082
3164
  }
3083
3165
  catch (error) {
3166
+ console.error('[startCall] failed:', error);
3167
+ this.twilioService.releaseSpecialCallGuard();
3084
3168
  this.showRingAnimation = false;
3085
3169
  // Whatever failed above (backend call, Twilio connect, etc.), the "Connecting..."
3086
3170
  // loader must always come down — previously this was left to endCall()/the socket
@@ -3246,6 +3330,74 @@ class CallProgressComponent {
3246
3330
  return false;
3247
3331
  });
3248
3332
  }
3333
+ updateSpecialCallFlag(conferenceId, specialCall) {
3334
+ if (!conferenceId)
3335
+ return;
3336
+ if (specialCall === true) {
3337
+ this.specialCallConferenceIds.add(conferenceId);
3338
+ }
3339
+ else if (specialCall === false) {
3340
+ this.specialCallConferenceIds.delete(conferenceId);
3341
+ }
3342
+ }
3343
+ isSpecialCall(conferenceId) {
3344
+ var _a;
3345
+ // this.conferenceId: fallback right after initiate call, before the socket fills currentCall.conferenceId
3346
+ const id = conferenceId || this.conferenceCallIDForParticipantList || ((_a = this.currentCall) === null || _a === void 0 ? void 0 : _a.conferenceId) || this.conferenceId;
3347
+ return !!id && this.specialCallConferenceIds.has(id);
3348
+ }
3349
+ confirmSpecialCallCharges(response) {
3350
+ var _a, _b;
3351
+ return __awaiter(this, void 0, void 0, function* () {
3352
+ if (this.isMinimised) {
3353
+ this.maximiseDialpad();
3354
+ }
3355
+ // Call screen is open (active/held conference) → show the modal on it, otherwise dialbox shows it over its loader.
3356
+ // twilioService also keeps the call screen alive while the user decides (socket ticks are empty until Twilio connects).
3357
+ // alertMessage (call charges text) comes from the initiate call response
3358
+ const alertMessage = ((_a = response === null || response === void 0 ? void 0 : response.callauth) === null || _a === void 0 ? void 0 : _a.alertMessage) || (response === null || response === void 0 ? void 0 : response.alertMessage);
3359
+ const confirmation = this.twilioService.requestSpecialCallConfirm(alertMessage, !!((_b = this.currentCallList) === null || _b === void 0 ? void 0 : _b.length));
3360
+ this.cdr.detectChanges();
3361
+ const isConfirmed = yield confirmation;
3362
+ return isConfirmed && !this.isComponentDestroyed;
3363
+ });
3364
+ }
3365
+ // Proceed / Cancel click of the special call charges modal
3366
+ onSpecialCallChargesAction(isConfirmed) {
3367
+ this.twilioService.resolveSpecialCallConfirm(isConfirmed);
3368
+ }
3369
+ // User rejected the charges: never connect via Twilio, close the conference created by initiate call
3370
+ cancelSpecialCall(conferenceId, isNewConference) {
3371
+ this.twilioService.releaseSpecialCallGuard();
3372
+ this.specialCallConferenceIds.delete(conferenceId);
3373
+ if (conferenceId) {
3374
+ this.extensionService.getRemoveParticipants('all', conferenceId).subscribe({
3375
+ error: (err) => console.error('Error closing rejected special call:', err)
3376
+ });
3377
+ }
3378
+ this.showRingAnimation = false;
3379
+ this.isNewCallLoader = false;
3380
+ this.isNewAddedCall = false;
3381
+ this.showNewCallLoader = false;
3382
+ this.callNumberToast.show = false;
3383
+ this.isCallCancelled = false;
3384
+ this.extensionService.isLoadershow.next(false);
3385
+ this.isLoadershown.emit(false);
3386
+ if (isNewConference) {
3387
+ this.unholdPendingConference();
3388
+ }
3389
+ else {
3390
+ this.endCallEvent.emit();
3391
+ this.endCall();
3392
+ }
3393
+ }
3394
+ isAddParticipantFailed(res) {
3395
+ return !res || ((res === null || res === void 0 ? void 0 : res.status) != null && (res === null || res === void 0 ? void 0 : res.status) != 200);
3396
+ }
3397
+ showAddParticipantError(res) {
3398
+ const message = Array.isArray(res === null || res === void 0 ? void 0 : res.message) ? res.message.join('<br/>') : res === null || res === void 0 ? void 0 : res.message;
3399
+ swal('Error', message || 'Failed to add participant. Please try again.', 'error');
3400
+ }
3249
3401
  initiateCall(payload) {
3250
3402
  return __awaiter(this, void 0, void 0, function* () {
3251
3403
  return yield this.extensionService.initiateCall(payload).toPromise();
@@ -3321,8 +3473,7 @@ class CallProgressComponent {
3321
3473
  To: callData.phone,
3322
3474
  Env: environment.abb,
3323
3475
  Token: token,
3324
- Ext: callData.extNum,
3325
- Name: callData.name
3476
+ Ext: callData.extNum
3326
3477
  },
3327
3478
  rtcConstraints: { audio: true },
3328
3479
  });
@@ -3450,6 +3601,7 @@ class CallProgressComponent {
3450
3601
  // this.isConference = false;
3451
3602
  this.showRingAnimation = false;
3452
3603
  if (isAllCallEnd) {
3604
+ this.specialCallConferenceIds.clear();
3453
3605
  this.stopTimer();
3454
3606
  this.onEndCall({}, isAllCallEnd);
3455
3607
  if (!((_a = this.currentCallList) === null || _a === void 0 ? void 0 : _a.length)) {
@@ -3797,6 +3949,11 @@ class CallProgressComponent {
3797
3949
  }
3798
3950
  console.log(phoneNumber);
3799
3951
  const targetConferenceId = this.conferenceCallIDForParticipantList || ((_c = this.currentCall) === null || _c === void 0 ? void 0 : _c.conferenceId);
3952
+ // Rejoin of an existing participant (participantInfo.id) is still allowed
3953
+ if (!(participantInfo === null || participantInfo === void 0 ? void 0 : participantInfo.id) && this.isSpecialCall(targetConferenceId)) {
3954
+ swal('Error', 'Adding participants is not allowed on this call.', 'error');
3955
+ return false;
3956
+ }
3800
3957
  if (!(options === null || options === void 0 ? void 0 : options.skipDuplicateCheck)) {
3801
3958
  if (targetConferenceId) {
3802
3959
  const alreadyInCall = this.currentCallList.find((res) => res.conferenceId === targetConferenceId &&
@@ -3824,6 +3981,11 @@ class CallProgressComponent {
3824
3981
  payload['recordId'] = participantInfo.id;
3825
3982
  }
3826
3983
  let data = yield this.addParticipantToCall(payload);
3984
+ if (this.isAddParticipantFailed(data)) {
3985
+ this.showRingAnimation = false;
3986
+ this.showAddParticipantError(data);
3987
+ return false;
3988
+ }
3827
3989
  let holdInfo = this.onholdOrUnholdParticipant({
3828
3990
  participantId: [(data === null || data === void 0 ? void 0 : data.participantId) || (data === null || data === void 0 ? void 0 : data.id)],
3829
3991
  conferenceId: (_h = this.currentCall) === null || _h === void 0 ? void 0 : _h.conferenceId,
@@ -3871,6 +4033,11 @@ class CallProgressComponent {
3871
4033
  countrycode: '',
3872
4034
  deviceId: this.deviceId
3873
4035
  });
4036
+ if (this.isAddParticipantFailed(data)) {
4037
+ this.showRingAnimation = false;
4038
+ this.showAddParticipantError(data);
4039
+ return false;
4040
+ }
3874
4041
  this.isCallOnHold = true;
3875
4042
  this.showRingAnimation = true;
3876
4043
  this.isConference = true;
@@ -3906,7 +4073,7 @@ class CallProgressComponent {
3906
4073
  catch (error) {
3907
4074
  console.error('Error adding participant:', error);
3908
4075
  this.showRingAnimation = false;
3909
- this.handleError('Failed to add participant. Please try again.');
4076
+ this.showAddParticipantError(error === null || error === void 0 ? void 0 : error.error);
3910
4077
  }
3911
4078
  });
3912
4079
  }
@@ -4915,14 +5082,20 @@ class CallProgressComponent {
4915
5082
  this.updateConferenceSettings();
4916
5083
  }
4917
5084
  ngOnDestroy() {
4918
- var _a, _b, _c;
5085
+ var _a, _b, _c, _d;
5086
+ this.isComponentDestroyed = true;
5087
+ // Destroyed while the charges modal was open → treat as reject so the call never connects
5088
+ if (this.twilioService.specialCallConfirm) {
5089
+ this.twilioService.resolveSpecialCallConfirm(false);
5090
+ }
5091
+ this.twilioService.releaseSpecialCallGuard();
4919
5092
  this.callData.dial = false;
4920
5093
  // setTimeout(() => {
4921
5094
  if (!((_a = this.newIncomingCallsList) === null || _a === void 0 ? void 0 : _a.length) && !this.isNewCallLoader) {
4922
5095
  console.log('Destroying device and disconnecting all calls 2572');
4923
5096
  (_b = this.twilioService.device) === null || _b === void 0 ? void 0 : _b.disconnectAll();
4924
- this.call.disconnect();
4925
- (_c = this.device) === null || _c === void 0 ? void 0 : _c.destroy();
5097
+ (_c = this.call) === null || _c === void 0 ? void 0 : _c.disconnect();
5098
+ (_d = this.device) === null || _d === void 0 ? void 0 : _d.destroy();
4926
5099
  }
4927
5100
  // }, 1500);
4928
5101
  if (this.timerSubscription) {
@@ -4931,10 +5104,10 @@ class CallProgressComponent {
4931
5104
  }
4932
5105
  }
4933
5106
  CallProgressComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CallProgressComponent, deps: [{ token: ExtensionService }, { token: i0.ChangeDetectorRef }, { token: TwilioService }, { token: IpAddressService }, { token: IncomeingCallSocketService }], target: i0.ɵɵFactoryTarget.Component });
4934
- CallProgressComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CallProgressComponent, selector: "lib-call-progress", inputs: { callData: "callData", selectedCallerId: "selectedCallerId", newIncomingCallData: "newIncomingCallData", newIncomingCallsList: "newIncomingCallsList", callerIdList: "callerIdList", newCallConference: "newCallConference", missCallInfo: "missCallInfo", userSettingInfo: "userSettingInfo", deviceId: "deviceId", callAction: "callAction", conferenceCallInfo: "conferenceCallInfo", incomingFromImage: "incomingFromImage", cancelConnectingAction: "cancelConnectingAction", outgoingContactName: "outgoingContactName" }, outputs: { endCallEvent: "endCallEvent", incomingCallsNewInfo: "incomingCallsNewInfo", minimiseEvent: "minimiseEvent", muteAllStatusEvent: "muteAllStatusEvent", incomingCallInitiated: "incomingCallInitiated", isLoadershown: "isLoadershown", endIncomingCallEvent: "endIncomingCallEvent" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"d-flex\">\r\n <div class=\"call-container\" *ngIf=\"!isMinimised && currentCallList?.length\"\r\n [ngClass]=\"{'collops': isCollops, 'incoming-call-container': isClickExpand, 'contacts-open': showContactsPanel }\">\r\n <div class=\"loader-wrapper outgoing-call-loader\"\r\n *ngIf=\"showNewCallLoader\">\r\n <div class=\"active-call\" style=\"display: flex; flex-direction: column; position: relative;\">\r\n <div class=\"call-animation call-animation-play\">\r\n <img class=\"avatar-img\" [src]=\"newCallLoaderData?.img || 'assets/images/user.jpg'\" alt=\"\" />\r\n </div>\r\n <div class=\"callerDetails\">\r\n <h1 style=\"margin-top: 8px;\">Connecting...</h1>\r\n <p style=\"text-transform: capitalize;\">{{ newCallLoaderData?.name || newCallLoaderData?.phone || 'Unknown' }}</p>\r\n </div>\r\n \r\n <div class=\"call-action-btns\">\r\n <div class=\"d-flex justify-content-center\">\r\n <button class=\"call-btn end-call-btn\" disabled (click)=\"endCall()\" style=\"visibility: hidden;\">\r\n <span class=\"material-symbols-outlined\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"dialpad-alerts\"\r\n [ngClass]=\"{\r\n 'conference-alert': isConference && currentCall?.isConference,\r\n 'normal-call-alert': !isConference\r\n }\" *ngIf=\"callNumberToast.show\">\r\n <div class=\"dialbox-pop1 alert fade show\"\r\n [ngClass]=\"callNumberToast.type\"\r\n role=\"alert\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div class=\"flex-grow-1 text-left\">\r\n You'r calling\r\n <strong>{{callNumberToast.displayNum}}</strong>\r\n </div>\r\n <div class=\"text-right\">\r\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelCallToast()\"> Cancel Call </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- All type Call Hold list -->\r\n <div class=\"held-call-banner\"\r\n *ngIf=\"(currentCallList.length > 1 && !!currentCall && ((isConferenceCallHold || isConference) || !isConference)) || !isAllAccepted\">\r\n <ng-container *ngFor=\"let conf of currentCallList\">\r\n <div class=\"held-call-content\" *ngIf=\"!conf?.isAcceptCall && currentCallList.length > 1 && deviceNumberList.includes(conf?.to) && conf?.isNotification\"\r\n [ngClass]=\"{'held-call-selected': selectedUserInfo?.participantId && selectedUserInfo?.participantId === conf?.participantId}\"\r\n (click)=\"conf?.businessNumber ? toggleC2CInfoPanel(conf) : null\"\r\n [ngStyle]=\"{'cursor': conf?.businessNumber ? 'pointer' : 'default'}\">\r\n <div class=\"held-info\">\r\n <div class=\"img\">\r\n <img class=\"avatar-img-wrapper border-radius-50\" [src]=\"conf?.img || 'assets/images/user.jpg'\" alt=\"\" width=\"35\" height=\"35\" />\r\n </div>\r\n <div class=\"held-caller\" *ngIf=\"!conf?.businessNumber\">\r\n <span class=\"held-label\">{{conf?.from}}</span>\r\n <span class=\"held-name\">{{conf?.fromName}}</span>\r\n </div>\r\n <div class=\"held-caller\" *ngIf=\"conf?.businessNumber\">\r\n <span class=\"held-main-label\">Call from C2C:</span>\r\n <span class=\"held-label\" ><span [title]=\"conf?.sourceName\">{{ truncateText(conf?.sourceName, 10) }}</span>|\r\n <span [title]=\"conf?.pointName\">{{ truncateText(conf?.pointName, 10) }}</span></span>\r\n <span class=\"held-label\">{{ truncateText(conf?.name, 26) }}</span>\r\n </div>\r\n </div>\r\n <div class=\"held-actions\">\r\n <ng-container *ngIf=\"isConnectingIncomingCallId == conf?.id\">\r\n <div class=\"connecting-wrapper mr-2\">\r\n <span class=\"ringing-text\">Connecting</span>\r\n <span class=\"dots\">\r\n <span>.</span>\r\n <span>.</span>\r\n <span>.</span>\r\n </span>\r\n </div>\r\n </ng-container>\r\n <button class=\"conference-hold-contact receive-btn\" (click)=\"waitingCallAccept(conf)\" [disabled]=\"isConnecting || isIncomingCallBtnDisable\" *ngIf=\"isConnectingIncomingCallId !== conf?.id\">\r\n <span class=\"material-symbols-outlined\"> call </span>\r\n </button>\r\n <button class=\"conference-contact\">\r\n <span class=\"material-symbols-outlined\" title=\"Call End\" (click)=\"onRejectCall(conf); $event.stopPropagation();\"> call_end </span>\r\n </button>\r\n <div *ngIf=\"conf?.businessNumber\" class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"toggleC2CInfoPanel(conf)\">\r\n <i class=\"fa fa-info\"></i>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let conf of conferenceCallList\">\r\n <div class=\"held-call-content\" *ngIf=\"(conf?.isConferenceHold || (showNewCallLoader && isConferenceCallHold)) && (conferenceCallList.length > 1 || showNewCallLoader)\"\r\n [ngClass]=\"{'held-call-selected': conf?.isBusinessNumber && selectedUserInfo?.participantId === conf?.businessParticipantId && isClickExpand}\"\r\n (click)=\"conf?.isBusinessNumber ? toggleC2CInfoPanel(conf) : null\"\r\n [ngStyle]=\"{'cursor': conf?.isBusinessNumber ? 'pointer' : 'default'}\">\r\n <div class=\"held-info\">\r\n <span class=\"material-symbols-outlined hold-icon\">pause_circle</span>\r\n <div class=\"held-caller\">\r\n <span class=\"held-label\">Hold</span>\r\n <span class=\"held-name\">{{conf?.callLabel}}</span>\r\n </div>\r\n </div>\r\n <div class=\"held-actions\">\r\n <button class=\"conference-hold-contact\" [ngClass]=\"{ 'on-hold': conf?.isConferenceHold }\"\r\n (click)=\"swapCalls(conf,true)\" [disabled]=\"isHoldBtnDisable\">\r\n <span *ngIf=\"conf?.isConferenceHold\" class=\"material-symbols-outlined\" [title]=\"'Resume'\"> resume </span>\r\n </button>\r\n <button class=\"conference-contact\" (click)=\"endConfereneceCall(conf); $event.stopPropagation();\">\r\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\r\n </button>\r\n <div class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"toggleContactsPanel(conf)\">\r\n <i class=\"fa fa-angle-right\"></i>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- For single incoming call -->\r\n <div class=\"h-100 py-5\" style=\"display: flex; flex-direction: column;\"\r\n *ngIf=\"currentCallList.length === 1 && currentCallList[0]?.isIncomingCall && !currentCallList[0]?.isAcceptCall\">\r\n <!-- <div class=\"callToNum\">Incoming call on <br /><span>{{currentCallList[0]?.to || 'Unknown Number'}}</span>\r\n </div> -->\r\n <div class=\"callToNum\">\r\n <ng-container *ngIf=\"currentCallList[0]?.businessNumber; else normalCall\">\r\n C2C CALL\r\n <br />\r\n <span> From : {{ currentCallList[0]?.sourceName }} | {{ currentCallList[0]?.pointName }} </span>\r\n </ng-container>\r\n\r\n <ng-template #normalCall>\r\n Incoming call on\r\n <br />\r\n <span>{{ currentCallList[0]?.to || 'Unknown Number' }}</span>\r\n </ng-template>\r\n </div>\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" [src]=\"incomingFromImage || 'assets/images/user.jpg'\" alt=\"\" width=\"120\" />\r\n </div>\r\n <div class=\"callerDetails\" *ngIf=\"!currentCallList[0]?.businessNumber\">\r\n <h1>{{ currentCallList[0]?.name ? currentCallList[0]?.name : currentCallList[0]?.phone || 'Unknown Number' }}</h1>\r\n <p *ngIf=\"!!currentCallList[0]?.name\">{{ currentCallList[0]?.phone }}</p>\r\n </div>\r\n <div class=\"callerDetails\" *ngIf=\"currentCallList[0]?.businessNumber\">\r\n <p *ngIf=\"!!currentCallList[0]?.name\">{{ truncateText(currentCallList[0]?.name, 45) }}</p>\r\n <p >{{ currentCallList[0]?.number }}</p>\r\n </div>\r\n <!-- Connecting overlay (shown after accept btn click, hidden on API response) -->\r\n <div class=\"connecting-overlay mt-auto\" *ngIf=\"isConnectingIncomingCallId == currentCallList[0]?.id\">\r\n <div class=\"connecting-dots\">\r\n <span></span><span></span><span></span>\r\n </div>\r\n <p class=\"connecting-text\">Connecting...</p>\r\n </div>\r\n\r\n <div class=\"call-action-btns mt-auto\" *ngIf=\"isConnectingIncomingCallId != currentCallList[0]?.id\">\r\n <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected\"\r\n [disabled]=\"isIncomingCallBtnDisable\" (click)=\"acceptIncomingCall(currentCallList[0])\">\r\n <span class=\"material-symbols-outlined\"> call </span>\r\n </button>\r\n <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"onRejectCall(currentCallList[0])\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For single active call -->\r\n <div *ngIf=\"(!isConference || isConferenceCallHold) && (!!currentCall?.id && !currentCall?.isConference) && currentCall?.isAcceptCall\"\r\n [ngStyle]=\"{'display': 'flex', 'flex-direction': 'column', 'position': 'relative'}\" class=\"active-call\">\r\n <div *ngIf=\"currentCall?.businessNumber;\" class=\"callToNum\">\r\n C2C CALL\r\n <br />\r\n <span> From : {{ currentCall?.userInfoId?.sourceName }} | {{ currentCall?.userInfoId?.pointName }} </span>\r\n </div>\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" *ngIf=\"!currentCall?.client\"\r\n [src]=\"currentCall?.direction == 'outgoing-call' ? currentCall?.toImage || 'assets/images/user.jpg' : currentCall?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n <img class=\"avatar-img\" *ngIf=\"currentCall?.client\"\r\n [src]=\"currentCall?.direction == 'outgoing-call' ? currentCall?.fromImage || 'assets/images/user.jpg' : currentCall?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n </div>\r\n <div class=\"callerDetails\">\r\n <!-- C2C Business Call -->\r\n <ng-container *ngIf=\"currentCall?.businessNumber; else normalCall\">\r\n <h1>{{ currentCall?.userInfoId?.name || 'Unknown' }}</h1>\r\n <p>{{ currentCall?.userInfoId?.number || currentCall?.from || 'Unknown' }}</p>\r\n </ng-container>\r\n\r\n <!-- Normal Call -->\r\n <ng-template #normalCall>\r\n <h1 *ngIf=\"!currentCall?.client\"\r\n [ngStyle]=\"{'margin-top': showKeypad ? '0':'8px'}\">\r\n {{ currentCall?.direction == 'outgoing-call'\r\n ? currentCall?.toName || outgoingContactName || 'Unknown'\r\n : currentCall?.fromName || 'Unknown' }}\r\n </h1>\r\n <h1 *ngIf=\"currentCall?.client\"\r\n [ngStyle]=\"{'margin-top': showKeypad ? '0':'8px'}\">\r\n {{ currentCall?.direction == 'outgoing-call'\r\n ? currentCall?.fromName || 'Unknown'\r\n : currentCall?.toName || outgoingContactName || 'Unknown' }}\r\n </h1>\r\n <p *ngIf=\"!currentCall?.client\">\r\n {{ currentCall?.direction == 'outgoing-call'\r\n ? currentCall?.to\r\n : currentCall?.from }}\r\n </p>\r\n <p *ngIf=\"currentCall?.client\">\r\n {{ currentCall?.direction == 'outgoing-call'\r\n ? currentCall?.from\r\n : currentCall?.to }}\r\n </p>\r\n </ng-template>\r\n <!-- <h1 *ngIf=\"!currentCall?.client\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall?.direction == 'outgoing-call' ? currentCall?.toName || outgoingContactName || 'Unknown' :\r\n currentCall?.fromName || 'Unknown'}}</h1>\r\n <h1 *ngIf=\"currentCall?.client\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall?.direction == 'outgoing-call' ? currentCall?.fromName || 'Unknown' :\r\n currentCall?.toName || 'Unknown'}}</h1>\r\n <p *ngIf=\"!currentCall?.client\">{{ currentCall?.direction == 'outgoing-call' ? currentCall?.to || 'Unknown' : currentCall?.from || 'Unknown'}}</p>\r\n <p *ngIf=\"currentCall?.client\">{{ currentCall?.direction == 'outgoing-call' ? currentCall?.from || 'Unknown' : currentCall?.to || 'Unknown'}}</p> -->\r\n <h4 style=\"margin-top: 4px\">{{ timer}}</h4>\r\n </div>\r\n <div class=\"record-action-btns\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\r\n <div class=\"record-btn-container\">\r\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\r\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording, 'disabled': userSettingInfo?.callRecording == 'N'}\" (click)=\"toggleRecording()\"\r\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"!currentCall?.isAcceptCall || userSettingInfo?.callRecording == 'N'\">\r\n <span class=\"recording-icon\"></span>\r\n </button>\r\n <div class=\"pause-resume-btns\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\" (click)=\"pauseRecording()\">\r\n <span class=\"material-symbols-outlined\"> pause </span>\r\n </button>\r\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"isRecording\" class=\"timer-display\">\r\n {{ getFormattedTime() }}\r\n </div>\r\n </div>\r\n <!-- Mute/unmute incoming call -->\r\n <div class=\"mute-incoming-row\" *ngIf=\"currentCall?.isAcceptCall && !showKeypad\">\r\n <span class=\"mute-incoming-label\">Mute incoming calls</span>\r\n <label class=\"switch mb-0\" title=\"Silence the ringtone of new incoming calls during this call\">\r\n <input type=\"checkbox\" [checked]=\"twilioService.isIncomingMuted\" (change)=\"toggleMuteIncomingCall()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"showKeypad\" class=\"sendDigit\">\r\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\" (keyup)=\"onCallInputEnter($event)\">\r\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\" (click)=\"clearInputs()\">close_small</span>\r\n </div>\r\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\r\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\r\n {{key.num}}\r\n <span class=\"btn-albhabets\">{{key.text ? key.text : '&nbsp;'}}</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"call-action-btns\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '723x'}\">\r\n <div class=\"flex align-items-center justify-content-evenly mb-3\">\r\n <button class=\"call-sec-btn mr-3\" [disabled]=\"!currentCall?.isAcceptCall || !canSelfToggleMute()\" [title]=\"selfMuteTooltip()\" (click)=\"toggleMute()\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isSelfEffectivelyMuted()\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isSelfEffectivelyMuted()\"> mic </span>\r\n </button>\r\n <button class=\"call-sec-btn mr-3\" [disabled]=\"!currentCall?.isAcceptCall\">\r\n <span class=\"material-symbols-outlined\" (click)=\"toggleKeypad()\"> transition_dissolve\r\n </span>\r\n </button>\r\n <button class=\"call-sec-btn\" [disabled]=\"!currentCall?.isAcceptCall\"\r\n (click)=\"toggleContactsPanel(currentCall)\">\r\n <span class=\"material-symbols-outlined\"> groups_2 </span>\r\n </button>\r\n </div>\r\n <div>\r\n <button class=\"call-btn end-call-btn\" [disabled]=\"!currentCall?.isAcceptCall\" (click)=\"endCall(false, currentCall)\">\r\n <span class=\"material-symbols-outlined\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- conference call view -->\r\n <div class=\"conference-call-view\" *ngIf=\"isConference\">\r\n <div class=\"conf-heading\">\r\n <span class=\"conf-icon material-symbols-outlined\"> groups </span>\r\n <span class=\"conf-title\">{{currentConferenceCall?.callLabel || 'Conference Call'}}</span>\r\n </div>\r\n <div class=\"scroll-container\">\r\n <div class=\"scroll-text conf-name\">\r\n <ng-container *ngFor=\"let call of currentCallList; let i = index\">\r\n <ng-container *ngIf=\"!call?.isConferenceHold\">\r\n <span *ngIf=\"shouldShowSeparator(i)\"> & </span>\r\n <span *ngIf=\"call?.client\">\r\n <ng-container *ngIf=\"!isSelfNumber(call) else selfNumber\">\r\n <span>{{call?.direction == 'outgoing-call' ? call?.fromName || call?.from :\r\n call?.toName || call?.to}}</span>\r\n </ng-container>\r\n <ng-template #selfNumber>\r\n <span>You</span>\r\n </ng-template>\r\n </span>\r\n <span *ngIf=\"!call?.client\">{{call?.direction == \"outgoing-call\" ? call?.toName || call?.to : call?.fromName || call?.from || 'Unknown number'}}</span>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <div class=\"conf-timer\">{{ currentConferenceCall?.timer || timer }}</div>\r\n <div class=\"record-action-btns mt-auto\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\r\n <div class=\"record-btn-container\" >\r\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\" [disabled]=\"userSettingInfo.callRecording == 'N'\"\r\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording, 'disabled': userSettingInfo?.callRecording == 'N'}\" (click)=\"toggleRecording()\"\r\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\">\r\n <span class=\"recording-icon\"></span>\r\n </button>\r\n <div class=\"pause-resume-btns\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\" (click)=\"pauseRecording()\">\r\n <span class=\"material-symbols-outlined\"> pause </span>\r\n </button>\r\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"isRecording\" class=\"timer-display\">\r\n {{ getFormattedTime() }}\r\n </div>\r\n </div>\r\n <!-- Mute/unmute incoming call -->\r\n <div class=\"mute-incoming-row\" *ngIf=\"currentCall?.isAcceptCall && !showKeypad\">\r\n <span class=\"mute-incoming-label\">Mute incoming calls</span>\r\n <label class=\"switch mb-0\" title=\"Silence the ringtone of new incoming calls during this call\">\r\n <input type=\"checkbox\" [checked]=\"twilioService.isIncomingMuted\" (change)=\"toggleMuteIncomingCall()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"showKeypad\" class=\"sendDigit mt-2\">\r\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\" (keyup)=\"onCallInputEnter($event)\">\r\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\" (click)=\"clearInputs()\">close_small</span>\r\n </div>\r\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\r\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\r\n {{key.num}}\r\n <span class=\"btn-albhabets\">{{key.text ? key.text : '&nbsp;'}}</span>\r\n </div>\r\n </div>\r\n <div class=\"conf-actions\">\r\n <button class=\"circle-btn\" [ngClass]=\"{'active': isSelfEffectivelyMuted()}\" [disabled]=\"!canSelfToggleMute()\" [title]=\"selfMuteTooltip()\" (click)=\"toggleMute(true)\">\r\n <span class=\"material-symbols-outlined\"> {{ isSelfEffectivelyMuted() ? 'mic_off' : 'mic' }} </span>\r\n </button>\r\n <button class=\"circle-btn\" (click)=\"toggleKeypad()\">\r\n <span class=\"material-symbols-outlined\"> transition_dissolve </span>\r\n </button>\r\n <button class=\"circle-btn\" (click)=\"toggleContactsPanel(currentCall)\">\r\n <span class=\"material-symbols-outlined\"> groups_2 </span>\r\n </button>\r\n </div>\r\n <div class=\"conf-end\">\r\n <button class=\"circle-btn danger\" (click)=\"endConfereneceCall(currentConferenceCall?.participants[0])\">\r\n <span class=\"material-symbols-outlined\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"wave-container\">\r\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\r\n <defs>\r\n <path id=\"gentle-wave\"\r\n d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n </div>\r\n\r\n <!-- Incoming call user details shown in model -->\r\n <div class=\"call-container-model p-3 text-white model-content call-container\" *ngIf=\"isClickExpand\">\r\n <div class=\"close-info-panel-section\">\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"currentConferenceCall?.conferenceId != selectedUserInfo?.conferenceId && newIncomingCallsList?.length > 1\">\r\n <p></p>\r\n <span class=\"material-symbols-outlined dial-close-btn \" (click)=\"onCloseC2CInfoPanel()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\r\n fill=\"#ffffff\">\r\n <path\r\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"mb-2 user-info-section\">\r\n <div class=\"text-center my-3\">\r\n <h3 class=\"text-white\">C2C CALL : {{selectedUserInfo?.sourceName}} | {{selectedUserInfo?.pointName}}</h3>\r\n </div>\r\n <div class=\"mb-3\">\r\n <h5 class=\"text-white mb-1\">Name:</h5>\r\n <h4 class=\"text-white userName\">{{selectedUserInfo?.name}}</h4>\r\n </div>\r\n <div class=\"f-13\">\r\n <div class=\"row mb-3\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"mb-1\">Extension:</div>\r\n <div class=\"ml-2\">{{selectedUserInfo?.extension}}</div>\r\n </div>\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"mb-1\">Number:</div>\r\n <div class=\"\">{{selectedUserInfo?.number}}</div>\r\n </div> \r\n </div>\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 mb-2\">\r\n <div class=\"me-2\">Email: </div>\r\n <div>{{selectedUserInfo?.email}}</div>\r\n </div>\r\n </div>\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 mb-2\">\r\n <div class=\"me-2\">Subject:</div>\r\n <div class=\"ml-2 subject-text\" title=\"{{selectedUserInfo?.subject}}\">\r\n {{selectedUserInfo?.subject}}</div>\r\n </div>\r\n </div>\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 mb-2\">\r\n <div class=\"me-2 mb-1\">Image:</div>\r\n <div class=\"text-ellipsis\">\r\n <ng-container\r\n *ngIf=\"selectedUserInfo?.image && selectedUserInfo?.image !== '-'; else noImage\">\r\n <img src=\"{{selectedUserInfo?.image}}\" alt=\"\" width=\"150\" class=\"ml-2\" />\r\n </ng-container>\r\n <ng-template #noImage>\r\n <span class=\"ml-2\">No Image Available</span>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\" mb-4\">\r\n <div class=\"\">\r\n <div class=\"mb-1\">Message:</div>\r\n <div>\r\n <div class=\"text-container\" [class.expanded]=\"isExpanded\">{{selectedUserInfo?.message}}\r\n </div>\r\n <small class=\"toggle-btn\" *ngIf=\"showButton\" (click)=\"toggleText()\">{{ isExpanded ? 'See\r\n less' : 'See more' }}</small>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- contact list panel -->\r\n <div class=\"contacts-panel\" *ngIf=\"showContactsPanel && !showNewCallLoader\">\r\n <div class=\"panel-loader-overlay p-3 text-center\" *ngIf=\"isParticipantPanelLoading\">\r\n <div class=\"spinner-border text-secondary\" role=\"status\">\r\n <span class=\"sr-only\">Loading...</span>\r\n </div>\r\n <p class=\"mt-2\"></p>\r\n </div>\r\n <div class=\"contacts-header\">\r\n <div class=\"participant-list-title\">\r\n {{ selectedConfName || 'Conference' }} Participants\r\n <!-- <ng-container *ngIf=\"totalParticipantsCount < 3; else confHeading\">\r\n Call Participants\r\n </ng-container>\r\n <ng-template #confHeading>\r\n </ng-template> -->\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n \r\n <span class=\"material-symbols-outlined settings-icon me-2\" *ngIf=\"isConferenceHost\" (click)=\"toggleSettingsPanel()\">\r\n settings\r\n </span>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"toggleContactsPanel({}, true)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\r\n fill=\"#000000\">\r\n <path\r\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"settings-overlay\" *ngIf=\"showSettingsPanel\" (click)=\"closeSettingsPanel()\">\r\n <div class=\"settings-drawer\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"settings-header\">\r\n <span class=\"material-symbols-outlined\" (click)=\"closeSettingsPanel()\">arrow_back</span>\r\n <span>Call Settings</span>\r\n <span></span> <!-- placeholder for alignment -->\r\n </div>\r\n \r\n <div class=\"settings-body\">\r\n <!-- Mute all participants -->\r\n <div class=\"setting-item\">\r\n <div class=\"setting-label\">\r\n <span>Mute all participants</span>\r\n <small>Off \u2014 participants can mute and unmute themselves at any time.</small>\r\n </div>\r\n <label class=\"switch\">\r\n <input type=\"checkbox\" [ngModel]=\"settings.muteAll\" [disabled]=\"isUpdatingConferenceSettings\"\r\n (ngModelChange)=\"onMuteAllToggle($event)\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n \r\n <hr>\r\n \r\n <!-- Participant Permissions -->\r\n <div class=\"setting-group\">\r\n <h6>PARTICIPANT PERMISSIONS</h6>\r\n \r\n <!-- Allow unmute -->\r\n <div class=\"setting-item\">\r\n <div class=\"setting-label\">\r\n <span>\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3Z\" stroke=\"currentColor\" stroke-width=\"1.8\"></path>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2M12 19v3\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\r\n </svg>\r\n Allow participants to self-unmute\r\n </span>\r\n <small>{{ settings.allowUnmute ? 'Yes \u2014 participants can unmute themselves after being muted\r\n individually by the host.' : 'No \u2014 participants cannot unmute themselves.' }}</small>\r\n </div>\r\n <label class=\"switch\">\r\n <input type=\"checkbox\" [ngModel]=\"settings.allowUnmute\" [disabled]=\"isUpdatingConferenceSettings\"\r\n (ngModelChange)=\"settings.allowUnmute = $event; updateConferenceSettings()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n \r\n <!-- Allow remove -->\r\n <div class=\"setting-item\">\r\n <div class=\"setting-label\">\r\n <span>\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M17 21v-2a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v2M15 3.13a4 4 0 0 1 0 7.75\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\r\n <circle cx=\"9\" cy=\"7\" r=\"4\" stroke=\"currentColor\" stroke-width=\"1.8\"></circle>\r\n <path d=\"M19 8h4\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\r\n </svg>\r\n Allow participants to remove\r\n </span>\r\n <small>{{ settings.allowRemove ? 'Yes \u2014 participants can remove other participants.' : 'No \u2014\r\n participants cannot remove other participants, and cannot remove the host.' }}</small>\r\n </div>\r\n <label class=\"switch\">\r\n <input type=\"checkbox\" [ngModel]=\"settings.allowRemove\" [disabled]=\"isUpdatingConferenceSettings\"\r\n (ngModelChange)=\"settings.allowRemove = $event; updateConferenceSettings()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n <div class=\"setting-item\">\r\n <div class=\"setting-label\">\r\n <span>Allow participants to unhold</span>\r\n <small>{{ settings.allowUnhold ? 'Yes \u2014 participants can place themselves on hold.' : 'No \u2014\r\n participants cannot place themselves on hold.' }}</small>\r\n </div>\r\n <label class=\"switch\">\r\n <input type=\"checkbox\" [ngModel]=\"settings.allowUnhold\" [disabled]=\"isUpdatingConferenceSettings\"\r\n (ngModelChange)=\"settings.allowUnhold = $event; updateConferenceSettings()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n <div class=\"setting-item\">\r\n <div class=\"setting-label\">\r\n <span>Allow participants to mute other participants</span>\r\n <small>{{ settings.allowMuteOthers ? 'Yes \u2014 Participants can mute other participants, and can mute the host.' : 'No \u2014\r\n Participants cannot mute other participants, and cannot mute the host.' }}</small>\r\n </div>\r\n <label class=\"switch\">\r\n <input type=\"checkbox\" [ngModel]=\"settings.allowMuteOthers\" [disabled]=\"isUpdatingConferenceSettings\"\r\n (ngModelChange)=\"settings.allowMuteOthers = $event; updateConferenceSettings()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- SEARCH INPUT (visible when isSearchVisible = true) -->\r\n <div class=\"search-bar p-3 position-relative\">\r\n <input type=\"text\" placeholder=\"Add a participant by Name or Number\" title=\"Add a participant by Name or Number\" [(ngModel)]=\"searchText\" (input)=\"applyFilter()\" />\r\n <div class=\"search-contacts-list\">\r\n <ng-container *ngFor=\"let c of filteredList\">\r\n <div class=\"contact-item\" *ngIf=\"searchText\">\r\n <img class=\"contact-avatar\" [src]=\"c?.image || 'assets/images/user.jpg'\" alt=\"\" />\r\n <div class=\"contact-info\">\r\n <div class=\"contact-name\">{{c?.firstName}} {{c?.middleName}} {{c?.lastName}}</div>\r\n <div class=\"contact-title\">{{ (c?.numbersList && c?.numbersList[0]?.number) }}{{ c?.numbersList[0]?.numberLabel ? ' (' + c.numbersList[0].numberLabel + ')' : '' }}</div>\r\n </div>\r\n <button class=\"contact-call-btn contact-add-btn mr-2\" (click)=\"callContact(c)\"\r\n *ngIf=\"!c?.IsConnected\" title=\"Add to call\">\r\n <span class=\"material-symbols-outlined\"> add </span>\r\n </button>\r\n <button class=\"contact-call-btn\" (click)=\"CallToUnsavedNumber(c?.numbersList[0]?.number, true)\"\r\n *ngIf=\"!c?.IsConnected\" title=\"New Call\">\r\n <span class=\"material-symbols-outlined\"> call </span>\r\n </button>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!filteredList.length && isDirectCallOptionShow && searchText\">\r\n <div class=\"contact-item\">\r\n <img class=\"contact-avatar\" [src]=\"'assets/images/user.jpg'\" alt=\"\" />\r\n <div class=\"contact-info\">\r\n <div class=\"contact-title\">{{ searchText }}</div>\r\n </div>\r\n <button class=\"contact-call-btn contact-add-btn mr-2\" (click)=\"CallToUnsavedNumber(searchText)\"\r\n title=\"Add to call\">\r\n <span class=\"material-symbols-outlined\"> add </span>\r\n </button>\r\n <button class=\"contact-call-btn\" (click)=\"CallToUnsavedNumber(searchText, true)\"\r\n title=\"New Call\">\r\n <span class=\"material-symbols-outlined\"> call </span>\r\n </button>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <div class=\"contacts-list\">\r\n <div class=\"px-2\">\r\n <h5 class=\"mb-0 title\">Active participants ({{ activeParticipantsCount }})</h5>\r\n </div>\r\n <hr class=\"mb-2 mt-1\">\r\n <ng-container *ngFor=\"let c of filteredParticipentList\">\r\n <div class=\"contact-item\" *ngIf=\"!c?.isLeft\">\r\n <img class=\"contact-avatar\" *ngIf=\"!c?.client\"\r\n [src]=\"c?.direction == 'outgoing-call' ? c?.toImage || 'assets/images/user.jpg' : c?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n <img class=\"contact-avatar\" *ngIf=\"c?.client\"\r\n [src]=\"c?.direction == 'outgoing-call' ? c?.fromImage || 'assets/images/user.jpg' : c?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n <div class=\"contact-info\">\r\n <div class=\"contact-name\" *ngIf=\"!c?.client\">{{c?.direction == 'outgoing-call' ? c?.toName || 'Unknown' : c?.fromName || 'Unknown'}}\r\n </div>\r\n <div class=\"contact-title\" *ngIf=\"!c?.client\">{{ c?.direction == 'outgoing-call' ? c?.to || 'Unknown' : c?.from || 'Unknown'}}</div>\r\n\r\n <div class=\"contact-name\" *ngIf=\"c?.client\">\r\n <ng-container *ngIf=\"!isSelfNumber(c) else selfNumber\">\r\n <span>{{c?.direction == 'outgoing-call' ? c?.fromName || 'Unknown' : c?.toName || 'Unknown'}}</span>\r\n </ng-container>\r\n <ng-template #selfNumber>\r\n <span>You</span>\r\n </ng-template>\r\n </div>\r\n <div class=\"contact-title\" *ngIf=\"c?.client\">{{ c?.direction == 'outgoing-call' ? c?.from || 'Unknown' : c?.to || 'Unknown'}}</div>\r\n <div class=\"d-flex\" *ngIf=\"c?.host\">\r\n <span class=\"organizer-label\">Organizer</span>\r\n </div>\r\n </div>\r\n <ng-container *ngIf=\"c?.joined && !c?.host\">\r\n <div class=\"connecting-wrapper mr-2\">\r\n <span class=\"ringing-text\">Ringing</span>\r\n <span class=\"dots\">\r\n <span>.</span>\r\n <span>.</span>\r\n <span>.</span>\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"c?.host && c?.isHold && !(deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call'))\">\r\n <div class=\"connecting-wrapper mr-2\">\r\n <span class=\"onHold-text\">On Hold</span>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!c?.joined || c?.host\">\r\n <button class=\"mic-btn mr-2\" [disabled]=\"c?.isHold || !canToggleMute(c)\" [title]=\"muteTooltip(c)\" (click)=\"onMuteUser(c)\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isEffectivelyMuted(c)\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isEffectivelyMuted(c)\"> mic </span>\r\n </button>\r\n <button class=\"conference-hold-contact mr-2\" [ngClass]=\"{ 'on-hold': c?.isHold }\"\r\n (click)=\"onHoldCall(c)\" *ngIf=\"!c?.host || (c?.host && (deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call')))\" [disabled]=\"isHoldBtnDisable || !canToggleHold(c)\">\r\n <span *ngIf=\"!c?.isHold\" class=\"material-symbols-outlined\" [title]=\"canToggleHold(c) ? 'Hold' : holdTooltip(c)\"> phone_paused</span>\r\n <span *ngIf=\"c?.isHold\" class=\"material-symbols-outlined\" [title]=\"canToggleHold(c) ? 'Resume' : holdTooltip(c)\"> resume </span>\r\n </button>\r\n </ng-container>\r\n <button class=\"conference-contact\" (click)=\"confirmLeaveParticipant(c)\"\r\n [disabled]=\"!canRemoveParticipant(c)\" [title]=\"removeTooltip(c)\" *ngIf=\"!c?.host\">\r\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\r\n </button>\r\n <button class=\"conference-contact\" (click)=\"endConfereneceCall(c)\"\r\n *ngIf=\"c?.host && (deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call'))\">\r\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\r\n </button>\r\n </div>\r\n </ng-container>\r\n <hr class=\"m-2\">\r\n <div class=\"mt-3 px-2\">\r\n <h5 class=\"mb-0 title\">Participant added to the call</h5>\r\n </div>\r\n <hr class=\"mb-2 mt-1\">\r\n <ng-container *ngFor=\"let c of filteredParticipentList\">\r\n <div class=\"contact-item\" *ngIf=\"c?.isLeft\">\r\n <img class=\"contact-avatar\" *ngIf=\"!c?.client\"\r\n [src]=\"c?.direction == 'outgoing-call' ? c?.toImage || 'assets/images/user.jpg' : c?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n <img class=\"contact-avatar\" *ngIf=\"c?.client\"\r\n [src]=\"c?.direction == 'outgoing-call' ? c?.fromImage || 'assets/images/user.jpg' : c?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n <div class=\"contact-info\">\r\n <div class=\"contact-name\" *ngIf=\"!c?.client\">{{c?.direction == 'outgoing-call' ? c?.toName || 'Unknown' : c?.fromName || 'Unknown'}}\r\n </div>\r\n <div class=\"contact-title\" *ngIf=\"!c?.client\">{{ c?.direction == 'outgoing-call' ? c?.to || 'Unknown' : c?.from || 'Unknown'}}</div>\r\n <div class=\"contact-name\" *ngIf=\"c?.client\">{{c?.direction == 'outgoing-call' ? c?.fromName || 'Unknown' : c?.toName || 'Unknown'}}\r\n </div>\r\n <div class=\"contact-title\" *ngIf=\"c?.client\">{{ c?.direction == 'outgoing-call' ? c?.from || 'Unknown' : c?.to || 'Unknown'}}</div>\r\n <div class=\"d-flex\" *ngIf=\"c?.host\">\r\n <span class=\"organizer-label\">Organizer</span>\r\n </div>\r\n </div>\r\n <div class=\"connecting-wrapper\" *ngIf=\"c?.joined\">\r\n <span class=\"ringing-text\">Ringing</span>\r\n <span class=\"dots\">\r\n <span>.</span>\r\n <span>.</span>\r\n <span>.</span>\r\n </span>\r\n </div>\r\n <button class=\"conference-contact\" (click)=\"onEndCall(c, false, true)\" *ngIf=\"!c?.host && c?.joined\">\r\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\r\n </button>\r\n <button class=\"contact-call-btn contact-add-btn\" *ngIf=\"!c?.client && !c?.joined && !c?.businessNumber\"\r\n (click)=\"CallToUnsavedNumber(c.direction == 'outgoing-call' ? c?.to : c?.from, false, { skipDuplicateCheck: true }, c)\">\r\n <span class=\"material-symbols-outlined\"> add </span>\r\n <span class=\"label\">Rejoin</span>\r\n </button>\r\n <button class=\"contact-call-btn contact-add-btn\" *ngIf=\"c?.client && !c?.joined && !c?.businessNumber\"\r\n (click)=\"CallToUnsavedNumber(c.direction == 'outgoing-call' ? c?.from : c?.to, false, { skipDuplicateCheck: true }, c)\">\r\n <span class=\"material-symbols-outlined\"> add </span>\r\n <span class=\"label\">Rejoin</span>\r\n </button>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Conference Warning Modal -->\r\n<div class=\"custom-modal\" *ngIf=\"showConferenceWarningModal\">\r\n <div class=\"modal-content warning-modal\">\r\n <div class=\"warning-icon\">\r\n <span class=\"material-symbols-outlined\">warning</span>\r\n </div>\r\n <h3>Warning</h3>\r\n <p>\r\n Starting a new call will put the current call on hold\r\n and cannot be merged later.\r\n </p>\r\n <div class=\"warning-actions\">\r\n <button class=\"cancel-btn\" (click)=\"cancelNewCall()\">\r\n Cancel\r\n </button>\r\n <button class=\"proceed-btn\" (click)=\"confirmNewCall()\">\r\n Proceed\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n</div>\r\n\r\n<div class=\"min-call-container\" *ngIf=\"isMinimised\">\r\n <span class=\"material-symbols-outlined fullscreen\" (click)=\"maximiseDialpad()\"> open_in_full </span>\r\n <div style=\"display: flex; width: 100%\">\r\n <div>\r\n <div class=\"min-call-animation\" id=\"call-avatar\">\r\n <img class=\"min-avatar-img\" [src]=\"callData.img\" alt=\"\" />\r\n </div>\r\n </div>\r\n <div>\r\n <div class=\"min-callerDetails\">\r\n <div class=\"name\">\r\n {{callData.name}}\r\n </div>\r\n <p style=\"margin: 0\">{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"min-btn-container\">\r\n <div class=\"min-timer\">{{timer}}</div>\r\n <button class=\"min-call-sec-btn\" (click)=\"toggleMute()\" [disabled]=\"disbaleEndCallBtn || !canSelfToggleMute()\" [title]=\"selfMuteTooltip()\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isSelfEffectivelyMuted()\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isSelfEffectivelyMuted()\"> mic </span>\r\n </button>\r\n <button class=\"min-call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\r\n <span class=\"material-symbols-outlined\"> call_end </span>\r\n </button>\r\n </div>\r\n</div>\r\n<!-- Call Disconnect Modal -->\r\n<div class=\"custom-modal\" *ngIf=\"showDisconnectModal\">\r\n <div class=\"modal-content p-3\">\r\n <div class=\"contacts-header p-0 pb-2\">\r\n <h4 class=\"title mb-0\">{{selectedConf?.conName || 'Call'}} Disconnect</h4>\r\n <div class=\"d-flex justify-content-between\">\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDisconnectModal = false\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\r\n fill=\"#000000\">\r\n <path\r\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"contant-body mb-2\">\r\n <p class=\"mt-2\">\r\n Exiting this call will not end the conference. The session will continue, and charges will incur to\r\n your\r\n account.\r\n </p>\r\n </div>\r\n <div class=\"button-group\">\r\n <div class=\"text-start d-flex align-items-center\">\r\n <label class=\"d-flex align-items-center mb-0 mr-2\">\r\n <input type=\"checkbox\" [(ngModel)]=\"isReasonChecked\" (ngModelChange)=\"onReasonCheckChanged($event)\" class=\"me-2\"/>\r\n </label>\r\n <div class=\"time-picker-24hr\">\r\n <!-- Hour picker -->\r\n <div class=\"custom-time-select\" [class.disabled-picker]=\"!isReasonChecked\">\r\n <div class=\"custom-time-display\" (click)=\"isReasonChecked && toggleHourDropdown()\">\r\n {{ leaveHour || 'HH' }}\r\n <span class=\"picker-arrow\">&#9660;</span>\r\n </div>\r\n <div class=\"custom-time-options\" *ngIf=\"showHourDropdown\">\r\n <div class=\"custom-time-option\"\r\n *ngFor=\"let h of hours\"\r\n [class.selected]=\"leaveHour === h\"\r\n (click)=\"selectHour(h)\">{{ h }}</div>\r\n </div>\r\n </div>\r\n <span class=\"time-sep\">:</span>\r\n <!-- Minute picker -->\r\n <div class=\"custom-time-select\" [class.disabled-picker]=\"!isReasonChecked\">\r\n <div class=\"custom-time-display\" (click)=\"isReasonChecked && toggleMinuteDropdown()\">\r\n {{ leaveMinute || 'MM' }}\r\n <span class=\"picker-arrow\">&#9660;</span>\r\n </div>\r\n <div class=\"custom-time-options\" *ngIf=\"showMinuteDropdown\">\r\n <div class=\"custom-time-option\"\r\n *ngFor=\"let m of minutes\"\r\n [class.selected]=\"leaveMinute === m\"\r\n (click)=\"selectMinute(m)\">{{ m }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <button class=\"btn end-btn\" (click)=\"leaveConference()\" [disabled]=\"isReasonChecked && (!leaveHour || !leaveMinute)\">\r\n Leave\r\n </button>\r\n <button class=\"btn end-btn\" (click)=\"endConference()\" *ngIf=\"showEndAllButton\">\r\n End All\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"custom-modal\" *ngIf=\"showLeaveConfirmationModal\">\r\n <div class=\"modal-content warning-modal\">\r\n <div class=\"warning-icon\">\r\n <span class=\"material-symbols-outlined\">info</span>\r\n </div>\r\n <h3>Leave Conference</h3>\r\n <p>\r\n You are about to leave <strong>{{ leaveConfConferenceName }}</strong>. \r\n Are you sure?\r\n </p>\r\n <div class=\"warning-actions\">\r\n <button class=\"cancel-btn\" (click)=\"cancelLeave()\">Cancel</button>\r\n <button class=\"proceed-btn\" (click)=\"confirmLeave()\">Leave</button>\r\n </div>\r\n </div>\r\n</div>", styles: [".call-container{width:385px;height:646px!important;margin:auto;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;box-sizing:border-box;position:relative;justify-content:center;align-items:center;z-index:1000;flex-flow:column;overflow-x:hidden;overflow-y:visible}.disabled{opacity:.5!important;pointer-events:none!important}.call-to-text{padding:6px 10px;border:1px solid #c2c2c2;border-radius:20px;font-size:13px}.collops{height:660px!important}.incoming-call-container{flex-flow:row!important}.active-call{width:385px!important}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto 0;border-radius:100%;border:solid 4px #fff;display:flex;align-items:center;justify-content:center}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.call-animation-play{animation:play 3s linear infinite}.call-info-wrapper{height:20px;overflow-y:auto;background:white;transition:height 1s}.open-collops{height:180px!important}.avatar-img{width:94px;height:94px;border-radius:100%}@keyframes play{0%{transform:scale(1)}15%{box-shadow:0 0 0 2px #fff6}25%{box-shadow:0 0 0 4px #fff6,0 0 0 8px #fff3}25%{box-shadow:0 0 0 8px #fff6,0 0 0 16px #fff3}50%{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3}to{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3;transform:scale(1.1);opacity:0}}.callerDetails{margin-top:8px;color:#fff;display:flex;flex-direction:column;align-items:center}.togglearrow-arrow{left:100%;background-color:#fff;width:25px;height:25px;text-align:center;cursor:pointer;border:1px solid #ccc;border-radius:50%;line-height:22px}.togglearrow-arrow.disabled{opacity:.3;cursor:not-allowed;pointer-events:none}.search-bar input{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;outline:none}.togglearrow-arrow.disabled:hover{opacity:.3;cursor:not-allowed}.callerDetails h1{width:260px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:12px 0 0;color:#fff;text-transform:capitalize;text-align:center}.callerDetails h4{margin:0;color:#fff}.tx-black,.title{color:#000!important}.callerDetails p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-btn,.mic-btn{position:relative;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:25px;padding:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226;width:50px;height:50px}.mic-btn{padding:5px;width:37px;height:37px}.receive-btn{background-color:#28a745!important;color:#fff!important}.receive-btn span{color:#fff!important}.scroll-container{width:100%;overflow:hidden;white-space:nowrap;position:relative}.scroll-text{display:inline-block;padding-left:100%;animation:scroll-left 12s linear infinite;font-size:16px}@keyframes scroll-left{0%{transform:translate(0)}to{transform:translate(-100%)}}.call-sec-btn span{color:#cccbcb}.call-btn{width:60px;height:60px;background-color:#fff;border-radius:30px;box-sizing:border-box;border:2px solid white;margin:0 16px}.end-call-btn{background-color:#e14e4e}.end-call-btn span{color:#fff!important}.call-btn span{color:#234de8}.btn-container{display:flex;flex-wrap:wrap;padding:0 30px}.key-btn{width:50px;height:50px;background-color:transparent;text-align:center;box-sizing:border-box;margin:0 18px;font-size:22px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#d3d3d3;cursor:pointer;opacity:.8}.call-action-btns{text-align:center}#call-input{background-color:transparent;border:none;outline:none;text-align:center;color:#fff}.sendDigit{position:relative;text-align:center;width:80%;margin:auto;background-color:#ffffff1a;padding:2px 0;border-radius:3px}.input-clear-btn{position:absolute;right:6px;color:#fff;cursor:pointer}#minimize-btn-div{position:absolute;right:14px;top:12px;z-index:10}.minimize-btn{color:#fff;cursor:pointer}.wave-container{position:absolute;bottom:0;overflow:hidden;width:100%}.waves{width:660px;position:relative;margin-bottom:-7px;height:40px;min-height:40px}.held-call-banner{position:absolute;top:0;left:0;right:0;z-index:2100;box-shadow:0 4px 12px #0000004d;border-radius:0 0 16px 16px;max-height:220px;overflow-y:auto}.held-call-content{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 6px;border-bottom:1px dotted #4b4b4b;border-left:3px solid transparent;transition:background .15s ease,border-left-color .15s ease;cursor:pointer}.held-call-content.held-call-selected{background:rgba(255,255,255,.15);border-left-color:#fff;border-radius:0 6px 6px 0}.held-main-label{font-size:13px;color:#fff;text-transform:uppercase;letter-spacing:.5px}.fa-info{font-size:smaller!important}.held-info{display:flex;align-items:center;gap:10px;flex:1}.hold-icon{font-size:24px;color:#fbbf24}.swap-icon{font-size:24px}.held-caller{display:flex;flex-direction:column;gap:2px}.held-label{font-size:10px;color:#ffffffb3;text-transform:uppercase;letter-spacing:.5px}.held-name{font-size:14px;font-weight:600;color:#fff}.held-number{font-size:13px;font-weight:500;color:#fff}.held-actions{display:flex;gap:8px;align-items:center}.held-btn{padding:6px 16px;border-radius:20px;border:none;font-size:13px;font-weight:600;cursor:pointer;transition:transform .2s,box-shadow .2s}.held-btn:hover{transform:scale(1.05);box-shadow:0 4px 12px #0003}.swap-btn{background:#3b82f6;color:#fff}.merge-btn{background:#10b981;color:#fff}.h-77px{height:77px}.incoming-banners-container{width:100%;padding:5px 8px;height:100%;gap:8px;overflow-y:auto}.call-container-model{width:385px!important;height:646px!important;margin:auto 0 0 1px;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;box-sizing:border-box;position:relative;overflow:hidden;justify-content:center;align-items:center}.incoming-banner{top:0;left:0;width:100%;right:0;background:linear-gradient(135deg,#1e3a8a 0%,#3b82f6 100%);padding:12px 16px;z-index:2000;box-shadow:0 4px 12px #0003;border-radius:16px}.incoming-banner-content{display:flex;align-items:center;justify-content:space-between;gap:12px}.incoming-info{flex:1;display:flex;flex-direction:column;gap:4px}.incoming-label{font-size:11px;color:#fffc;text-transform:uppercase;letter-spacing:.5px}.incoming-caller{display:flex;flex-direction:column;gap:2px}.caller-name{font-size:15px;font-weight:600;color:#fff}.caller-number{font-size:13px;color:#ffffffe6}.incoming-actions{display:flex;gap:8px;align-items:center}.banner-btn{width:44px;height:44px;border-radius:50%;border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:transform .2s}.banner-btn:hover{transform:scale(1.1)}.banner-btn .material-symbols-outlined{font-size:20px}.accept-btn{background:#10b981}.accept-btn .material-symbols-outlined{color:#fff}.reject-btn{background:#ef4444}.reject-btn .material-symbols-outlined{color:#fff}.contacts-panel{position:absolute;top:0;bottom:12px;width:340px;background:#ffffff;border-radius:16px;box-shadow:0 10px 25px #00000026;display:flex;flex-direction:column;overflow:hidden;height:40.4rem;left:24.1rem;z-index:1000000;color:#111827!important}.contacts-header{height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;border-bottom:1px solid #f0f0f0;color:#111827!important}.modal-content .contacts-header{height:40px}.search-contacts-list{max-height:196px;overflow:auto;position:absolute;width:91%;background:white;z-index:1000;box-shadow:0 4px 8px #0003,0 6px 20px #00000030;border-radius:0 10px 10px}.contant-body p{font-size:14px;color:#5f6061!important}.contacts-header .title{font-weight:600;color:#111827!important}.contacts-header .back,.contacts-header .search{color:#9aa0a6;cursor:pointer}.disabled{opacity:.5;pointer-events:none}.contacts-list{padding:8px 8px 12px;overflow-y:auto}.contact-item{display:flex;align-items:center;padding:10px 8px;border-radius:10px}.contact-item:hover{background:#f7f9fc}.contact-avatar{width:37px;height:37px;border-radius:50%;object-fit:cover;margin-right:12px}.contact-info{flex:1;min-width:0;overflow:hidden}.contact-name{font-weight:600;color:#111827;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.contact-title{font-size:12px;color:#6b7280}.contact-call-btn{display:inline-flex;align-items:center;gap:6px;background:#234de8;color:#fff;border:none;border-radius:16px;padding:8px;cursor:pointer}.contact-add-btn{background-color:#2ecc71!important}.conference-hold-contact{display:inline-flex;align-items:center;gap:5px;background:#727070;color:#fff;border:none;border-radius:50%;padding:7px;cursor:pointer}.conference-hold-contact.on-hold{background:#28a745!important;color:#fff}.user-info-section{width:100%;height:100%;overflow-y:auto;overflow-x:hidden!important}.user-info-section::-webkit-scrollbar{display:none}.toggle-btn{cursor:pointer}.text-container{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;transition:all .3s ease}.mute-incoming-row{display:flex;align-items:center;justify-content:center;gap:8px;margin:0 0 10px}.mute-incoming-label{font-size:11px;color:#fff}.switch{position:relative;display:inline-block;width:38px;height:19px;flex-shrink:0}.switch-slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;border-radius:22px;transition:.3s}.close-info-panel-section{width:100%;height:20px}.close-info-panel-section .material-symbols-outlined{font-size:12px;cursor:pointer}.c2c-title{color:#fff;white-space:normal;word-break:break-word;line-height:1.4}.switch-slider:before{content:\"\";position:absolute;height:14px;width:15px;left:3px;bottom:3px;background-color:#fff;border-radius:50%;transition:.3s}.switch input:checked+.switch-slider{background-color:#2ecc71}.switch input:checked+.switch-slider:before{transform:translate(18px)}.text-container.expanded{-webkit-line-clamp:unset}.userName{font-family:FontAwesome}.subject-text{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden}.conference-contact{display:inline-flex;align-items:center;gap:5px;background:#e14e4e;color:#fff;border:none;border-radius:50%;padding:7px;cursor:pointer}.organizer-label{padding:1px 5px;font-size:11px;border-radius:10px;border:1px solid #a0a0a0;margin-top:2px;background:#fcfcfc;color:#000}.custom-modal{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;align-items:center;z-index:10000001;border-radius:21px}.modal-content{background:#ffffff;padding:25px;border-radius:8px;width:350px;text-align:center}.title{margin-bottom:15px;color:#d9534f}.message{margin-bottom:20px}.button-group{display:flex;justify-content:space-between}.btn{padding:8px 15px;border:none;border-radius:5px;cursor:pointer;font-weight:500}.end-btn{background-color:#dc3545;color:#fff;display:flex;align-items:center;font-size:13px}.leave-btn{background-color:#007bff;color:#fff}.contact-call-btn .material-symbols-outlined{font-size:18px;color:#fff}.contact-call-btn .label{font-size:12px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}.animated-margin{transition:margin-top .5s ease}app-incoming-call{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1001}.min-call-container{width:320px;height:124px;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;flex-direction:column;box-sizing:border-box;position:relative;overflow:hidden;margin:auto;align-items:center;padding:12px 16px;color:#fff}.min-call-animation{background:#fff;width:48px;height:48px;position:relative;margin:0 12px 0 auto;border-radius:100%;border:solid 2px #fff}.min-avatar-img{width:46px;height:46px;border-radius:100%;position:absolute;left:0;top:0}.border-radius-50{border-radius:50%}.min-callerDetails{color:#fff;display:flex;flex-direction:column;align-items:flex-start}.name{width:170px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:20px;margin:0;color:#fff}.min-callerDetails p{margin:0;color:#fff}.min-btn-container{position:relative;display:flex;width:100%;justify-content:flex-start;align-items:center;margin-top:6px}.min-call-sec-btn{width:40px;height:40px;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:20px;display:flex;align-items:center;justify-content:center;margin-right:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226}.min-call-sec-btn span{color:#cccbcb}.min-call-btn{width:40px;height:40px;border-radius:20px;box-sizing:border-box;border:2px solid white;display:flex;align-items:center;justify-content:center}.fullscreen{position:absolute;right:18px;top:14px;color:#e8e8e8;font-size:18px;cursor:pointer}.btn-container{display:flex;flex-wrap:wrap;padding:0 24px}.dial-btn{width:40px;height:40px;background-color:transparent;text-align:center;box-sizing:border-box;margin:4px 25px;font-size:24px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#b5b5b5;cursor:pointer}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.min-timer{width:50px;font-size:18px;margin-right:10px;border-radius:4px;height:35px;display:flex;align-items:center}.record-action-btns{display:flex;flex-direction:column;align-items:center;margin-top:35px}.record-btn-container{position:relative}.record-btn{border:none;border-radius:50%;width:50px;height:50px;display:flex;align-items:center;justify-content:center;cursor:pointer;margin:0 5px;position:relative;overflow:hidden}.record-btn.start-stop .recording-icon{width:50%;height:50%;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.record-btn.start-stop.recording .recording-icon{background-color:#000}.record-btn.start-stop.recording{border:3px solid #000}.record-btn.start-stop.stopped .recording-icon{background-color:red;border:3px solid #ff0000;border-radius:50%;position:absolute}.record-btn.start-stop.stopped{border:3px solid #ff0000}.record-btn.start-stop.stopped .recording-icon{width:40%;height:40%;border-radius:0;background-color:red}.pause-resume-btns{display:flex;flex-direction:column;align-items:center;margin-top:10px}.record-btn.pause-resume{border:none;border-radius:50%;width:50px;height:50px;background:white;display:flex;align-items:center;justify-content:center;margin:5px 0}.record-btn.pause-resume .material-symbols-outlined{font-size:20px;color:#000}.timer-display{font-size:1.2em;margin-top:10px;color:#000}.w-40{width:40%}.w-60{width:60%}.callToNum{color:#fff;font-weight:400;text-align:center}.callToNum span{font-weight:600}.conference-call-view{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;width:100%;padding:12px 16px 35px;color:#fff;height:100%}.conf-heading{display:flex;align-items:center;gap:8px;margin-top:45px}.conf-icon{color:#4579aa;font-size:32px;width:50px;height:50px;border:1px solid gray;border-radius:50%;display:flex;align-items:center;justify-content:center;background:#e1e1e1}.conf-title{font-weight:600;font-size:20px}.conf-name{margin-top:10px;font-size:17px;font-weight:600;text-align:center}.conf-timer{margin-top:4px;font-size:12px;opacity:.9}.conf-record{margin-top:14px}.record-stop-btn{width:44px;height:44px;border-radius:50%;border:none;background:#fff;display:flex;align-items:center;justify-content:center}.record-stop-btn .material-symbols-outlined{color:#e14e4e;font-size:28px}.conf-remove{margin-top:8px}.remove-btn{background:#ff0000!important;color:#fff;border:none;border-radius:6px;padding:6px 12px;font-size:12px;width:82px!important;height:auto}.conf-actions{margin-top:14px;display:flex;align-items:center;justify-content:center;gap:18px}.circle-btn{width:56px;height:56px;border-radius:50%;border:none;background:#000;display:flex;align-items:center;justify-content:center}.circle-btn .material-symbols-outlined{color:#fff;font-size:24px}.circle-btn.active{opacity:.85}.conf-end{margin-top:16px}.circle-btn.danger{background:#e14e4e}.circle-btn.danger .material-symbols-outlined{color:#fff}.warning-modal{background:white;width:360px;border-radius:18px;padding:24px;text-align:center;box-shadow:0 10px 30px #00000040}.warning-icon{margin-bottom:12px}.warning-icon .material-symbols-outlined{font-size:48px;color:#f59e0b}.warning-modal h3{margin-bottom:12px;font-size:20px;font-weight:600;color:#111827!important}.warning-modal p{color:#555!important;font-size:14px;line-height:1.5;margin-bottom:24px}.warning-modal p strong{color:#111827!important}.warning-actions{display:flex;justify-content:center;gap:12px}.cancel-btn,.proceed-btn{border:none;padding:10px 18px;border-radius:8px;cursor:pointer;font-weight:600}.cancel-btn{background:#e5e7eb;color:#111827}.proceed-btn{background:#234de8;color:#fff}.time-picker-24hr{display:flex;align-items:center;gap:4px}.time-sep{font-weight:700;font-size:16px;color:#333}.custom-time-select{position:relative;width:58px;-webkit-user-select:none;user-select:none}.custom-time-select.disabled-picker{opacity:.45;pointer-events:none}.custom-time-display{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;border:1px solid #ced4da;border-radius:4px;background:#fff;font-size:13px;cursor:pointer;white-space:nowrap;color:#333!important}.custom-time-display:hover{border-color:#234de8}.picker-arrow{font-size:9px;margin-left:4px;color:#666}.custom-time-options{position:fixed;background:#fff;border:1px solid #ced4da;border-radius:4px;max-height:160px;overflow-y:auto;z-index:99999999;min-width:58px;box-shadow:0 4px 12px #00000026}.custom-time-option{padding:5px 10px;font-size:13px;cursor:pointer;text-align:center;color:#333}.custom-time-option:hover{background:#e8eeff;color:#234de8}.custom-time-option.selected{background:#234de8;color:#fff;font-weight:600}.dialpad-alerts{position:absolute;left:50%;transform:translate(-50%);width:calc(100% - 32px);z-index:9999999}.normal-call-alert{top:78px}.conference-alert{top:145px}.dialbox-pop1{background:#dff6dd!important;color:#1d4d1d!important;border-radius:10px;padding:10px 14px;font-size:14px;box-shadow:0 4px 12px #00000040;border:1px solid #b7dfc3}.btn-disc{border:none;background:transparent;color:#6b7280!important;font-size:13px;font-weight:500}.connecting-overlay{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:16px 0 24px}.connecting-text{color:#ffffffe6;font-size:15px;font-weight:500;letter-spacing:.5px;margin:0}.connecting-dots{display:flex;gap:8px;align-items:center}.connecting-dots span{display:inline-block;width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.85);animation:connecting-bounce 1.2s infinite ease-in-out}.connecting-dots span:nth-child(1){animation-delay:0s}.connecting-dots span:nth-child(2){animation-delay:.2s}.connecting-dots span:nth-child(3){animation-delay:.4s}@keyframes connecting-bounce{0%,80%,to{transform:scale(.6);opacity:.4}40%{transform:scale(1.2);opacity:1}}.connecting-wrapper{display:flex;align-items:center;font-size:13px;color:#4caf50;margin-top:4px;font-weight:500}.participant-list-title,.onHold-text{color:#000}.ringing-text,.onHold-text{margin-right:2px;font-size:11px}.held-actions .connecting-wrapper{color:#fff}.dots span{animation:blink 1.4s infinite;opacity:0;font-size:16px}.dots span:nth-child(1){animation-delay:0s}.dots span:nth-child(2){animation-delay:.2s}.dots span:nth-child(3){animation-delay:.4s}@keyframes blink{0%{opacity:0}50%{opacity:1}to{opacity:0}}.loader-wrapper.outgoing-call-loader{position:absolute;inset:0;z-index:100;display:flex;align-items:center;justify-content:center}.panel-loader-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffffb3;display:flex;justify-content:center;align-items:center;z-index:10000009}.settings-icon{cursor:pointer;font-size:24px;color:#555;position:relative;top:5px;right:2px}.settings-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:1000001;display:flex;align-items:flex-start;justify-content:flex-end}.settings-drawer{background:#fff;width:100%;max-width:100%;height:100%;padding:1.5rem 1rem;overflow-y:auto;box-sizing:border-box;transform:translate(100%);animation:slideInFromRight .3s forwards}@keyframes slideInFromRight{to{transform:translate(0)}}.settings-header{display:flex;justify-content:space-between;align-items:center;font-size:1.2rem;font-weight:600;padding-bottom:.75rem;border-bottom:1px solid #eee}.settings-header span:first-child{cursor:pointer}.settings-body{margin-top:1.5rem}.setting-item{display:flex;justify-content:space-between;align-items:center;padding:.75rem 0;gap:1rem}.setting-label{flex:1}.setting-label span{font-weight:500}.setting-label svg{width:15px;height:15px;color:#393939;flex-shrink:0}.setting-label small{display:block;font-size:.75rem;color:#666;margin-top:.15rem}.setting-group h6{font-weight:600;color:#888;font-size:.75rem;letter-spacing:.5px;margin:1rem 0 .5rem}hr{margin:.5rem 0;border-color:#f0f0f0}.switch{position:relative;display:inline-block;width:44px;height:24px;flex-shrink:0}.switch input{opacity:0;width:0;height:0}.switch-slider{position:absolute;cursor:pointer;inset:0;background:#ccc;border-radius:24px;transition:.3s}.switch-slider:before{content:\"\";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background:white;border-radius:50%;transition:.3s}.switch input:checked+.switch-slider{background:#007bff}.switch input:checked+.switch-slider:before{transform:translate(20px)}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
5107
+ CallProgressComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CallProgressComponent, selector: "lib-call-progress", inputs: { callData: "callData", selectedCallerId: "selectedCallerId", newIncomingCallData: "newIncomingCallData", newIncomingCallsList: "newIncomingCallsList", callerIdList: "callerIdList", newCallConference: "newCallConference", missCallInfo: "missCallInfo", userSettingInfo: "userSettingInfo", deviceId: "deviceId", callAction: "callAction", conferenceCallInfo: "conferenceCallInfo", incomingFromImage: "incomingFromImage", cancelConnectingAction: "cancelConnectingAction", outgoingContactName: "outgoingContactName" }, outputs: { endCallEvent: "endCallEvent", incomingCallsNewInfo: "incomingCallsNewInfo", minimiseEvent: "minimiseEvent", muteAllStatusEvent: "muteAllStatusEvent", incomingCallInitiated: "incomingCallInitiated", isLoadershown: "isLoadershown", endIncomingCallEvent: "endIncomingCallEvent" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"d-flex\">\n <div class=\"call-container\" *ngIf=\"!isMinimised && currentCallList?.length\"\n [ngClass]=\"{'collops': isCollops, 'incoming-call-container': isClickExpand, 'contacts-open': showContactsPanel }\">\n <div class=\"loader-wrapper outgoing-call-loader\"\n *ngIf=\"showNewCallLoader\">\n <div class=\"active-call\" style=\"display: flex; flex-direction: column; position: relative;\">\n <div class=\"call-animation call-animation-play\">\n <img class=\"avatar-img\" [src]=\"newCallLoaderData?.img || 'assets/images/user.jpg'\" alt=\"\" />\n </div>\n <div class=\"callerDetails\">\n <h1 style=\"margin-top: 8px;\">Connecting...</h1>\n <p style=\"text-transform: capitalize;\">{{ newCallLoaderData?.name || newCallLoaderData?.phone || 'Unknown' }}</p>\n </div>\n \n <div class=\"call-action-btns\">\n <div class=\"d-flex justify-content-center\">\n <button class=\"call-btn end-call-btn\" disabled (click)=\"endCall()\" style=\"visibility: hidden;\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"dialpad-alerts\"\n [ngClass]=\"{\n 'conference-alert': isConference && currentCall?.isConference,\n 'normal-call-alert': !isConference\n }\" *ngIf=\"callNumberToast.show\">\n <div class=\"dialbox-pop1 alert fade show\"\n [ngClass]=\"callNumberToast.type\"\n role=\"alert\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <div class=\"flex-grow-1 text-left\">\n You'r calling\n <strong>{{callNumberToast.displayNum}}</strong>\n </div>\n <div class=\"text-right\">\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelCallToast()\"> Cancel Call </button>\n </div>\n </div>\n </div>\n </div>\n <!-- All type Call Hold list -->\n <div class=\"held-call-banner\"\n *ngIf=\"(currentCallList.length > 1 && !!currentCall && ((isConferenceCallHold || isConference) || !isConference)) || !isAllAccepted\">\n <ng-container *ngFor=\"let conf of currentCallList\">\n <div class=\"held-call-content\" *ngIf=\"!conf?.isAcceptCall && currentCallList.length > 1 && deviceNumberList.includes(conf?.to) && conf?.isNotification\"\n [ngClass]=\"{'held-call-selected': selectedUserInfo?.participantId && selectedUserInfo?.participantId === conf?.participantId}\"\n (click)=\"conf?.businessNumber ? toggleC2CInfoPanel(conf) : null\"\n [ngStyle]=\"{'cursor': conf?.businessNumber ? 'pointer' : 'default'}\">\n <div class=\"held-info\">\n <div class=\"img\">\n <img class=\"avatar-img-wrapper border-radius-50\" [src]=\"conf?.img || 'assets/images/user.jpg'\" alt=\"\" width=\"35\" height=\"35\" />\n </div>\n <div class=\"held-caller\" *ngIf=\"!conf?.businessNumber\">\n <span class=\"held-label\">{{conf?.from}}</span>\n <span class=\"held-name\">{{conf?.fromName}}</span>\n </div>\n <div class=\"held-caller\" *ngIf=\"conf?.businessNumber\">\n <span class=\"held-main-label\">Call from C2C:</span>\n <span class=\"held-label\" ><span [title]=\"conf?.sourceName\">{{ truncateText(conf?.sourceName, 10) }}</span>|\n <span [title]=\"conf?.pointName\">{{ truncateText(conf?.pointName, 10) }}</span></span>\n <span class=\"held-label\">{{ truncateText(conf?.name, 26) }}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <ng-container *ngIf=\"isConnectingIncomingCallId == conf?.id\">\n <div class=\"connecting-wrapper mr-2\">\n <span class=\"ringing-text\">Connecting</span>\n <span class=\"dots\">\n <span>.</span>\n <span>.</span>\n <span>.</span>\n </span>\n </div>\n </ng-container>\n <button class=\"conference-hold-contact receive-btn\" (click)=\"waitingCallAccept(conf)\" [disabled]=\"isConnecting || isIncomingCallBtnDisable\" *ngIf=\"isConnectingIncomingCallId !== conf?.id\">\n <span class=\"material-symbols-outlined\"> call </span>\n </button>\n <button class=\"conference-contact\">\n <span class=\"material-symbols-outlined\" title=\"Call End\" (click)=\"onRejectCall(conf); $event.stopPropagation();\"> call_end </span>\n </button>\n <div *ngIf=\"conf?.businessNumber\" class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"toggleC2CInfoPanel(conf)\">\n <i class=\"fa fa-info\"></i>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-container *ngFor=\"let conf of conferenceCallList\">\n <div class=\"held-call-content\" *ngIf=\"(conf?.isConferenceHold || (showNewCallLoader && isConferenceCallHold)) && (conferenceCallList.length > 1 || showNewCallLoader)\"\n [ngClass]=\"{'held-call-selected': conf?.isBusinessNumber && selectedUserInfo?.participantId === conf?.businessParticipantId && isClickExpand}\"\n (click)=\"conf?.isBusinessNumber ? toggleC2CInfoPanel(conf) : null\"\n [ngStyle]=\"{'cursor': conf?.isBusinessNumber ? 'pointer' : 'default'}\">\n <div class=\"held-info\">\n <span class=\"material-symbols-outlined hold-icon\">pause_circle</span>\n <div class=\"held-caller\">\n <span class=\"held-label\">Hold</span>\n <span class=\"held-name\">{{conf?.callLabel}}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <button class=\"conference-hold-contact\" [ngClass]=\"{ 'on-hold': conf?.isConferenceHold }\"\n (click)=\"swapCalls(conf,true)\" [disabled]=\"isHoldBtnDisable\">\n <span *ngIf=\"conf?.isConferenceHold\" class=\"material-symbols-outlined\" [title]=\"'Resume'\"> resume </span>\n </button>\n <button class=\"conference-contact\" (click)=\"endConfereneceCall(conf); $event.stopPropagation();\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n </button>\n <div class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"toggleContactsPanel(conf)\">\n <i class=\"fa fa-angle-right\"></i>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- For single incoming call -->\n <div class=\"h-100 py-5\" style=\"display: flex; flex-direction: column;\"\n *ngIf=\"currentCallList.length === 1 && currentCallList[0]?.isIncomingCall && !currentCallList[0]?.isAcceptCall\">\n <!-- <div class=\"callToNum\">Incoming call on <br /><span>{{currentCallList[0]?.to || 'Unknown Number'}}</span>\n </div> -->\n <div class=\"callToNum\">\n <ng-container *ngIf=\"currentCallList[0]?.businessNumber; else normalCall\">\n C2C CALL\n <br />\n <span> From : {{ currentCallList[0]?.sourceName }} | {{ currentCallList[0]?.pointName }} </span>\n </ng-container>\n\n <ng-template #normalCall>\n Incoming call on\n <br />\n <span>{{ currentCallList[0]?.to || 'Unknown Number' }}</span>\n </ng-template>\n </div>\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\n <img class=\"avatar-img\" [src]=\"incomingFromImage || 'assets/images/user.jpg'\" alt=\"\" width=\"120\" />\n </div>\n <div class=\"callerDetails\" *ngIf=\"!currentCallList[0]?.businessNumber\">\n <h1>{{ currentCallList[0]?.name ? currentCallList[0]?.name : currentCallList[0]?.phone || 'Unknown Number' }}</h1>\n <p *ngIf=\"!!currentCallList[0]?.name\">{{ currentCallList[0]?.phone }}</p>\n </div>\n <div class=\"callerDetails\" *ngIf=\"currentCallList[0]?.businessNumber\">\n <p *ngIf=\"!!currentCallList[0]?.name\">{{ truncateText(currentCallList[0]?.name, 45) }}</p>\n <p >{{ currentCallList[0]?.number }}</p>\n </div>\n <!-- Connecting overlay (shown after accept btn click, hidden on API response) -->\n <div class=\"connecting-overlay mt-auto\" *ngIf=\"isConnectingIncomingCallId == currentCallList[0]?.id\">\n <div class=\"connecting-dots\">\n <span></span><span></span><span></span>\n </div>\n <p class=\"connecting-text\">Connecting...</p>\n </div>\n\n <div class=\"call-action-btns mt-auto\" *ngIf=\"isConnectingIncomingCallId != currentCallList[0]?.id\">\n <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected\"\n [disabled]=\"isIncomingCallBtnDisable\" (click)=\"acceptIncomingCall(currentCallList[0])\">\n <span class=\"material-symbols-outlined\"> call </span>\n </button>\n <button class=\"call-btn reject-btn\">\n <span class=\"material-symbols-outlined\" (click)=\"onRejectCall(currentCallList[0])\"> call_end </span>\n </button>\n </div>\n </div>\n\n <!-- For single active call -->\n <div *ngIf=\"(!isConference || isConferenceCallHold) && (!!currentCall?.id && !currentCall?.isConference) && currentCall?.isAcceptCall\"\n [ngStyle]=\"{'display': 'flex', 'flex-direction': 'column', 'position': 'relative'}\" class=\"active-call\">\n <div *ngIf=\"currentCall?.businessNumber;\" class=\"callToNum\">\n C2C CALL\n <br />\n <span> From : {{ currentCall?.userInfoId?.sourceName }} | {{ currentCall?.userInfoId?.pointName }} </span>\n </div>\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\n <img class=\"avatar-img\" *ngIf=\"!currentCall?.client\"\n [src]=\"currentCall?.direction == 'outgoing-call' ? currentCall?.toImage || 'assets/images/user.jpg' : currentCall?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\n <img class=\"avatar-img\" *ngIf=\"currentCall?.client\"\n [src]=\"currentCall?.direction == 'outgoing-call' ? currentCall?.fromImage || 'assets/images/user.jpg' : currentCall?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\n </div>\n <div class=\"callerDetails\">\n <!-- C2C Business Call -->\n <ng-container *ngIf=\"currentCall?.businessNumber; else normalCall\">\n <h1>{{ currentCall?.userInfoId?.name || 'Unknown' }}</h1>\n <p>{{ currentCall?.userInfoId?.number || currentCall?.from || 'Unknown' }}</p>\n </ng-container>\n\n <!-- Normal Call -->\n <ng-template #normalCall>\n <h1 *ngIf=\"!currentCall?.client\"\n [ngStyle]=\"{'margin-top': showKeypad ? '0':'8px'}\">\n {{ currentCall?.direction == 'outgoing-call'\n ? currentCall?.toName || outgoingContactName || 'Unknown'\n : currentCall?.fromName || 'Unknown' }}\n </h1>\n <h1 *ngIf=\"currentCall?.client\"\n [ngStyle]=\"{'margin-top': showKeypad ? '0':'8px'}\">\n {{ currentCall?.direction == 'outgoing-call'\n ? currentCall?.fromName || 'Unknown'\n : currentCall?.toName || outgoingContactName || 'Unknown' }}\n </h1>\n <p *ngIf=\"!currentCall?.client\">\n {{ currentCall?.direction == 'outgoing-call'\n ? currentCall?.to\n : currentCall?.from }}\n </p>\n <p *ngIf=\"currentCall?.client\">\n {{ currentCall?.direction == 'outgoing-call'\n ? currentCall?.from\n : currentCall?.to }}\n </p>\n </ng-template>\n <!-- <h1 *ngIf=\"!currentCall?.client\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall?.direction == 'outgoing-call' ? currentCall?.toName || outgoingContactName || 'Unknown' :\n currentCall?.fromName || 'Unknown'}}</h1>\n <h1 *ngIf=\"currentCall?.client\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall?.direction == 'outgoing-call' ? currentCall?.fromName || 'Unknown' :\n currentCall?.toName || 'Unknown'}}</h1>\n <p *ngIf=\"!currentCall?.client\">{{ currentCall?.direction == 'outgoing-call' ? currentCall?.to || 'Unknown' : currentCall?.from || 'Unknown'}}</p>\n <p *ngIf=\"currentCall?.client\">{{ currentCall?.direction == 'outgoing-call' ? currentCall?.from || 'Unknown' : currentCall?.to || 'Unknown'}}</p> -->\n <h4 style=\"margin-top: 4px\">{{ timer}}</h4>\n </div>\n <div class=\"record-action-btns\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\">\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording, 'disabled': userSettingInfo?.callRecording == 'N'}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"!currentCall?.isAcceptCall || userSettingInfo?.callRecording == 'N'\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\" (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n <!-- Mute/unmute incoming call -->\n <div class=\"mute-incoming-row\" *ngIf=\"currentCall?.isAcceptCall && !showKeypad\">\n <span class=\"mute-incoming-label\">Mute incoming calls</span>\n <label class=\"switch mb-0\" title=\"Silence the ringtone of new incoming calls during this call\">\n <input type=\"checkbox\" [checked]=\"twilioService.isIncomingMuted\" (change)=\"toggleMuteIncomingCall()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n <div *ngIf=\"showKeypad\" class=\"sendDigit\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\" (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\" (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : '&nbsp;'}}</span>\n </div>\n </div>\n\n <div class=\"call-action-btns\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '723x'}\">\n <div class=\"flex align-items-center justify-content-evenly mb-3\">\n <button class=\"call-sec-btn mr-3\" [disabled]=\"!currentCall?.isAcceptCall || !canSelfToggleMute()\" [title]=\"selfMuteTooltip()\" (click)=\"toggleMute()\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isSelfEffectivelyMuted()\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isSelfEffectivelyMuted()\"> mic </span>\n </button>\n <button class=\"call-sec-btn mr-3\" [disabled]=\"!currentCall?.isAcceptCall\">\n <span class=\"material-symbols-outlined\" (click)=\"toggleKeypad()\"> transition_dissolve\n </span>\n </button>\n <button class=\"call-sec-btn\" [disabled]=\"!currentCall?.isAcceptCall\"\n (click)=\"toggleContactsPanel(currentCall)\">\n <span class=\"material-symbols-outlined\"> groups_2 </span>\n </button>\n </div>\n <div>\n <button class=\"call-btn end-call-btn\" [disabled]=\"!currentCall?.isAcceptCall\" (click)=\"endCall(false, currentCall)\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n </div>\n\n <!-- conference call view -->\n <div class=\"conference-call-view\" *ngIf=\"isConference\">\n <div class=\"conf-heading\">\n <span class=\"conf-icon material-symbols-outlined\"> groups </span>\n <span class=\"conf-title\">{{currentConferenceCall?.callLabel || 'Conference Call'}}</span>\n </div>\n <div class=\"scroll-container\">\n <div class=\"scroll-text conf-name\">\n <ng-container *ngFor=\"let call of currentCallList; let i = index\">\n <ng-container *ngIf=\"!call?.isConferenceHold\">\n <span *ngIf=\"shouldShowSeparator(i)\"> & </span>\n <span *ngIf=\"call?.client\">\n <ng-container *ngIf=\"!isSelfNumber(call) else selfNumber\">\n <span>{{call?.direction == 'outgoing-call' ? call?.fromName || call?.from :\n call?.toName || call?.to}}</span>\n </ng-container>\n <ng-template #selfNumber>\n <span>You</span>\n </ng-template>\n </span>\n <span *ngIf=\"!call?.client\">{{call?.direction == \"outgoing-call\" ? call?.toName || call?.to : call?.fromName || call?.from || 'Unknown number'}}</span>\n </ng-container>\n </ng-container>\n </div>\n </div>\n <div class=\"conf-timer\">{{ currentConferenceCall?.timer || timer }}</div>\n <div class=\"record-action-btns mt-auto\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\" >\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\" [disabled]=\"userSettingInfo.callRecording == 'N'\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording, 'disabled': userSettingInfo?.callRecording == 'N'}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\" (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n <!-- Mute/unmute incoming call -->\n <div class=\"mute-incoming-row\" *ngIf=\"currentCall?.isAcceptCall && !showKeypad\">\n <span class=\"mute-incoming-label\">Mute incoming calls</span>\n <label class=\"switch mb-0\" title=\"Silence the ringtone of new incoming calls during this call\">\n <input type=\"checkbox\" [checked]=\"twilioService.isIncomingMuted\" (change)=\"toggleMuteIncomingCall()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n <div *ngIf=\"showKeypad\" class=\"sendDigit mt-2\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\" (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\" (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : '&nbsp;'}}</span>\n </div>\n </div>\n <div class=\"conf-actions\">\n <button class=\"circle-btn\" [ngClass]=\"{'active': isSelfEffectivelyMuted()}\" [disabled]=\"!canSelfToggleMute()\" [title]=\"selfMuteTooltip()\" (click)=\"toggleMute(true)\">\n <span class=\"material-symbols-outlined\"> {{ isSelfEffectivelyMuted() ? 'mic_off' : 'mic' }} </span>\n </button>\n <button class=\"circle-btn\" (click)=\"toggleKeypad()\">\n <span class=\"material-symbols-outlined\"> transition_dissolve </span>\n </button>\n <button class=\"circle-btn\" (click)=\"toggleContactsPanel(currentCall)\">\n <span class=\"material-symbols-outlined\"> groups_2 </span>\n </button>\n </div>\n <div class=\"conf-end\">\n <button class=\"circle-btn danger\" (click)=\"endConfereneceCall(currentConferenceCall?.participants[0])\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n\n <div class=\"wave-container\">\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\n <defs>\n <path id=\"gentle-wave\"\n d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\n </defs>\n <g class=\"parallax\">\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\n </g>\n </svg>\n </div>\n </div>\n\n <!-- Incoming call user details shown in model -->\n <div class=\"call-container-model p-3 text-white model-content call-container\" *ngIf=\"isClickExpand\">\n <div class=\"close-info-panel-section\">\n <div class=\"d-flex justify-content-between\" *ngIf=\"currentConferenceCall?.conferenceId != selectedUserInfo?.conferenceId && newIncomingCallsList?.length > 1\">\n <p></p>\n <span class=\"material-symbols-outlined dial-close-btn \" (click)=\"onCloseC2CInfoPanel()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"#ffffff\">\n <path\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\n </svg>\n </span>\n </div>\n </div>\n <div class=\"mb-2 user-info-section\">\n <div class=\"text-center my-3\">\n <h3 class=\"text-white\">C2C CALL : {{selectedUserInfo?.sourceName}} | {{selectedUserInfo?.pointName}}</h3>\n </div>\n <div class=\"mb-3\">\n <h5 class=\"text-white mb-1\">Name:</h5>\n <h4 class=\"text-white userName\">{{selectedUserInfo?.name}}</h4>\n </div>\n <div class=\"f-13\">\n <div class=\"row mb-3\">\n <div class=\"col-6 mb-2\">\n <div class=\"mb-1\">Extension:</div>\n <div class=\"ml-2\">{{selectedUserInfo?.extension}}</div>\n </div>\n <div class=\"col-6 mb-2\">\n <div class=\"mb-1\">Number:</div>\n <div class=\"\">{{selectedUserInfo?.number}}</div>\n </div> \n </div>\n <div class=\"row mb-3\">\n <div class=\"col-12 mb-2\">\n <div class=\"me-2\">Email: </div>\n <div>{{selectedUserInfo?.email}}</div>\n </div>\n </div>\n <div class=\"row mb-3\">\n <div class=\"col-12 mb-2\">\n <div class=\"me-2\">Subject:</div>\n <div class=\"ml-2 subject-text\" title=\"{{selectedUserInfo?.subject}}\">\n {{selectedUserInfo?.subject}}</div>\n </div>\n </div>\n <div class=\"row mb-3\">\n <div class=\"col-12 mb-2\">\n <div class=\"me-2 mb-1\">Image:</div>\n <div class=\"text-ellipsis\">\n <ng-container\n *ngIf=\"selectedUserInfo?.image && selectedUserInfo?.image !== '-'; else noImage\">\n <img src=\"{{selectedUserInfo?.image}}\" alt=\"\" width=\"150\" class=\"ml-2\" />\n </ng-container>\n <ng-template #noImage>\n <span class=\"ml-2\">No Image Available</span>\n </ng-template>\n </div>\n </div>\n </div>\n <div class=\" mb-4\">\n <div class=\"\">\n <div class=\"mb-1\">Message:</div>\n <div>\n <div class=\"text-container\" [class.expanded]=\"isExpanded\">{{selectedUserInfo?.message}}\n </div>\n <small class=\"toggle-btn\" *ngIf=\"showButton\" (click)=\"toggleText()\">{{ isExpanded ? 'See\n less' : 'See more' }}</small>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- contact list panel -->\n <div class=\"contacts-panel\" *ngIf=\"showContactsPanel && !showNewCallLoader\">\n <div class=\"panel-loader-overlay p-3 text-center\" *ngIf=\"isParticipantPanelLoading\">\n <div class=\"spinner-border text-secondary\" role=\"status\">\n <span class=\"sr-only\">Loading...</span>\n </div>\n <p class=\"mt-2\"></p>\n </div>\n <div class=\"contacts-header\">\n <div class=\"participant-list-title\">\n {{ selectedConfName || 'Conference' }} Participants\n <!-- <ng-container *ngIf=\"totalParticipantsCount < 3; else confHeading\">\n Call Participants\n </ng-container>\n <ng-template #confHeading>\n </ng-template> -->\n </div>\n <div class=\"d-flex justify-content-between\">\n \n <span class=\"material-symbols-outlined settings-icon me-2\" *ngIf=\"isConferenceHost\" (click)=\"toggleSettingsPanel()\">\n settings\n </span>\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"toggleContactsPanel({}, true)\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"#000000\">\n <path\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\n </svg>\n </span>\n </div>\n </div>\n <div class=\"settings-overlay\" *ngIf=\"showSettingsPanel\" (click)=\"closeSettingsPanel()\">\n <div class=\"settings-drawer\" (click)=\"$event.stopPropagation()\">\n <div class=\"settings-header\">\n <span class=\"material-symbols-outlined\" (click)=\"closeSettingsPanel()\">arrow_back</span>\n <span>Call Settings</span>\n <span></span> <!-- placeholder for alignment -->\n </div>\n \n <div class=\"settings-body\">\n <!-- Mute all participants -->\n <div class=\"setting-item\">\n <div class=\"setting-label\">\n <span>Mute all participants</span>\n <small>Off \u2014 participants can mute and unmute themselves at any time.</small>\n </div>\n <label class=\"switch\">\n <input type=\"checkbox\" [ngModel]=\"settings.muteAll\" [disabled]=\"isUpdatingConferenceSettings\"\n (ngModelChange)=\"onMuteAllToggle($event)\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n \n <hr>\n \n <!-- Participant Permissions -->\n <div class=\"setting-group\">\n <h6>PARTICIPANT PERMISSIONS</h6>\n \n <!-- Allow unmute -->\n <div class=\"setting-item\">\n <div class=\"setting-label\">\n <span>\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3Z\" stroke=\"currentColor\" stroke-width=\"1.8\"></path>\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2M12 19v3\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\n </svg>\n Allow participants to self-unmute\n </span>\n <small>{{ settings.allowUnmute ? 'Yes \u2014 participants can unmute themselves after being muted\n individually by the host.' : 'No \u2014 participants cannot unmute themselves.' }}</small>\n </div>\n <label class=\"switch\">\n <input type=\"checkbox\" [ngModel]=\"settings.allowUnmute\" [disabled]=\"isUpdatingConferenceSettings\"\n (ngModelChange)=\"settings.allowUnmute = $event; updateConferenceSettings()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n \n <!-- Allow remove -->\n <div class=\"setting-item\">\n <div class=\"setting-label\">\n <span>\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M17 21v-2a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v2M15 3.13a4 4 0 0 1 0 7.75\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\n <circle cx=\"9\" cy=\"7\" r=\"4\" stroke=\"currentColor\" stroke-width=\"1.8\"></circle>\n <path d=\"M19 8h4\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\n </svg>\n Allow participants to remove\n </span>\n <small>{{ settings.allowRemove ? 'Yes \u2014 participants can remove other participants.' : 'No \u2014\n participants cannot remove other participants, and cannot remove the host.' }}</small>\n </div>\n <label class=\"switch\">\n <input type=\"checkbox\" [ngModel]=\"settings.allowRemove\" [disabled]=\"isUpdatingConferenceSettings\"\n (ngModelChange)=\"settings.allowRemove = $event; updateConferenceSettings()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n <div class=\"setting-item\">\n <div class=\"setting-label\">\n <span>Allow participants to unhold</span>\n <small>{{ settings.allowUnhold ? 'Yes \u2014 participants can place themselves on hold.' : 'No \u2014\n participants cannot place themselves on hold.' }}</small>\n </div>\n <label class=\"switch\">\n <input type=\"checkbox\" [ngModel]=\"settings.allowUnhold\" [disabled]=\"isUpdatingConferenceSettings\"\n (ngModelChange)=\"settings.allowUnhold = $event; updateConferenceSettings()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n <div class=\"setting-item\">\n <div class=\"setting-label\">\n <span>Allow participants to mute other participants</span>\n <small>{{ settings.allowMuteOthers ? 'Yes \u2014 Participants can mute other participants, and can mute the host.' : 'No \u2014\n Participants cannot mute other participants, and cannot mute the host.' }}</small>\n </div>\n <label class=\"switch\">\n <input type=\"checkbox\" [ngModel]=\"settings.allowMuteOthers\" [disabled]=\"isUpdatingConferenceSettings\"\n (ngModelChange)=\"settings.allowMuteOthers = $event; updateConferenceSettings()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- SEARCH INPUT (visible when isSearchVisible = true) -->\n <div class=\"search-bar p-3 position-relative\">\n <input type=\"text\" [placeholder]=\"isSpecialCall() ? 'Search by Name or Number for a new call' : 'Add a participant by Name or Number'\"\n [title]=\"isSpecialCall() ? 'Adding participants is not allowed on this call' : 'Add a participant by Name or Number'\" [(ngModel)]=\"searchText\" (input)=\"applyFilter()\" />\n <div class=\"search-contacts-list\">\n <ng-container *ngFor=\"let c of filteredList\">\n <div class=\"contact-item\" *ngIf=\"searchText\">\n <img class=\"contact-avatar\" [src]=\"c?.image || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c?.firstName}} {{c?.middleName}} {{c?.lastName}}</div>\n <div class=\"contact-title\">{{ (c?.numbersList && c?.numbersList[0]?.number) }}{{ c?.numbersList[0]?.numberLabel ? ' (' + c.numbersList[0].numberLabel + ')' : '' }}</div>\n </div>\n <button class=\"contact-call-btn contact-add-btn mr-2\" (click)=\"callContact(c)\"\n *ngIf=\"!c?.IsConnected && !isSpecialCall()\" title=\"Add to call\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n <button class=\"contact-call-btn\" (click)=\"CallToUnsavedNumber(c?.numbersList[0]?.number, true)\"\n *ngIf=\"!c?.IsConnected\" title=\"New Call\">\n <span class=\"material-symbols-outlined\"> call </span>\n </button>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!filteredList.length && isDirectCallOptionShow && searchText\">\n <div class=\"contact-item\">\n <img class=\"contact-avatar\" [src]=\"'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-title\">{{ searchText }}</div>\n </div>\n <button class=\"contact-call-btn contact-add-btn mr-2\" (click)=\"CallToUnsavedNumber(searchText)\"\n *ngIf=\"!isSpecialCall()\" title=\"Add to call\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n <button class=\"contact-call-btn\" (click)=\"CallToUnsavedNumber(searchText, true)\"\n title=\"New Call\">\n <span class=\"material-symbols-outlined\"> call </span>\n </button>\n </div>\n </ng-container>\n </div>\n </div>\n <div class=\"contacts-list\">\n <div class=\"px-2\">\n <h5 class=\"mb-0 title\">Active participants ({{ activeParticipantsCount }})</h5>\n </div>\n <hr class=\"mb-2 mt-1\">\n <ng-container *ngFor=\"let c of filteredParticipentList\">\n <div class=\"contact-item\" *ngIf=\"!c?.isLeft\">\n <img class=\"contact-avatar\" *ngIf=\"!c?.client\"\n [src]=\"c?.direction == 'outgoing-call' ? c?.toImage || 'assets/images/user.jpg' : c?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\n <img class=\"contact-avatar\" *ngIf=\"c?.client\"\n [src]=\"c?.direction == 'outgoing-call' ? c?.fromImage || 'assets/images/user.jpg' : c?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\" *ngIf=\"!c?.client\">{{c?.direction == 'outgoing-call' ? c?.toName || 'Unknown' : c?.fromName || 'Unknown'}}\n </div>\n <div class=\"contact-title\" *ngIf=\"!c?.client\">{{ c?.direction == 'outgoing-call' ? c?.to || 'Unknown' : c?.from || 'Unknown'}}</div>\n\n <div class=\"contact-name\" *ngIf=\"c?.client\">\n <ng-container *ngIf=\"!isSelfNumber(c) else selfNumber\">\n <span>{{c?.direction == 'outgoing-call' ? c?.fromName || 'Unknown' : c?.toName || 'Unknown'}}</span>\n </ng-container>\n <ng-template #selfNumber>\n <span>You</span>\n </ng-template>\n </div>\n <div class=\"contact-title\" *ngIf=\"c?.client\">{{ c?.direction == 'outgoing-call' ? c?.from || 'Unknown' : c?.to || 'Unknown'}}</div>\n <div class=\"d-flex\" *ngIf=\"c?.host\">\n <span class=\"organizer-label\">Organizer</span>\n </div>\n </div>\n <ng-container *ngIf=\"c?.joined && !c?.host\">\n <div class=\"connecting-wrapper mr-2\">\n <span class=\"ringing-text\">Ringing</span>\n <span class=\"dots\">\n <span>.</span>\n <span>.</span>\n <span>.</span>\n </span>\n </div>\n </ng-container>\n <ng-container *ngIf=\"c?.host && c?.isHold && !(deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call'))\">\n <div class=\"connecting-wrapper mr-2\">\n <span class=\"onHold-text\">On Hold</span>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!c?.joined || c?.host\">\n <button class=\"mic-btn mr-2\" [disabled]=\"c?.isHold || !canToggleMute(c)\" [title]=\"muteTooltip(c)\" (click)=\"onMuteUser(c)\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isEffectivelyMuted(c)\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isEffectivelyMuted(c)\"> mic </span>\n </button>\n <button class=\"conference-hold-contact mr-2\" [ngClass]=\"{ 'on-hold': c?.isHold }\"\n (click)=\"onHoldCall(c)\" *ngIf=\"!c?.host || (c?.host && (deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call')))\" [disabled]=\"isHoldBtnDisable || !canToggleHold(c)\">\n <span *ngIf=\"!c?.isHold\" class=\"material-symbols-outlined\" [title]=\"canToggleHold(c) ? 'Hold' : holdTooltip(c)\"> phone_paused</span>\n <span *ngIf=\"c?.isHold\" class=\"material-symbols-outlined\" [title]=\"canToggleHold(c) ? 'Resume' : holdTooltip(c)\"> resume </span>\n </button>\n </ng-container>\n <button class=\"conference-contact\" (click)=\"confirmLeaveParticipant(c)\"\n [disabled]=\"!canRemoveParticipant(c)\" [title]=\"removeTooltip(c)\" *ngIf=\"!c?.host\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n </button>\n <button class=\"conference-contact\" (click)=\"endConfereneceCall(c)\"\n *ngIf=\"c?.host && (deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call'))\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n </button>\n </div>\n </ng-container>\n <hr class=\"m-2\">\n <div class=\"mt-3 px-2\">\n <h5 class=\"mb-0 title\">Participant added to the call</h5>\n </div>\n <hr class=\"mb-2 mt-1\">\n <ng-container *ngFor=\"let c of filteredParticipentList\">\n <div class=\"contact-item\" *ngIf=\"c?.isLeft\">\n <img class=\"contact-avatar\" *ngIf=\"!c?.client\"\n [src]=\"c?.direction == 'outgoing-call' ? c?.toImage || 'assets/images/user.jpg' : c?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\n <img class=\"contact-avatar\" *ngIf=\"c?.client\"\n [src]=\"c?.direction == 'outgoing-call' ? c?.fromImage || 'assets/images/user.jpg' : c?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\" *ngIf=\"!c?.client\">{{c?.direction == 'outgoing-call' ? c?.toName || 'Unknown' : c?.fromName || 'Unknown'}}\n </div>\n <div class=\"contact-title\" *ngIf=\"!c?.client\">{{ c?.direction == 'outgoing-call' ? c?.to || 'Unknown' : c?.from || 'Unknown'}}</div>\n <div class=\"contact-name\" *ngIf=\"c?.client\">{{c?.direction == 'outgoing-call' ? c?.fromName || 'Unknown' : c?.toName || 'Unknown'}}\n </div>\n <div class=\"contact-title\" *ngIf=\"c?.client\">{{ c?.direction == 'outgoing-call' ? c?.from || 'Unknown' : c?.to || 'Unknown'}}</div>\n <div class=\"d-flex\" *ngIf=\"c?.host\">\n <span class=\"organizer-label\">Organizer</span>\n </div>\n </div>\n <div class=\"connecting-wrapper\" *ngIf=\"c?.joined\">\n <span class=\"ringing-text\">Ringing</span>\n <span class=\"dots\">\n <span>.</span>\n <span>.</span>\n <span>.</span>\n </span>\n </div>\n <button class=\"conference-contact\" (click)=\"onEndCall(c, false, true)\" *ngIf=\"!c?.host && c?.joined\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n </button>\n <button class=\"contact-call-btn contact-add-btn\" *ngIf=\"!c?.client && !c?.joined && !c?.businessNumber\"\n (click)=\"CallToUnsavedNumber(c.direction == 'outgoing-call' ? c?.to : c?.from, false, { skipDuplicateCheck: true }, c)\">\n <span class=\"material-symbols-outlined\"> add </span>\n <span class=\"label\">Rejoin</span>\n </button>\n <button class=\"contact-call-btn contact-add-btn\" *ngIf=\"c?.client && !c?.joined && !c?.businessNumber\"\n (click)=\"CallToUnsavedNumber(c.direction == 'outgoing-call' ? c?.from : c?.to, false, { skipDuplicateCheck: true }, c)\">\n <span class=\"material-symbols-outlined\"> add </span>\n <span class=\"label\">Rejoin</span>\n </button>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Conference Warning Modal -->\n<div class=\"custom-modal\" *ngIf=\"showConferenceWarningModal\">\n <div class=\"modal-content warning-modal\">\n <div class=\"warning-icon\">\n <span class=\"material-symbols-outlined\">warning</span>\n </div>\n <h3>Warning</h3>\n <p>\n Starting a new call will put the current call on hold\n and cannot be merged later.\n </p>\n <div class=\"warning-actions\">\n <button class=\"cancel-btn\" (click)=\"cancelNewCall()\">\n Cancel\n </button>\n <button class=\"proceed-btn\" (click)=\"confirmNewCall()\">\n Proceed\n </button>\n </div>\n </div>\n</div>\n\n<!-- Special Call Charges Modal (call screen open: active/held conference + new call).\n First call (no call screen yet) is shown by dialbox over its \"Connecting...\" loader. -->\n<div class=\"custom-modal\" *ngIf=\"twilioService.specialCallConfirm?.inCallScreen\">\n <div class=\"modal-content warning-modal\">\n <div class=\"warning-icon\">\n <span class=\"material-symbols-outlined\">warning</span>\n </div>\n <h3>Call Charges</h3>\n <p *ngIf=\"twilioService.specialCallConfirm?.message\">{{ twilioService.specialCallConfirm?.message }}</p>\n <p *ngIf=\"!twilioService.specialCallConfirm?.message\">\n Additional charges apply to this call. Do you want to proceed?\n </p>\n <div class=\"warning-actions\">\n <button class=\"cancel-btn\" (click)=\"onSpecialCallChargesAction(false)\">\n Cancel\n </button>\n <button class=\"proceed-btn\" (click)=\"onSpecialCallChargesAction(true)\">\n Proceed\n </button>\n </div>\n </div>\n</div>\n</div>\n\n<div class=\"min-call-container\" *ngIf=\"isMinimised\">\n <span class=\"material-symbols-outlined fullscreen\" (click)=\"maximiseDialpad()\"> open_in_full </span>\n <div style=\"display: flex; width: 100%\">\n <div>\n <div class=\"min-call-animation\" id=\"call-avatar\">\n <img class=\"min-avatar-img\" [src]=\"callData.img\" alt=\"\" />\n </div>\n </div>\n <div>\n <div class=\"min-callerDetails\">\n <div class=\"name\">\n {{callData.name}}\n </div>\n <p style=\"margin: 0\">{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\n </div>\n </div>\n </div>\n <div class=\"min-btn-container\">\n <div class=\"min-timer\">{{timer}}</div>\n <button class=\"min-call-sec-btn\" (click)=\"toggleMute()\" [disabled]=\"disbaleEndCallBtn || !canSelfToggleMute()\" [title]=\"selfMuteTooltip()\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isSelfEffectivelyMuted()\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isSelfEffectivelyMuted()\"> mic </span>\n </button>\n <button class=\"min-call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n</div>\n<!-- Call Disconnect Modal -->\n<div class=\"custom-modal\" *ngIf=\"showDisconnectModal\">\n <div class=\"modal-content p-3\">\n <div class=\"contacts-header p-0 pb-2\">\n <h4 class=\"title mb-0\">{{selectedConf?.conName || 'Call'}} Disconnect</h4>\n <div class=\"d-flex justify-content-between\">\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDisconnectModal = false\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"#000000\">\n <path\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\n </svg>\n </span>\n </div>\n </div>\n <div class=\"contant-body mb-2\">\n <p class=\"mt-2\">\n Exiting this call will not end the conference. The session will continue, and charges will incur to\n your\n account.\n </p>\n </div>\n <div class=\"button-group\">\n <div class=\"text-start d-flex align-items-center\">\n <label class=\"d-flex align-items-center mb-0 mr-2\">\n <input type=\"checkbox\" [(ngModel)]=\"isReasonChecked\" (ngModelChange)=\"onReasonCheckChanged($event)\" class=\"me-2\"/>\n </label>\n <div class=\"time-picker-24hr\">\n <!-- Hour picker -->\n <div class=\"custom-time-select\" [class.disabled-picker]=\"!isReasonChecked\">\n <div class=\"custom-time-display\" (click)=\"isReasonChecked && toggleHourDropdown()\">\n {{ leaveHour || 'HH' }}\n <span class=\"picker-arrow\">&#9660;</span>\n </div>\n <div class=\"custom-time-options\" *ngIf=\"showHourDropdown\">\n <div class=\"custom-time-option\"\n *ngFor=\"let h of hours\"\n [class.selected]=\"leaveHour === h\"\n (click)=\"selectHour(h)\">{{ h }}</div>\n </div>\n </div>\n <span class=\"time-sep\">:</span>\n <!-- Minute picker -->\n <div class=\"custom-time-select\" [class.disabled-picker]=\"!isReasonChecked\">\n <div class=\"custom-time-display\" (click)=\"isReasonChecked && toggleMinuteDropdown()\">\n {{ leaveMinute || 'MM' }}\n <span class=\"picker-arrow\">&#9660;</span>\n </div>\n <div class=\"custom-time-options\" *ngIf=\"showMinuteDropdown\">\n <div class=\"custom-time-option\"\n *ngFor=\"let m of minutes\"\n [class.selected]=\"leaveMinute === m\"\n (click)=\"selectMinute(m)\">{{ m }}</div>\n </div>\n </div>\n </div>\n </div>\n <button class=\"btn end-btn\" (click)=\"leaveConference()\" [disabled]=\"isReasonChecked && (!leaveHour || !leaveMinute)\">\n Leave\n </button>\n <button class=\"btn end-btn\" (click)=\"endConference()\" *ngIf=\"showEndAllButton\">\n End All\n </button>\n </div>\n </div>\n</div>\n<div class=\"custom-modal\" *ngIf=\"showLeaveConfirmationModal\">\n <div class=\"modal-content warning-modal\">\n <div class=\"warning-icon\">\n <span class=\"material-symbols-outlined\">info</span>\n </div>\n <h3>Leave Conference</h3>\n <p>\n You are about to leave <strong>{{ leaveConfConferenceName }}</strong>. \n Are you sure?\n </p>\n <div class=\"warning-actions\">\n <button class=\"cancel-btn\" (click)=\"cancelLeave()\">Cancel</button>\n <button class=\"proceed-btn\" (click)=\"confirmLeave()\">Leave</button>\n </div>\n </div>\n</div>", styles: [".call-container{width:385px;height:646px!important;margin:auto;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;box-sizing:border-box;position:relative;justify-content:center;align-items:center;z-index:1000;flex-flow:column;overflow-x:hidden;overflow-y:visible}.disabled{opacity:.5!important;pointer-events:none!important}.call-to-text{padding:6px 10px;border:1px solid #c2c2c2;border-radius:20px;font-size:13px}.collops{height:660px!important}.incoming-call-container{flex-flow:row!important}.active-call{width:385px!important}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto 0;border-radius:100%;border:solid 4px #fff;display:flex;align-items:center;justify-content:center}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.call-animation-play{animation:play 3s linear infinite}.call-info-wrapper{height:20px;overflow-y:auto;background:white;transition:height 1s}.open-collops{height:180px!important}.avatar-img{width:94px;height:94px;border-radius:100%}@keyframes play{0%{transform:scale(1)}15%{box-shadow:0 0 0 2px #fff6}25%{box-shadow:0 0 0 4px #fff6,0 0 0 8px #fff3}25%{box-shadow:0 0 0 8px #fff6,0 0 0 16px #fff3}50%{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3}to{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3;transform:scale(1.1);opacity:0}}.callerDetails{margin-top:8px;color:#fff;display:flex;flex-direction:column;align-items:center}.togglearrow-arrow{left:100%;background-color:#fff;width:25px;height:25px;text-align:center;cursor:pointer;border:1px solid #ccc;border-radius:50%;line-height:22px}.togglearrow-arrow.disabled{opacity:.3;cursor:not-allowed;pointer-events:none}.search-bar input{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;outline:none}.togglearrow-arrow.disabled:hover{opacity:.3;cursor:not-allowed}.callerDetails h1{width:260px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:12px 0 0;color:#fff;text-transform:capitalize;text-align:center}.callerDetails h4{margin:0;color:#fff}.tx-black,.title{color:#000!important}.callerDetails p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-btn,.mic-btn{position:relative;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:25px;padding:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226;width:50px;height:50px}.mic-btn{padding:5px;width:37px;height:37px}.receive-btn{background-color:#28a745!important;color:#fff!important}.receive-btn span{color:#fff!important}.scroll-container{width:100%;overflow:hidden;white-space:nowrap;position:relative}.scroll-text{display:inline-block;padding-left:100%;animation:scroll-left 12s linear infinite;font-size:16px}@keyframes scroll-left{0%{transform:translate(0)}to{transform:translate(-100%)}}.call-sec-btn span{color:#cccbcb}.call-btn{width:60px;height:60px;background-color:#fff;border-radius:30px;box-sizing:border-box;border:2px solid white;margin:0 16px}.end-call-btn{background-color:#e14e4e}.end-call-btn span{color:#fff!important}.call-btn span{color:#234de8}.btn-container{display:flex;flex-wrap:wrap;padding:0 30px}.key-btn{width:50px;height:50px;background-color:transparent;text-align:center;box-sizing:border-box;margin:0 18px;font-size:22px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#d3d3d3;cursor:pointer;opacity:.8}.call-action-btns{text-align:center}#call-input{background-color:transparent;border:none;outline:none;text-align:center;color:#fff}.sendDigit{position:relative;text-align:center;width:80%;margin:auto;background-color:#ffffff1a;padding:2px 0;border-radius:3px}.input-clear-btn{position:absolute;right:6px;color:#fff;cursor:pointer}#minimize-btn-div{position:absolute;right:14px;top:12px;z-index:10}.minimize-btn{color:#fff;cursor:pointer}.wave-container{position:absolute;bottom:0;overflow:hidden;width:100%}.waves{width:660px;position:relative;margin-bottom:-7px;height:40px;min-height:40px}.held-call-banner{position:absolute;top:0;left:0;right:0;z-index:2100;box-shadow:0 4px 12px #0000004d;border-radius:0 0 16px 16px;max-height:220px;overflow-y:auto}.held-call-content{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 6px;border-bottom:1px dotted #4b4b4b;border-left:3px solid transparent;transition:background .15s ease,border-left-color .15s ease;cursor:pointer}.held-call-content.held-call-selected{background:rgba(255,255,255,.15);border-left-color:#fff;border-radius:0 6px 6px 0}.held-main-label{font-size:13px;color:#fff;text-transform:uppercase;letter-spacing:.5px}.fa-info{font-size:smaller!important}.held-info{display:flex;align-items:center;gap:10px;flex:1}.hold-icon{font-size:24px;color:#fbbf24}.swap-icon{font-size:24px}.held-caller{display:flex;flex-direction:column;gap:2px}.held-label{font-size:10px;color:#ffffffb3;text-transform:uppercase;letter-spacing:.5px}.held-name{font-size:14px;font-weight:600;color:#fff}.held-number{font-size:13px;font-weight:500;color:#fff}.held-actions{display:flex;gap:8px;align-items:center}.held-btn{padding:6px 16px;border-radius:20px;border:none;font-size:13px;font-weight:600;cursor:pointer;transition:transform .2s,box-shadow .2s}.held-btn:hover{transform:scale(1.05);box-shadow:0 4px 12px #0003}.swap-btn{background:#3b82f6;color:#fff}.merge-btn{background:#10b981;color:#fff}.h-77px{height:77px}.incoming-banners-container{width:100%;padding:5px 8px;height:100%;gap:8px;overflow-y:auto}.call-container-model{width:385px!important;height:646px!important;margin:auto 0 0 1px;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;box-sizing:border-box;position:relative;overflow:hidden;justify-content:center;align-items:center}.incoming-banner{top:0;left:0;width:100%;right:0;background:linear-gradient(135deg,#1e3a8a 0%,#3b82f6 100%);padding:12px 16px;z-index:2000;box-shadow:0 4px 12px #0003;border-radius:16px}.incoming-banner-content{display:flex;align-items:center;justify-content:space-between;gap:12px}.incoming-info{flex:1;display:flex;flex-direction:column;gap:4px}.incoming-label{font-size:11px;color:#fffc;text-transform:uppercase;letter-spacing:.5px}.incoming-caller{display:flex;flex-direction:column;gap:2px}.caller-name{font-size:15px;font-weight:600;color:#fff}.caller-number{font-size:13px;color:#ffffffe6}.incoming-actions{display:flex;gap:8px;align-items:center}.banner-btn{width:44px;height:44px;border-radius:50%;border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:transform .2s}.banner-btn:hover{transform:scale(1.1)}.banner-btn .material-symbols-outlined{font-size:20px}.accept-btn{background:#10b981}.accept-btn .material-symbols-outlined{color:#fff}.reject-btn{background:#ef4444}.reject-btn .material-symbols-outlined{color:#fff}.contacts-panel{position:absolute;top:0;bottom:12px;width:340px;background:#ffffff;border-radius:16px;box-shadow:0 10px 25px #00000026;display:flex;flex-direction:column;overflow:hidden;height:40.4rem;left:24.1rem;z-index:1000000;color:#111827!important}.contacts-header{height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;border-bottom:1px solid #f0f0f0;color:#111827!important}.modal-content .contacts-header{height:40px}.search-contacts-list{max-height:196px;overflow:auto;position:absolute;width:91%;background:white;z-index:1000;box-shadow:0 4px 8px #0003,0 6px 20px #00000030;border-radius:0 10px 10px}.contant-body p{font-size:14px;color:#5f6061!important}.contacts-header .title{font-weight:600;color:#111827!important}.contacts-header .back,.contacts-header .search{color:#9aa0a6;cursor:pointer}.disabled{opacity:.5;pointer-events:none}.contacts-list{padding:8px 8px 12px;overflow-y:auto}.contact-item{display:flex;align-items:center;padding:10px 8px;border-radius:10px}.contact-item:hover{background:#f7f9fc}.contact-avatar{width:37px;height:37px;border-radius:50%;object-fit:cover;margin-right:12px}.contact-info{flex:1;min-width:0;overflow:hidden}.contact-name{font-weight:600;color:#111827;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.contact-title{font-size:12px;color:#6b7280}.contact-call-btn{display:inline-flex;align-items:center;gap:6px;background:#234de8;color:#fff;border:none;border-radius:16px;padding:8px;cursor:pointer}.contact-add-btn{background-color:#2ecc71!important}.conference-hold-contact{display:inline-flex;align-items:center;gap:5px;background:#727070;color:#fff;border:none;border-radius:50%;padding:7px;cursor:pointer}.conference-hold-contact.on-hold{background:#28a745!important;color:#fff}.user-info-section{width:100%;height:100%;overflow-y:auto;overflow-x:hidden!important}.user-info-section::-webkit-scrollbar{display:none}.toggle-btn{cursor:pointer}.text-container{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;transition:all .3s ease}.mute-incoming-row{display:flex;align-items:center;justify-content:center;gap:8px;margin:0 0 10px}.mute-incoming-label{font-size:11px;color:#fff}.switch{position:relative;display:inline-block;width:38px;height:19px;flex-shrink:0}.switch-slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;border-radius:22px;transition:.3s}.close-info-panel-section{width:100%;height:20px}.close-info-panel-section .material-symbols-outlined{font-size:12px;cursor:pointer}.c2c-title{color:#fff;white-space:normal;word-break:break-word;line-height:1.4}.switch-slider:before{content:\"\";position:absolute;height:14px;width:15px;left:3px;bottom:3px;background-color:#fff;border-radius:50%;transition:.3s}.switch input:checked+.switch-slider{background-color:#2ecc71}.switch input:checked+.switch-slider:before{transform:translate(18px)}.text-container.expanded{-webkit-line-clamp:unset}.userName{font-family:FontAwesome}.subject-text{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden}.conference-contact{display:inline-flex;align-items:center;gap:5px;background:#e14e4e;color:#fff;border:none;border-radius:50%;padding:7px;cursor:pointer}.organizer-label{padding:1px 5px;font-size:11px;border-radius:10px;border:1px solid #a0a0a0;margin-top:2px;background:#fcfcfc;color:#000}.custom-modal{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;align-items:center;z-index:10000001;border-radius:21px}.modal-content{background:#ffffff;padding:25px;border-radius:8px;width:350px;text-align:center}.title{margin-bottom:15px;color:#d9534f}.message{margin-bottom:20px}.button-group{display:flex;justify-content:space-between}.btn{padding:8px 15px;border:none;border-radius:5px;cursor:pointer;font-weight:500}.end-btn{background-color:#dc3545;color:#fff;display:flex;align-items:center;font-size:13px}.leave-btn{background-color:#007bff;color:#fff}.contact-call-btn .material-symbols-outlined{font-size:18px;color:#fff}.contact-call-btn .label{font-size:12px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}.animated-margin{transition:margin-top .5s ease}app-incoming-call{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1001}.min-call-container{width:320px;height:124px;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;flex-direction:column;box-sizing:border-box;position:relative;overflow:hidden;margin:auto;align-items:center;padding:12px 16px;color:#fff}.min-call-animation{background:#fff;width:48px;height:48px;position:relative;margin:0 12px 0 auto;border-radius:100%;border:solid 2px #fff}.min-avatar-img{width:46px;height:46px;border-radius:100%;position:absolute;left:0;top:0}.border-radius-50{border-radius:50%}.min-callerDetails{color:#fff;display:flex;flex-direction:column;align-items:flex-start}.name{width:170px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:20px;margin:0;color:#fff}.min-callerDetails p{margin:0;color:#fff}.min-btn-container{position:relative;display:flex;width:100%;justify-content:flex-start;align-items:center;margin-top:6px}.min-call-sec-btn{width:40px;height:40px;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:20px;display:flex;align-items:center;justify-content:center;margin-right:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226}.min-call-sec-btn span{color:#cccbcb}.min-call-btn{width:40px;height:40px;border-radius:20px;box-sizing:border-box;border:2px solid white;display:flex;align-items:center;justify-content:center}.fullscreen{position:absolute;right:18px;top:14px;color:#e8e8e8;font-size:18px;cursor:pointer}.btn-container{display:flex;flex-wrap:wrap;padding:0 24px}.dial-btn{width:40px;height:40px;background-color:transparent;text-align:center;box-sizing:border-box;margin:4px 25px;font-size:24px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#b5b5b5;cursor:pointer}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.min-timer{width:50px;font-size:18px;margin-right:10px;border-radius:4px;height:35px;display:flex;align-items:center}.record-action-btns{display:flex;flex-direction:column;align-items:center;margin-top:35px}.record-btn-container{position:relative}.record-btn{border:none;border-radius:50%;width:50px;height:50px;display:flex;align-items:center;justify-content:center;cursor:pointer;margin:0 5px;position:relative;overflow:hidden}.record-btn.start-stop .recording-icon{width:50%;height:50%;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.record-btn.start-stop.recording .recording-icon{background-color:#000}.record-btn.start-stop.recording{border:3px solid #000}.record-btn.start-stop.stopped .recording-icon{background-color:red;border:3px solid #ff0000;border-radius:50%;position:absolute}.record-btn.start-stop.stopped{border:3px solid #ff0000}.record-btn.start-stop.stopped .recording-icon{width:40%;height:40%;border-radius:0;background-color:red}.pause-resume-btns{display:flex;flex-direction:column;align-items:center;margin-top:10px}.record-btn.pause-resume{border:none;border-radius:50%;width:50px;height:50px;background:white;display:flex;align-items:center;justify-content:center;margin:5px 0}.record-btn.pause-resume .material-symbols-outlined{font-size:20px;color:#000}.timer-display{font-size:1.2em;margin-top:10px;color:#000}.w-40{width:40%}.w-60{width:60%}.callToNum{color:#fff;font-weight:400;text-align:center}.callToNum span{font-weight:600}.conference-call-view{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;width:100%;padding:12px 16px 35px;color:#fff;height:100%}.conf-heading{display:flex;align-items:center;gap:8px;margin-top:45px}.conf-icon{color:#4579aa;font-size:32px;width:50px;height:50px;border:1px solid gray;border-radius:50%;display:flex;align-items:center;justify-content:center;background:#e1e1e1}.conf-title{font-weight:600;font-size:20px}.conf-name{margin-top:10px;font-size:17px;font-weight:600;text-align:center}.conf-timer{margin-top:4px;font-size:12px;opacity:.9}.conf-record{margin-top:14px}.record-stop-btn{width:44px;height:44px;border-radius:50%;border:none;background:#fff;display:flex;align-items:center;justify-content:center}.record-stop-btn .material-symbols-outlined{color:#e14e4e;font-size:28px}.conf-remove{margin-top:8px}.remove-btn{background:#ff0000!important;color:#fff;border:none;border-radius:6px;padding:6px 12px;font-size:12px;width:82px!important;height:auto}.conf-actions{margin-top:14px;display:flex;align-items:center;justify-content:center;gap:18px}.circle-btn{width:56px;height:56px;border-radius:50%;border:none;background:#000;display:flex;align-items:center;justify-content:center}.circle-btn .material-symbols-outlined{color:#fff;font-size:24px}.circle-btn.active{opacity:.85}.conf-end{margin-top:16px}.circle-btn.danger{background:#e14e4e}.circle-btn.danger .material-symbols-outlined{color:#fff}.warning-modal{background:white;width:360px;border-radius:18px;padding:24px;text-align:center;box-shadow:0 10px 30px #00000040}.warning-icon{margin-bottom:12px}.warning-icon .material-symbols-outlined{font-size:48px;color:#f59e0b}.warning-modal h3{margin-bottom:12px;font-size:20px;font-weight:600;color:#111827!important}.warning-modal p{color:#555!important;font-size:14px;line-height:1.5;margin-bottom:24px}.warning-modal p strong{color:#111827!important}.warning-actions{display:flex;justify-content:center;gap:12px}.cancel-btn,.proceed-btn{border:none;padding:10px 18px;border-radius:8px;cursor:pointer;font-weight:600}.cancel-btn{background:#e5e7eb;color:#111827}.proceed-btn{background:#234de8;color:#fff}.time-picker-24hr{display:flex;align-items:center;gap:4px}.time-sep{font-weight:700;font-size:16px;color:#333}.custom-time-select{position:relative;width:58px;-webkit-user-select:none;user-select:none}.custom-time-select.disabled-picker{opacity:.45;pointer-events:none}.custom-time-display{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;border:1px solid #ced4da;border-radius:4px;background:#fff;font-size:13px;cursor:pointer;white-space:nowrap;color:#333!important}.custom-time-display:hover{border-color:#234de8}.picker-arrow{font-size:9px;margin-left:4px;color:#666}.custom-time-options{position:fixed;background:#fff;border:1px solid #ced4da;border-radius:4px;max-height:160px;overflow-y:auto;z-index:99999999;min-width:58px;box-shadow:0 4px 12px #00000026}.custom-time-option{padding:5px 10px;font-size:13px;cursor:pointer;text-align:center;color:#333}.custom-time-option:hover{background:#e8eeff;color:#234de8}.custom-time-option.selected{background:#234de8;color:#fff;font-weight:600}.dialpad-alerts{position:absolute;left:50%;transform:translate(-50%);width:calc(100% - 32px);z-index:9999999}.normal-call-alert{top:78px}.conference-alert{top:145px}.dialbox-pop1{background:#dff6dd!important;color:#1d4d1d!important;border-radius:10px;padding:10px 14px;font-size:14px;box-shadow:0 4px 12px #00000040;border:1px solid #b7dfc3}.btn-disc{border:none;background:transparent;color:#6b7280!important;font-size:13px;font-weight:500}.connecting-overlay{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:16px 0 24px}.connecting-text{color:#ffffffe6;font-size:15px;font-weight:500;letter-spacing:.5px;margin:0}.connecting-dots{display:flex;gap:8px;align-items:center}.connecting-dots span{display:inline-block;width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.85);animation:connecting-bounce 1.2s infinite ease-in-out}.connecting-dots span:nth-child(1){animation-delay:0s}.connecting-dots span:nth-child(2){animation-delay:.2s}.connecting-dots span:nth-child(3){animation-delay:.4s}@keyframes connecting-bounce{0%,80%,to{transform:scale(.6);opacity:.4}40%{transform:scale(1.2);opacity:1}}.connecting-wrapper{display:flex;align-items:center;font-size:13px;color:#4caf50;margin-top:4px;font-weight:500}.participant-list-title,.onHold-text{color:#000}.ringing-text,.onHold-text{margin-right:2px;font-size:11px}.held-actions .connecting-wrapper{color:#fff}.dots span{animation:blink 1.4s infinite;opacity:0;font-size:16px}.dots span:nth-child(1){animation-delay:0s}.dots span:nth-child(2){animation-delay:.2s}.dots span:nth-child(3){animation-delay:.4s}@keyframes blink{0%{opacity:0}50%{opacity:1}to{opacity:0}}.loader-wrapper.outgoing-call-loader{position:absolute;inset:0;z-index:100;display:flex;align-items:center;justify-content:center}.panel-loader-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffffb3;display:flex;justify-content:center;align-items:center;z-index:10000009}.settings-icon{cursor:pointer;font-size:24px;color:#555;position:relative;top:5px;right:2px}.settings-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:1000001;display:flex;align-items:flex-start;justify-content:flex-end}.settings-drawer{background:#fff;width:100%;max-width:100%;height:100%;padding:1.5rem 1rem;overflow-y:auto;box-sizing:border-box;transform:translate(100%);animation:slideInFromRight .3s forwards}@keyframes slideInFromRight{to{transform:translate(0)}}.settings-header{display:flex;justify-content:space-between;align-items:center;font-size:1.2rem;font-weight:600;padding-bottom:.75rem;border-bottom:1px solid #eee}.settings-header span:first-child{cursor:pointer}.settings-body{margin-top:1.5rem}.setting-item{display:flex;justify-content:space-between;align-items:center;padding:.75rem 0;gap:1rem}.setting-label{flex:1}.setting-label span{font-weight:500}.setting-label svg{width:15px;height:15px;color:#393939;flex-shrink:0}.setting-label small{display:block;font-size:.75rem;color:#666;margin-top:.15rem}.setting-group h6{font-weight:600;color:#888;font-size:.75rem;letter-spacing:.5px;margin:1rem 0 .5rem}hr{margin:.5rem 0;border-color:#f0f0f0}.switch{position:relative;display:inline-block;width:44px;height:24px;flex-shrink:0}.switch input{opacity:0;width:0;height:0}.switch-slider{position:absolute;cursor:pointer;inset:0;background:#ccc;border-radius:24px;transition:.3s}.switch-slider:before{content:\"\";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background:white;border-radius:50%;transition:.3s}.switch input:checked+.switch-slider{background:#007bff}.switch input:checked+.switch-slider:before{transform:translate(20px)}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
4935
5108
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CallProgressComponent, decorators: [{
4936
5109
  type: Component,
4937
- args: [{ selector: 'lib-call-progress', template: "<div class=\"d-flex\">\r\n <div class=\"call-container\" *ngIf=\"!isMinimised && currentCallList?.length\"\r\n [ngClass]=\"{'collops': isCollops, 'incoming-call-container': isClickExpand, 'contacts-open': showContactsPanel }\">\r\n <div class=\"loader-wrapper outgoing-call-loader\"\r\n *ngIf=\"showNewCallLoader\">\r\n <div class=\"active-call\" style=\"display: flex; flex-direction: column; position: relative;\">\r\n <div class=\"call-animation call-animation-play\">\r\n <img class=\"avatar-img\" [src]=\"newCallLoaderData?.img || 'assets/images/user.jpg'\" alt=\"\" />\r\n </div>\r\n <div class=\"callerDetails\">\r\n <h1 style=\"margin-top: 8px;\">Connecting...</h1>\r\n <p style=\"text-transform: capitalize;\">{{ newCallLoaderData?.name || newCallLoaderData?.phone || 'Unknown' }}</p>\r\n </div>\r\n \r\n <div class=\"call-action-btns\">\r\n <div class=\"d-flex justify-content-center\">\r\n <button class=\"call-btn end-call-btn\" disabled (click)=\"endCall()\" style=\"visibility: hidden;\">\r\n <span class=\"material-symbols-outlined\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"dialpad-alerts\"\r\n [ngClass]=\"{\r\n 'conference-alert': isConference && currentCall?.isConference,\r\n 'normal-call-alert': !isConference\r\n }\" *ngIf=\"callNumberToast.show\">\r\n <div class=\"dialbox-pop1 alert fade show\"\r\n [ngClass]=\"callNumberToast.type\"\r\n role=\"alert\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <div class=\"flex-grow-1 text-left\">\r\n You'r calling\r\n <strong>{{callNumberToast.displayNum}}</strong>\r\n </div>\r\n <div class=\"text-right\">\r\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelCallToast()\"> Cancel Call </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- All type Call Hold list -->\r\n <div class=\"held-call-banner\"\r\n *ngIf=\"(currentCallList.length > 1 && !!currentCall && ((isConferenceCallHold || isConference) || !isConference)) || !isAllAccepted\">\r\n <ng-container *ngFor=\"let conf of currentCallList\">\r\n <div class=\"held-call-content\" *ngIf=\"!conf?.isAcceptCall && currentCallList.length > 1 && deviceNumberList.includes(conf?.to) && conf?.isNotification\"\r\n [ngClass]=\"{'held-call-selected': selectedUserInfo?.participantId && selectedUserInfo?.participantId === conf?.participantId}\"\r\n (click)=\"conf?.businessNumber ? toggleC2CInfoPanel(conf) : null\"\r\n [ngStyle]=\"{'cursor': conf?.businessNumber ? 'pointer' : 'default'}\">\r\n <div class=\"held-info\">\r\n <div class=\"img\">\r\n <img class=\"avatar-img-wrapper border-radius-50\" [src]=\"conf?.img || 'assets/images/user.jpg'\" alt=\"\" width=\"35\" height=\"35\" />\r\n </div>\r\n <div class=\"held-caller\" *ngIf=\"!conf?.businessNumber\">\r\n <span class=\"held-label\">{{conf?.from}}</span>\r\n <span class=\"held-name\">{{conf?.fromName}}</span>\r\n </div>\r\n <div class=\"held-caller\" *ngIf=\"conf?.businessNumber\">\r\n <span class=\"held-main-label\">Call from C2C:</span>\r\n <span class=\"held-label\" ><span [title]=\"conf?.sourceName\">{{ truncateText(conf?.sourceName, 10) }}</span>|\r\n <span [title]=\"conf?.pointName\">{{ truncateText(conf?.pointName, 10) }}</span></span>\r\n <span class=\"held-label\">{{ truncateText(conf?.name, 26) }}</span>\r\n </div>\r\n </div>\r\n <div class=\"held-actions\">\r\n <ng-container *ngIf=\"isConnectingIncomingCallId == conf?.id\">\r\n <div class=\"connecting-wrapper mr-2\">\r\n <span class=\"ringing-text\">Connecting</span>\r\n <span class=\"dots\">\r\n <span>.</span>\r\n <span>.</span>\r\n <span>.</span>\r\n </span>\r\n </div>\r\n </ng-container>\r\n <button class=\"conference-hold-contact receive-btn\" (click)=\"waitingCallAccept(conf)\" [disabled]=\"isConnecting || isIncomingCallBtnDisable\" *ngIf=\"isConnectingIncomingCallId !== conf?.id\">\r\n <span class=\"material-symbols-outlined\"> call </span>\r\n </button>\r\n <button class=\"conference-contact\">\r\n <span class=\"material-symbols-outlined\" title=\"Call End\" (click)=\"onRejectCall(conf); $event.stopPropagation();\"> call_end </span>\r\n </button>\r\n <div *ngIf=\"conf?.businessNumber\" class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"toggleC2CInfoPanel(conf)\">\r\n <i class=\"fa fa-info\"></i>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngFor=\"let conf of conferenceCallList\">\r\n <div class=\"held-call-content\" *ngIf=\"(conf?.isConferenceHold || (showNewCallLoader && isConferenceCallHold)) && (conferenceCallList.length > 1 || showNewCallLoader)\"\r\n [ngClass]=\"{'held-call-selected': conf?.isBusinessNumber && selectedUserInfo?.participantId === conf?.businessParticipantId && isClickExpand}\"\r\n (click)=\"conf?.isBusinessNumber ? toggleC2CInfoPanel(conf) : null\"\r\n [ngStyle]=\"{'cursor': conf?.isBusinessNumber ? 'pointer' : 'default'}\">\r\n <div class=\"held-info\">\r\n <span class=\"material-symbols-outlined hold-icon\">pause_circle</span>\r\n <div class=\"held-caller\">\r\n <span class=\"held-label\">Hold</span>\r\n <span class=\"held-name\">{{conf?.callLabel}}</span>\r\n </div>\r\n </div>\r\n <div class=\"held-actions\">\r\n <button class=\"conference-hold-contact\" [ngClass]=\"{ 'on-hold': conf?.isConferenceHold }\"\r\n (click)=\"swapCalls(conf,true)\" [disabled]=\"isHoldBtnDisable\">\r\n <span *ngIf=\"conf?.isConferenceHold\" class=\"material-symbols-outlined\" [title]=\"'Resume'\"> resume </span>\r\n </button>\r\n <button class=\"conference-contact\" (click)=\"endConfereneceCall(conf); $event.stopPropagation();\">\r\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\r\n </button>\r\n <div class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"toggleContactsPanel(conf)\">\r\n <i class=\"fa fa-angle-right\"></i>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- For single incoming call -->\r\n <div class=\"h-100 py-5\" style=\"display: flex; flex-direction: column;\"\r\n *ngIf=\"currentCallList.length === 1 && currentCallList[0]?.isIncomingCall && !currentCallList[0]?.isAcceptCall\">\r\n <!-- <div class=\"callToNum\">Incoming call on <br /><span>{{currentCallList[0]?.to || 'Unknown Number'}}</span>\r\n </div> -->\r\n <div class=\"callToNum\">\r\n <ng-container *ngIf=\"currentCallList[0]?.businessNumber; else normalCall\">\r\n C2C CALL\r\n <br />\r\n <span> From : {{ currentCallList[0]?.sourceName }} | {{ currentCallList[0]?.pointName }} </span>\r\n </ng-container>\r\n\r\n <ng-template #normalCall>\r\n Incoming call on\r\n <br />\r\n <span>{{ currentCallList[0]?.to || 'Unknown Number' }}</span>\r\n </ng-template>\r\n </div>\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" [src]=\"incomingFromImage || 'assets/images/user.jpg'\" alt=\"\" width=\"120\" />\r\n </div>\r\n <div class=\"callerDetails\" *ngIf=\"!currentCallList[0]?.businessNumber\">\r\n <h1>{{ currentCallList[0]?.name ? currentCallList[0]?.name : currentCallList[0]?.phone || 'Unknown Number' }}</h1>\r\n <p *ngIf=\"!!currentCallList[0]?.name\">{{ currentCallList[0]?.phone }}</p>\r\n </div>\r\n <div class=\"callerDetails\" *ngIf=\"currentCallList[0]?.businessNumber\">\r\n <p *ngIf=\"!!currentCallList[0]?.name\">{{ truncateText(currentCallList[0]?.name, 45) }}</p>\r\n <p >{{ currentCallList[0]?.number }}</p>\r\n </div>\r\n <!-- Connecting overlay (shown after accept btn click, hidden on API response) -->\r\n <div class=\"connecting-overlay mt-auto\" *ngIf=\"isConnectingIncomingCallId == currentCallList[0]?.id\">\r\n <div class=\"connecting-dots\">\r\n <span></span><span></span><span></span>\r\n </div>\r\n <p class=\"connecting-text\">Connecting...</p>\r\n </div>\r\n\r\n <div class=\"call-action-btns mt-auto\" *ngIf=\"isConnectingIncomingCallId != currentCallList[0]?.id\">\r\n <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected\"\r\n [disabled]=\"isIncomingCallBtnDisable\" (click)=\"acceptIncomingCall(currentCallList[0])\">\r\n <span class=\"material-symbols-outlined\"> call </span>\r\n </button>\r\n <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"onRejectCall(currentCallList[0])\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- For single active call -->\r\n <div *ngIf=\"(!isConference || isConferenceCallHold) && (!!currentCall?.id && !currentCall?.isConference) && currentCall?.isAcceptCall\"\r\n [ngStyle]=\"{'display': 'flex', 'flex-direction': 'column', 'position': 'relative'}\" class=\"active-call\">\r\n <div *ngIf=\"currentCall?.businessNumber;\" class=\"callToNum\">\r\n C2C CALL\r\n <br />\r\n <span> From : {{ currentCall?.userInfoId?.sourceName }} | {{ currentCall?.userInfoId?.pointName }} </span>\r\n </div>\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" *ngIf=\"!currentCall?.client\"\r\n [src]=\"currentCall?.direction == 'outgoing-call' ? currentCall?.toImage || 'assets/images/user.jpg' : currentCall?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n <img class=\"avatar-img\" *ngIf=\"currentCall?.client\"\r\n [src]=\"currentCall?.direction == 'outgoing-call' ? currentCall?.fromImage || 'assets/images/user.jpg' : currentCall?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n </div>\r\n <div class=\"callerDetails\">\r\n <!-- C2C Business Call -->\r\n <ng-container *ngIf=\"currentCall?.businessNumber; else normalCall\">\r\n <h1>{{ currentCall?.userInfoId?.name || 'Unknown' }}</h1>\r\n <p>{{ currentCall?.userInfoId?.number || currentCall?.from || 'Unknown' }}</p>\r\n </ng-container>\r\n\r\n <!-- Normal Call -->\r\n <ng-template #normalCall>\r\n <h1 *ngIf=\"!currentCall?.client\"\r\n [ngStyle]=\"{'margin-top': showKeypad ? '0':'8px'}\">\r\n {{ currentCall?.direction == 'outgoing-call'\r\n ? currentCall?.toName || outgoingContactName || 'Unknown'\r\n : currentCall?.fromName || 'Unknown' }}\r\n </h1>\r\n <h1 *ngIf=\"currentCall?.client\"\r\n [ngStyle]=\"{'margin-top': showKeypad ? '0':'8px'}\">\r\n {{ currentCall?.direction == 'outgoing-call'\r\n ? currentCall?.fromName || 'Unknown'\r\n : currentCall?.toName || outgoingContactName || 'Unknown' }}\r\n </h1>\r\n <p *ngIf=\"!currentCall?.client\">\r\n {{ currentCall?.direction == 'outgoing-call'\r\n ? currentCall?.to\r\n : currentCall?.from }}\r\n </p>\r\n <p *ngIf=\"currentCall?.client\">\r\n {{ currentCall?.direction == 'outgoing-call'\r\n ? currentCall?.from\r\n : currentCall?.to }}\r\n </p>\r\n </ng-template>\r\n <!-- <h1 *ngIf=\"!currentCall?.client\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall?.direction == 'outgoing-call' ? currentCall?.toName || outgoingContactName || 'Unknown' :\r\n currentCall?.fromName || 'Unknown'}}</h1>\r\n <h1 *ngIf=\"currentCall?.client\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall?.direction == 'outgoing-call' ? currentCall?.fromName || 'Unknown' :\r\n currentCall?.toName || 'Unknown'}}</h1>\r\n <p *ngIf=\"!currentCall?.client\">{{ currentCall?.direction == 'outgoing-call' ? currentCall?.to || 'Unknown' : currentCall?.from || 'Unknown'}}</p>\r\n <p *ngIf=\"currentCall?.client\">{{ currentCall?.direction == 'outgoing-call' ? currentCall?.from || 'Unknown' : currentCall?.to || 'Unknown'}}</p> -->\r\n <h4 style=\"margin-top: 4px\">{{ timer}}</h4>\r\n </div>\r\n <div class=\"record-action-btns\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\r\n <div class=\"record-btn-container\">\r\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\r\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording, 'disabled': userSettingInfo?.callRecording == 'N'}\" (click)=\"toggleRecording()\"\r\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"!currentCall?.isAcceptCall || userSettingInfo?.callRecording == 'N'\">\r\n <span class=\"recording-icon\"></span>\r\n </button>\r\n <div class=\"pause-resume-btns\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\" (click)=\"pauseRecording()\">\r\n <span class=\"material-symbols-outlined\"> pause </span>\r\n </button>\r\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"isRecording\" class=\"timer-display\">\r\n {{ getFormattedTime() }}\r\n </div>\r\n </div>\r\n <!-- Mute/unmute incoming call -->\r\n <div class=\"mute-incoming-row\" *ngIf=\"currentCall?.isAcceptCall && !showKeypad\">\r\n <span class=\"mute-incoming-label\">Mute incoming calls</span>\r\n <label class=\"switch mb-0\" title=\"Silence the ringtone of new incoming calls during this call\">\r\n <input type=\"checkbox\" [checked]=\"twilioService.isIncomingMuted\" (change)=\"toggleMuteIncomingCall()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"showKeypad\" class=\"sendDigit\">\r\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\" (keyup)=\"onCallInputEnter($event)\">\r\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\" (click)=\"clearInputs()\">close_small</span>\r\n </div>\r\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\r\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\r\n {{key.num}}\r\n <span class=\"btn-albhabets\">{{key.text ? key.text : '&nbsp;'}}</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"call-action-btns\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '723x'}\">\r\n <div class=\"flex align-items-center justify-content-evenly mb-3\">\r\n <button class=\"call-sec-btn mr-3\" [disabled]=\"!currentCall?.isAcceptCall || !canSelfToggleMute()\" [title]=\"selfMuteTooltip()\" (click)=\"toggleMute()\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isSelfEffectivelyMuted()\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isSelfEffectivelyMuted()\"> mic </span>\r\n </button>\r\n <button class=\"call-sec-btn mr-3\" [disabled]=\"!currentCall?.isAcceptCall\">\r\n <span class=\"material-symbols-outlined\" (click)=\"toggleKeypad()\"> transition_dissolve\r\n </span>\r\n </button>\r\n <button class=\"call-sec-btn\" [disabled]=\"!currentCall?.isAcceptCall\"\r\n (click)=\"toggleContactsPanel(currentCall)\">\r\n <span class=\"material-symbols-outlined\"> groups_2 </span>\r\n </button>\r\n </div>\r\n <div>\r\n <button class=\"call-btn end-call-btn\" [disabled]=\"!currentCall?.isAcceptCall\" (click)=\"endCall(false, currentCall)\">\r\n <span class=\"material-symbols-outlined\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- conference call view -->\r\n <div class=\"conference-call-view\" *ngIf=\"isConference\">\r\n <div class=\"conf-heading\">\r\n <span class=\"conf-icon material-symbols-outlined\"> groups </span>\r\n <span class=\"conf-title\">{{currentConferenceCall?.callLabel || 'Conference Call'}}</span>\r\n </div>\r\n <div class=\"scroll-container\">\r\n <div class=\"scroll-text conf-name\">\r\n <ng-container *ngFor=\"let call of currentCallList; let i = index\">\r\n <ng-container *ngIf=\"!call?.isConferenceHold\">\r\n <span *ngIf=\"shouldShowSeparator(i)\"> & </span>\r\n <span *ngIf=\"call?.client\">\r\n <ng-container *ngIf=\"!isSelfNumber(call) else selfNumber\">\r\n <span>{{call?.direction == 'outgoing-call' ? call?.fromName || call?.from :\r\n call?.toName || call?.to}}</span>\r\n </ng-container>\r\n <ng-template #selfNumber>\r\n <span>You</span>\r\n </ng-template>\r\n </span>\r\n <span *ngIf=\"!call?.client\">{{call?.direction == \"outgoing-call\" ? call?.toName || call?.to : call?.fromName || call?.from || 'Unknown number'}}</span>\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <div class=\"conf-timer\">{{ currentConferenceCall?.timer || timer }}</div>\r\n <div class=\"record-action-btns mt-auto\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\r\n <div class=\"record-btn-container\" >\r\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\" [disabled]=\"userSettingInfo.callRecording == 'N'\"\r\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording, 'disabled': userSettingInfo?.callRecording == 'N'}\" (click)=\"toggleRecording()\"\r\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\">\r\n <span class=\"recording-icon\"></span>\r\n </button>\r\n <div class=\"pause-resume-btns\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\" (click)=\"pauseRecording()\">\r\n <span class=\"material-symbols-outlined\"> pause </span>\r\n </button>\r\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"isRecording\" class=\"timer-display\">\r\n {{ getFormattedTime() }}\r\n </div>\r\n </div>\r\n <!-- Mute/unmute incoming call -->\r\n <div class=\"mute-incoming-row\" *ngIf=\"currentCall?.isAcceptCall && !showKeypad\">\r\n <span class=\"mute-incoming-label\">Mute incoming calls</span>\r\n <label class=\"switch mb-0\" title=\"Silence the ringtone of new incoming calls during this call\">\r\n <input type=\"checkbox\" [checked]=\"twilioService.isIncomingMuted\" (change)=\"toggleMuteIncomingCall()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n <div *ngIf=\"showKeypad\" class=\"sendDigit mt-2\">\r\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\" (keyup)=\"onCallInputEnter($event)\">\r\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\" (click)=\"clearInputs()\">close_small</span>\r\n </div>\r\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\r\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\r\n {{key.num}}\r\n <span class=\"btn-albhabets\">{{key.text ? key.text : '&nbsp;'}}</span>\r\n </div>\r\n </div>\r\n <div class=\"conf-actions\">\r\n <button class=\"circle-btn\" [ngClass]=\"{'active': isSelfEffectivelyMuted()}\" [disabled]=\"!canSelfToggleMute()\" [title]=\"selfMuteTooltip()\" (click)=\"toggleMute(true)\">\r\n <span class=\"material-symbols-outlined\"> {{ isSelfEffectivelyMuted() ? 'mic_off' : 'mic' }} </span>\r\n </button>\r\n <button class=\"circle-btn\" (click)=\"toggleKeypad()\">\r\n <span class=\"material-symbols-outlined\"> transition_dissolve </span>\r\n </button>\r\n <button class=\"circle-btn\" (click)=\"toggleContactsPanel(currentCall)\">\r\n <span class=\"material-symbols-outlined\"> groups_2 </span>\r\n </button>\r\n </div>\r\n <div class=\"conf-end\">\r\n <button class=\"circle-btn danger\" (click)=\"endConfereneceCall(currentConferenceCall?.participants[0])\">\r\n <span class=\"material-symbols-outlined\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"wave-container\">\r\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\r\n <defs>\r\n <path id=\"gentle-wave\"\r\n d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n </div>\r\n\r\n <!-- Incoming call user details shown in model -->\r\n <div class=\"call-container-model p-3 text-white model-content call-container\" *ngIf=\"isClickExpand\">\r\n <div class=\"close-info-panel-section\">\r\n <div class=\"d-flex justify-content-between\" *ngIf=\"currentConferenceCall?.conferenceId != selectedUserInfo?.conferenceId && newIncomingCallsList?.length > 1\">\r\n <p></p>\r\n <span class=\"material-symbols-outlined dial-close-btn \" (click)=\"onCloseC2CInfoPanel()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\r\n fill=\"#ffffff\">\r\n <path\r\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"mb-2 user-info-section\">\r\n <div class=\"text-center my-3\">\r\n <h3 class=\"text-white\">C2C CALL : {{selectedUserInfo?.sourceName}} | {{selectedUserInfo?.pointName}}</h3>\r\n </div>\r\n <div class=\"mb-3\">\r\n <h5 class=\"text-white mb-1\">Name:</h5>\r\n <h4 class=\"text-white userName\">{{selectedUserInfo?.name}}</h4>\r\n </div>\r\n <div class=\"f-13\">\r\n <div class=\"row mb-3\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"mb-1\">Extension:</div>\r\n <div class=\"ml-2\">{{selectedUserInfo?.extension}}</div>\r\n </div>\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"mb-1\">Number:</div>\r\n <div class=\"\">{{selectedUserInfo?.number}}</div>\r\n </div> \r\n </div>\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 mb-2\">\r\n <div class=\"me-2\">Email: </div>\r\n <div>{{selectedUserInfo?.email}}</div>\r\n </div>\r\n </div>\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 mb-2\">\r\n <div class=\"me-2\">Subject:</div>\r\n <div class=\"ml-2 subject-text\" title=\"{{selectedUserInfo?.subject}}\">\r\n {{selectedUserInfo?.subject}}</div>\r\n </div>\r\n </div>\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 mb-2\">\r\n <div class=\"me-2 mb-1\">Image:</div>\r\n <div class=\"text-ellipsis\">\r\n <ng-container\r\n *ngIf=\"selectedUserInfo?.image && selectedUserInfo?.image !== '-'; else noImage\">\r\n <img src=\"{{selectedUserInfo?.image}}\" alt=\"\" width=\"150\" class=\"ml-2\" />\r\n </ng-container>\r\n <ng-template #noImage>\r\n <span class=\"ml-2\">No Image Available</span>\r\n </ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\" mb-4\">\r\n <div class=\"\">\r\n <div class=\"mb-1\">Message:</div>\r\n <div>\r\n <div class=\"text-container\" [class.expanded]=\"isExpanded\">{{selectedUserInfo?.message}}\r\n </div>\r\n <small class=\"toggle-btn\" *ngIf=\"showButton\" (click)=\"toggleText()\">{{ isExpanded ? 'See\r\n less' : 'See more' }}</small>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- contact list panel -->\r\n <div class=\"contacts-panel\" *ngIf=\"showContactsPanel && !showNewCallLoader\">\r\n <div class=\"panel-loader-overlay p-3 text-center\" *ngIf=\"isParticipantPanelLoading\">\r\n <div class=\"spinner-border text-secondary\" role=\"status\">\r\n <span class=\"sr-only\">Loading...</span>\r\n </div>\r\n <p class=\"mt-2\"></p>\r\n </div>\r\n <div class=\"contacts-header\">\r\n <div class=\"participant-list-title\">\r\n {{ selectedConfName || 'Conference' }} Participants\r\n <!-- <ng-container *ngIf=\"totalParticipantsCount < 3; else confHeading\">\r\n Call Participants\r\n </ng-container>\r\n <ng-template #confHeading>\r\n </ng-template> -->\r\n </div>\r\n <div class=\"d-flex justify-content-between\">\r\n \r\n <span class=\"material-symbols-outlined settings-icon me-2\" *ngIf=\"isConferenceHost\" (click)=\"toggleSettingsPanel()\">\r\n settings\r\n </span>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"toggleContactsPanel({}, true)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\r\n fill=\"#000000\">\r\n <path\r\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"settings-overlay\" *ngIf=\"showSettingsPanel\" (click)=\"closeSettingsPanel()\">\r\n <div class=\"settings-drawer\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"settings-header\">\r\n <span class=\"material-symbols-outlined\" (click)=\"closeSettingsPanel()\">arrow_back</span>\r\n <span>Call Settings</span>\r\n <span></span> <!-- placeholder for alignment -->\r\n </div>\r\n \r\n <div class=\"settings-body\">\r\n <!-- Mute all participants -->\r\n <div class=\"setting-item\">\r\n <div class=\"setting-label\">\r\n <span>Mute all participants</span>\r\n <small>Off \u2014 participants can mute and unmute themselves at any time.</small>\r\n </div>\r\n <label class=\"switch\">\r\n <input type=\"checkbox\" [ngModel]=\"settings.muteAll\" [disabled]=\"isUpdatingConferenceSettings\"\r\n (ngModelChange)=\"onMuteAllToggle($event)\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n \r\n <hr>\r\n \r\n <!-- Participant Permissions -->\r\n <div class=\"setting-group\">\r\n <h6>PARTICIPANT PERMISSIONS</h6>\r\n \r\n <!-- Allow unmute -->\r\n <div class=\"setting-item\">\r\n <div class=\"setting-label\">\r\n <span>\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3Z\" stroke=\"currentColor\" stroke-width=\"1.8\"></path>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2M12 19v3\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\r\n </svg>\r\n Allow participants to self-unmute\r\n </span>\r\n <small>{{ settings.allowUnmute ? 'Yes \u2014 participants can unmute themselves after being muted\r\n individually by the host.' : 'No \u2014 participants cannot unmute themselves.' }}</small>\r\n </div>\r\n <label class=\"switch\">\r\n <input type=\"checkbox\" [ngModel]=\"settings.allowUnmute\" [disabled]=\"isUpdatingConferenceSettings\"\r\n (ngModelChange)=\"settings.allowUnmute = $event; updateConferenceSettings()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n \r\n <!-- Allow remove -->\r\n <div class=\"setting-item\">\r\n <div class=\"setting-label\">\r\n <span>\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M17 21v-2a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v2M15 3.13a4 4 0 0 1 0 7.75\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\r\n <circle cx=\"9\" cy=\"7\" r=\"4\" stroke=\"currentColor\" stroke-width=\"1.8\"></circle>\r\n <path d=\"M19 8h4\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\r\n </svg>\r\n Allow participants to remove\r\n </span>\r\n <small>{{ settings.allowRemove ? 'Yes \u2014 participants can remove other participants.' : 'No \u2014\r\n participants cannot remove other participants, and cannot remove the host.' }}</small>\r\n </div>\r\n <label class=\"switch\">\r\n <input type=\"checkbox\" [ngModel]=\"settings.allowRemove\" [disabled]=\"isUpdatingConferenceSettings\"\r\n (ngModelChange)=\"settings.allowRemove = $event; updateConferenceSettings()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n <div class=\"setting-item\">\r\n <div class=\"setting-label\">\r\n <span>Allow participants to unhold</span>\r\n <small>{{ settings.allowUnhold ? 'Yes \u2014 participants can place themselves on hold.' : 'No \u2014\r\n participants cannot place themselves on hold.' }}</small>\r\n </div>\r\n <label class=\"switch\">\r\n <input type=\"checkbox\" [ngModel]=\"settings.allowUnhold\" [disabled]=\"isUpdatingConferenceSettings\"\r\n (ngModelChange)=\"settings.allowUnhold = $event; updateConferenceSettings()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n <div class=\"setting-item\">\r\n <div class=\"setting-label\">\r\n <span>Allow participants to mute other participants</span>\r\n <small>{{ settings.allowMuteOthers ? 'Yes \u2014 Participants can mute other participants, and can mute the host.' : 'No \u2014\r\n Participants cannot mute other participants, and cannot mute the host.' }}</small>\r\n </div>\r\n <label class=\"switch\">\r\n <input type=\"checkbox\" [ngModel]=\"settings.allowMuteOthers\" [disabled]=\"isUpdatingConferenceSettings\"\r\n (ngModelChange)=\"settings.allowMuteOthers = $event; updateConferenceSettings()\">\r\n <span class=\"switch-slider\"></span>\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- SEARCH INPUT (visible when isSearchVisible = true) -->\r\n <div class=\"search-bar p-3 position-relative\">\r\n <input type=\"text\" placeholder=\"Add a participant by Name or Number\" title=\"Add a participant by Name or Number\" [(ngModel)]=\"searchText\" (input)=\"applyFilter()\" />\r\n <div class=\"search-contacts-list\">\r\n <ng-container *ngFor=\"let c of filteredList\">\r\n <div class=\"contact-item\" *ngIf=\"searchText\">\r\n <img class=\"contact-avatar\" [src]=\"c?.image || 'assets/images/user.jpg'\" alt=\"\" />\r\n <div class=\"contact-info\">\r\n <div class=\"contact-name\">{{c?.firstName}} {{c?.middleName}} {{c?.lastName}}</div>\r\n <div class=\"contact-title\">{{ (c?.numbersList && c?.numbersList[0]?.number) }}{{ c?.numbersList[0]?.numberLabel ? ' (' + c.numbersList[0].numberLabel + ')' : '' }}</div>\r\n </div>\r\n <button class=\"contact-call-btn contact-add-btn mr-2\" (click)=\"callContact(c)\"\r\n *ngIf=\"!c?.IsConnected\" title=\"Add to call\">\r\n <span class=\"material-symbols-outlined\"> add </span>\r\n </button>\r\n <button class=\"contact-call-btn\" (click)=\"CallToUnsavedNumber(c?.numbersList[0]?.number, true)\"\r\n *ngIf=\"!c?.IsConnected\" title=\"New Call\">\r\n <span class=\"material-symbols-outlined\"> call </span>\r\n </button>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!filteredList.length && isDirectCallOptionShow && searchText\">\r\n <div class=\"contact-item\">\r\n <img class=\"contact-avatar\" [src]=\"'assets/images/user.jpg'\" alt=\"\" />\r\n <div class=\"contact-info\">\r\n <div class=\"contact-title\">{{ searchText }}</div>\r\n </div>\r\n <button class=\"contact-call-btn contact-add-btn mr-2\" (click)=\"CallToUnsavedNumber(searchText)\"\r\n title=\"Add to call\">\r\n <span class=\"material-symbols-outlined\"> add </span>\r\n </button>\r\n <button class=\"contact-call-btn\" (click)=\"CallToUnsavedNumber(searchText, true)\"\r\n title=\"New Call\">\r\n <span class=\"material-symbols-outlined\"> call </span>\r\n </button>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <div class=\"contacts-list\">\r\n <div class=\"px-2\">\r\n <h5 class=\"mb-0 title\">Active participants ({{ activeParticipantsCount }})</h5>\r\n </div>\r\n <hr class=\"mb-2 mt-1\">\r\n <ng-container *ngFor=\"let c of filteredParticipentList\">\r\n <div class=\"contact-item\" *ngIf=\"!c?.isLeft\">\r\n <img class=\"contact-avatar\" *ngIf=\"!c?.client\"\r\n [src]=\"c?.direction == 'outgoing-call' ? c?.toImage || 'assets/images/user.jpg' : c?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n <img class=\"contact-avatar\" *ngIf=\"c?.client\"\r\n [src]=\"c?.direction == 'outgoing-call' ? c?.fromImage || 'assets/images/user.jpg' : c?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n <div class=\"contact-info\">\r\n <div class=\"contact-name\" *ngIf=\"!c?.client\">{{c?.direction == 'outgoing-call' ? c?.toName || 'Unknown' : c?.fromName || 'Unknown'}}\r\n </div>\r\n <div class=\"contact-title\" *ngIf=\"!c?.client\">{{ c?.direction == 'outgoing-call' ? c?.to || 'Unknown' : c?.from || 'Unknown'}}</div>\r\n\r\n <div class=\"contact-name\" *ngIf=\"c?.client\">\r\n <ng-container *ngIf=\"!isSelfNumber(c) else selfNumber\">\r\n <span>{{c?.direction == 'outgoing-call' ? c?.fromName || 'Unknown' : c?.toName || 'Unknown'}}</span>\r\n </ng-container>\r\n <ng-template #selfNumber>\r\n <span>You</span>\r\n </ng-template>\r\n </div>\r\n <div class=\"contact-title\" *ngIf=\"c?.client\">{{ c?.direction == 'outgoing-call' ? c?.from || 'Unknown' : c?.to || 'Unknown'}}</div>\r\n <div class=\"d-flex\" *ngIf=\"c?.host\">\r\n <span class=\"organizer-label\">Organizer</span>\r\n </div>\r\n </div>\r\n <ng-container *ngIf=\"c?.joined && !c?.host\">\r\n <div class=\"connecting-wrapper mr-2\">\r\n <span class=\"ringing-text\">Ringing</span>\r\n <span class=\"dots\">\r\n <span>.</span>\r\n <span>.</span>\r\n <span>.</span>\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"c?.host && c?.isHold && !(deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call'))\">\r\n <div class=\"connecting-wrapper mr-2\">\r\n <span class=\"onHold-text\">On Hold</span>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!c?.joined || c?.host\">\r\n <button class=\"mic-btn mr-2\" [disabled]=\"c?.isHold || !canToggleMute(c)\" [title]=\"muteTooltip(c)\" (click)=\"onMuteUser(c)\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isEffectivelyMuted(c)\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isEffectivelyMuted(c)\"> mic </span>\r\n </button>\r\n <button class=\"conference-hold-contact mr-2\" [ngClass]=\"{ 'on-hold': c?.isHold }\"\r\n (click)=\"onHoldCall(c)\" *ngIf=\"!c?.host || (c?.host && (deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call')))\" [disabled]=\"isHoldBtnDisable || !canToggleHold(c)\">\r\n <span *ngIf=\"!c?.isHold\" class=\"material-symbols-outlined\" [title]=\"canToggleHold(c) ? 'Hold' : holdTooltip(c)\"> phone_paused</span>\r\n <span *ngIf=\"c?.isHold\" class=\"material-symbols-outlined\" [title]=\"canToggleHold(c) ? 'Resume' : holdTooltip(c)\"> resume </span>\r\n </button>\r\n </ng-container>\r\n <button class=\"conference-contact\" (click)=\"confirmLeaveParticipant(c)\"\r\n [disabled]=\"!canRemoveParticipant(c)\" [title]=\"removeTooltip(c)\" *ngIf=\"!c?.host\">\r\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\r\n </button>\r\n <button class=\"conference-contact\" (click)=\"endConfereneceCall(c)\"\r\n *ngIf=\"c?.host && (deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call'))\">\r\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\r\n </button>\r\n </div>\r\n </ng-container>\r\n <hr class=\"m-2\">\r\n <div class=\"mt-3 px-2\">\r\n <h5 class=\"mb-0 title\">Participant added to the call</h5>\r\n </div>\r\n <hr class=\"mb-2 mt-1\">\r\n <ng-container *ngFor=\"let c of filteredParticipentList\">\r\n <div class=\"contact-item\" *ngIf=\"c?.isLeft\">\r\n <img class=\"contact-avatar\" *ngIf=\"!c?.client\"\r\n [src]=\"c?.direction == 'outgoing-call' ? c?.toImage || 'assets/images/user.jpg' : c?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n <img class=\"contact-avatar\" *ngIf=\"c?.client\"\r\n [src]=\"c?.direction == 'outgoing-call' ? c?.fromImage || 'assets/images/user.jpg' : c?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\r\n <div class=\"contact-info\">\r\n <div class=\"contact-name\" *ngIf=\"!c?.client\">{{c?.direction == 'outgoing-call' ? c?.toName || 'Unknown' : c?.fromName || 'Unknown'}}\r\n </div>\r\n <div class=\"contact-title\" *ngIf=\"!c?.client\">{{ c?.direction == 'outgoing-call' ? c?.to || 'Unknown' : c?.from || 'Unknown'}}</div>\r\n <div class=\"contact-name\" *ngIf=\"c?.client\">{{c?.direction == 'outgoing-call' ? c?.fromName || 'Unknown' : c?.toName || 'Unknown'}}\r\n </div>\r\n <div class=\"contact-title\" *ngIf=\"c?.client\">{{ c?.direction == 'outgoing-call' ? c?.from || 'Unknown' : c?.to || 'Unknown'}}</div>\r\n <div class=\"d-flex\" *ngIf=\"c?.host\">\r\n <span class=\"organizer-label\">Organizer</span>\r\n </div>\r\n </div>\r\n <div class=\"connecting-wrapper\" *ngIf=\"c?.joined\">\r\n <span class=\"ringing-text\">Ringing</span>\r\n <span class=\"dots\">\r\n <span>.</span>\r\n <span>.</span>\r\n <span>.</span>\r\n </span>\r\n </div>\r\n <button class=\"conference-contact\" (click)=\"onEndCall(c, false, true)\" *ngIf=\"!c?.host && c?.joined\">\r\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\r\n </button>\r\n <button class=\"contact-call-btn contact-add-btn\" *ngIf=\"!c?.client && !c?.joined && !c?.businessNumber\"\r\n (click)=\"CallToUnsavedNumber(c.direction == 'outgoing-call' ? c?.to : c?.from, false, { skipDuplicateCheck: true }, c)\">\r\n <span class=\"material-symbols-outlined\"> add </span>\r\n <span class=\"label\">Rejoin</span>\r\n </button>\r\n <button class=\"contact-call-btn contact-add-btn\" *ngIf=\"c?.client && !c?.joined && !c?.businessNumber\"\r\n (click)=\"CallToUnsavedNumber(c.direction == 'outgoing-call' ? c?.from : c?.to, false, { skipDuplicateCheck: true }, c)\">\r\n <span class=\"material-symbols-outlined\"> add </span>\r\n <span class=\"label\">Rejoin</span>\r\n </button>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Conference Warning Modal -->\r\n<div class=\"custom-modal\" *ngIf=\"showConferenceWarningModal\">\r\n <div class=\"modal-content warning-modal\">\r\n <div class=\"warning-icon\">\r\n <span class=\"material-symbols-outlined\">warning</span>\r\n </div>\r\n <h3>Warning</h3>\r\n <p>\r\n Starting a new call will put the current call on hold\r\n and cannot be merged later.\r\n </p>\r\n <div class=\"warning-actions\">\r\n <button class=\"cancel-btn\" (click)=\"cancelNewCall()\">\r\n Cancel\r\n </button>\r\n <button class=\"proceed-btn\" (click)=\"confirmNewCall()\">\r\n Proceed\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n</div>\r\n\r\n<div class=\"min-call-container\" *ngIf=\"isMinimised\">\r\n <span class=\"material-symbols-outlined fullscreen\" (click)=\"maximiseDialpad()\"> open_in_full </span>\r\n <div style=\"display: flex; width: 100%\">\r\n <div>\r\n <div class=\"min-call-animation\" id=\"call-avatar\">\r\n <img class=\"min-avatar-img\" [src]=\"callData.img\" alt=\"\" />\r\n </div>\r\n </div>\r\n <div>\r\n <div class=\"min-callerDetails\">\r\n <div class=\"name\">\r\n {{callData.name}}\r\n </div>\r\n <p style=\"margin: 0\">{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"min-btn-container\">\r\n <div class=\"min-timer\">{{timer}}</div>\r\n <button class=\"min-call-sec-btn\" (click)=\"toggleMute()\" [disabled]=\"disbaleEndCallBtn || !canSelfToggleMute()\" [title]=\"selfMuteTooltip()\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isSelfEffectivelyMuted()\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isSelfEffectivelyMuted()\"> mic </span>\r\n </button>\r\n <button class=\"min-call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\r\n <span class=\"material-symbols-outlined\"> call_end </span>\r\n </button>\r\n </div>\r\n</div>\r\n<!-- Call Disconnect Modal -->\r\n<div class=\"custom-modal\" *ngIf=\"showDisconnectModal\">\r\n <div class=\"modal-content p-3\">\r\n <div class=\"contacts-header p-0 pb-2\">\r\n <h4 class=\"title mb-0\">{{selectedConf?.conName || 'Call'}} Disconnect</h4>\r\n <div class=\"d-flex justify-content-between\">\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDisconnectModal = false\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\r\n fill=\"#000000\">\r\n <path\r\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"contant-body mb-2\">\r\n <p class=\"mt-2\">\r\n Exiting this call will not end the conference. The session will continue, and charges will incur to\r\n your\r\n account.\r\n </p>\r\n </div>\r\n <div class=\"button-group\">\r\n <div class=\"text-start d-flex align-items-center\">\r\n <label class=\"d-flex align-items-center mb-0 mr-2\">\r\n <input type=\"checkbox\" [(ngModel)]=\"isReasonChecked\" (ngModelChange)=\"onReasonCheckChanged($event)\" class=\"me-2\"/>\r\n </label>\r\n <div class=\"time-picker-24hr\">\r\n <!-- Hour picker -->\r\n <div class=\"custom-time-select\" [class.disabled-picker]=\"!isReasonChecked\">\r\n <div class=\"custom-time-display\" (click)=\"isReasonChecked && toggleHourDropdown()\">\r\n {{ leaveHour || 'HH' }}\r\n <span class=\"picker-arrow\">&#9660;</span>\r\n </div>\r\n <div class=\"custom-time-options\" *ngIf=\"showHourDropdown\">\r\n <div class=\"custom-time-option\"\r\n *ngFor=\"let h of hours\"\r\n [class.selected]=\"leaveHour === h\"\r\n (click)=\"selectHour(h)\">{{ h }}</div>\r\n </div>\r\n </div>\r\n <span class=\"time-sep\">:</span>\r\n <!-- Minute picker -->\r\n <div class=\"custom-time-select\" [class.disabled-picker]=\"!isReasonChecked\">\r\n <div class=\"custom-time-display\" (click)=\"isReasonChecked && toggleMinuteDropdown()\">\r\n {{ leaveMinute || 'MM' }}\r\n <span class=\"picker-arrow\">&#9660;</span>\r\n </div>\r\n <div class=\"custom-time-options\" *ngIf=\"showMinuteDropdown\">\r\n <div class=\"custom-time-option\"\r\n *ngFor=\"let m of minutes\"\r\n [class.selected]=\"leaveMinute === m\"\r\n (click)=\"selectMinute(m)\">{{ m }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <button class=\"btn end-btn\" (click)=\"leaveConference()\" [disabled]=\"isReasonChecked && (!leaveHour || !leaveMinute)\">\r\n Leave\r\n </button>\r\n <button class=\"btn end-btn\" (click)=\"endConference()\" *ngIf=\"showEndAllButton\">\r\n End All\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"custom-modal\" *ngIf=\"showLeaveConfirmationModal\">\r\n <div class=\"modal-content warning-modal\">\r\n <div class=\"warning-icon\">\r\n <span class=\"material-symbols-outlined\">info</span>\r\n </div>\r\n <h3>Leave Conference</h3>\r\n <p>\r\n You are about to leave <strong>{{ leaveConfConferenceName }}</strong>. \r\n Are you sure?\r\n </p>\r\n <div class=\"warning-actions\">\r\n <button class=\"cancel-btn\" (click)=\"cancelLeave()\">Cancel</button>\r\n <button class=\"proceed-btn\" (click)=\"confirmLeave()\">Leave</button>\r\n </div>\r\n </div>\r\n</div>", styles: [".call-container{width:385px;height:646px!important;margin:auto;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;box-sizing:border-box;position:relative;justify-content:center;align-items:center;z-index:1000;flex-flow:column;overflow-x:hidden;overflow-y:visible}.disabled{opacity:.5!important;pointer-events:none!important}.call-to-text{padding:6px 10px;border:1px solid #c2c2c2;border-radius:20px;font-size:13px}.collops{height:660px!important}.incoming-call-container{flex-flow:row!important}.active-call{width:385px!important}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto 0;border-radius:100%;border:solid 4px #fff;display:flex;align-items:center;justify-content:center}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.call-animation-play{animation:play 3s linear infinite}.call-info-wrapper{height:20px;overflow-y:auto;background:white;transition:height 1s}.open-collops{height:180px!important}.avatar-img{width:94px;height:94px;border-radius:100%}@keyframes play{0%{transform:scale(1)}15%{box-shadow:0 0 0 2px #fff6}25%{box-shadow:0 0 0 4px #fff6,0 0 0 8px #fff3}25%{box-shadow:0 0 0 8px #fff6,0 0 0 16px #fff3}50%{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3}to{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3;transform:scale(1.1);opacity:0}}.callerDetails{margin-top:8px;color:#fff;display:flex;flex-direction:column;align-items:center}.togglearrow-arrow{left:100%;background-color:#fff;width:25px;height:25px;text-align:center;cursor:pointer;border:1px solid #ccc;border-radius:50%;line-height:22px}.togglearrow-arrow.disabled{opacity:.3;cursor:not-allowed;pointer-events:none}.search-bar input{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;outline:none}.togglearrow-arrow.disabled:hover{opacity:.3;cursor:not-allowed}.callerDetails h1{width:260px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:12px 0 0;color:#fff;text-transform:capitalize;text-align:center}.callerDetails h4{margin:0;color:#fff}.tx-black,.title{color:#000!important}.callerDetails p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-btn,.mic-btn{position:relative;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:25px;padding:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226;width:50px;height:50px}.mic-btn{padding:5px;width:37px;height:37px}.receive-btn{background-color:#28a745!important;color:#fff!important}.receive-btn span{color:#fff!important}.scroll-container{width:100%;overflow:hidden;white-space:nowrap;position:relative}.scroll-text{display:inline-block;padding-left:100%;animation:scroll-left 12s linear infinite;font-size:16px}@keyframes scroll-left{0%{transform:translate(0)}to{transform:translate(-100%)}}.call-sec-btn span{color:#cccbcb}.call-btn{width:60px;height:60px;background-color:#fff;border-radius:30px;box-sizing:border-box;border:2px solid white;margin:0 16px}.end-call-btn{background-color:#e14e4e}.end-call-btn span{color:#fff!important}.call-btn span{color:#234de8}.btn-container{display:flex;flex-wrap:wrap;padding:0 30px}.key-btn{width:50px;height:50px;background-color:transparent;text-align:center;box-sizing:border-box;margin:0 18px;font-size:22px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#d3d3d3;cursor:pointer;opacity:.8}.call-action-btns{text-align:center}#call-input{background-color:transparent;border:none;outline:none;text-align:center;color:#fff}.sendDigit{position:relative;text-align:center;width:80%;margin:auto;background-color:#ffffff1a;padding:2px 0;border-radius:3px}.input-clear-btn{position:absolute;right:6px;color:#fff;cursor:pointer}#minimize-btn-div{position:absolute;right:14px;top:12px;z-index:10}.minimize-btn{color:#fff;cursor:pointer}.wave-container{position:absolute;bottom:0;overflow:hidden;width:100%}.waves{width:660px;position:relative;margin-bottom:-7px;height:40px;min-height:40px}.held-call-banner{position:absolute;top:0;left:0;right:0;z-index:2100;box-shadow:0 4px 12px #0000004d;border-radius:0 0 16px 16px;max-height:220px;overflow-y:auto}.held-call-content{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 6px;border-bottom:1px dotted #4b4b4b;border-left:3px solid transparent;transition:background .15s ease,border-left-color .15s ease;cursor:pointer}.held-call-content.held-call-selected{background:rgba(255,255,255,.15);border-left-color:#fff;border-radius:0 6px 6px 0}.held-main-label{font-size:13px;color:#fff;text-transform:uppercase;letter-spacing:.5px}.fa-info{font-size:smaller!important}.held-info{display:flex;align-items:center;gap:10px;flex:1}.hold-icon{font-size:24px;color:#fbbf24}.swap-icon{font-size:24px}.held-caller{display:flex;flex-direction:column;gap:2px}.held-label{font-size:10px;color:#ffffffb3;text-transform:uppercase;letter-spacing:.5px}.held-name{font-size:14px;font-weight:600;color:#fff}.held-number{font-size:13px;font-weight:500;color:#fff}.held-actions{display:flex;gap:8px;align-items:center}.held-btn{padding:6px 16px;border-radius:20px;border:none;font-size:13px;font-weight:600;cursor:pointer;transition:transform .2s,box-shadow .2s}.held-btn:hover{transform:scale(1.05);box-shadow:0 4px 12px #0003}.swap-btn{background:#3b82f6;color:#fff}.merge-btn{background:#10b981;color:#fff}.h-77px{height:77px}.incoming-banners-container{width:100%;padding:5px 8px;height:100%;gap:8px;overflow-y:auto}.call-container-model{width:385px!important;height:646px!important;margin:auto 0 0 1px;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;box-sizing:border-box;position:relative;overflow:hidden;justify-content:center;align-items:center}.incoming-banner{top:0;left:0;width:100%;right:0;background:linear-gradient(135deg,#1e3a8a 0%,#3b82f6 100%);padding:12px 16px;z-index:2000;box-shadow:0 4px 12px #0003;border-radius:16px}.incoming-banner-content{display:flex;align-items:center;justify-content:space-between;gap:12px}.incoming-info{flex:1;display:flex;flex-direction:column;gap:4px}.incoming-label{font-size:11px;color:#fffc;text-transform:uppercase;letter-spacing:.5px}.incoming-caller{display:flex;flex-direction:column;gap:2px}.caller-name{font-size:15px;font-weight:600;color:#fff}.caller-number{font-size:13px;color:#ffffffe6}.incoming-actions{display:flex;gap:8px;align-items:center}.banner-btn{width:44px;height:44px;border-radius:50%;border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:transform .2s}.banner-btn:hover{transform:scale(1.1)}.banner-btn .material-symbols-outlined{font-size:20px}.accept-btn{background:#10b981}.accept-btn .material-symbols-outlined{color:#fff}.reject-btn{background:#ef4444}.reject-btn .material-symbols-outlined{color:#fff}.contacts-panel{position:absolute;top:0;bottom:12px;width:340px;background:#ffffff;border-radius:16px;box-shadow:0 10px 25px #00000026;display:flex;flex-direction:column;overflow:hidden;height:40.4rem;left:24.1rem;z-index:1000000;color:#111827!important}.contacts-header{height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;border-bottom:1px solid #f0f0f0;color:#111827!important}.modal-content .contacts-header{height:40px}.search-contacts-list{max-height:196px;overflow:auto;position:absolute;width:91%;background:white;z-index:1000;box-shadow:0 4px 8px #0003,0 6px 20px #00000030;border-radius:0 10px 10px}.contant-body p{font-size:14px;color:#5f6061!important}.contacts-header .title{font-weight:600;color:#111827!important}.contacts-header .back,.contacts-header .search{color:#9aa0a6;cursor:pointer}.disabled{opacity:.5;pointer-events:none}.contacts-list{padding:8px 8px 12px;overflow-y:auto}.contact-item{display:flex;align-items:center;padding:10px 8px;border-radius:10px}.contact-item:hover{background:#f7f9fc}.contact-avatar{width:37px;height:37px;border-radius:50%;object-fit:cover;margin-right:12px}.contact-info{flex:1;min-width:0;overflow:hidden}.contact-name{font-weight:600;color:#111827;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.contact-title{font-size:12px;color:#6b7280}.contact-call-btn{display:inline-flex;align-items:center;gap:6px;background:#234de8;color:#fff;border:none;border-radius:16px;padding:8px;cursor:pointer}.contact-add-btn{background-color:#2ecc71!important}.conference-hold-contact{display:inline-flex;align-items:center;gap:5px;background:#727070;color:#fff;border:none;border-radius:50%;padding:7px;cursor:pointer}.conference-hold-contact.on-hold{background:#28a745!important;color:#fff}.user-info-section{width:100%;height:100%;overflow-y:auto;overflow-x:hidden!important}.user-info-section::-webkit-scrollbar{display:none}.toggle-btn{cursor:pointer}.text-container{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;transition:all .3s ease}.mute-incoming-row{display:flex;align-items:center;justify-content:center;gap:8px;margin:0 0 10px}.mute-incoming-label{font-size:11px;color:#fff}.switch{position:relative;display:inline-block;width:38px;height:19px;flex-shrink:0}.switch-slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;border-radius:22px;transition:.3s}.close-info-panel-section{width:100%;height:20px}.close-info-panel-section .material-symbols-outlined{font-size:12px;cursor:pointer}.c2c-title{color:#fff;white-space:normal;word-break:break-word;line-height:1.4}.switch-slider:before{content:\"\";position:absolute;height:14px;width:15px;left:3px;bottom:3px;background-color:#fff;border-radius:50%;transition:.3s}.switch input:checked+.switch-slider{background-color:#2ecc71}.switch input:checked+.switch-slider:before{transform:translate(18px)}.text-container.expanded{-webkit-line-clamp:unset}.userName{font-family:FontAwesome}.subject-text{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden}.conference-contact{display:inline-flex;align-items:center;gap:5px;background:#e14e4e;color:#fff;border:none;border-radius:50%;padding:7px;cursor:pointer}.organizer-label{padding:1px 5px;font-size:11px;border-radius:10px;border:1px solid #a0a0a0;margin-top:2px;background:#fcfcfc;color:#000}.custom-modal{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;align-items:center;z-index:10000001;border-radius:21px}.modal-content{background:#ffffff;padding:25px;border-radius:8px;width:350px;text-align:center}.title{margin-bottom:15px;color:#d9534f}.message{margin-bottom:20px}.button-group{display:flex;justify-content:space-between}.btn{padding:8px 15px;border:none;border-radius:5px;cursor:pointer;font-weight:500}.end-btn{background-color:#dc3545;color:#fff;display:flex;align-items:center;font-size:13px}.leave-btn{background-color:#007bff;color:#fff}.contact-call-btn .material-symbols-outlined{font-size:18px;color:#fff}.contact-call-btn .label{font-size:12px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}.animated-margin{transition:margin-top .5s ease}app-incoming-call{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1001}.min-call-container{width:320px;height:124px;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;flex-direction:column;box-sizing:border-box;position:relative;overflow:hidden;margin:auto;align-items:center;padding:12px 16px;color:#fff}.min-call-animation{background:#fff;width:48px;height:48px;position:relative;margin:0 12px 0 auto;border-radius:100%;border:solid 2px #fff}.min-avatar-img{width:46px;height:46px;border-radius:100%;position:absolute;left:0;top:0}.border-radius-50{border-radius:50%}.min-callerDetails{color:#fff;display:flex;flex-direction:column;align-items:flex-start}.name{width:170px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:20px;margin:0;color:#fff}.min-callerDetails p{margin:0;color:#fff}.min-btn-container{position:relative;display:flex;width:100%;justify-content:flex-start;align-items:center;margin-top:6px}.min-call-sec-btn{width:40px;height:40px;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:20px;display:flex;align-items:center;justify-content:center;margin-right:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226}.min-call-sec-btn span{color:#cccbcb}.min-call-btn{width:40px;height:40px;border-radius:20px;box-sizing:border-box;border:2px solid white;display:flex;align-items:center;justify-content:center}.fullscreen{position:absolute;right:18px;top:14px;color:#e8e8e8;font-size:18px;cursor:pointer}.btn-container{display:flex;flex-wrap:wrap;padding:0 24px}.dial-btn{width:40px;height:40px;background-color:transparent;text-align:center;box-sizing:border-box;margin:4px 25px;font-size:24px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#b5b5b5;cursor:pointer}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.min-timer{width:50px;font-size:18px;margin-right:10px;border-radius:4px;height:35px;display:flex;align-items:center}.record-action-btns{display:flex;flex-direction:column;align-items:center;margin-top:35px}.record-btn-container{position:relative}.record-btn{border:none;border-radius:50%;width:50px;height:50px;display:flex;align-items:center;justify-content:center;cursor:pointer;margin:0 5px;position:relative;overflow:hidden}.record-btn.start-stop .recording-icon{width:50%;height:50%;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.record-btn.start-stop.recording .recording-icon{background-color:#000}.record-btn.start-stop.recording{border:3px solid #000}.record-btn.start-stop.stopped .recording-icon{background-color:red;border:3px solid #ff0000;border-radius:50%;position:absolute}.record-btn.start-stop.stopped{border:3px solid #ff0000}.record-btn.start-stop.stopped .recording-icon{width:40%;height:40%;border-radius:0;background-color:red}.pause-resume-btns{display:flex;flex-direction:column;align-items:center;margin-top:10px}.record-btn.pause-resume{border:none;border-radius:50%;width:50px;height:50px;background:white;display:flex;align-items:center;justify-content:center;margin:5px 0}.record-btn.pause-resume .material-symbols-outlined{font-size:20px;color:#000}.timer-display{font-size:1.2em;margin-top:10px;color:#000}.w-40{width:40%}.w-60{width:60%}.callToNum{color:#fff;font-weight:400;text-align:center}.callToNum span{font-weight:600}.conference-call-view{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;width:100%;padding:12px 16px 35px;color:#fff;height:100%}.conf-heading{display:flex;align-items:center;gap:8px;margin-top:45px}.conf-icon{color:#4579aa;font-size:32px;width:50px;height:50px;border:1px solid gray;border-radius:50%;display:flex;align-items:center;justify-content:center;background:#e1e1e1}.conf-title{font-weight:600;font-size:20px}.conf-name{margin-top:10px;font-size:17px;font-weight:600;text-align:center}.conf-timer{margin-top:4px;font-size:12px;opacity:.9}.conf-record{margin-top:14px}.record-stop-btn{width:44px;height:44px;border-radius:50%;border:none;background:#fff;display:flex;align-items:center;justify-content:center}.record-stop-btn .material-symbols-outlined{color:#e14e4e;font-size:28px}.conf-remove{margin-top:8px}.remove-btn{background:#ff0000!important;color:#fff;border:none;border-radius:6px;padding:6px 12px;font-size:12px;width:82px!important;height:auto}.conf-actions{margin-top:14px;display:flex;align-items:center;justify-content:center;gap:18px}.circle-btn{width:56px;height:56px;border-radius:50%;border:none;background:#000;display:flex;align-items:center;justify-content:center}.circle-btn .material-symbols-outlined{color:#fff;font-size:24px}.circle-btn.active{opacity:.85}.conf-end{margin-top:16px}.circle-btn.danger{background:#e14e4e}.circle-btn.danger .material-symbols-outlined{color:#fff}.warning-modal{background:white;width:360px;border-radius:18px;padding:24px;text-align:center;box-shadow:0 10px 30px #00000040}.warning-icon{margin-bottom:12px}.warning-icon .material-symbols-outlined{font-size:48px;color:#f59e0b}.warning-modal h3{margin-bottom:12px;font-size:20px;font-weight:600;color:#111827!important}.warning-modal p{color:#555!important;font-size:14px;line-height:1.5;margin-bottom:24px}.warning-modal p strong{color:#111827!important}.warning-actions{display:flex;justify-content:center;gap:12px}.cancel-btn,.proceed-btn{border:none;padding:10px 18px;border-radius:8px;cursor:pointer;font-weight:600}.cancel-btn{background:#e5e7eb;color:#111827}.proceed-btn{background:#234de8;color:#fff}.time-picker-24hr{display:flex;align-items:center;gap:4px}.time-sep{font-weight:700;font-size:16px;color:#333}.custom-time-select{position:relative;width:58px;-webkit-user-select:none;user-select:none}.custom-time-select.disabled-picker{opacity:.45;pointer-events:none}.custom-time-display{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;border:1px solid #ced4da;border-radius:4px;background:#fff;font-size:13px;cursor:pointer;white-space:nowrap;color:#333!important}.custom-time-display:hover{border-color:#234de8}.picker-arrow{font-size:9px;margin-left:4px;color:#666}.custom-time-options{position:fixed;background:#fff;border:1px solid #ced4da;border-radius:4px;max-height:160px;overflow-y:auto;z-index:99999999;min-width:58px;box-shadow:0 4px 12px #00000026}.custom-time-option{padding:5px 10px;font-size:13px;cursor:pointer;text-align:center;color:#333}.custom-time-option:hover{background:#e8eeff;color:#234de8}.custom-time-option.selected{background:#234de8;color:#fff;font-weight:600}.dialpad-alerts{position:absolute;left:50%;transform:translate(-50%);width:calc(100% - 32px);z-index:9999999}.normal-call-alert{top:78px}.conference-alert{top:145px}.dialbox-pop1{background:#dff6dd!important;color:#1d4d1d!important;border-radius:10px;padding:10px 14px;font-size:14px;box-shadow:0 4px 12px #00000040;border:1px solid #b7dfc3}.btn-disc{border:none;background:transparent;color:#6b7280!important;font-size:13px;font-weight:500}.connecting-overlay{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:16px 0 24px}.connecting-text{color:#ffffffe6;font-size:15px;font-weight:500;letter-spacing:.5px;margin:0}.connecting-dots{display:flex;gap:8px;align-items:center}.connecting-dots span{display:inline-block;width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.85);animation:connecting-bounce 1.2s infinite ease-in-out}.connecting-dots span:nth-child(1){animation-delay:0s}.connecting-dots span:nth-child(2){animation-delay:.2s}.connecting-dots span:nth-child(3){animation-delay:.4s}@keyframes connecting-bounce{0%,80%,to{transform:scale(.6);opacity:.4}40%{transform:scale(1.2);opacity:1}}.connecting-wrapper{display:flex;align-items:center;font-size:13px;color:#4caf50;margin-top:4px;font-weight:500}.participant-list-title,.onHold-text{color:#000}.ringing-text,.onHold-text{margin-right:2px;font-size:11px}.held-actions .connecting-wrapper{color:#fff}.dots span{animation:blink 1.4s infinite;opacity:0;font-size:16px}.dots span:nth-child(1){animation-delay:0s}.dots span:nth-child(2){animation-delay:.2s}.dots span:nth-child(3){animation-delay:.4s}@keyframes blink{0%{opacity:0}50%{opacity:1}to{opacity:0}}.loader-wrapper.outgoing-call-loader{position:absolute;inset:0;z-index:100;display:flex;align-items:center;justify-content:center}.panel-loader-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffffb3;display:flex;justify-content:center;align-items:center;z-index:10000009}.settings-icon{cursor:pointer;font-size:24px;color:#555;position:relative;top:5px;right:2px}.settings-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:1000001;display:flex;align-items:flex-start;justify-content:flex-end}.settings-drawer{background:#fff;width:100%;max-width:100%;height:100%;padding:1.5rem 1rem;overflow-y:auto;box-sizing:border-box;transform:translate(100%);animation:slideInFromRight .3s forwards}@keyframes slideInFromRight{to{transform:translate(0)}}.settings-header{display:flex;justify-content:space-between;align-items:center;font-size:1.2rem;font-weight:600;padding-bottom:.75rem;border-bottom:1px solid #eee}.settings-header span:first-child{cursor:pointer}.settings-body{margin-top:1.5rem}.setting-item{display:flex;justify-content:space-between;align-items:center;padding:.75rem 0;gap:1rem}.setting-label{flex:1}.setting-label span{font-weight:500}.setting-label svg{width:15px;height:15px;color:#393939;flex-shrink:0}.setting-label small{display:block;font-size:.75rem;color:#666;margin-top:.15rem}.setting-group h6{font-weight:600;color:#888;font-size:.75rem;letter-spacing:.5px;margin:1rem 0 .5rem}hr{margin:.5rem 0;border-color:#f0f0f0}.switch{position:relative;display:inline-block;width:44px;height:24px;flex-shrink:0}.switch input{opacity:0;width:0;height:0}.switch-slider{position:absolute;cursor:pointer;inset:0;background:#ccc;border-radius:24px;transition:.3s}.switch-slider:before{content:\"\";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background:white;border-radius:50%;transition:.3s}.switch input:checked+.switch-slider{background:#007bff}.switch input:checked+.switch-slider:before{transform:translate(20px)}\n"] }]
5110
+ args: [{ selector: 'lib-call-progress', template: "<div class=\"d-flex\">\n <div class=\"call-container\" *ngIf=\"!isMinimised && currentCallList?.length\"\n [ngClass]=\"{'collops': isCollops, 'incoming-call-container': isClickExpand, 'contacts-open': showContactsPanel }\">\n <div class=\"loader-wrapper outgoing-call-loader\"\n *ngIf=\"showNewCallLoader\">\n <div class=\"active-call\" style=\"display: flex; flex-direction: column; position: relative;\">\n <div class=\"call-animation call-animation-play\">\n <img class=\"avatar-img\" [src]=\"newCallLoaderData?.img || 'assets/images/user.jpg'\" alt=\"\" />\n </div>\n <div class=\"callerDetails\">\n <h1 style=\"margin-top: 8px;\">Connecting...</h1>\n <p style=\"text-transform: capitalize;\">{{ newCallLoaderData?.name || newCallLoaderData?.phone || 'Unknown' }}</p>\n </div>\n \n <div class=\"call-action-btns\">\n <div class=\"d-flex justify-content-center\">\n <button class=\"call-btn end-call-btn\" disabled (click)=\"endCall()\" style=\"visibility: hidden;\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"dialpad-alerts\"\n [ngClass]=\"{\n 'conference-alert': isConference && currentCall?.isConference,\n 'normal-call-alert': !isConference\n }\" *ngIf=\"callNumberToast.show\">\n <div class=\"dialbox-pop1 alert fade show\"\n [ngClass]=\"callNumberToast.type\"\n role=\"alert\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <div class=\"flex-grow-1 text-left\">\n You'r calling\n <strong>{{callNumberToast.displayNum}}</strong>\n </div>\n <div class=\"text-right\">\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelCallToast()\"> Cancel Call </button>\n </div>\n </div>\n </div>\n </div>\n <!-- All type Call Hold list -->\n <div class=\"held-call-banner\"\n *ngIf=\"(currentCallList.length > 1 && !!currentCall && ((isConferenceCallHold || isConference) || !isConference)) || !isAllAccepted\">\n <ng-container *ngFor=\"let conf of currentCallList\">\n <div class=\"held-call-content\" *ngIf=\"!conf?.isAcceptCall && currentCallList.length > 1 && deviceNumberList.includes(conf?.to) && conf?.isNotification\"\n [ngClass]=\"{'held-call-selected': selectedUserInfo?.participantId && selectedUserInfo?.participantId === conf?.participantId}\"\n (click)=\"conf?.businessNumber ? toggleC2CInfoPanel(conf) : null\"\n [ngStyle]=\"{'cursor': conf?.businessNumber ? 'pointer' : 'default'}\">\n <div class=\"held-info\">\n <div class=\"img\">\n <img class=\"avatar-img-wrapper border-radius-50\" [src]=\"conf?.img || 'assets/images/user.jpg'\" alt=\"\" width=\"35\" height=\"35\" />\n </div>\n <div class=\"held-caller\" *ngIf=\"!conf?.businessNumber\">\n <span class=\"held-label\">{{conf?.from}}</span>\n <span class=\"held-name\">{{conf?.fromName}}</span>\n </div>\n <div class=\"held-caller\" *ngIf=\"conf?.businessNumber\">\n <span class=\"held-main-label\">Call from C2C:</span>\n <span class=\"held-label\" ><span [title]=\"conf?.sourceName\">{{ truncateText(conf?.sourceName, 10) }}</span>|\n <span [title]=\"conf?.pointName\">{{ truncateText(conf?.pointName, 10) }}</span></span>\n <span class=\"held-label\">{{ truncateText(conf?.name, 26) }}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <ng-container *ngIf=\"isConnectingIncomingCallId == conf?.id\">\n <div class=\"connecting-wrapper mr-2\">\n <span class=\"ringing-text\">Connecting</span>\n <span class=\"dots\">\n <span>.</span>\n <span>.</span>\n <span>.</span>\n </span>\n </div>\n </ng-container>\n <button class=\"conference-hold-contact receive-btn\" (click)=\"waitingCallAccept(conf)\" [disabled]=\"isConnecting || isIncomingCallBtnDisable\" *ngIf=\"isConnectingIncomingCallId !== conf?.id\">\n <span class=\"material-symbols-outlined\"> call </span>\n </button>\n <button class=\"conference-contact\">\n <span class=\"material-symbols-outlined\" title=\"Call End\" (click)=\"onRejectCall(conf); $event.stopPropagation();\"> call_end </span>\n </button>\n <div *ngIf=\"conf?.businessNumber\" class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"toggleC2CInfoPanel(conf)\">\n <i class=\"fa fa-info\"></i>\n </div>\n </div>\n </div>\n </ng-container>\n <ng-container *ngFor=\"let conf of conferenceCallList\">\n <div class=\"held-call-content\" *ngIf=\"(conf?.isConferenceHold || (showNewCallLoader && isConferenceCallHold)) && (conferenceCallList.length > 1 || showNewCallLoader)\"\n [ngClass]=\"{'held-call-selected': conf?.isBusinessNumber && selectedUserInfo?.participantId === conf?.businessParticipantId && isClickExpand}\"\n (click)=\"conf?.isBusinessNumber ? toggleC2CInfoPanel(conf) : null\"\n [ngStyle]=\"{'cursor': conf?.isBusinessNumber ? 'pointer' : 'default'}\">\n <div class=\"held-info\">\n <span class=\"material-symbols-outlined hold-icon\">pause_circle</span>\n <div class=\"held-caller\">\n <span class=\"held-label\">Hold</span>\n <span class=\"held-name\">{{conf?.callLabel}}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <button class=\"conference-hold-contact\" [ngClass]=\"{ 'on-hold': conf?.isConferenceHold }\"\n (click)=\"swapCalls(conf,true)\" [disabled]=\"isHoldBtnDisable\">\n <span *ngIf=\"conf?.isConferenceHold\" class=\"material-symbols-outlined\" [title]=\"'Resume'\"> resume </span>\n </button>\n <button class=\"conference-contact\" (click)=\"endConfereneceCall(conf); $event.stopPropagation();\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n </button>\n <div class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"toggleContactsPanel(conf)\">\n <i class=\"fa fa-angle-right\"></i>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- For single incoming call -->\n <div class=\"h-100 py-5\" style=\"display: flex; flex-direction: column;\"\n *ngIf=\"currentCallList.length === 1 && currentCallList[0]?.isIncomingCall && !currentCallList[0]?.isAcceptCall\">\n <!-- <div class=\"callToNum\">Incoming call on <br /><span>{{currentCallList[0]?.to || 'Unknown Number'}}</span>\n </div> -->\n <div class=\"callToNum\">\n <ng-container *ngIf=\"currentCallList[0]?.businessNumber; else normalCall\">\n C2C CALL\n <br />\n <span> From : {{ currentCallList[0]?.sourceName }} | {{ currentCallList[0]?.pointName }} </span>\n </ng-container>\n\n <ng-template #normalCall>\n Incoming call on\n <br />\n <span>{{ currentCallList[0]?.to || 'Unknown Number' }}</span>\n </ng-template>\n </div>\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\n <img class=\"avatar-img\" [src]=\"incomingFromImage || 'assets/images/user.jpg'\" alt=\"\" width=\"120\" />\n </div>\n <div class=\"callerDetails\" *ngIf=\"!currentCallList[0]?.businessNumber\">\n <h1>{{ currentCallList[0]?.name ? currentCallList[0]?.name : currentCallList[0]?.phone || 'Unknown Number' }}</h1>\n <p *ngIf=\"!!currentCallList[0]?.name\">{{ currentCallList[0]?.phone }}</p>\n </div>\n <div class=\"callerDetails\" *ngIf=\"currentCallList[0]?.businessNumber\">\n <p *ngIf=\"!!currentCallList[0]?.name\">{{ truncateText(currentCallList[0]?.name, 45) }}</p>\n <p >{{ currentCallList[0]?.number }}</p>\n </div>\n <!-- Connecting overlay (shown after accept btn click, hidden on API response) -->\n <div class=\"connecting-overlay mt-auto\" *ngIf=\"isConnectingIncomingCallId == currentCallList[0]?.id\">\n <div class=\"connecting-dots\">\n <span></span><span></span><span></span>\n </div>\n <p class=\"connecting-text\">Connecting...</p>\n </div>\n\n <div class=\"call-action-btns mt-auto\" *ngIf=\"isConnectingIncomingCallId != currentCallList[0]?.id\">\n <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected\"\n [disabled]=\"isIncomingCallBtnDisable\" (click)=\"acceptIncomingCall(currentCallList[0])\">\n <span class=\"material-symbols-outlined\"> call </span>\n </button>\n <button class=\"call-btn reject-btn\">\n <span class=\"material-symbols-outlined\" (click)=\"onRejectCall(currentCallList[0])\"> call_end </span>\n </button>\n </div>\n </div>\n\n <!-- For single active call -->\n <div *ngIf=\"(!isConference || isConferenceCallHold) && (!!currentCall?.id && !currentCall?.isConference) && currentCall?.isAcceptCall\"\n [ngStyle]=\"{'display': 'flex', 'flex-direction': 'column', 'position': 'relative'}\" class=\"active-call\">\n <div *ngIf=\"currentCall?.businessNumber;\" class=\"callToNum\">\n C2C CALL\n <br />\n <span> From : {{ currentCall?.userInfoId?.sourceName }} | {{ currentCall?.userInfoId?.pointName }} </span>\n </div>\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\n <img class=\"avatar-img\" *ngIf=\"!currentCall?.client\"\n [src]=\"currentCall?.direction == 'outgoing-call' ? currentCall?.toImage || 'assets/images/user.jpg' : currentCall?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\n <img class=\"avatar-img\" *ngIf=\"currentCall?.client\"\n [src]=\"currentCall?.direction == 'outgoing-call' ? currentCall?.fromImage || 'assets/images/user.jpg' : currentCall?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\n </div>\n <div class=\"callerDetails\">\n <!-- C2C Business Call -->\n <ng-container *ngIf=\"currentCall?.businessNumber; else normalCall\">\n <h1>{{ currentCall?.userInfoId?.name || 'Unknown' }}</h1>\n <p>{{ currentCall?.userInfoId?.number || currentCall?.from || 'Unknown' }}</p>\n </ng-container>\n\n <!-- Normal Call -->\n <ng-template #normalCall>\n <h1 *ngIf=\"!currentCall?.client\"\n [ngStyle]=\"{'margin-top': showKeypad ? '0':'8px'}\">\n {{ currentCall?.direction == 'outgoing-call'\n ? currentCall?.toName || outgoingContactName || 'Unknown'\n : currentCall?.fromName || 'Unknown' }}\n </h1>\n <h1 *ngIf=\"currentCall?.client\"\n [ngStyle]=\"{'margin-top': showKeypad ? '0':'8px'}\">\n {{ currentCall?.direction == 'outgoing-call'\n ? currentCall?.fromName || 'Unknown'\n : currentCall?.toName || outgoingContactName || 'Unknown' }}\n </h1>\n <p *ngIf=\"!currentCall?.client\">\n {{ currentCall?.direction == 'outgoing-call'\n ? currentCall?.to\n : currentCall?.from }}\n </p>\n <p *ngIf=\"currentCall?.client\">\n {{ currentCall?.direction == 'outgoing-call'\n ? currentCall?.from\n : currentCall?.to }}\n </p>\n </ng-template>\n <!-- <h1 *ngIf=\"!currentCall?.client\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall?.direction == 'outgoing-call' ? currentCall?.toName || outgoingContactName || 'Unknown' :\n currentCall?.fromName || 'Unknown'}}</h1>\n <h1 *ngIf=\"currentCall?.client\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall?.direction == 'outgoing-call' ? currentCall?.fromName || 'Unknown' :\n currentCall?.toName || 'Unknown'}}</h1>\n <p *ngIf=\"!currentCall?.client\">{{ currentCall?.direction == 'outgoing-call' ? currentCall?.to || 'Unknown' : currentCall?.from || 'Unknown'}}</p>\n <p *ngIf=\"currentCall?.client\">{{ currentCall?.direction == 'outgoing-call' ? currentCall?.from || 'Unknown' : currentCall?.to || 'Unknown'}}</p> -->\n <h4 style=\"margin-top: 4px\">{{ timer}}</h4>\n </div>\n <div class=\"record-action-btns\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\">\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording, 'disabled': userSettingInfo?.callRecording == 'N'}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"!currentCall?.isAcceptCall || userSettingInfo?.callRecording == 'N'\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\" (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n <!-- Mute/unmute incoming call -->\n <div class=\"mute-incoming-row\" *ngIf=\"currentCall?.isAcceptCall && !showKeypad\">\n <span class=\"mute-incoming-label\">Mute incoming calls</span>\n <label class=\"switch mb-0\" title=\"Silence the ringtone of new incoming calls during this call\">\n <input type=\"checkbox\" [checked]=\"twilioService.isIncomingMuted\" (change)=\"toggleMuteIncomingCall()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n <div *ngIf=\"showKeypad\" class=\"sendDigit\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\" (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\" (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : '&nbsp;'}}</span>\n </div>\n </div>\n\n <div class=\"call-action-btns\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '723x'}\">\n <div class=\"flex align-items-center justify-content-evenly mb-3\">\n <button class=\"call-sec-btn mr-3\" [disabled]=\"!currentCall?.isAcceptCall || !canSelfToggleMute()\" [title]=\"selfMuteTooltip()\" (click)=\"toggleMute()\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isSelfEffectivelyMuted()\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isSelfEffectivelyMuted()\"> mic </span>\n </button>\n <button class=\"call-sec-btn mr-3\" [disabled]=\"!currentCall?.isAcceptCall\">\n <span class=\"material-symbols-outlined\" (click)=\"toggleKeypad()\"> transition_dissolve\n </span>\n </button>\n <button class=\"call-sec-btn\" [disabled]=\"!currentCall?.isAcceptCall\"\n (click)=\"toggleContactsPanel(currentCall)\">\n <span class=\"material-symbols-outlined\"> groups_2 </span>\n </button>\n </div>\n <div>\n <button class=\"call-btn end-call-btn\" [disabled]=\"!currentCall?.isAcceptCall\" (click)=\"endCall(false, currentCall)\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n </div>\n\n <!-- conference call view -->\n <div class=\"conference-call-view\" *ngIf=\"isConference\">\n <div class=\"conf-heading\">\n <span class=\"conf-icon material-symbols-outlined\"> groups </span>\n <span class=\"conf-title\">{{currentConferenceCall?.callLabel || 'Conference Call'}}</span>\n </div>\n <div class=\"scroll-container\">\n <div class=\"scroll-text conf-name\">\n <ng-container *ngFor=\"let call of currentCallList; let i = index\">\n <ng-container *ngIf=\"!call?.isConferenceHold\">\n <span *ngIf=\"shouldShowSeparator(i)\"> & </span>\n <span *ngIf=\"call?.client\">\n <ng-container *ngIf=\"!isSelfNumber(call) else selfNumber\">\n <span>{{call?.direction == 'outgoing-call' ? call?.fromName || call?.from :\n call?.toName || call?.to}}</span>\n </ng-container>\n <ng-template #selfNumber>\n <span>You</span>\n </ng-template>\n </span>\n <span *ngIf=\"!call?.client\">{{call?.direction == \"outgoing-call\" ? call?.toName || call?.to : call?.fromName || call?.from || 'Unknown number'}}</span>\n </ng-container>\n </ng-container>\n </div>\n </div>\n <div class=\"conf-timer\">{{ currentConferenceCall?.timer || timer }}</div>\n <div class=\"record-action-btns mt-auto\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\" >\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\" [disabled]=\"userSettingInfo.callRecording == 'N'\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording, 'disabled': userSettingInfo?.callRecording == 'N'}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\" (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n <!-- Mute/unmute incoming call -->\n <div class=\"mute-incoming-row\" *ngIf=\"currentCall?.isAcceptCall && !showKeypad\">\n <span class=\"mute-incoming-label\">Mute incoming calls</span>\n <label class=\"switch mb-0\" title=\"Silence the ringtone of new incoming calls during this call\">\n <input type=\"checkbox\" [checked]=\"twilioService.isIncomingMuted\" (change)=\"toggleMuteIncomingCall()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n <div *ngIf=\"showKeypad\" class=\"sendDigit mt-2\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\" (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\" (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : '&nbsp;'}}</span>\n </div>\n </div>\n <div class=\"conf-actions\">\n <button class=\"circle-btn\" [ngClass]=\"{'active': isSelfEffectivelyMuted()}\" [disabled]=\"!canSelfToggleMute()\" [title]=\"selfMuteTooltip()\" (click)=\"toggleMute(true)\">\n <span class=\"material-symbols-outlined\"> {{ isSelfEffectivelyMuted() ? 'mic_off' : 'mic' }} </span>\n </button>\n <button class=\"circle-btn\" (click)=\"toggleKeypad()\">\n <span class=\"material-symbols-outlined\"> transition_dissolve </span>\n </button>\n <button class=\"circle-btn\" (click)=\"toggleContactsPanel(currentCall)\">\n <span class=\"material-symbols-outlined\"> groups_2 </span>\n </button>\n </div>\n <div class=\"conf-end\">\n <button class=\"circle-btn danger\" (click)=\"endConfereneceCall(currentConferenceCall?.participants[0])\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n\n <div class=\"wave-container\">\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\n <defs>\n <path id=\"gentle-wave\"\n d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\n </defs>\n <g class=\"parallax\">\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\n </g>\n </svg>\n </div>\n </div>\n\n <!-- Incoming call user details shown in model -->\n <div class=\"call-container-model p-3 text-white model-content call-container\" *ngIf=\"isClickExpand\">\n <div class=\"close-info-panel-section\">\n <div class=\"d-flex justify-content-between\" *ngIf=\"currentConferenceCall?.conferenceId != selectedUserInfo?.conferenceId && newIncomingCallsList?.length > 1\">\n <p></p>\n <span class=\"material-symbols-outlined dial-close-btn \" (click)=\"onCloseC2CInfoPanel()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"#ffffff\">\n <path\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\n </svg>\n </span>\n </div>\n </div>\n <div class=\"mb-2 user-info-section\">\n <div class=\"text-center my-3\">\n <h3 class=\"text-white\">C2C CALL : {{selectedUserInfo?.sourceName}} | {{selectedUserInfo?.pointName}}</h3>\n </div>\n <div class=\"mb-3\">\n <h5 class=\"text-white mb-1\">Name:</h5>\n <h4 class=\"text-white userName\">{{selectedUserInfo?.name}}</h4>\n </div>\n <div class=\"f-13\">\n <div class=\"row mb-3\">\n <div class=\"col-6 mb-2\">\n <div class=\"mb-1\">Extension:</div>\n <div class=\"ml-2\">{{selectedUserInfo?.extension}}</div>\n </div>\n <div class=\"col-6 mb-2\">\n <div class=\"mb-1\">Number:</div>\n <div class=\"\">{{selectedUserInfo?.number}}</div>\n </div> \n </div>\n <div class=\"row mb-3\">\n <div class=\"col-12 mb-2\">\n <div class=\"me-2\">Email: </div>\n <div>{{selectedUserInfo?.email}}</div>\n </div>\n </div>\n <div class=\"row mb-3\">\n <div class=\"col-12 mb-2\">\n <div class=\"me-2\">Subject:</div>\n <div class=\"ml-2 subject-text\" title=\"{{selectedUserInfo?.subject}}\">\n {{selectedUserInfo?.subject}}</div>\n </div>\n </div>\n <div class=\"row mb-3\">\n <div class=\"col-12 mb-2\">\n <div class=\"me-2 mb-1\">Image:</div>\n <div class=\"text-ellipsis\">\n <ng-container\n *ngIf=\"selectedUserInfo?.image && selectedUserInfo?.image !== '-'; else noImage\">\n <img src=\"{{selectedUserInfo?.image}}\" alt=\"\" width=\"150\" class=\"ml-2\" />\n </ng-container>\n <ng-template #noImage>\n <span class=\"ml-2\">No Image Available</span>\n </ng-template>\n </div>\n </div>\n </div>\n <div class=\" mb-4\">\n <div class=\"\">\n <div class=\"mb-1\">Message:</div>\n <div>\n <div class=\"text-container\" [class.expanded]=\"isExpanded\">{{selectedUserInfo?.message}}\n </div>\n <small class=\"toggle-btn\" *ngIf=\"showButton\" (click)=\"toggleText()\">{{ isExpanded ? 'See\n less' : 'See more' }}</small>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- contact list panel -->\n <div class=\"contacts-panel\" *ngIf=\"showContactsPanel && !showNewCallLoader\">\n <div class=\"panel-loader-overlay p-3 text-center\" *ngIf=\"isParticipantPanelLoading\">\n <div class=\"spinner-border text-secondary\" role=\"status\">\n <span class=\"sr-only\">Loading...</span>\n </div>\n <p class=\"mt-2\"></p>\n </div>\n <div class=\"contacts-header\">\n <div class=\"participant-list-title\">\n {{ selectedConfName || 'Conference' }} Participants\n <!-- <ng-container *ngIf=\"totalParticipantsCount < 3; else confHeading\">\n Call Participants\n </ng-container>\n <ng-template #confHeading>\n </ng-template> -->\n </div>\n <div class=\"d-flex justify-content-between\">\n \n <span class=\"material-symbols-outlined settings-icon me-2\" *ngIf=\"isConferenceHost\" (click)=\"toggleSettingsPanel()\">\n settings\n </span>\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"toggleContactsPanel({}, true)\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"#000000\">\n <path\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\n </svg>\n </span>\n </div>\n </div>\n <div class=\"settings-overlay\" *ngIf=\"showSettingsPanel\" (click)=\"closeSettingsPanel()\">\n <div class=\"settings-drawer\" (click)=\"$event.stopPropagation()\">\n <div class=\"settings-header\">\n <span class=\"material-symbols-outlined\" (click)=\"closeSettingsPanel()\">arrow_back</span>\n <span>Call Settings</span>\n <span></span> <!-- placeholder for alignment -->\n </div>\n \n <div class=\"settings-body\">\n <!-- Mute all participants -->\n <div class=\"setting-item\">\n <div class=\"setting-label\">\n <span>Mute all participants</span>\n <small>Off \u2014 participants can mute and unmute themselves at any time.</small>\n </div>\n <label class=\"switch\">\n <input type=\"checkbox\" [ngModel]=\"settings.muteAll\" [disabled]=\"isUpdatingConferenceSettings\"\n (ngModelChange)=\"onMuteAllToggle($event)\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n \n <hr>\n \n <!-- Participant Permissions -->\n <div class=\"setting-group\">\n <h6>PARTICIPANT PERMISSIONS</h6>\n \n <!-- Allow unmute -->\n <div class=\"setting-item\">\n <div class=\"setting-label\">\n <span>\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3Z\" stroke=\"currentColor\" stroke-width=\"1.8\"></path>\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2M12 19v3\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\n </svg>\n Allow participants to self-unmute\n </span>\n <small>{{ settings.allowUnmute ? 'Yes \u2014 participants can unmute themselves after being muted\n individually by the host.' : 'No \u2014 participants cannot unmute themselves.' }}</small>\n </div>\n <label class=\"switch\">\n <input type=\"checkbox\" [ngModel]=\"settings.allowUnmute\" [disabled]=\"isUpdatingConferenceSettings\"\n (ngModelChange)=\"settings.allowUnmute = $event; updateConferenceSettings()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n \n <!-- Allow remove -->\n <div class=\"setting-item\">\n <div class=\"setting-label\">\n <span>\n <svg viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M17 21v-2a4 4 0 0 0-4-4H7a4 4 0 0 0-4 4v2M15 3.13a4 4 0 0 1 0 7.75\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\n <circle cx=\"9\" cy=\"7\" r=\"4\" stroke=\"currentColor\" stroke-width=\"1.8\"></circle>\n <path d=\"M19 8h4\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path>\n </svg>\n Allow participants to remove\n </span>\n <small>{{ settings.allowRemove ? 'Yes \u2014 participants can remove other participants.' : 'No \u2014\n participants cannot remove other participants, and cannot remove the host.' }}</small>\n </div>\n <label class=\"switch\">\n <input type=\"checkbox\" [ngModel]=\"settings.allowRemove\" [disabled]=\"isUpdatingConferenceSettings\"\n (ngModelChange)=\"settings.allowRemove = $event; updateConferenceSettings()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n <div class=\"setting-item\">\n <div class=\"setting-label\">\n <span>Allow participants to unhold</span>\n <small>{{ settings.allowUnhold ? 'Yes \u2014 participants can place themselves on hold.' : 'No \u2014\n participants cannot place themselves on hold.' }}</small>\n </div>\n <label class=\"switch\">\n <input type=\"checkbox\" [ngModel]=\"settings.allowUnhold\" [disabled]=\"isUpdatingConferenceSettings\"\n (ngModelChange)=\"settings.allowUnhold = $event; updateConferenceSettings()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n <div class=\"setting-item\">\n <div class=\"setting-label\">\n <span>Allow participants to mute other participants</span>\n <small>{{ settings.allowMuteOthers ? 'Yes \u2014 Participants can mute other participants, and can mute the host.' : 'No \u2014\n Participants cannot mute other participants, and cannot mute the host.' }}</small>\n </div>\n <label class=\"switch\">\n <input type=\"checkbox\" [ngModel]=\"settings.allowMuteOthers\" [disabled]=\"isUpdatingConferenceSettings\"\n (ngModelChange)=\"settings.allowMuteOthers = $event; updateConferenceSettings()\">\n <span class=\"switch-slider\"></span>\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n <!-- SEARCH INPUT (visible when isSearchVisible = true) -->\n <div class=\"search-bar p-3 position-relative\">\n <input type=\"text\" [placeholder]=\"isSpecialCall() ? 'Search by Name or Number for a new call' : 'Add a participant by Name or Number'\"\n [title]=\"isSpecialCall() ? 'Adding participants is not allowed on this call' : 'Add a participant by Name or Number'\" [(ngModel)]=\"searchText\" (input)=\"applyFilter()\" />\n <div class=\"search-contacts-list\">\n <ng-container *ngFor=\"let c of filteredList\">\n <div class=\"contact-item\" *ngIf=\"searchText\">\n <img class=\"contact-avatar\" [src]=\"c?.image || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c?.firstName}} {{c?.middleName}} {{c?.lastName}}</div>\n <div class=\"contact-title\">{{ (c?.numbersList && c?.numbersList[0]?.number) }}{{ c?.numbersList[0]?.numberLabel ? ' (' + c.numbersList[0].numberLabel + ')' : '' }}</div>\n </div>\n <button class=\"contact-call-btn contact-add-btn mr-2\" (click)=\"callContact(c)\"\n *ngIf=\"!c?.IsConnected && !isSpecialCall()\" title=\"Add to call\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n <button class=\"contact-call-btn\" (click)=\"CallToUnsavedNumber(c?.numbersList[0]?.number, true)\"\n *ngIf=\"!c?.IsConnected\" title=\"New Call\">\n <span class=\"material-symbols-outlined\"> call </span>\n </button>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!filteredList.length && isDirectCallOptionShow && searchText\">\n <div class=\"contact-item\">\n <img class=\"contact-avatar\" [src]=\"'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-title\">{{ searchText }}</div>\n </div>\n <button class=\"contact-call-btn contact-add-btn mr-2\" (click)=\"CallToUnsavedNumber(searchText)\"\n *ngIf=\"!isSpecialCall()\" title=\"Add to call\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n <button class=\"contact-call-btn\" (click)=\"CallToUnsavedNumber(searchText, true)\"\n title=\"New Call\">\n <span class=\"material-symbols-outlined\"> call </span>\n </button>\n </div>\n </ng-container>\n </div>\n </div>\n <div class=\"contacts-list\">\n <div class=\"px-2\">\n <h5 class=\"mb-0 title\">Active participants ({{ activeParticipantsCount }})</h5>\n </div>\n <hr class=\"mb-2 mt-1\">\n <ng-container *ngFor=\"let c of filteredParticipentList\">\n <div class=\"contact-item\" *ngIf=\"!c?.isLeft\">\n <img class=\"contact-avatar\" *ngIf=\"!c?.client\"\n [src]=\"c?.direction == 'outgoing-call' ? c?.toImage || 'assets/images/user.jpg' : c?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\n <img class=\"contact-avatar\" *ngIf=\"c?.client\"\n [src]=\"c?.direction == 'outgoing-call' ? c?.fromImage || 'assets/images/user.jpg' : c?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\" *ngIf=\"!c?.client\">{{c?.direction == 'outgoing-call' ? c?.toName || 'Unknown' : c?.fromName || 'Unknown'}}\n </div>\n <div class=\"contact-title\" *ngIf=\"!c?.client\">{{ c?.direction == 'outgoing-call' ? c?.to || 'Unknown' : c?.from || 'Unknown'}}</div>\n\n <div class=\"contact-name\" *ngIf=\"c?.client\">\n <ng-container *ngIf=\"!isSelfNumber(c) else selfNumber\">\n <span>{{c?.direction == 'outgoing-call' ? c?.fromName || 'Unknown' : c?.toName || 'Unknown'}}</span>\n </ng-container>\n <ng-template #selfNumber>\n <span>You</span>\n </ng-template>\n </div>\n <div class=\"contact-title\" *ngIf=\"c?.client\">{{ c?.direction == 'outgoing-call' ? c?.from || 'Unknown' : c?.to || 'Unknown'}}</div>\n <div class=\"d-flex\" *ngIf=\"c?.host\">\n <span class=\"organizer-label\">Organizer</span>\n </div>\n </div>\n <ng-container *ngIf=\"c?.joined && !c?.host\">\n <div class=\"connecting-wrapper mr-2\">\n <span class=\"ringing-text\">Ringing</span>\n <span class=\"dots\">\n <span>.</span>\n <span>.</span>\n <span>.</span>\n </span>\n </div>\n </ng-container>\n <ng-container *ngIf=\"c?.host && c?.isHold && !(deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call'))\">\n <div class=\"connecting-wrapper mr-2\">\n <span class=\"onHold-text\">On Hold</span>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!c?.joined || c?.host\">\n <button class=\"mic-btn mr-2\" [disabled]=\"c?.isHold || !canToggleMute(c)\" [title]=\"muteTooltip(c)\" (click)=\"onMuteUser(c)\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isEffectivelyMuted(c)\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isEffectivelyMuted(c)\"> mic </span>\n </button>\n <button class=\"conference-hold-contact mr-2\" [ngClass]=\"{ 'on-hold': c?.isHold }\"\n (click)=\"onHoldCall(c)\" *ngIf=\"!c?.host || (c?.host && (deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call')))\" [disabled]=\"isHoldBtnDisable || !canToggleHold(c)\">\n <span *ngIf=\"!c?.isHold\" class=\"material-symbols-outlined\" [title]=\"canToggleHold(c) ? 'Hold' : holdTooltip(c)\"> phone_paused</span>\n <span *ngIf=\"c?.isHold\" class=\"material-symbols-outlined\" [title]=\"canToggleHold(c) ? 'Resume' : holdTooltip(c)\"> resume </span>\n </button>\n </ng-container>\n <button class=\"conference-contact\" (click)=\"confirmLeaveParticipant(c)\"\n [disabled]=\"!canRemoveParticipant(c)\" [title]=\"removeTooltip(c)\" *ngIf=\"!c?.host\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n </button>\n <button class=\"conference-contact\" (click)=\"endConfereneceCall(c)\"\n *ngIf=\"c?.host && (deviceNumberList.includes(c?.from) || (deviceNumberList.includes(c?.to) && c?.direction == 'incoming-call'))\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n </button>\n </div>\n </ng-container>\n <hr class=\"m-2\">\n <div class=\"mt-3 px-2\">\n <h5 class=\"mb-0 title\">Participant added to the call</h5>\n </div>\n <hr class=\"mb-2 mt-1\">\n <ng-container *ngFor=\"let c of filteredParticipentList\">\n <div class=\"contact-item\" *ngIf=\"c?.isLeft\">\n <img class=\"contact-avatar\" *ngIf=\"!c?.client\"\n [src]=\"c?.direction == 'outgoing-call' ? c?.toImage || 'assets/images/user.jpg' : c?.fromImage || 'assets/images/user.jpg'\" alt=\"\" />\n <img class=\"contact-avatar\" *ngIf=\"c?.client\"\n [src]=\"c?.direction == 'outgoing-call' ? c?.fromImage || 'assets/images/user.jpg' : c?.toImage || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\" *ngIf=\"!c?.client\">{{c?.direction == 'outgoing-call' ? c?.toName || 'Unknown' : c?.fromName || 'Unknown'}}\n </div>\n <div class=\"contact-title\" *ngIf=\"!c?.client\">{{ c?.direction == 'outgoing-call' ? c?.to || 'Unknown' : c?.from || 'Unknown'}}</div>\n <div class=\"contact-name\" *ngIf=\"c?.client\">{{c?.direction == 'outgoing-call' ? c?.fromName || 'Unknown' : c?.toName || 'Unknown'}}\n </div>\n <div class=\"contact-title\" *ngIf=\"c?.client\">{{ c?.direction == 'outgoing-call' ? c?.from || 'Unknown' : c?.to || 'Unknown'}}</div>\n <div class=\"d-flex\" *ngIf=\"c?.host\">\n <span class=\"organizer-label\">Organizer</span>\n </div>\n </div>\n <div class=\"connecting-wrapper\" *ngIf=\"c?.joined\">\n <span class=\"ringing-text\">Ringing</span>\n <span class=\"dots\">\n <span>.</span>\n <span>.</span>\n <span>.</span>\n </span>\n </div>\n <button class=\"conference-contact\" (click)=\"onEndCall(c, false, true)\" *ngIf=\"!c?.host && c?.joined\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n </button>\n <button class=\"contact-call-btn contact-add-btn\" *ngIf=\"!c?.client && !c?.joined && !c?.businessNumber\"\n (click)=\"CallToUnsavedNumber(c.direction == 'outgoing-call' ? c?.to : c?.from, false, { skipDuplicateCheck: true }, c)\">\n <span class=\"material-symbols-outlined\"> add </span>\n <span class=\"label\">Rejoin</span>\n </button>\n <button class=\"contact-call-btn contact-add-btn\" *ngIf=\"c?.client && !c?.joined && !c?.businessNumber\"\n (click)=\"CallToUnsavedNumber(c.direction == 'outgoing-call' ? c?.from : c?.to, false, { skipDuplicateCheck: true }, c)\">\n <span class=\"material-symbols-outlined\"> add </span>\n <span class=\"label\">Rejoin</span>\n </button>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Conference Warning Modal -->\n<div class=\"custom-modal\" *ngIf=\"showConferenceWarningModal\">\n <div class=\"modal-content warning-modal\">\n <div class=\"warning-icon\">\n <span class=\"material-symbols-outlined\">warning</span>\n </div>\n <h3>Warning</h3>\n <p>\n Starting a new call will put the current call on hold\n and cannot be merged later.\n </p>\n <div class=\"warning-actions\">\n <button class=\"cancel-btn\" (click)=\"cancelNewCall()\">\n Cancel\n </button>\n <button class=\"proceed-btn\" (click)=\"confirmNewCall()\">\n Proceed\n </button>\n </div>\n </div>\n</div>\n\n<!-- Special Call Charges Modal (call screen open: active/held conference + new call).\n First call (no call screen yet) is shown by dialbox over its \"Connecting...\" loader. -->\n<div class=\"custom-modal\" *ngIf=\"twilioService.specialCallConfirm?.inCallScreen\">\n <div class=\"modal-content warning-modal\">\n <div class=\"warning-icon\">\n <span class=\"material-symbols-outlined\">warning</span>\n </div>\n <h3>Call Charges</h3>\n <p *ngIf=\"twilioService.specialCallConfirm?.message\">{{ twilioService.specialCallConfirm?.message }}</p>\n <p *ngIf=\"!twilioService.specialCallConfirm?.message\">\n Additional charges apply to this call. Do you want to proceed?\n </p>\n <div class=\"warning-actions\">\n <button class=\"cancel-btn\" (click)=\"onSpecialCallChargesAction(false)\">\n Cancel\n </button>\n <button class=\"proceed-btn\" (click)=\"onSpecialCallChargesAction(true)\">\n Proceed\n </button>\n </div>\n </div>\n</div>\n</div>\n\n<div class=\"min-call-container\" *ngIf=\"isMinimised\">\n <span class=\"material-symbols-outlined fullscreen\" (click)=\"maximiseDialpad()\"> open_in_full </span>\n <div style=\"display: flex; width: 100%\">\n <div>\n <div class=\"min-call-animation\" id=\"call-avatar\">\n <img class=\"min-avatar-img\" [src]=\"callData.img\" alt=\"\" />\n </div>\n </div>\n <div>\n <div class=\"min-callerDetails\">\n <div class=\"name\">\n {{callData.name}}\n </div>\n <p style=\"margin: 0\">{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\n </div>\n </div>\n </div>\n <div class=\"min-btn-container\">\n <div class=\"min-timer\">{{timer}}</div>\n <button class=\"min-call-sec-btn\" (click)=\"toggleMute()\" [disabled]=\"disbaleEndCallBtn || !canSelfToggleMute()\" [title]=\"selfMuteTooltip()\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isSelfEffectivelyMuted()\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isSelfEffectivelyMuted()\"> mic </span>\n </button>\n <button class=\"min-call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n</div>\n<!-- Call Disconnect Modal -->\n<div class=\"custom-modal\" *ngIf=\"showDisconnectModal\">\n <div class=\"modal-content p-3\">\n <div class=\"contacts-header p-0 pb-2\">\n <h4 class=\"title mb-0\">{{selectedConf?.conName || 'Call'}} Disconnect</h4>\n <div class=\"d-flex justify-content-between\">\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDisconnectModal = false\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"#000000\">\n <path\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\n </svg>\n </span>\n </div>\n </div>\n <div class=\"contant-body mb-2\">\n <p class=\"mt-2\">\n Exiting this call will not end the conference. The session will continue, and charges will incur to\n your\n account.\n </p>\n </div>\n <div class=\"button-group\">\n <div class=\"text-start d-flex align-items-center\">\n <label class=\"d-flex align-items-center mb-0 mr-2\">\n <input type=\"checkbox\" [(ngModel)]=\"isReasonChecked\" (ngModelChange)=\"onReasonCheckChanged($event)\" class=\"me-2\"/>\n </label>\n <div class=\"time-picker-24hr\">\n <!-- Hour picker -->\n <div class=\"custom-time-select\" [class.disabled-picker]=\"!isReasonChecked\">\n <div class=\"custom-time-display\" (click)=\"isReasonChecked && toggleHourDropdown()\">\n {{ leaveHour || 'HH' }}\n <span class=\"picker-arrow\">&#9660;</span>\n </div>\n <div class=\"custom-time-options\" *ngIf=\"showHourDropdown\">\n <div class=\"custom-time-option\"\n *ngFor=\"let h of hours\"\n [class.selected]=\"leaveHour === h\"\n (click)=\"selectHour(h)\">{{ h }}</div>\n </div>\n </div>\n <span class=\"time-sep\">:</span>\n <!-- Minute picker -->\n <div class=\"custom-time-select\" [class.disabled-picker]=\"!isReasonChecked\">\n <div class=\"custom-time-display\" (click)=\"isReasonChecked && toggleMinuteDropdown()\">\n {{ leaveMinute || 'MM' }}\n <span class=\"picker-arrow\">&#9660;</span>\n </div>\n <div class=\"custom-time-options\" *ngIf=\"showMinuteDropdown\">\n <div class=\"custom-time-option\"\n *ngFor=\"let m of minutes\"\n [class.selected]=\"leaveMinute === m\"\n (click)=\"selectMinute(m)\">{{ m }}</div>\n </div>\n </div>\n </div>\n </div>\n <button class=\"btn end-btn\" (click)=\"leaveConference()\" [disabled]=\"isReasonChecked && (!leaveHour || !leaveMinute)\">\n Leave\n </button>\n <button class=\"btn end-btn\" (click)=\"endConference()\" *ngIf=\"showEndAllButton\">\n End All\n </button>\n </div>\n </div>\n</div>\n<div class=\"custom-modal\" *ngIf=\"showLeaveConfirmationModal\">\n <div class=\"modal-content warning-modal\">\n <div class=\"warning-icon\">\n <span class=\"material-symbols-outlined\">info</span>\n </div>\n <h3>Leave Conference</h3>\n <p>\n You are about to leave <strong>{{ leaveConfConferenceName }}</strong>. \n Are you sure?\n </p>\n <div class=\"warning-actions\">\n <button class=\"cancel-btn\" (click)=\"cancelLeave()\">Cancel</button>\n <button class=\"proceed-btn\" (click)=\"confirmLeave()\">Leave</button>\n </div>\n </div>\n</div>", styles: [".call-container{width:385px;height:646px!important;margin:auto;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;box-sizing:border-box;position:relative;justify-content:center;align-items:center;z-index:1000;flex-flow:column;overflow-x:hidden;overflow-y:visible}.disabled{opacity:.5!important;pointer-events:none!important}.call-to-text{padding:6px 10px;border:1px solid #c2c2c2;border-radius:20px;font-size:13px}.collops{height:660px!important}.incoming-call-container{flex-flow:row!important}.active-call{width:385px!important}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto 0;border-radius:100%;border:solid 4px #fff;display:flex;align-items:center;justify-content:center}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.call-animation-play{animation:play 3s linear infinite}.call-info-wrapper{height:20px;overflow-y:auto;background:white;transition:height 1s}.open-collops{height:180px!important}.avatar-img{width:94px;height:94px;border-radius:100%}@keyframes play{0%{transform:scale(1)}15%{box-shadow:0 0 0 2px #fff6}25%{box-shadow:0 0 0 4px #fff6,0 0 0 8px #fff3}25%{box-shadow:0 0 0 8px #fff6,0 0 0 16px #fff3}50%{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3}to{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3;transform:scale(1.1);opacity:0}}.callerDetails{margin-top:8px;color:#fff;display:flex;flex-direction:column;align-items:center}.togglearrow-arrow{left:100%;background-color:#fff;width:25px;height:25px;text-align:center;cursor:pointer;border:1px solid #ccc;border-radius:50%;line-height:22px}.togglearrow-arrow.disabled{opacity:.3;cursor:not-allowed;pointer-events:none}.search-bar input{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;outline:none}.togglearrow-arrow.disabled:hover{opacity:.3;cursor:not-allowed}.callerDetails h1{width:260px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:12px 0 0;color:#fff;text-transform:capitalize;text-align:center}.callerDetails h4{margin:0;color:#fff}.tx-black,.title{color:#000!important}.callerDetails p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-btn,.mic-btn{position:relative;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:25px;padding:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226;width:50px;height:50px}.mic-btn{padding:5px;width:37px;height:37px}.receive-btn{background-color:#28a745!important;color:#fff!important}.receive-btn span{color:#fff!important}.scroll-container{width:100%;overflow:hidden;white-space:nowrap;position:relative}.scroll-text{display:inline-block;padding-left:100%;animation:scroll-left 12s linear infinite;font-size:16px}@keyframes scroll-left{0%{transform:translate(0)}to{transform:translate(-100%)}}.call-sec-btn span{color:#cccbcb}.call-btn{width:60px;height:60px;background-color:#fff;border-radius:30px;box-sizing:border-box;border:2px solid white;margin:0 16px}.end-call-btn{background-color:#e14e4e}.end-call-btn span{color:#fff!important}.call-btn span{color:#234de8}.btn-container{display:flex;flex-wrap:wrap;padding:0 30px}.key-btn{width:50px;height:50px;background-color:transparent;text-align:center;box-sizing:border-box;margin:0 18px;font-size:22px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#d3d3d3;cursor:pointer;opacity:.8}.call-action-btns{text-align:center}#call-input{background-color:transparent;border:none;outline:none;text-align:center;color:#fff}.sendDigit{position:relative;text-align:center;width:80%;margin:auto;background-color:#ffffff1a;padding:2px 0;border-radius:3px}.input-clear-btn{position:absolute;right:6px;color:#fff;cursor:pointer}#minimize-btn-div{position:absolute;right:14px;top:12px;z-index:10}.minimize-btn{color:#fff;cursor:pointer}.wave-container{position:absolute;bottom:0;overflow:hidden;width:100%}.waves{width:660px;position:relative;margin-bottom:-7px;height:40px;min-height:40px}.held-call-banner{position:absolute;top:0;left:0;right:0;z-index:2100;box-shadow:0 4px 12px #0000004d;border-radius:0 0 16px 16px;max-height:220px;overflow-y:auto}.held-call-content{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 6px;border-bottom:1px dotted #4b4b4b;border-left:3px solid transparent;transition:background .15s ease,border-left-color .15s ease;cursor:pointer}.held-call-content.held-call-selected{background:rgba(255,255,255,.15);border-left-color:#fff;border-radius:0 6px 6px 0}.held-main-label{font-size:13px;color:#fff;text-transform:uppercase;letter-spacing:.5px}.fa-info{font-size:smaller!important}.held-info{display:flex;align-items:center;gap:10px;flex:1}.hold-icon{font-size:24px;color:#fbbf24}.swap-icon{font-size:24px}.held-caller{display:flex;flex-direction:column;gap:2px}.held-label{font-size:10px;color:#ffffffb3;text-transform:uppercase;letter-spacing:.5px}.held-name{font-size:14px;font-weight:600;color:#fff}.held-number{font-size:13px;font-weight:500;color:#fff}.held-actions{display:flex;gap:8px;align-items:center}.held-btn{padding:6px 16px;border-radius:20px;border:none;font-size:13px;font-weight:600;cursor:pointer;transition:transform .2s,box-shadow .2s}.held-btn:hover{transform:scale(1.05);box-shadow:0 4px 12px #0003}.swap-btn{background:#3b82f6;color:#fff}.merge-btn{background:#10b981;color:#fff}.h-77px{height:77px}.incoming-banners-container{width:100%;padding:5px 8px;height:100%;gap:8px;overflow-y:auto}.call-container-model{width:385px!important;height:646px!important;margin:auto 0 0 1px;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;box-sizing:border-box;position:relative;overflow:hidden;justify-content:center;align-items:center}.incoming-banner{top:0;left:0;width:100%;right:0;background:linear-gradient(135deg,#1e3a8a 0%,#3b82f6 100%);padding:12px 16px;z-index:2000;box-shadow:0 4px 12px #0003;border-radius:16px}.incoming-banner-content{display:flex;align-items:center;justify-content:space-between;gap:12px}.incoming-info{flex:1;display:flex;flex-direction:column;gap:4px}.incoming-label{font-size:11px;color:#fffc;text-transform:uppercase;letter-spacing:.5px}.incoming-caller{display:flex;flex-direction:column;gap:2px}.caller-name{font-size:15px;font-weight:600;color:#fff}.caller-number{font-size:13px;color:#ffffffe6}.incoming-actions{display:flex;gap:8px;align-items:center}.banner-btn{width:44px;height:44px;border-radius:50%;border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:transform .2s}.banner-btn:hover{transform:scale(1.1)}.banner-btn .material-symbols-outlined{font-size:20px}.accept-btn{background:#10b981}.accept-btn .material-symbols-outlined{color:#fff}.reject-btn{background:#ef4444}.reject-btn .material-symbols-outlined{color:#fff}.contacts-panel{position:absolute;top:0;bottom:12px;width:340px;background:#ffffff;border-radius:16px;box-shadow:0 10px 25px #00000026;display:flex;flex-direction:column;overflow:hidden;height:40.4rem;left:24.1rem;z-index:1000000;color:#111827!important}.contacts-header{height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;border-bottom:1px solid #f0f0f0;color:#111827!important}.modal-content .contacts-header{height:40px}.search-contacts-list{max-height:196px;overflow:auto;position:absolute;width:91%;background:white;z-index:1000;box-shadow:0 4px 8px #0003,0 6px 20px #00000030;border-radius:0 10px 10px}.contant-body p{font-size:14px;color:#5f6061!important}.contacts-header .title{font-weight:600;color:#111827!important}.contacts-header .back,.contacts-header .search{color:#9aa0a6;cursor:pointer}.disabled{opacity:.5;pointer-events:none}.contacts-list{padding:8px 8px 12px;overflow-y:auto}.contact-item{display:flex;align-items:center;padding:10px 8px;border-radius:10px}.contact-item:hover{background:#f7f9fc}.contact-avatar{width:37px;height:37px;border-radius:50%;object-fit:cover;margin-right:12px}.contact-info{flex:1;min-width:0;overflow:hidden}.contact-name{font-weight:600;color:#111827;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.contact-title{font-size:12px;color:#6b7280}.contact-call-btn{display:inline-flex;align-items:center;gap:6px;background:#234de8;color:#fff;border:none;border-radius:16px;padding:8px;cursor:pointer}.contact-add-btn{background-color:#2ecc71!important}.conference-hold-contact{display:inline-flex;align-items:center;gap:5px;background:#727070;color:#fff;border:none;border-radius:50%;padding:7px;cursor:pointer}.conference-hold-contact.on-hold{background:#28a745!important;color:#fff}.user-info-section{width:100%;height:100%;overflow-y:auto;overflow-x:hidden!important}.user-info-section::-webkit-scrollbar{display:none}.toggle-btn{cursor:pointer}.text-container{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;transition:all .3s ease}.mute-incoming-row{display:flex;align-items:center;justify-content:center;gap:8px;margin:0 0 10px}.mute-incoming-label{font-size:11px;color:#fff}.switch{position:relative;display:inline-block;width:38px;height:19px;flex-shrink:0}.switch-slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;border-radius:22px;transition:.3s}.close-info-panel-section{width:100%;height:20px}.close-info-panel-section .material-symbols-outlined{font-size:12px;cursor:pointer}.c2c-title{color:#fff;white-space:normal;word-break:break-word;line-height:1.4}.switch-slider:before{content:\"\";position:absolute;height:14px;width:15px;left:3px;bottom:3px;background-color:#fff;border-radius:50%;transition:.3s}.switch input:checked+.switch-slider{background-color:#2ecc71}.switch input:checked+.switch-slider:before{transform:translate(18px)}.text-container.expanded{-webkit-line-clamp:unset}.userName{font-family:FontAwesome}.subject-text{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden}.conference-contact{display:inline-flex;align-items:center;gap:5px;background:#e14e4e;color:#fff;border:none;border-radius:50%;padding:7px;cursor:pointer}.organizer-label{padding:1px 5px;font-size:11px;border-radius:10px;border:1px solid #a0a0a0;margin-top:2px;background:#fcfcfc;color:#000}.custom-modal{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:flex;align-items:center;z-index:10000001;border-radius:21px}.modal-content{background:#ffffff;padding:25px;border-radius:8px;width:350px;text-align:center}.title{margin-bottom:15px;color:#d9534f}.message{margin-bottom:20px}.button-group{display:flex;justify-content:space-between}.btn{padding:8px 15px;border:none;border-radius:5px;cursor:pointer;font-weight:500}.end-btn{background-color:#dc3545;color:#fff;display:flex;align-items:center;font-size:13px}.leave-btn{background-color:#007bff;color:#fff}.contact-call-btn .material-symbols-outlined{font-size:18px;color:#fff}.contact-call-btn .label{font-size:12px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}.animated-margin{transition:margin-top .5s ease}app-incoming-call{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1001}.min-call-container{width:320px;height:124px;border-radius:20px;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;display:flex;flex-direction:column;box-sizing:border-box;position:relative;overflow:hidden;margin:auto;align-items:center;padding:12px 16px;color:#fff}.min-call-animation{background:#fff;width:48px;height:48px;position:relative;margin:0 12px 0 auto;border-radius:100%;border:solid 2px #fff}.min-avatar-img{width:46px;height:46px;border-radius:100%;position:absolute;left:0;top:0}.border-radius-50{border-radius:50%}.min-callerDetails{color:#fff;display:flex;flex-direction:column;align-items:flex-start}.name{width:170px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:20px;margin:0;color:#fff}.min-callerDetails p{margin:0;color:#fff}.min-btn-container{position:relative;display:flex;width:100%;justify-content:flex-start;align-items:center;margin-top:6px}.min-call-sec-btn{width:40px;height:40px;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:20px;display:flex;align-items:center;justify-content:center;margin-right:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226}.min-call-sec-btn span{color:#cccbcb}.min-call-btn{width:40px;height:40px;border-radius:20px;box-sizing:border-box;border:2px solid white;display:flex;align-items:center;justify-content:center}.fullscreen{position:absolute;right:18px;top:14px;color:#e8e8e8;font-size:18px;cursor:pointer}.btn-container{display:flex;flex-wrap:wrap;padding:0 24px}.dial-btn{width:40px;height:40px;background-color:transparent;text-align:center;box-sizing:border-box;margin:4px 25px;font-size:24px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#b5b5b5;cursor:pointer}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.min-timer{width:50px;font-size:18px;margin-right:10px;border-radius:4px;height:35px;display:flex;align-items:center}.record-action-btns{display:flex;flex-direction:column;align-items:center;margin-top:35px}.record-btn-container{position:relative}.record-btn{border:none;border-radius:50%;width:50px;height:50px;display:flex;align-items:center;justify-content:center;cursor:pointer;margin:0 5px;position:relative;overflow:hidden}.record-btn.start-stop .recording-icon{width:50%;height:50%;border-radius:50%;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.record-btn.start-stop.recording .recording-icon{background-color:#000}.record-btn.start-stop.recording{border:3px solid #000}.record-btn.start-stop.stopped .recording-icon{background-color:red;border:3px solid #ff0000;border-radius:50%;position:absolute}.record-btn.start-stop.stopped{border:3px solid #ff0000}.record-btn.start-stop.stopped .recording-icon{width:40%;height:40%;border-radius:0;background-color:red}.pause-resume-btns{display:flex;flex-direction:column;align-items:center;margin-top:10px}.record-btn.pause-resume{border:none;border-radius:50%;width:50px;height:50px;background:white;display:flex;align-items:center;justify-content:center;margin:5px 0}.record-btn.pause-resume .material-symbols-outlined{font-size:20px;color:#000}.timer-display{font-size:1.2em;margin-top:10px;color:#000}.w-40{width:40%}.w-60{width:60%}.callToNum{color:#fff;font-weight:400;text-align:center}.callToNum span{font-weight:600}.conference-call-view{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;width:100%;padding:12px 16px 35px;color:#fff;height:100%}.conf-heading{display:flex;align-items:center;gap:8px;margin-top:45px}.conf-icon{color:#4579aa;font-size:32px;width:50px;height:50px;border:1px solid gray;border-radius:50%;display:flex;align-items:center;justify-content:center;background:#e1e1e1}.conf-title{font-weight:600;font-size:20px}.conf-name{margin-top:10px;font-size:17px;font-weight:600;text-align:center}.conf-timer{margin-top:4px;font-size:12px;opacity:.9}.conf-record{margin-top:14px}.record-stop-btn{width:44px;height:44px;border-radius:50%;border:none;background:#fff;display:flex;align-items:center;justify-content:center}.record-stop-btn .material-symbols-outlined{color:#e14e4e;font-size:28px}.conf-remove{margin-top:8px}.remove-btn{background:#ff0000!important;color:#fff;border:none;border-radius:6px;padding:6px 12px;font-size:12px;width:82px!important;height:auto}.conf-actions{margin-top:14px;display:flex;align-items:center;justify-content:center;gap:18px}.circle-btn{width:56px;height:56px;border-radius:50%;border:none;background:#000;display:flex;align-items:center;justify-content:center}.circle-btn .material-symbols-outlined{color:#fff;font-size:24px}.circle-btn.active{opacity:.85}.conf-end{margin-top:16px}.circle-btn.danger{background:#e14e4e}.circle-btn.danger .material-symbols-outlined{color:#fff}.warning-modal{background:white;width:360px;border-radius:18px;padding:24px;text-align:center;box-shadow:0 10px 30px #00000040}.warning-icon{margin-bottom:12px}.warning-icon .material-symbols-outlined{font-size:48px;color:#f59e0b}.warning-modal h3{margin-bottom:12px;font-size:20px;font-weight:600;color:#111827!important}.warning-modal p{color:#555!important;font-size:14px;line-height:1.5;margin-bottom:24px}.warning-modal p strong{color:#111827!important}.warning-actions{display:flex;justify-content:center;gap:12px}.cancel-btn,.proceed-btn{border:none;padding:10px 18px;border-radius:8px;cursor:pointer;font-weight:600}.cancel-btn{background:#e5e7eb;color:#111827}.proceed-btn{background:#234de8;color:#fff}.time-picker-24hr{display:flex;align-items:center;gap:4px}.time-sep{font-weight:700;font-size:16px;color:#333}.custom-time-select{position:relative;width:58px;-webkit-user-select:none;user-select:none}.custom-time-select.disabled-picker{opacity:.45;pointer-events:none}.custom-time-display{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;border:1px solid #ced4da;border-radius:4px;background:#fff;font-size:13px;cursor:pointer;white-space:nowrap;color:#333!important}.custom-time-display:hover{border-color:#234de8}.picker-arrow{font-size:9px;margin-left:4px;color:#666}.custom-time-options{position:fixed;background:#fff;border:1px solid #ced4da;border-radius:4px;max-height:160px;overflow-y:auto;z-index:99999999;min-width:58px;box-shadow:0 4px 12px #00000026}.custom-time-option{padding:5px 10px;font-size:13px;cursor:pointer;text-align:center;color:#333}.custom-time-option:hover{background:#e8eeff;color:#234de8}.custom-time-option.selected{background:#234de8;color:#fff;font-weight:600}.dialpad-alerts{position:absolute;left:50%;transform:translate(-50%);width:calc(100% - 32px);z-index:9999999}.normal-call-alert{top:78px}.conference-alert{top:145px}.dialbox-pop1{background:#dff6dd!important;color:#1d4d1d!important;border-radius:10px;padding:10px 14px;font-size:14px;box-shadow:0 4px 12px #00000040;border:1px solid #b7dfc3}.btn-disc{border:none;background:transparent;color:#6b7280!important;font-size:13px;font-weight:500}.connecting-overlay{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:16px 0 24px}.connecting-text{color:#ffffffe6;font-size:15px;font-weight:500;letter-spacing:.5px;margin:0}.connecting-dots{display:flex;gap:8px;align-items:center}.connecting-dots span{display:inline-block;width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.85);animation:connecting-bounce 1.2s infinite ease-in-out}.connecting-dots span:nth-child(1){animation-delay:0s}.connecting-dots span:nth-child(2){animation-delay:.2s}.connecting-dots span:nth-child(3){animation-delay:.4s}@keyframes connecting-bounce{0%,80%,to{transform:scale(.6);opacity:.4}40%{transform:scale(1.2);opacity:1}}.connecting-wrapper{display:flex;align-items:center;font-size:13px;color:#4caf50;margin-top:4px;font-weight:500}.participant-list-title,.onHold-text{color:#000}.ringing-text,.onHold-text{margin-right:2px;font-size:11px}.held-actions .connecting-wrapper{color:#fff}.dots span{animation:blink 1.4s infinite;opacity:0;font-size:16px}.dots span:nth-child(1){animation-delay:0s}.dots span:nth-child(2){animation-delay:.2s}.dots span:nth-child(3){animation-delay:.4s}@keyframes blink{0%{opacity:0}50%{opacity:1}to{opacity:0}}.loader-wrapper.outgoing-call-loader{position:absolute;inset:0;z-index:100;display:flex;align-items:center;justify-content:center}.panel-loader-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffffb3;display:flex;justify-content:center;align-items:center;z-index:10000009}.settings-icon{cursor:pointer;font-size:24px;color:#555;position:relative;top:5px;right:2px}.settings-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);z-index:1000001;display:flex;align-items:flex-start;justify-content:flex-end}.settings-drawer{background:#fff;width:100%;max-width:100%;height:100%;padding:1.5rem 1rem;overflow-y:auto;box-sizing:border-box;transform:translate(100%);animation:slideInFromRight .3s forwards}@keyframes slideInFromRight{to{transform:translate(0)}}.settings-header{display:flex;justify-content:space-between;align-items:center;font-size:1.2rem;font-weight:600;padding-bottom:.75rem;border-bottom:1px solid #eee}.settings-header span:first-child{cursor:pointer}.settings-body{margin-top:1.5rem}.setting-item{display:flex;justify-content:space-between;align-items:center;padding:.75rem 0;gap:1rem}.setting-label{flex:1}.setting-label span{font-weight:500}.setting-label svg{width:15px;height:15px;color:#393939;flex-shrink:0}.setting-label small{display:block;font-size:.75rem;color:#666;margin-top:.15rem}.setting-group h6{font-weight:600;color:#888;font-size:.75rem;letter-spacing:.5px;margin:1rem 0 .5rem}hr{margin:.5rem 0;border-color:#f0f0f0}.switch{position:relative;display:inline-block;width:44px;height:24px;flex-shrink:0}.switch input{opacity:0;width:0;height:0}.switch-slider{position:absolute;cursor:pointer;inset:0;background:#ccc;border-radius:24px;transition:.3s}.switch-slider:before{content:\"\";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background:white;border-radius:50%;transition:.3s}.switch input:checked+.switch-slider{background:#007bff}.switch input:checked+.switch-slider:before{transform:translate(20px)}\n"] }]
4938
5111
  }], ctorParameters: function () { return [{ type: ExtensionService }, { type: i0.ChangeDetectorRef }, { type: TwilioService }, { type: IpAddressService }, { type: IncomeingCallSocketService }]; }, propDecorators: { callData: [{
4939
5112
  type: Input
4940
5113
  }], selectedCallerId: [{
@@ -5063,58 +5236,6 @@ class DialboxComponent {
5063
5236
  get isDialpadHidden() {
5064
5237
  return this._isDialpadHidden;
5065
5238
  }
5066
- // Intercept the keyboard refresh shortcuts (F5, Ctrl+R / Cmd+R) so we can
5067
- // show OUR custom-worded confirmation instead of the browser's generic one.
5068
- // @HostListener('window:keydown', ['$event'])
5069
- // handleRefreshShortcut(event: KeyboardEvent) {
5070
- // const isRefreshKey =
5071
- // event.key === 'F5' ||
5072
- // ((event.ctrlKey || event.metaKey) && (event.key === 'r' || event.key === 'R'));
5073
- // if (isRefreshKey && (this.isCallInProgress || this.incomingCallsList?.length)) {
5074
- // // Stop the browser's default refresh so our modal can decide.
5075
- // event.preventDefault();
5076
- // event.returnValue = true;
5077
- // // this.confirmReloadDuringCall();
5078
- // }
5079
- // }
5080
- // private confirmReloadDuringCall() {
5081
- // if (this.isReloadConfirmed) {
5082
- // return;
5083
- // }
5084
- // swal({
5085
- // title: 'Reload page?',
5086
- // text: 'Reloading this page will disconnect your active call. Are you sure you want to continue?',
5087
- // type: 'warning',
5088
- // showCancelButton: true,
5089
- // confirmButtonText: 'Reload',
5090
- // cancelButtonText: 'Cancel',
5091
- // // Tag only THIS modal's container so the z-index override applies to the
5092
- // // reload warning alone, not to other swal error/warning alerts.
5093
- // onBeforeOpen: (modalElement: HTMLElement) => {
5094
- // modalElement?.parentElement?.classList.add('swal-reload-on-top');
5095
- // },
5096
- // })
5097
- // .then(async (result) => {
5098
- // if (!result.value) {
5099
- // // Cancel / dismiss -> stay on the page, keep the call active.
5100
- // return;
5101
- // }
5102
- // // Reload confirmed: tear down the call, then reload. The flag prevents
5103
- // // the native beforeunload dialog from appearing on top of this.
5104
- // this.isReloadConfirmed = true;
5105
- // const conferenceId = this.incomingCallsList?.[0]?.conferenceId;
5106
- // if (conferenceId) {
5107
- // try {
5108
- // await this.extensionService
5109
- // .getRemoveParticipants('all', conferenceId)
5110
- // .toPromise();
5111
- // } catch {
5112
- // // Proceed with reload even if cleanup fails.
5113
- // }
5114
- // }
5115
- // window.location.reload();
5116
- // });
5117
- // }
5118
5239
  beforeUnloadHandler($event) {
5119
5240
  var _a;
5120
5241
  // Already confirmed via our custom modal -> reload silently.
@@ -5242,7 +5363,19 @@ class DialboxComponent {
5242
5363
  this.incomeingCallSocketService.connect(this.deviceId);
5243
5364
  try {
5244
5365
  this.incomeingCallSocketService.listen().subscribe((incomingCallData) => __awaiter(this, void 0, void 0, function* () {
5245
- var _a, _b, _c, _d, _e;
5366
+ var _a, _b, _c, _d;
5367
+ // A special number added to a normal call fails on BE (error already shown), but the socket
5368
+ // still sends that participant without an isLeft key, so it showed up as active. Treat it as left.
5369
+ if (Array.isArray(incomingCallData)) {
5370
+ incomingCallData.forEach((callInfo) => {
5371
+ var _a;
5372
+ (_a = callInfo === null || callInfo === void 0 ? void 0 : callInfo.participants) === null || _a === void 0 ? void 0 : _a.forEach((participant) => {
5373
+ if ((participant === null || participant === void 0 ? void 0 : participant.specialCall) === true && (participant === null || participant === void 0 ? void 0 : participant.isLeft) === undefined) {
5374
+ participant.isLeft = true;
5375
+ }
5376
+ });
5377
+ });
5378
+ }
5246
5379
  this.twilioService.conferenceCallInfo = incomingCallData;
5247
5380
  this.conferenceCallList.emit(incomingCallData);
5248
5381
  this.token = localStorage.getItem('ext_token') || '';
@@ -5318,7 +5451,6 @@ class DialboxComponent {
5318
5451
  if (((_b = this.incomingCallsList) === null || _b === void 0 ? void 0 : _b.length) && (incomingCallData === null || incomingCallData === void 0 ? void 0 : incomingCallData.length)) {
5319
5452
  this.isCallInProgress = true;
5320
5453
  this.isDialpadHidden = false;
5321
- // this.isLoadershow = false;
5322
5454
  this.isIncomingCallnotification = false;
5323
5455
  this.cdk.detectChanges();
5324
5456
  }
@@ -5329,7 +5461,7 @@ class DialboxComponent {
5329
5461
  this.isCallInProgress = true;
5330
5462
  this.cdk.detectChanges();
5331
5463
  }
5332
- else if (!this.isIncomingCallnotification) {
5464
+ else if (!this.isIncomingCallnotification && !this.twilioService.isAwaitingSpecialCallConfirm) {
5333
5465
  // Genuinely idle: no answered calls and no ringing notifications → full reset.
5334
5466
  this.callData = [];
5335
5467
  this.incomingCallsList = [];
@@ -5345,16 +5477,6 @@ class DialboxComponent {
5345
5477
  }, 2000);
5346
5478
  }
5347
5479
  }
5348
- if (!((_e = this.incomingCallsList) === null || _e === void 0 ? void 0 : _e.length)) {
5349
- // setTimeout(() => {
5350
- // if(!this.incomingCallsList?.length) {
5351
- // this.isCallInProgress = false;
5352
- // this.twilioService.device?.disconnectAll();
5353
- // this.twilioService.spareDevice?.disconnectAll();
5354
- // this.twilioService.acceptedCallList = [];
5355
- // }
5356
- // }, 5000);
5357
- }
5358
5480
  }));
5359
5481
  this.token = localStorage.getItem('ext_token') || '';
5360
5482
  this.getContactList();
@@ -5554,13 +5676,8 @@ class DialboxComponent {
5554
5676
  this.incomingCallsList.splice(incomingCallIndex, 1);
5555
5677
  this.incomeingCallSocketService.pause();
5556
5678
  this.cdk.detectChanges();
5557
- // if (!this.incomingCallsList?.length) {
5558
- // console.log('407');
5559
- // this.isCallInProgress = false;
5560
- // }
5561
5679
  }
5562
5680
  if (this.connectingIncomingCallId == ((_q = (_p = snapshot === null || snapshot === void 0 ? void 0 : snapshot.data) === null || _p === void 0 ? void 0 : _p.data) === null || _q === void 0 ? void 0 : _q.recordId) || this.connectingIncomingCallId == ((_s = (_r = snapshot === null || snapshot === void 0 ? void 0 : snapshot.data) === null || _r === void 0 ? void 0 : _r.data) === null || _s === void 0 ? void 0 : _s.participantId) && ((_u = (_t = snapshot === null || snapshot === void 0 ? void 0 : snapshot.data) === null || _t === void 0 ? void 0 : _t.data) === null || _u === void 0 ? void 0 : _u.status) != "accepted") {
5563
- // swal("Error", 'Internal Server Error', "error");
5564
5681
  this.twilioService.isConnectingIncomingCallId.next('');
5565
5682
  }
5566
5683
  console.log('test', this.incomingCallsList);
@@ -6372,10 +6489,10 @@ class DialboxComponent {
6372
6489
  }
6373
6490
  }
6374
6491
  DialboxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DialboxComponent, deps: [{ token: TwilioService }, { token: ExtensionService }, { token: IpAddressService }, { token: ExtensionService }, { token: i0.ChangeDetectorRef }, { token: i4.Router }, { token: IncomeingCallSocketService }], target: i0.ɵɵFactoryTarget.Component });
6375
- DialboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DialboxComponent, selector: "lib-dialbox", inputs: { autoOpenOnIncoming: "autoOpenOnIncoming", contactInfo: "contactInfo", deviceId: "deviceId", userId: "userId", callAction: "callAction", isDialpadHidden: "isDialpadHidden", incomingCallData: "incomingCallData", incomingCallnotification: "incomingCallnotification", updatedTwilioToken: "updatedTwilioToken" }, outputs: { closeDialpadEvent: "closeDialpadEvent", callInitiated: "callInitiated", endCallEvent: "endCallEvent", minimiseEvent: "minimiseEvent", incomingCallsNewInfoEvent: "incomingCallsNewInfoEvent", incomingCallInitiated: "incomingCallInitiated", conferenceCallList: "conferenceCallList", numberDialed: "numberDialed" }, host: { listeners: { "window:beforeunload": "beforeUnloadHandler($event)", "window:unload": "unloadHandler()" } }, viewQueries: [{ propertyName: "dialInputElement", first: true, predicate: ["dialInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"dragparent1\" [ngStyle]=\"{'display':isDialpadHidden ? 'none': 'block'}\">\r\n <lib-call-progress *ngIf=\"isCallInProgress\" (endCallEvent)=\"endCall()\" (minimiseEvent)=\"onMinimise($event)\"\r\n (muteAllStatusEvent)=\"showDialAlert($event)\"\r\n (incomingCallInitiated)=\"newIncomingCallInitiated()\" [newIncomingCallData]=\"newIncomingCallData\"\r\n [deviceId]=\"deviceId\" [newIncomingCallsList]=\"incomingCallsList\" [missCallInfo]=\"missCallInfo\"\r\n (incomingCallsNewInfo)=\"incomingCallsNewInfo($event)\" [selectedCallerId]=\"selectedCallerId\"\r\n [callerIdList]=\"callerIdList\" [callAction]=\"callAction\" [conferenceCallInfo]=\"conferenceCallInfo\"\r\n [newCallConference]=\"newCallConference\" [userSettingInfo]=\"userSettingInfo\"\r\n [cancelConnectingAction]=\"cancelConnectingAction\"\r\n [outgoingContactName]=\"outgoingContactName\"\r\n [incomingFromImage]=\"incomingFromImage\"\r\n (endIncomingCallEvent)=\"endIncomingCall($event)\" (isLoadershown)=\"onLoadershow($event)\" [callData]=\"callData\">\r\n </lib-call-progress>\r\n\r\n <div class=\"loader-wrapper outgoing-call-loader\" *ngIf=\"isLoadershow\">\r\n <div class=\"active-call\" style=\"display: flex; flex-direction: column; position: relative;\">\r\n <div class=\"call-animation call-animation-play\">\r\n <img class=\"avatar-img\" [src]=\"contactImgForLoader\" alt=\"\" />\r\n </div>\r\n <div class=\"callerDetails\">\r\n <h1 style=\"margin-top: 8px;\">Connecting...</h1>\r\n <p style=\"text-transform: capitalize;\">{{ contactNameForLoader || dialedNumber }}</p>\r\n </div>\r\n \r\n <div class=\"call-action-btns\">\r\n <div class=\"d-flex justify-content-center\">\r\n <button class=\"call-btn end-call-btn\" disabled style=\"visibility: hidden;\" (click)=\"cancelConnectingCall()\">\r\n <span class=\"material-symbols-outlined\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"dialpad-container\" [ngClass]=\"{'mini-dialpad': isMinimised}\"\r\n *ngIf=\"(!isCallInProgress && !incomingCallsList.length) && !isLoadershow\" tabindex=\"0\" (keydown)=\"handleDivKeydown($event)\">\r\n <div id=\"topPanel\" [ngStyle]=\"{'height': callerIdList.length ? '40%' : '39%'}\">\r\n <div class=\"dialpad-alerts\" *ngIf=\"dialAlert.show\">\r\n <div class=\"no-selection-alert\">\r\n <p class=\"mb-0\">{{dialAlert.msg}}</p>\r\n <span class=\"fa fa-times\" (click)=\"shakeDedicatedBtn = false\"></span>\r\n </div>\r\n </div>\r\n <div class=\"dialpad-alerts\" *ngIf=\"callNumberToast.show\">\r\n <div class=\"dialbox-pop1 alert fade show\" [ngClass]=\"callNumberToast.type\" role=\"alert\">\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"flex-grow-1 my-auto text-left\">\r\n You'r calling <strong>{{callNumberToast.displayNum}}</strong>\r\n </div>\r\n <div class=\"text-right\">\r\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelDialNumber()\">Cancel Call</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div style=\"padding: 0 18px\" (paste)=\"handleNumberPaste($event)\">\r\n <div class=\"d-flex justify-content-between mt-2\">\r\n <p></p>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"hideDialpad()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"#ffffff\">\r\n <path\r\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"input-box\">\r\n <input type=\"text\" #dialInput placeholder=\"Enter a name or number\" tabindex=\"1\" [(ngModel)]=\"dialedNumber\"\r\n (ngModelChange)=\"onDialInputChange($event)\" />\r\n <span class=\"\" id=\"input-clear-btn\" (click)=\"clearInput()\" *ngIf=\"showInputClearBtn\">\r\n <svg width=\"50px\" height=\"30px\" viewBox=\"0 10 40 60\" xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" baseProfile=\"full\"\r\n enable-background=\"new 0 0 76.00 76.00\" xml:space=\"preserve\">\r\n <path fill=\"#5d6061\" fill-opacity=\"1\" stroke-width=\"0.2\" stroke-linejoin=\"round\"\r\n d=\"M 47.5282,42.9497L 42.5784,38L 47.5282,33.0502L 44.9497,30.4718L 40,35.4216L 35.0502,30.4718L 32.4718,33.0502L 37.4216,38L 32.4718,42.9497L 35.0502,45.5282L 40,40.5784L 44.9497,45.5282L 47.5282,42.9497 Z M 18.0147,41.5355L 26.9646,50.4854C 28.0683,51.589 29,52 31,52L 52,52C 54.7614,52 57,49.7614 57,47L 57,29C 57,26.2386 54.7614,24 52,24L 31,24C 29,24 28.0683,24.4113 26.9646,25.5149L 18.0147,34.4645C 16.0621,36.4171 16.0621,39.5829 18.0147,41.5355 Z M 31,49C 30,49 29.6048,48.8828 29.086,48.3641L 20.1361,39.4142C 19.355,38.6332 19.355,37.3669 20.1361,36.5858L 29.086,27.6362C 29.6048,27.1175 30,27 31,27.0001L 52,27.0001C 53.1046,27.0001 54,27.8955 54,29.0001L 54,47.0001C 54,48.1046 53.1046,49.0001 52,49.0001L 31,49 Z \" />\r\n </svg>\r\n </span>\r\n <span class=\"input-info-icon\" placement=\"bottom-right\" tooltipClass=\"input-tooltip\"\r\n ngbTooltip=\"For extension dialing, use formats like +12345678910 x123,+12345678910 ext.123, +12345678910,123\"><i\r\n class=\"fa fa-info-circle\"></i></span>\r\n </div>\r\n <div class=\"guide\" *ngIf=\"callerIdList.length && !(dialedNumber.length > 2)\">\r\n <span class=\"guidetext\">Please enter a number or select a saved contact</span>\r\n </div>\r\n <div style=\"height: 119px; overflow: auto;\">\r\n <div class=\"contact-card\" *ngFor=\"let contact of filteredContactList\" (click)=\"onContactSelect(contact)\">\r\n <div class=\"contact-img\">\r\n <img [src]=\"contact.image\" alt=\"user image\" loading=\"lazy\" *ngIf=\"contact.image else alphaName\" />\r\n <ng-template #alphaName>\r\n <span class=\"contact-alpha-img\">{{getFirstLetter(contact.firstName)}}</span>\r\n </ng-template>\r\n </div>\r\n <div class=\"contact-details\">\r\n <p style=\"margin-bottom: 4px\" class=\"contact-name\">{{getFullName(contact) }}</p>\r\n <p>{{contact.selectedNumber.number}}</p>\r\n </div>\r\n </div>\r\n <div class=\"contact-card\" *ngIf=\"!filteredContactList.length && dialedNumber.length > 2 && !isValidationMessageShow\">\r\n <div class=\"no-contact-message\">\r\n No Contacts Found\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"wave-container\">\r\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\r\n <defs>\r\n <path id=\"gentle-wave\" d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n </div>\r\n <div class=\"btn-container\" *ngIf=\"!isMinimised\">\r\n <button class=\"dial-btn\" *ngFor=\"let key of keypadVal;let i = index\" (keydown.enter)=\"onEnter(key.num)\"\r\n [ngStyle]=\"{'margin-top': key.text === '+' ? '3px' : '0'}\" [tabindex]=\"dialedNumber.length ? '0': i+2\" longPress\r\n (longPress)=\"addNumber(key.text)\" shortPress (shortPress)=\"addNumber(key.num)\">\r\n {{key.num}}\r\n <span *ngIf=\"key.num == 1;else otherThanOne\" class=\"material-symbols-outlined voicemail\">\r\n voicemail\r\n </span>\r\n <ng-template #otherThanOne>\r\n <span class=\"btn-albhabets\" [ngClass]=\"{'plusSign': key.text === '+'}\">{{key.text ? key.text :\r\n '&nbsp;'}}</span>\r\n </ng-template>\r\n </button>\r\n </div>\r\n <div class=\"call-btn-container\" *ngIf=\"!isMinimised\" (mouseenter)=\"onCallBtnMouseEnter($event)\"\r\n (mouseleave)=\"onCallBtnMouseLeave($event)\">\r\n <div class=\"call-btn\" (click)=\"initiateCall()\" [tabindex]=\"dialedNumber.length ? '2': '15'\"\r\n [ngStyle]=\"{'pointer-events': dialedNumber.length && selectedCallerId ? 'auto' : 'none', 'opacity': dialedNumber.length && selectedCallerId ? '1' : '0.5'}\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call\r\n </span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"callerIdList.length && !isMinimised\" class=\"position-relative\">\r\n <div class=\"shownCallerId\" *ngIf=\"selectedCallerId; else askBlock\" (click)=\"toggleCallerIdDiv()\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + selectedCallerId?.isoCode?.toLowerCase()\"></span>\r\n {{selectedCallerId?.number}}\r\n </div>\r\n </div>\r\n <ng-template #askBlock>\r\n <div class=\"shownCallerId\" (click)=\"toggleCallerIdDiv()\" [ngClass]=\"{ 'tilt-shaking': shakeDedicatedBtn }\">\r\n <div class=\"d-flex justify-content-center\">\r\n <h5 class=\"mb-0\">Select C2C number</h5>\r\n <span class=\"fa fa-angle-down ml-2 text-blue\" style=\"margin-top:2px\"></span>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <div class=\"guide2\" *ngIf=\"shakeDedicatedBtn\">\r\n <span class=\"guidetext\">Please select a number from below dropdown</span>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"callerIdList.length; else noCallerIdMessage\">\r\n <div class=\"caller-id-list-container\" *ngIf=\"callerIdList.length && !isMinimised\" id=\"callerIdContainer\"\r\n [ngClass]=\"{'visible': !isCallerIdHidden}\">\r\n <div style=\"display: flex; justify-content: space-between\">\r\n <!-- <h4>Select C2C Softphone Number</h4> -->\r\n <h4>Make outgoing call using</h4>\r\n <span class=\"material-symbols-outlined\" style=\"cursor: pointer\" (click)=\"isCallerIdHidden = true\">\r\n close\r\n </span>\r\n </div>\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\"\r\n (click)=\"onDedicatedNumSelect(callerId)\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n <ng-template #noCallerIdMessage>\r\n <span class=\"no-caller-id-message\">To make any voice calls, please <a\r\n routerLink=\"/extension/dedicatednumber/{{token}}\" class=\"click-here-link\"\r\n title=\"Settings > C2C Number\">subscribe</a> to a voice capable C2C Number.\r\n </span>\r\n </ng-template>\r\n <div class=\"dedicated-overlay\" *ngIf=\"showDedicatedPopup\">\r\n <div class=\"card dedicatedNumPopup\">\r\n <div class=\"card-header chooseDedicatedHeader\">\r\n <h5>Choose C2C Number</h5>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDedicatedPopup = false\">close</span>\r\n </div>\r\n <div class=\"card-body dedicatedNumList\">\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\"\r\n (click)=\"showDedicatedPopup = false\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: ["#dragparent1{position:fixed;left:100px;z-index:9999999;font-family:Lato,sans-serif;display:none}.dialpad-container{width:320px!important;height:600px!important;background:white;margin:auto;border-radius:30px;box-shadow:#00000040 0 54px 55px,#0000001f 0 -12px 30px,#0000001f 0 4px 6px,#0000002b 0 12px 13px,#00000017 0 -3px 5px;display:flex;flex-direction:column;box-sizing:border-box;position:relative;line-height:1.1}.dialpad-alerts{position:absolute;width:calc(100% - 28px);left:14px;top:8px;z-index:1200}.btn-disc{font-size:12px}.dialbox-pop1{font-size:.8rem;z-index:9;padding:8px}.input-error>span{color:#dfdfdf;margin-bottom:2px}.dial-close-btn{cursor:pointer;opacity:.6}.dial-close-btn:hover{opacity:1}.btn-container{display:flex;flex-wrap:wrap;padding:0 18px}.dial-btn{width:50px;height:50px;background-color:#fff;border-radius:4px;text-align:center;box-sizing:border-box;margin:4px 22px;font-size:28px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#2b434d;cursor:pointer;opacity:.8;border:none}.dial-btn:hover{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:focus{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:active{box-shadow:#32325d40 0 30px 60px -12px inset,#0000004d 0 18px 36px -18px inset}.call-btn-container{display:flex;margin-top:8px;justify-content:center;position:relative}.call-btn{display:flex;align-items:center;justify-content:center;width:54px;height:54px;border-radius:27px;background-color:#2ecc71;outline:none;border:none;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;opacity:.8;cursor:pointer}.call-btn:hover{opacity:1}.call-btn:focus{opacity:1}.caller-id-list-container{width:100%;height:auto;position:absolute;bottom:-100%;left:0;border-radius:0 0 30px 30px/0px 0px 30px 30px;padding:8px 12px 32px;box-sizing:border-box;color:#8a8a8a}.visible{animation:slideUp .8s forwards}#callerIdContainer ul{list-style:none;padding-left:0;margin:0}.dialpad-container h4{font-family:Lato,sans-serif;margin:0 0 8px}#callerIdContainer ul li{background-color:#fff;padding:8px;margin-top:7px;display:flex;border-radius:4px;justify-content:space-between;font-size:14px;cursor:pointer}.fi{border-radius:2px;margin-right:2px}@keyframes slideUp{0%{bottom:-100%}to{bottom:0}}.selectedCallerIdClass{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;border:1px solid #e0e0e0;color:#3a3a3a}.toggleBtn{color:gray;border:none;background-color:#e5eef1}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.plusSign{font-weight:600;font-size:14px}.shownCallerId{text-align:center;padding:8px 10px;font-family:Lato,sans-serif;color:#2ecc71;border:1px solid #d7d7d7;background-color:#fff;width:80%;margin:12px auto auto;border-radius:12px;position:relative;cursor:pointer}.no-contact-message{width:100%;margin:auto 16px;color:#fff}.input-box{width:100%;background-color:#fff;padding:4px 10px;border:1px solid rgb(197,197,197);box-sizing:border-box;border-radius:24px;margin-top:12px;display:flex;justify-content:space-between}.input-box:focus-within{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026}.input-box input{font-size:18px;padding:8px 6px;width:100%;box-sizing:border-box;border:none;outline:none;font-weight:600;color:#2b434d}.input-box input::placeholder{font-size:16px;font-weight:500}#input-clear-btn{color:gray;display:flex;align-items:center;cursor:pointer}.contact-card{width:100%;height:54px;display:flex;border-radius:12px;overflow:hidden;margin-top:4px;box-shadow:6px 6px 10px -1px #e6eefc26;cursor:pointer;opacity:0;transform:translateY(20px);animation:slideIn .5s forwards}@keyframes slideIn{to{opacity:1;transform:translateY(0)}}.contact-img{width:50px;display:flex;align-items:center;justify-content:center;border-right:1px solid #bebebe;background-color:#fff}.contact-img img{max-width:50px}.contact-alpha-img{width:50px;display:flex;justify-content:center;align-items:center;font-size:38px;font-weight:600}.contact-details{padding:4px 8px;display:flex;flex-direction:column;justify-content:center}.contact-details p{margin:0;line-height:1;color:#fff}.contact-name{font-weight:600}#topPanel{height:39%;position:relative;margin-bottom:4px;padding:0;border-top-right-radius:30px;border-top-left-radius:30px}.wave-container{position:absolute;bottom:2px}.waves{width:320px;position:relative;margin-bottom:-7px;height:31px;min-height:31px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}app-call-progress{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1000}.mini-dialpad{height:124px!important}.voicemail{line-height:.7;font-size:18px}.dedicated-overlay{position:absolute;width:100%;height:100%;background-color:#2b434d99;display:flex;align-items:center;justify-content:center}.dedicatedNumPopup{width:90%;height:auto;box-sizing:border-box;color:#8a8a8a;background-color:#cbe7df}.chooseDedicatedHeader{padding:.75rem;display:flex;justify-content:space-between}.chooseDedicatedHeader h5{margin-bottom:0}.dedicatedNumList>ul{list-style-type:none;padding:0}.dedicatedNumList>ul li{background-color:#fff;padding:4px;cursor:pointer}@keyframes tilt-shaking{0%{transform:rotate(0)}25%{transform:rotate(5deg)}50%{transform:rotate(0)}75%{transform:rotate(-5deg)}to{transform:rotate(0)}}.tilt-shaking{background-color:#d45858;animation:tilt-shaking .5s infinite;color:#fff}.tilt-shaking h5,.dark .tilt-shaking span,.tilt-shaking span{color:#fff}.no-caller-id-message{display:inline-block;text-align:center;height:10vh;background-color:#fff3cd;color:#000;font-size:.9rem;line-height:1.5;padding:8px}.click-here-link{color:#0f9aee;text-decoration:underline;font-weight:700}.input-info-icon{margin-top:9px;cursor:pointer;color:#2b434d;opacity:.7}::ng-deep .input-tooltip .tooltip-inner{background-color:#000!important}.no-selection-alert{padding:3px 11px;border:1px solid;border-radius:4px;display:flex;justify-content:space-between;color:#721c24;background-color:#f8d7da;border-color:#f5c6cb;align-items:center}.guide{position:relative;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px}.guide:before{content:\"\";position:absolute;top:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid #303030}.guide2{position:absolute;top:-32px;left:24px;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px;pointer-events:none}.guide2:before{content:\"\";position:absolute;bottom:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #303030}.incoming-call-widget{position:absolute;right:-320px;top:30px;width:320px;height:68px;background-color:#3052cd;border-top-right-radius:8px;border-bottom-right-radius:8px;display:flex;align-items:center;padding:4px 12px}.incoming-call-widget h6,.incoming-call-widget p{margin-bottom:0;line-height:1.2;color:#fff}.inc-user-img{width:48px;height:48px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;box-sizing:border-box;margin-right:8px}.inc-user-img img{width:100%}.inc-call-btn{width:40px;height:40px;border-radius:50%;outline:none;border-width:0;display:flex;align-items:center;justify-content:center}.inc-call-btn span{font-size:16px}.inc-accept-btn{background-color:#2ecc71;color:#fff}.inc-reject-btn{background-color:#e14e4e;color:#fff}.inc-user-name{font-weight:600}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;border-radius:50%}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;width:36px;height:36px}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;width:36px;height:36px;animation:spin89345 1s linear infinite;position:absolute;top:50%;left:44%;z-index:100000}.loader-wrapper{width:320px;height:600px;z-index:100000;display:block;position:absolute;border-radius:31px}@keyframes spin89345{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.outgoing-call-loader{display:flex;flex-direction:column;justify-content:center;align-items:center}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto 0;border-radius:100%;border:solid 4px #fff;display:flex;align-items:center;justify-content:center}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.call-animation-play{animation:play 3s linear infinite}.avatar-img{width:94px;height:94px;border-radius:100%}@keyframes play{0%{transform:scale(1)}15%{box-shadow:0 0 0 2px #fff6}25%{box-shadow:0 0 0 4px #fff6,0 0 0 8px #fff3}25%{box-shadow:0 0 0 8px #fff6,0 0 0 16px #fff3}50%{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3}to{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3;transform:scale(1.1);opacity:0}}.callerDetails{margin-top:8px;display:flex;flex-direction:column;align-items:center}.callerDetails h1,.callerDetails p{margin-top:8px;color:#fff}.call-action-btns{text-align:center;margin-top:90px}.end-call-btn{background-color:#e14e4e}.end-call-btn span{color:#fff!important}.call-btn span{color:#234de8}.call-sec-btn,.mic-btn{position:relative;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:25px;padding:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226;width:50px;height:50px}.mic-btn{padding:5px;width:37px;height:37px}::ng-deep .swal2-container.swal-reload-on-top{z-index:10000000000000!important}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: CallProgressComponent, selector: "lib-call-progress", inputs: ["callData", "selectedCallerId", "newIncomingCallData", "newIncomingCallsList", "callerIdList", "newCallConference", "missCallInfo", "userSettingInfo", "deviceId", "callAction", "conferenceCallInfo", "incomingFromImage", "cancelConnectingAction", "outgoingContactName"], outputs: ["endCallEvent", "incomingCallsNewInfo", "minimiseEvent", "muteAllStatusEvent", "incomingCallInitiated", "isLoadershown", "endIncomingCallEvent"] }, { kind: "directive", type: ShortPressDirective, selector: "[shortPress]", outputs: ["shortPress"] }, { kind: "directive", type: LongPressDirective, selector: "[longPress]", outputs: ["longPress"] }] });
6492
+ DialboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DialboxComponent, selector: "lib-dialbox", inputs: { autoOpenOnIncoming: "autoOpenOnIncoming", contactInfo: "contactInfo", deviceId: "deviceId", userId: "userId", callAction: "callAction", isDialpadHidden: "isDialpadHidden", incomingCallData: "incomingCallData", incomingCallnotification: "incomingCallnotification", updatedTwilioToken: "updatedTwilioToken" }, outputs: { closeDialpadEvent: "closeDialpadEvent", callInitiated: "callInitiated", endCallEvent: "endCallEvent", minimiseEvent: "minimiseEvent", incomingCallsNewInfoEvent: "incomingCallsNewInfoEvent", incomingCallInitiated: "incomingCallInitiated", conferenceCallList: "conferenceCallList", numberDialed: "numberDialed" }, host: { listeners: { "window:beforeunload": "beforeUnloadHandler($event)", "window:unload": "unloadHandler()" } }, viewQueries: [{ propertyName: "dialInputElement", first: true, predicate: ["dialInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"dragparent1\" [ngStyle]=\"{'display':isDialpadHidden ? 'none': 'block'}\">\n <lib-call-progress *ngIf=\"isCallInProgress\" (endCallEvent)=\"endCall()\" (minimiseEvent)=\"onMinimise($event)\"\n (muteAllStatusEvent)=\"showDialAlert($event)\"\n (incomingCallInitiated)=\"newIncomingCallInitiated()\" [newIncomingCallData]=\"newIncomingCallData\"\n [deviceId]=\"deviceId\" [newIncomingCallsList]=\"incomingCallsList\" [missCallInfo]=\"missCallInfo\"\n (incomingCallsNewInfo)=\"incomingCallsNewInfo($event)\" [selectedCallerId]=\"selectedCallerId\"\n [callerIdList]=\"callerIdList\" [callAction]=\"callAction\" [conferenceCallInfo]=\"conferenceCallInfo\"\n [newCallConference]=\"newCallConference\" [userSettingInfo]=\"userSettingInfo\"\n [cancelConnectingAction]=\"cancelConnectingAction\"\n [outgoingContactName]=\"outgoingContactName\"\n [incomingFromImage]=\"incomingFromImage\"\n (endIncomingCallEvent)=\"endIncomingCall($event)\" (isLoadershown)=\"onLoadershow($event)\" [callData]=\"callData\">\n </lib-call-progress>\n\n <div class=\"loader-wrapper outgoing-call-loader\" *ngIf=\"isLoadershow\">\n <div class=\"active-call\" style=\"display: flex; flex-direction: column; position: relative;\">\n <div class=\"call-animation call-animation-play\">\n <img class=\"avatar-img\" [src]=\"contactImgForLoader\" alt=\"\" />\n </div>\n <div class=\"callerDetails\">\n <h1 style=\"margin-top: 8px;\">Connecting...</h1>\n <p style=\"text-transform: capitalize;\">{{ contactNameForLoader || dialedNumber }}</p>\n </div>\n \n <div class=\"call-action-btns\">\n <div class=\"d-flex justify-content-center\">\n <button class=\"call-btn end-call-btn\" disabled style=\"visibility: hidden;\" (click)=\"cancelConnectingCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Special Call Charges Modal (first call: shown over the \"Connecting...\" loader, same position as .loader-wrapper).\n When a call screen is already open, lib-call-progress shows this modal instead. -->\n <div class=\"loader-wrapper special-call-modal-wrapper\" *ngIf=\"twilioService.specialCallConfirm && !twilioService.specialCallConfirm.inCallScreen\">\n <div class=\"special-call-modal\">\n <div class=\"warning-icon\">\n <span class=\"material-symbols-outlined\">warning</span>\n </div>\n <h3>Call Charges</h3>\n <p *ngIf=\"twilioService.specialCallConfirm?.message\">{{ twilioService.specialCallConfirm?.message }}</p>\n <p *ngIf=\"!twilioService.specialCallConfirm?.message\">\n Additional charges apply to this call. Do you want to proceed?\n </p>\n <div class=\"warning-actions\">\n <button class=\"cancel-btn\" (click)=\"twilioService.resolveSpecialCallConfirm(false)\">\n Cancel\n </button>\n <button class=\"proceed-btn\" (click)=\"twilioService.resolveSpecialCallConfirm(true)\">\n Proceed\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"dialpad-container\" [ngClass]=\"{'mini-dialpad': isMinimised}\"\n *ngIf=\"(!isCallInProgress && !incomingCallsList.length) && !isLoadershow\" tabindex=\"0\" (keydown)=\"handleDivKeydown($event)\">\n <div id=\"topPanel\" [ngStyle]=\"{'height': callerIdList.length ? '40%' : '39%'}\">\n <div class=\"dialpad-alerts\" *ngIf=\"dialAlert.show\">\n <div class=\"no-selection-alert\">\n <p class=\"mb-0\">{{dialAlert.msg}}</p>\n <span class=\"fa fa-times\" (click)=\"shakeDedicatedBtn = false\"></span>\n </div>\n </div>\n <div class=\"dialpad-alerts\" *ngIf=\"callNumberToast.show\">\n <div class=\"dialbox-pop1 alert fade show\" [ngClass]=\"callNumberToast.type\" role=\"alert\">\n <div class=\"d-flex justify-content-between\">\n <div class=\"flex-grow-1 my-auto text-left\">\n You'r calling <strong>{{callNumberToast.displayNum}}</strong>\n </div>\n <div class=\"text-right\">\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelDialNumber()\">Cancel Call</button>\n </div>\n </div>\n </div>\n </div>\n <div style=\"padding: 0 18px\" (paste)=\"handleNumberPaste($event)\">\n <div class=\"d-flex justify-content-between mt-2\">\n <p></p>\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"hideDialpad()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"#ffffff\">\n <path\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\n </svg>\n </span>\n </div>\n <div class=\"input-box\">\n <input type=\"text\" #dialInput placeholder=\"Enter a name or number\" tabindex=\"1\" [(ngModel)]=\"dialedNumber\"\n (ngModelChange)=\"onDialInputChange($event)\" />\n <span class=\"\" id=\"input-clear-btn\" (click)=\"clearInput()\" *ngIf=\"showInputClearBtn\">\n <svg width=\"50px\" height=\"30px\" viewBox=\"0 10 40 60\" xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" baseProfile=\"full\"\n enable-background=\"new 0 0 76.00 76.00\" xml:space=\"preserve\">\n <path fill=\"#5d6061\" fill-opacity=\"1\" stroke-width=\"0.2\" stroke-linejoin=\"round\"\n d=\"M 47.5282,42.9497L 42.5784,38L 47.5282,33.0502L 44.9497,30.4718L 40,35.4216L 35.0502,30.4718L 32.4718,33.0502L 37.4216,38L 32.4718,42.9497L 35.0502,45.5282L 40,40.5784L 44.9497,45.5282L 47.5282,42.9497 Z M 18.0147,41.5355L 26.9646,50.4854C 28.0683,51.589 29,52 31,52L 52,52C 54.7614,52 57,49.7614 57,47L 57,29C 57,26.2386 54.7614,24 52,24L 31,24C 29,24 28.0683,24.4113 26.9646,25.5149L 18.0147,34.4645C 16.0621,36.4171 16.0621,39.5829 18.0147,41.5355 Z M 31,49C 30,49 29.6048,48.8828 29.086,48.3641L 20.1361,39.4142C 19.355,38.6332 19.355,37.3669 20.1361,36.5858L 29.086,27.6362C 29.6048,27.1175 30,27 31,27.0001L 52,27.0001C 53.1046,27.0001 54,27.8955 54,29.0001L 54,47.0001C 54,48.1046 53.1046,49.0001 52,49.0001L 31,49 Z \" />\n </svg>\n </span>\n <span class=\"input-info-icon\" placement=\"bottom-right\" tooltipClass=\"input-tooltip\"\n ngbTooltip=\"For extension dialing, use formats like +12345678910 x123,+12345678910 ext.123, +12345678910,123\"><i\n class=\"fa fa-info-circle\"></i></span>\n </div>\n <div class=\"guide\" *ngIf=\"callerIdList.length && !(dialedNumber.length > 2)\">\n <span class=\"guidetext\">Please enter a number or select a saved contact</span>\n </div>\n <div style=\"height: 119px; overflow: auto;\">\n <div class=\"contact-card\" *ngFor=\"let contact of filteredContactList\" (click)=\"onContactSelect(contact)\">\n <div class=\"contact-img\">\n <img [src]=\"contact.image\" alt=\"user image\" loading=\"lazy\" *ngIf=\"contact.image else alphaName\" />\n <ng-template #alphaName>\n <span class=\"contact-alpha-img\">{{getFirstLetter(contact.firstName)}}</span>\n </ng-template>\n </div>\n <div class=\"contact-details\">\n <p style=\"margin-bottom: 4px\" class=\"contact-name\">{{getFullName(contact) }}</p>\n <p>{{contact.selectedNumber.number}}</p>\n </div>\n </div>\n <div class=\"contact-card\" *ngIf=\"!filteredContactList.length && dialedNumber.length > 2 && !isValidationMessageShow\">\n <div class=\"no-contact-message\">\n No Contacts Found\n </div>\n </div>\n </div>\n </div>\n <div class=\"wave-container\">\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\n <defs>\n <path id=\"gentle-wave\" d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\n </defs>\n <g class=\"parallax\">\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\n </g>\n </svg>\n </div>\n </div>\n <div class=\"btn-container\" *ngIf=\"!isMinimised\">\n <button class=\"dial-btn\" *ngFor=\"let key of keypadVal;let i = index\" (keydown.enter)=\"onEnter(key.num)\"\n [ngStyle]=\"{'margin-top': key.text === '+' ? '3px' : '0'}\" [tabindex]=\"dialedNumber.length ? '0': i+2\" longPress\n (longPress)=\"addNumber(key.text)\" shortPress (shortPress)=\"addNumber(key.num)\">\n {{key.num}}\n <span *ngIf=\"key.num == 1;else otherThanOne\" class=\"material-symbols-outlined voicemail\">\n voicemail\n </span>\n <ng-template #otherThanOne>\n <span class=\"btn-albhabets\" [ngClass]=\"{'plusSign': key.text === '+'}\">{{key.text ? key.text :\n '&nbsp;'}}</span>\n </ng-template>\n </button>\n </div>\n <div class=\"call-btn-container\" *ngIf=\"!isMinimised\" (mouseenter)=\"onCallBtnMouseEnter($event)\"\n (mouseleave)=\"onCallBtnMouseLeave($event)\">\n <div class=\"call-btn\" (click)=\"initiateCall()\" [tabindex]=\"dialedNumber.length ? '2': '15'\"\n [ngStyle]=\"{'pointer-events': dialedNumber.length && selectedCallerId ? 'auto' : 'none', 'opacity': dialedNumber.length && selectedCallerId ? '1' : '0.5'}\">\n <span class=\"material-symbols-outlined\" style=\"color: white\">\n call\n </span>\n </div>\n </div>\n <div *ngIf=\"callerIdList.length && !isMinimised\" class=\"position-relative\">\n <div class=\"shownCallerId\" *ngIf=\"selectedCallerId; else askBlock\" (click)=\"toggleCallerIdDiv()\">\n <div>\n <span [ngClass]=\"'fi fi-' + selectedCallerId?.isoCode?.toLowerCase()\"></span>\n {{selectedCallerId?.number}}\n </div>\n </div>\n <ng-template #askBlock>\n <div class=\"shownCallerId\" (click)=\"toggleCallerIdDiv()\" [ngClass]=\"{ 'tilt-shaking': shakeDedicatedBtn }\">\n <div class=\"d-flex justify-content-center\">\n <h5 class=\"mb-0\">Select C2C number</h5>\n <span class=\"fa fa-angle-down ml-2 text-blue\" style=\"margin-top:2px\"></span>\n </div>\n </div>\n </ng-template>\n <div class=\"guide2\" *ngIf=\"shakeDedicatedBtn\">\n <span class=\"guidetext\">Please select a number from below dropdown</span>\n </div>\n </div>\n\n <div *ngIf=\"callerIdList.length; else noCallerIdMessage\">\n <div class=\"caller-id-list-container\" *ngIf=\"callerIdList.length && !isMinimised\" id=\"callerIdContainer\"\n [ngClass]=\"{'visible': !isCallerIdHidden}\">\n <div style=\"display: flex; justify-content: space-between\">\n <!-- <h4>Select C2C Softphone Number</h4> -->\n <h4>Make outgoing call using</h4>\n <span class=\"material-symbols-outlined\" style=\"cursor: pointer\" (click)=\"isCallerIdHidden = true\">\n close\n </span>\n </div>\n <ul>\n <ng-container *ngFor=\"let callerId of callerIdList\">\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\"\n (click)=\"onDedicatedNumSelect(callerId)\">\n <div>\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\n {{callerId?.number}}\n </div>\n <span>{{callerId?.countryName}}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n </div>\n <ng-template #noCallerIdMessage>\n <span class=\"no-caller-id-message\">To make any voice calls, please <a\n routerLink=\"/extension/dedicatednumber/{{token}}\" class=\"click-here-link\"\n title=\"Settings > C2C Number\">subscribe</a> to a voice capable C2C Number.\n </span>\n </ng-template>\n <div class=\"dedicated-overlay\" *ngIf=\"showDedicatedPopup\">\n <div class=\"card dedicatedNumPopup\">\n <div class=\"card-header chooseDedicatedHeader\">\n <h5>Choose C2C Number</h5>\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDedicatedPopup = false\">close</span>\n </div>\n <div class=\"card-body dedicatedNumList\">\n <ul>\n <ng-container *ngFor=\"let callerId of callerIdList\">\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\"\n (click)=\"showDedicatedPopup = false\">\n <div>\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\n {{callerId?.number}}\n </div>\n <span>{{callerId?.countryName}}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: ["#dragparent1{position:fixed;left:100px;z-index:9999999;font-family:Lato,sans-serif;display:none}.dialpad-container{width:320px!important;height:600px!important;background:white;margin:auto;border-radius:30px;box-shadow:#00000040 0 54px 55px,#0000001f 0 -12px 30px,#0000001f 0 4px 6px,#0000002b 0 12px 13px,#00000017 0 -3px 5px;display:flex;flex-direction:column;box-sizing:border-box;position:relative;line-height:1.1}.dialpad-alerts{position:absolute;width:calc(100% - 28px);left:14px;top:8px;z-index:1200}.btn-disc{font-size:12px}.dialbox-pop1{font-size:.8rem;z-index:9;padding:8px}.input-error>span{color:#dfdfdf;margin-bottom:2px}.dial-close-btn{cursor:pointer;opacity:.6}.dial-close-btn:hover{opacity:1}.btn-container{display:flex;flex-wrap:wrap;padding:0 18px}.dial-btn{width:50px;height:50px;background-color:#fff;border-radius:4px;text-align:center;box-sizing:border-box;margin:4px 22px;font-size:28px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#2b434d;cursor:pointer;opacity:.8;border:none}.dial-btn:hover{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:focus{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:active{box-shadow:#32325d40 0 30px 60px -12px inset,#0000004d 0 18px 36px -18px inset}.call-btn-container{display:flex;margin-top:8px;justify-content:center;position:relative}.call-btn{display:flex;align-items:center;justify-content:center;width:54px;height:54px;border-radius:27px;background-color:#2ecc71;outline:none;border:none;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;opacity:.8;cursor:pointer}.call-btn:hover{opacity:1}.call-btn:focus{opacity:1}.caller-id-list-container{width:100%;height:auto;position:absolute;bottom:-100%;left:0;border-radius:0 0 30px 30px/0px 0px 30px 30px;padding:8px 12px 32px;box-sizing:border-box;color:#8a8a8a}.visible{animation:slideUp .8s forwards}#callerIdContainer ul{list-style:none;padding-left:0;margin:0}.dialpad-container h4{font-family:Lato,sans-serif;margin:0 0 8px}#callerIdContainer ul li{background-color:#fff;padding:8px;margin-top:7px;display:flex;border-radius:4px;justify-content:space-between;font-size:14px;cursor:pointer}.fi{border-radius:2px;margin-right:2px}@keyframes slideUp{0%{bottom:-100%}to{bottom:0}}.selectedCallerIdClass{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;border:1px solid #e0e0e0;color:#3a3a3a}.toggleBtn{color:gray;border:none;background-color:#e5eef1}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.plusSign{font-weight:600;font-size:14px}.shownCallerId{text-align:center;padding:8px 10px;font-family:Lato,sans-serif;color:#2ecc71;border:1px solid #d7d7d7;background-color:#fff;width:80%;margin:12px auto auto;border-radius:12px;position:relative;cursor:pointer}.no-contact-message{width:100%;margin:auto 16px;color:#fff}.input-box{width:100%;background-color:#fff;padding:4px 10px;border:1px solid rgb(197,197,197);box-sizing:border-box;border-radius:24px;margin-top:12px;display:flex;justify-content:space-between}.input-box:focus-within{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026}.input-box input{font-size:18px;padding:8px 6px;width:100%;box-sizing:border-box;border:none;outline:none;font-weight:600;color:#2b434d}.input-box input::placeholder{font-size:16px;font-weight:500}#input-clear-btn{color:gray;display:flex;align-items:center;cursor:pointer}.contact-card{width:100%;height:54px;display:flex;border-radius:12px;overflow:hidden;margin-top:4px;box-shadow:6px 6px 10px -1px #e6eefc26;cursor:pointer;opacity:0;transform:translateY(20px);animation:slideIn .5s forwards}@keyframes slideIn{to{opacity:1;transform:translateY(0)}}.contact-img{width:50px;display:flex;align-items:center;justify-content:center;border-right:1px solid #bebebe;background-color:#fff}.contact-img img{max-width:50px}.contact-alpha-img{width:50px;display:flex;justify-content:center;align-items:center;font-size:38px;font-weight:600}.contact-details{padding:4px 8px;display:flex;flex-direction:column;justify-content:center}.contact-details p{margin:0;line-height:1;color:#fff}.contact-name{font-weight:600}#topPanel{height:39%;position:relative;margin-bottom:4px;padding:0;border-top-right-radius:30px;border-top-left-radius:30px}.wave-container{position:absolute;bottom:2px}.waves{width:320px;position:relative;margin-bottom:-7px;height:31px;min-height:31px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}app-call-progress{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1000}.mini-dialpad{height:124px!important}.voicemail{line-height:.7;font-size:18px}.dedicated-overlay{position:absolute;width:100%;height:100%;background-color:#2b434d99;display:flex;align-items:center;justify-content:center}.dedicatedNumPopup{width:90%;height:auto;box-sizing:border-box;color:#8a8a8a;background-color:#cbe7df}.chooseDedicatedHeader{padding:.75rem;display:flex;justify-content:space-between}.chooseDedicatedHeader h5{margin-bottom:0}.dedicatedNumList>ul{list-style-type:none;padding:0}.dedicatedNumList>ul li{background-color:#fff;padding:4px;cursor:pointer}@keyframes tilt-shaking{0%{transform:rotate(0)}25%{transform:rotate(5deg)}50%{transform:rotate(0)}75%{transform:rotate(-5deg)}to{transform:rotate(0)}}.tilt-shaking{background-color:#d45858;animation:tilt-shaking .5s infinite;color:#fff}.tilt-shaking h5,.dark .tilt-shaking span,.tilt-shaking span{color:#fff}.no-caller-id-message{display:inline-block;text-align:center;height:10vh;background-color:#fff3cd;color:#000;font-size:.9rem;line-height:1.5;padding:8px}.click-here-link{color:#0f9aee;text-decoration:underline;font-weight:700}.input-info-icon{margin-top:9px;cursor:pointer;color:#2b434d;opacity:.7}::ng-deep .input-tooltip .tooltip-inner{background-color:#000!important}.no-selection-alert{padding:3px 11px;border:1px solid;border-radius:4px;display:flex;justify-content:space-between;color:#721c24;background-color:#f8d7da;border-color:#f5c6cb;align-items:center}.guide{position:relative;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px}.guide:before{content:\"\";position:absolute;top:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid #303030}.guide2{position:absolute;top:-32px;left:24px;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px;pointer-events:none}.guide2:before{content:\"\";position:absolute;bottom:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #303030}.incoming-call-widget{position:absolute;right:-320px;top:30px;width:320px;height:68px;background-color:#3052cd;border-top-right-radius:8px;border-bottom-right-radius:8px;display:flex;align-items:center;padding:4px 12px}.incoming-call-widget h6,.incoming-call-widget p{margin-bottom:0;line-height:1.2;color:#fff}.inc-user-img{width:48px;height:48px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;box-sizing:border-box;margin-right:8px}.inc-user-img img{width:100%}.inc-call-btn{width:40px;height:40px;border-radius:50%;outline:none;border-width:0;display:flex;align-items:center;justify-content:center}.inc-call-btn span{font-size:16px}.inc-accept-btn{background-color:#2ecc71;color:#fff}.inc-reject-btn{background-color:#e14e4e;color:#fff}.inc-user-name{font-weight:600}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;border-radius:50%}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;width:36px;height:36px}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;width:36px;height:36px;animation:spin89345 1s linear infinite;position:absolute;top:50%;left:44%;z-index:100000}.loader-wrapper{width:320px;height:600px;z-index:100000;display:block;position:absolute;border-radius:31px}@keyframes spin89345{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.outgoing-call-loader{display:flex;flex-direction:column;justify-content:center;align-items:center}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto 0;border-radius:100%;border:solid 4px #fff;display:flex;align-items:center;justify-content:center}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.call-animation-play{animation:play 3s linear infinite}.avatar-img{width:94px;height:94px;border-radius:100%}@keyframes play{0%{transform:scale(1)}15%{box-shadow:0 0 0 2px #fff6}25%{box-shadow:0 0 0 4px #fff6,0 0 0 8px #fff3}25%{box-shadow:0 0 0 8px #fff6,0 0 0 16px #fff3}50%{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3}to{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3;transform:scale(1.1);opacity:0}}.callerDetails{margin-top:8px;display:flex;flex-direction:column;align-items:center}.callerDetails h1,.callerDetails p{margin-top:8px;color:#fff}.call-action-btns{text-align:center;margin-top:90px}.end-call-btn{background-color:#e14e4e}.end-call-btn span{color:#fff!important}.call-btn span{color:#234de8}.call-sec-btn,.mic-btn{position:relative;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:25px;padding:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226;width:50px;height:50px}.mic-btn{padding:5px;width:37px;height:37px}::ng-deep .swal2-container.swal-reload-on-top{z-index:10000000000000!important}.special-call-modal-wrapper{display:flex;align-items:center;justify-content:center;z-index:100001;background:rgba(0,0,0,.5)}.special-call-modal{background:#ffffff;width:280px;border-radius:18px;padding:24px;text-align:center;box-shadow:0 10px 30px #00000040}.special-call-modal .warning-icon{margin-bottom:12px}.special-call-modal .warning-icon .material-symbols-outlined{font-size:48px;color:#f59e0b}.special-call-modal h3{margin-bottom:12px;font-size:20px;font-weight:600;color:#111827!important}.special-call-modal p{color:#555!important;font-size:14px;line-height:1.5;margin-bottom:24px}.special-call-modal p strong{color:#111827!important}.special-call-modal .warning-actions{display:flex;justify-content:center;gap:12px}.special-call-modal .cancel-btn,.special-call-modal .proceed-btn{border:none;padding:10px 18px;border-radius:8px;cursor:pointer;font-weight:600}.special-call-modal .cancel-btn{background:#e5e7eb;color:#111827}.special-call-modal .proceed-btn{background:#234de8;color:#fff}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: CallProgressComponent, selector: "lib-call-progress", inputs: ["callData", "selectedCallerId", "newIncomingCallData", "newIncomingCallsList", "callerIdList", "newCallConference", "missCallInfo", "userSettingInfo", "deviceId", "callAction", "conferenceCallInfo", "incomingFromImage", "cancelConnectingAction", "outgoingContactName"], outputs: ["endCallEvent", "incomingCallsNewInfo", "minimiseEvent", "muteAllStatusEvent", "incomingCallInitiated", "isLoadershown", "endIncomingCallEvent"] }, { kind: "directive", type: ShortPressDirective, selector: "[shortPress]", outputs: ["shortPress"] }, { kind: "directive", type: LongPressDirective, selector: "[longPress]", outputs: ["longPress"] }] });
6376
6493
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DialboxComponent, decorators: [{
6377
6494
  type: Component,
6378
- args: [{ selector: 'lib-dialbox', template: "<div id=\"dragparent1\" [ngStyle]=\"{'display':isDialpadHidden ? 'none': 'block'}\">\r\n <lib-call-progress *ngIf=\"isCallInProgress\" (endCallEvent)=\"endCall()\" (minimiseEvent)=\"onMinimise($event)\"\r\n (muteAllStatusEvent)=\"showDialAlert($event)\"\r\n (incomingCallInitiated)=\"newIncomingCallInitiated()\" [newIncomingCallData]=\"newIncomingCallData\"\r\n [deviceId]=\"deviceId\" [newIncomingCallsList]=\"incomingCallsList\" [missCallInfo]=\"missCallInfo\"\r\n (incomingCallsNewInfo)=\"incomingCallsNewInfo($event)\" [selectedCallerId]=\"selectedCallerId\"\r\n [callerIdList]=\"callerIdList\" [callAction]=\"callAction\" [conferenceCallInfo]=\"conferenceCallInfo\"\r\n [newCallConference]=\"newCallConference\" [userSettingInfo]=\"userSettingInfo\"\r\n [cancelConnectingAction]=\"cancelConnectingAction\"\r\n [outgoingContactName]=\"outgoingContactName\"\r\n [incomingFromImage]=\"incomingFromImage\"\r\n (endIncomingCallEvent)=\"endIncomingCall($event)\" (isLoadershown)=\"onLoadershow($event)\" [callData]=\"callData\">\r\n </lib-call-progress>\r\n\r\n <div class=\"loader-wrapper outgoing-call-loader\" *ngIf=\"isLoadershow\">\r\n <div class=\"active-call\" style=\"display: flex; flex-direction: column; position: relative;\">\r\n <div class=\"call-animation call-animation-play\">\r\n <img class=\"avatar-img\" [src]=\"contactImgForLoader\" alt=\"\" />\r\n </div>\r\n <div class=\"callerDetails\">\r\n <h1 style=\"margin-top: 8px;\">Connecting...</h1>\r\n <p style=\"text-transform: capitalize;\">{{ contactNameForLoader || dialedNumber }}</p>\r\n </div>\r\n \r\n <div class=\"call-action-btns\">\r\n <div class=\"d-flex justify-content-center\">\r\n <button class=\"call-btn end-call-btn\" disabled style=\"visibility: hidden;\" (click)=\"cancelConnectingCall()\">\r\n <span class=\"material-symbols-outlined\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"dialpad-container\" [ngClass]=\"{'mini-dialpad': isMinimised}\"\r\n *ngIf=\"(!isCallInProgress && !incomingCallsList.length) && !isLoadershow\" tabindex=\"0\" (keydown)=\"handleDivKeydown($event)\">\r\n <div id=\"topPanel\" [ngStyle]=\"{'height': callerIdList.length ? '40%' : '39%'}\">\r\n <div class=\"dialpad-alerts\" *ngIf=\"dialAlert.show\">\r\n <div class=\"no-selection-alert\">\r\n <p class=\"mb-0\">{{dialAlert.msg}}</p>\r\n <span class=\"fa fa-times\" (click)=\"shakeDedicatedBtn = false\"></span>\r\n </div>\r\n </div>\r\n <div class=\"dialpad-alerts\" *ngIf=\"callNumberToast.show\">\r\n <div class=\"dialbox-pop1 alert fade show\" [ngClass]=\"callNumberToast.type\" role=\"alert\">\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"flex-grow-1 my-auto text-left\">\r\n You'r calling <strong>{{callNumberToast.displayNum}}</strong>\r\n </div>\r\n <div class=\"text-right\">\r\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelDialNumber()\">Cancel Call</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div style=\"padding: 0 18px\" (paste)=\"handleNumberPaste($event)\">\r\n <div class=\"d-flex justify-content-between mt-2\">\r\n <p></p>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"hideDialpad()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"#ffffff\">\r\n <path\r\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"input-box\">\r\n <input type=\"text\" #dialInput placeholder=\"Enter a name or number\" tabindex=\"1\" [(ngModel)]=\"dialedNumber\"\r\n (ngModelChange)=\"onDialInputChange($event)\" />\r\n <span class=\"\" id=\"input-clear-btn\" (click)=\"clearInput()\" *ngIf=\"showInputClearBtn\">\r\n <svg width=\"50px\" height=\"30px\" viewBox=\"0 10 40 60\" xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" baseProfile=\"full\"\r\n enable-background=\"new 0 0 76.00 76.00\" xml:space=\"preserve\">\r\n <path fill=\"#5d6061\" fill-opacity=\"1\" stroke-width=\"0.2\" stroke-linejoin=\"round\"\r\n d=\"M 47.5282,42.9497L 42.5784,38L 47.5282,33.0502L 44.9497,30.4718L 40,35.4216L 35.0502,30.4718L 32.4718,33.0502L 37.4216,38L 32.4718,42.9497L 35.0502,45.5282L 40,40.5784L 44.9497,45.5282L 47.5282,42.9497 Z M 18.0147,41.5355L 26.9646,50.4854C 28.0683,51.589 29,52 31,52L 52,52C 54.7614,52 57,49.7614 57,47L 57,29C 57,26.2386 54.7614,24 52,24L 31,24C 29,24 28.0683,24.4113 26.9646,25.5149L 18.0147,34.4645C 16.0621,36.4171 16.0621,39.5829 18.0147,41.5355 Z M 31,49C 30,49 29.6048,48.8828 29.086,48.3641L 20.1361,39.4142C 19.355,38.6332 19.355,37.3669 20.1361,36.5858L 29.086,27.6362C 29.6048,27.1175 30,27 31,27.0001L 52,27.0001C 53.1046,27.0001 54,27.8955 54,29.0001L 54,47.0001C 54,48.1046 53.1046,49.0001 52,49.0001L 31,49 Z \" />\r\n </svg>\r\n </span>\r\n <span class=\"input-info-icon\" placement=\"bottom-right\" tooltipClass=\"input-tooltip\"\r\n ngbTooltip=\"For extension dialing, use formats like +12345678910 x123,+12345678910 ext.123, +12345678910,123\"><i\r\n class=\"fa fa-info-circle\"></i></span>\r\n </div>\r\n <div class=\"guide\" *ngIf=\"callerIdList.length && !(dialedNumber.length > 2)\">\r\n <span class=\"guidetext\">Please enter a number or select a saved contact</span>\r\n </div>\r\n <div style=\"height: 119px; overflow: auto;\">\r\n <div class=\"contact-card\" *ngFor=\"let contact of filteredContactList\" (click)=\"onContactSelect(contact)\">\r\n <div class=\"contact-img\">\r\n <img [src]=\"contact.image\" alt=\"user image\" loading=\"lazy\" *ngIf=\"contact.image else alphaName\" />\r\n <ng-template #alphaName>\r\n <span class=\"contact-alpha-img\">{{getFirstLetter(contact.firstName)}}</span>\r\n </ng-template>\r\n </div>\r\n <div class=\"contact-details\">\r\n <p style=\"margin-bottom: 4px\" class=\"contact-name\">{{getFullName(contact) }}</p>\r\n <p>{{contact.selectedNumber.number}}</p>\r\n </div>\r\n </div>\r\n <div class=\"contact-card\" *ngIf=\"!filteredContactList.length && dialedNumber.length > 2 && !isValidationMessageShow\">\r\n <div class=\"no-contact-message\">\r\n No Contacts Found\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"wave-container\">\r\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\r\n <defs>\r\n <path id=\"gentle-wave\" d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n </div>\r\n <div class=\"btn-container\" *ngIf=\"!isMinimised\">\r\n <button class=\"dial-btn\" *ngFor=\"let key of keypadVal;let i = index\" (keydown.enter)=\"onEnter(key.num)\"\r\n [ngStyle]=\"{'margin-top': key.text === '+' ? '3px' : '0'}\" [tabindex]=\"dialedNumber.length ? '0': i+2\" longPress\r\n (longPress)=\"addNumber(key.text)\" shortPress (shortPress)=\"addNumber(key.num)\">\r\n {{key.num}}\r\n <span *ngIf=\"key.num == 1;else otherThanOne\" class=\"material-symbols-outlined voicemail\">\r\n voicemail\r\n </span>\r\n <ng-template #otherThanOne>\r\n <span class=\"btn-albhabets\" [ngClass]=\"{'plusSign': key.text === '+'}\">{{key.text ? key.text :\r\n '&nbsp;'}}</span>\r\n </ng-template>\r\n </button>\r\n </div>\r\n <div class=\"call-btn-container\" *ngIf=\"!isMinimised\" (mouseenter)=\"onCallBtnMouseEnter($event)\"\r\n (mouseleave)=\"onCallBtnMouseLeave($event)\">\r\n <div class=\"call-btn\" (click)=\"initiateCall()\" [tabindex]=\"dialedNumber.length ? '2': '15'\"\r\n [ngStyle]=\"{'pointer-events': dialedNumber.length && selectedCallerId ? 'auto' : 'none', 'opacity': dialedNumber.length && selectedCallerId ? '1' : '0.5'}\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call\r\n </span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"callerIdList.length && !isMinimised\" class=\"position-relative\">\r\n <div class=\"shownCallerId\" *ngIf=\"selectedCallerId; else askBlock\" (click)=\"toggleCallerIdDiv()\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + selectedCallerId?.isoCode?.toLowerCase()\"></span>\r\n {{selectedCallerId?.number}}\r\n </div>\r\n </div>\r\n <ng-template #askBlock>\r\n <div class=\"shownCallerId\" (click)=\"toggleCallerIdDiv()\" [ngClass]=\"{ 'tilt-shaking': shakeDedicatedBtn }\">\r\n <div class=\"d-flex justify-content-center\">\r\n <h5 class=\"mb-0\">Select C2C number</h5>\r\n <span class=\"fa fa-angle-down ml-2 text-blue\" style=\"margin-top:2px\"></span>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <div class=\"guide2\" *ngIf=\"shakeDedicatedBtn\">\r\n <span class=\"guidetext\">Please select a number from below dropdown</span>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"callerIdList.length; else noCallerIdMessage\">\r\n <div class=\"caller-id-list-container\" *ngIf=\"callerIdList.length && !isMinimised\" id=\"callerIdContainer\"\r\n [ngClass]=\"{'visible': !isCallerIdHidden}\">\r\n <div style=\"display: flex; justify-content: space-between\">\r\n <!-- <h4>Select C2C Softphone Number</h4> -->\r\n <h4>Make outgoing call using</h4>\r\n <span class=\"material-symbols-outlined\" style=\"cursor: pointer\" (click)=\"isCallerIdHidden = true\">\r\n close\r\n </span>\r\n </div>\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\"\r\n (click)=\"onDedicatedNumSelect(callerId)\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n <ng-template #noCallerIdMessage>\r\n <span class=\"no-caller-id-message\">To make any voice calls, please <a\r\n routerLink=\"/extension/dedicatednumber/{{token}}\" class=\"click-here-link\"\r\n title=\"Settings > C2C Number\">subscribe</a> to a voice capable C2C Number.\r\n </span>\r\n </ng-template>\r\n <div class=\"dedicated-overlay\" *ngIf=\"showDedicatedPopup\">\r\n <div class=\"card dedicatedNumPopup\">\r\n <div class=\"card-header chooseDedicatedHeader\">\r\n <h5>Choose C2C Number</h5>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDedicatedPopup = false\">close</span>\r\n </div>\r\n <div class=\"card-body dedicatedNumList\">\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\"\r\n (click)=\"showDedicatedPopup = false\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: ["#dragparent1{position:fixed;left:100px;z-index:9999999;font-family:Lato,sans-serif;display:none}.dialpad-container{width:320px!important;height:600px!important;background:white;margin:auto;border-radius:30px;box-shadow:#00000040 0 54px 55px,#0000001f 0 -12px 30px,#0000001f 0 4px 6px,#0000002b 0 12px 13px,#00000017 0 -3px 5px;display:flex;flex-direction:column;box-sizing:border-box;position:relative;line-height:1.1}.dialpad-alerts{position:absolute;width:calc(100% - 28px);left:14px;top:8px;z-index:1200}.btn-disc{font-size:12px}.dialbox-pop1{font-size:.8rem;z-index:9;padding:8px}.input-error>span{color:#dfdfdf;margin-bottom:2px}.dial-close-btn{cursor:pointer;opacity:.6}.dial-close-btn:hover{opacity:1}.btn-container{display:flex;flex-wrap:wrap;padding:0 18px}.dial-btn{width:50px;height:50px;background-color:#fff;border-radius:4px;text-align:center;box-sizing:border-box;margin:4px 22px;font-size:28px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#2b434d;cursor:pointer;opacity:.8;border:none}.dial-btn:hover{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:focus{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:active{box-shadow:#32325d40 0 30px 60px -12px inset,#0000004d 0 18px 36px -18px inset}.call-btn-container{display:flex;margin-top:8px;justify-content:center;position:relative}.call-btn{display:flex;align-items:center;justify-content:center;width:54px;height:54px;border-radius:27px;background-color:#2ecc71;outline:none;border:none;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;opacity:.8;cursor:pointer}.call-btn:hover{opacity:1}.call-btn:focus{opacity:1}.caller-id-list-container{width:100%;height:auto;position:absolute;bottom:-100%;left:0;border-radius:0 0 30px 30px/0px 0px 30px 30px;padding:8px 12px 32px;box-sizing:border-box;color:#8a8a8a}.visible{animation:slideUp .8s forwards}#callerIdContainer ul{list-style:none;padding-left:0;margin:0}.dialpad-container h4{font-family:Lato,sans-serif;margin:0 0 8px}#callerIdContainer ul li{background-color:#fff;padding:8px;margin-top:7px;display:flex;border-radius:4px;justify-content:space-between;font-size:14px;cursor:pointer}.fi{border-radius:2px;margin-right:2px}@keyframes slideUp{0%{bottom:-100%}to{bottom:0}}.selectedCallerIdClass{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;border:1px solid #e0e0e0;color:#3a3a3a}.toggleBtn{color:gray;border:none;background-color:#e5eef1}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.plusSign{font-weight:600;font-size:14px}.shownCallerId{text-align:center;padding:8px 10px;font-family:Lato,sans-serif;color:#2ecc71;border:1px solid #d7d7d7;background-color:#fff;width:80%;margin:12px auto auto;border-radius:12px;position:relative;cursor:pointer}.no-contact-message{width:100%;margin:auto 16px;color:#fff}.input-box{width:100%;background-color:#fff;padding:4px 10px;border:1px solid rgb(197,197,197);box-sizing:border-box;border-radius:24px;margin-top:12px;display:flex;justify-content:space-between}.input-box:focus-within{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026}.input-box input{font-size:18px;padding:8px 6px;width:100%;box-sizing:border-box;border:none;outline:none;font-weight:600;color:#2b434d}.input-box input::placeholder{font-size:16px;font-weight:500}#input-clear-btn{color:gray;display:flex;align-items:center;cursor:pointer}.contact-card{width:100%;height:54px;display:flex;border-radius:12px;overflow:hidden;margin-top:4px;box-shadow:6px 6px 10px -1px #e6eefc26;cursor:pointer;opacity:0;transform:translateY(20px);animation:slideIn .5s forwards}@keyframes slideIn{to{opacity:1;transform:translateY(0)}}.contact-img{width:50px;display:flex;align-items:center;justify-content:center;border-right:1px solid #bebebe;background-color:#fff}.contact-img img{max-width:50px}.contact-alpha-img{width:50px;display:flex;justify-content:center;align-items:center;font-size:38px;font-weight:600}.contact-details{padding:4px 8px;display:flex;flex-direction:column;justify-content:center}.contact-details p{margin:0;line-height:1;color:#fff}.contact-name{font-weight:600}#topPanel{height:39%;position:relative;margin-bottom:4px;padding:0;border-top-right-radius:30px;border-top-left-radius:30px}.wave-container{position:absolute;bottom:2px}.waves{width:320px;position:relative;margin-bottom:-7px;height:31px;min-height:31px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}app-call-progress{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1000}.mini-dialpad{height:124px!important}.voicemail{line-height:.7;font-size:18px}.dedicated-overlay{position:absolute;width:100%;height:100%;background-color:#2b434d99;display:flex;align-items:center;justify-content:center}.dedicatedNumPopup{width:90%;height:auto;box-sizing:border-box;color:#8a8a8a;background-color:#cbe7df}.chooseDedicatedHeader{padding:.75rem;display:flex;justify-content:space-between}.chooseDedicatedHeader h5{margin-bottom:0}.dedicatedNumList>ul{list-style-type:none;padding:0}.dedicatedNumList>ul li{background-color:#fff;padding:4px;cursor:pointer}@keyframes tilt-shaking{0%{transform:rotate(0)}25%{transform:rotate(5deg)}50%{transform:rotate(0)}75%{transform:rotate(-5deg)}to{transform:rotate(0)}}.tilt-shaking{background-color:#d45858;animation:tilt-shaking .5s infinite;color:#fff}.tilt-shaking h5,.dark .tilt-shaking span,.tilt-shaking span{color:#fff}.no-caller-id-message{display:inline-block;text-align:center;height:10vh;background-color:#fff3cd;color:#000;font-size:.9rem;line-height:1.5;padding:8px}.click-here-link{color:#0f9aee;text-decoration:underline;font-weight:700}.input-info-icon{margin-top:9px;cursor:pointer;color:#2b434d;opacity:.7}::ng-deep .input-tooltip .tooltip-inner{background-color:#000!important}.no-selection-alert{padding:3px 11px;border:1px solid;border-radius:4px;display:flex;justify-content:space-between;color:#721c24;background-color:#f8d7da;border-color:#f5c6cb;align-items:center}.guide{position:relative;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px}.guide:before{content:\"\";position:absolute;top:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid #303030}.guide2{position:absolute;top:-32px;left:24px;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px;pointer-events:none}.guide2:before{content:\"\";position:absolute;bottom:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #303030}.incoming-call-widget{position:absolute;right:-320px;top:30px;width:320px;height:68px;background-color:#3052cd;border-top-right-radius:8px;border-bottom-right-radius:8px;display:flex;align-items:center;padding:4px 12px}.incoming-call-widget h6,.incoming-call-widget p{margin-bottom:0;line-height:1.2;color:#fff}.inc-user-img{width:48px;height:48px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;box-sizing:border-box;margin-right:8px}.inc-user-img img{width:100%}.inc-call-btn{width:40px;height:40px;border-radius:50%;outline:none;border-width:0;display:flex;align-items:center;justify-content:center}.inc-call-btn span{font-size:16px}.inc-accept-btn{background-color:#2ecc71;color:#fff}.inc-reject-btn{background-color:#e14e4e;color:#fff}.inc-user-name{font-weight:600}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;border-radius:50%}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;width:36px;height:36px}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;width:36px;height:36px;animation:spin89345 1s linear infinite;position:absolute;top:50%;left:44%;z-index:100000}.loader-wrapper{width:320px;height:600px;z-index:100000;display:block;position:absolute;border-radius:31px}@keyframes spin89345{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.outgoing-call-loader{display:flex;flex-direction:column;justify-content:center;align-items:center}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto 0;border-radius:100%;border:solid 4px #fff;display:flex;align-items:center;justify-content:center}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.call-animation-play{animation:play 3s linear infinite}.avatar-img{width:94px;height:94px;border-radius:100%}@keyframes play{0%{transform:scale(1)}15%{box-shadow:0 0 0 2px #fff6}25%{box-shadow:0 0 0 4px #fff6,0 0 0 8px #fff3}25%{box-shadow:0 0 0 8px #fff6,0 0 0 16px #fff3}50%{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3}to{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3;transform:scale(1.1);opacity:0}}.callerDetails{margin-top:8px;display:flex;flex-direction:column;align-items:center}.callerDetails h1,.callerDetails p{margin-top:8px;color:#fff}.call-action-btns{text-align:center;margin-top:90px}.end-call-btn{background-color:#e14e4e}.end-call-btn span{color:#fff!important}.call-btn span{color:#234de8}.call-sec-btn,.mic-btn{position:relative;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:25px;padding:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226;width:50px;height:50px}.mic-btn{padding:5px;width:37px;height:37px}::ng-deep .swal2-container.swal-reload-on-top{z-index:10000000000000!important}\n"] }]
6495
+ args: [{ selector: 'lib-dialbox', template: "<div id=\"dragparent1\" [ngStyle]=\"{'display':isDialpadHidden ? 'none': 'block'}\">\n <lib-call-progress *ngIf=\"isCallInProgress\" (endCallEvent)=\"endCall()\" (minimiseEvent)=\"onMinimise($event)\"\n (muteAllStatusEvent)=\"showDialAlert($event)\"\n (incomingCallInitiated)=\"newIncomingCallInitiated()\" [newIncomingCallData]=\"newIncomingCallData\"\n [deviceId]=\"deviceId\" [newIncomingCallsList]=\"incomingCallsList\" [missCallInfo]=\"missCallInfo\"\n (incomingCallsNewInfo)=\"incomingCallsNewInfo($event)\" [selectedCallerId]=\"selectedCallerId\"\n [callerIdList]=\"callerIdList\" [callAction]=\"callAction\" [conferenceCallInfo]=\"conferenceCallInfo\"\n [newCallConference]=\"newCallConference\" [userSettingInfo]=\"userSettingInfo\"\n [cancelConnectingAction]=\"cancelConnectingAction\"\n [outgoingContactName]=\"outgoingContactName\"\n [incomingFromImage]=\"incomingFromImage\"\n (endIncomingCallEvent)=\"endIncomingCall($event)\" (isLoadershown)=\"onLoadershow($event)\" [callData]=\"callData\">\n </lib-call-progress>\n\n <div class=\"loader-wrapper outgoing-call-loader\" *ngIf=\"isLoadershow\">\n <div class=\"active-call\" style=\"display: flex; flex-direction: column; position: relative;\">\n <div class=\"call-animation call-animation-play\">\n <img class=\"avatar-img\" [src]=\"contactImgForLoader\" alt=\"\" />\n </div>\n <div class=\"callerDetails\">\n <h1 style=\"margin-top: 8px;\">Connecting...</h1>\n <p style=\"text-transform: capitalize;\">{{ contactNameForLoader || dialedNumber }}</p>\n </div>\n \n <div class=\"call-action-btns\">\n <div class=\"d-flex justify-content-center\">\n <button class=\"call-btn end-call-btn\" disabled style=\"visibility: hidden;\" (click)=\"cancelConnectingCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Special Call Charges Modal (first call: shown over the \"Connecting...\" loader, same position as .loader-wrapper).\n When a call screen is already open, lib-call-progress shows this modal instead. -->\n <div class=\"loader-wrapper special-call-modal-wrapper\" *ngIf=\"twilioService.specialCallConfirm && !twilioService.specialCallConfirm.inCallScreen\">\n <div class=\"special-call-modal\">\n <div class=\"warning-icon\">\n <span class=\"material-symbols-outlined\">warning</span>\n </div>\n <h3>Call Charges</h3>\n <p *ngIf=\"twilioService.specialCallConfirm?.message\">{{ twilioService.specialCallConfirm?.message }}</p>\n <p *ngIf=\"!twilioService.specialCallConfirm?.message\">\n Additional charges apply to this call. Do you want to proceed?\n </p>\n <div class=\"warning-actions\">\n <button class=\"cancel-btn\" (click)=\"twilioService.resolveSpecialCallConfirm(false)\">\n Cancel\n </button>\n <button class=\"proceed-btn\" (click)=\"twilioService.resolveSpecialCallConfirm(true)\">\n Proceed\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"dialpad-container\" [ngClass]=\"{'mini-dialpad': isMinimised}\"\n *ngIf=\"(!isCallInProgress && !incomingCallsList.length) && !isLoadershow\" tabindex=\"0\" (keydown)=\"handleDivKeydown($event)\">\n <div id=\"topPanel\" [ngStyle]=\"{'height': callerIdList.length ? '40%' : '39%'}\">\n <div class=\"dialpad-alerts\" *ngIf=\"dialAlert.show\">\n <div class=\"no-selection-alert\">\n <p class=\"mb-0\">{{dialAlert.msg}}</p>\n <span class=\"fa fa-times\" (click)=\"shakeDedicatedBtn = false\"></span>\n </div>\n </div>\n <div class=\"dialpad-alerts\" *ngIf=\"callNumberToast.show\">\n <div class=\"dialbox-pop1 alert fade show\" [ngClass]=\"callNumberToast.type\" role=\"alert\">\n <div class=\"d-flex justify-content-between\">\n <div class=\"flex-grow-1 my-auto text-left\">\n You'r calling <strong>{{callNumberToast.displayNum}}</strong>\n </div>\n <div class=\"text-right\">\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelDialNumber()\">Cancel Call</button>\n </div>\n </div>\n </div>\n </div>\n <div style=\"padding: 0 18px\" (paste)=\"handleNumberPaste($event)\">\n <div class=\"d-flex justify-content-between mt-2\">\n <p></p>\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"hideDialpad()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"#ffffff\">\n <path\n d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\n </svg>\n </span>\n </div>\n <div class=\"input-box\">\n <input type=\"text\" #dialInput placeholder=\"Enter a name or number\" tabindex=\"1\" [(ngModel)]=\"dialedNumber\"\n (ngModelChange)=\"onDialInputChange($event)\" />\n <span class=\"\" id=\"input-clear-btn\" (click)=\"clearInput()\" *ngIf=\"showInputClearBtn\">\n <svg width=\"50px\" height=\"30px\" viewBox=\"0 10 40 60\" xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" baseProfile=\"full\"\n enable-background=\"new 0 0 76.00 76.00\" xml:space=\"preserve\">\n <path fill=\"#5d6061\" fill-opacity=\"1\" stroke-width=\"0.2\" stroke-linejoin=\"round\"\n d=\"M 47.5282,42.9497L 42.5784,38L 47.5282,33.0502L 44.9497,30.4718L 40,35.4216L 35.0502,30.4718L 32.4718,33.0502L 37.4216,38L 32.4718,42.9497L 35.0502,45.5282L 40,40.5784L 44.9497,45.5282L 47.5282,42.9497 Z M 18.0147,41.5355L 26.9646,50.4854C 28.0683,51.589 29,52 31,52L 52,52C 54.7614,52 57,49.7614 57,47L 57,29C 57,26.2386 54.7614,24 52,24L 31,24C 29,24 28.0683,24.4113 26.9646,25.5149L 18.0147,34.4645C 16.0621,36.4171 16.0621,39.5829 18.0147,41.5355 Z M 31,49C 30,49 29.6048,48.8828 29.086,48.3641L 20.1361,39.4142C 19.355,38.6332 19.355,37.3669 20.1361,36.5858L 29.086,27.6362C 29.6048,27.1175 30,27 31,27.0001L 52,27.0001C 53.1046,27.0001 54,27.8955 54,29.0001L 54,47.0001C 54,48.1046 53.1046,49.0001 52,49.0001L 31,49 Z \" />\n </svg>\n </span>\n <span class=\"input-info-icon\" placement=\"bottom-right\" tooltipClass=\"input-tooltip\"\n ngbTooltip=\"For extension dialing, use formats like +12345678910 x123,+12345678910 ext.123, +12345678910,123\"><i\n class=\"fa fa-info-circle\"></i></span>\n </div>\n <div class=\"guide\" *ngIf=\"callerIdList.length && !(dialedNumber.length > 2)\">\n <span class=\"guidetext\">Please enter a number or select a saved contact</span>\n </div>\n <div style=\"height: 119px; overflow: auto;\">\n <div class=\"contact-card\" *ngFor=\"let contact of filteredContactList\" (click)=\"onContactSelect(contact)\">\n <div class=\"contact-img\">\n <img [src]=\"contact.image\" alt=\"user image\" loading=\"lazy\" *ngIf=\"contact.image else alphaName\" />\n <ng-template #alphaName>\n <span class=\"contact-alpha-img\">{{getFirstLetter(contact.firstName)}}</span>\n </ng-template>\n </div>\n <div class=\"contact-details\">\n <p style=\"margin-bottom: 4px\" class=\"contact-name\">{{getFullName(contact) }}</p>\n <p>{{contact.selectedNumber.number}}</p>\n </div>\n </div>\n <div class=\"contact-card\" *ngIf=\"!filteredContactList.length && dialedNumber.length > 2 && !isValidationMessageShow\">\n <div class=\"no-contact-message\">\n No Contacts Found\n </div>\n </div>\n </div>\n </div>\n <div class=\"wave-container\">\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\n <defs>\n <path id=\"gentle-wave\" d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\n </defs>\n <g class=\"parallax\">\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\n </g>\n </svg>\n </div>\n </div>\n <div class=\"btn-container\" *ngIf=\"!isMinimised\">\n <button class=\"dial-btn\" *ngFor=\"let key of keypadVal;let i = index\" (keydown.enter)=\"onEnter(key.num)\"\n [ngStyle]=\"{'margin-top': key.text === '+' ? '3px' : '0'}\" [tabindex]=\"dialedNumber.length ? '0': i+2\" longPress\n (longPress)=\"addNumber(key.text)\" shortPress (shortPress)=\"addNumber(key.num)\">\n {{key.num}}\n <span *ngIf=\"key.num == 1;else otherThanOne\" class=\"material-symbols-outlined voicemail\">\n voicemail\n </span>\n <ng-template #otherThanOne>\n <span class=\"btn-albhabets\" [ngClass]=\"{'plusSign': key.text === '+'}\">{{key.text ? key.text :\n '&nbsp;'}}</span>\n </ng-template>\n </button>\n </div>\n <div class=\"call-btn-container\" *ngIf=\"!isMinimised\" (mouseenter)=\"onCallBtnMouseEnter($event)\"\n (mouseleave)=\"onCallBtnMouseLeave($event)\">\n <div class=\"call-btn\" (click)=\"initiateCall()\" [tabindex]=\"dialedNumber.length ? '2': '15'\"\n [ngStyle]=\"{'pointer-events': dialedNumber.length && selectedCallerId ? 'auto' : 'none', 'opacity': dialedNumber.length && selectedCallerId ? '1' : '0.5'}\">\n <span class=\"material-symbols-outlined\" style=\"color: white\">\n call\n </span>\n </div>\n </div>\n <div *ngIf=\"callerIdList.length && !isMinimised\" class=\"position-relative\">\n <div class=\"shownCallerId\" *ngIf=\"selectedCallerId; else askBlock\" (click)=\"toggleCallerIdDiv()\">\n <div>\n <span [ngClass]=\"'fi fi-' + selectedCallerId?.isoCode?.toLowerCase()\"></span>\n {{selectedCallerId?.number}}\n </div>\n </div>\n <ng-template #askBlock>\n <div class=\"shownCallerId\" (click)=\"toggleCallerIdDiv()\" [ngClass]=\"{ 'tilt-shaking': shakeDedicatedBtn }\">\n <div class=\"d-flex justify-content-center\">\n <h5 class=\"mb-0\">Select C2C number</h5>\n <span class=\"fa fa-angle-down ml-2 text-blue\" style=\"margin-top:2px\"></span>\n </div>\n </div>\n </ng-template>\n <div class=\"guide2\" *ngIf=\"shakeDedicatedBtn\">\n <span class=\"guidetext\">Please select a number from below dropdown</span>\n </div>\n </div>\n\n <div *ngIf=\"callerIdList.length; else noCallerIdMessage\">\n <div class=\"caller-id-list-container\" *ngIf=\"callerIdList.length && !isMinimised\" id=\"callerIdContainer\"\n [ngClass]=\"{'visible': !isCallerIdHidden}\">\n <div style=\"display: flex; justify-content: space-between\">\n <!-- <h4>Select C2C Softphone Number</h4> -->\n <h4>Make outgoing call using</h4>\n <span class=\"material-symbols-outlined\" style=\"cursor: pointer\" (click)=\"isCallerIdHidden = true\">\n close\n </span>\n </div>\n <ul>\n <ng-container *ngFor=\"let callerId of callerIdList\">\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\"\n (click)=\"onDedicatedNumSelect(callerId)\">\n <div>\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\n {{callerId?.number}}\n </div>\n <span>{{callerId?.countryName}}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n </div>\n <ng-template #noCallerIdMessage>\n <span class=\"no-caller-id-message\">To make any voice calls, please <a\n routerLink=\"/extension/dedicatednumber/{{token}}\" class=\"click-here-link\"\n title=\"Settings > C2C Number\">subscribe</a> to a voice capable C2C Number.\n </span>\n </ng-template>\n <div class=\"dedicated-overlay\" *ngIf=\"showDedicatedPopup\">\n <div class=\"card dedicatedNumPopup\">\n <div class=\"card-header chooseDedicatedHeader\">\n <h5>Choose C2C Number</h5>\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDedicatedPopup = false\">close</span>\n </div>\n <div class=\"card-body dedicatedNumList\">\n <ul>\n <ng-container *ngFor=\"let callerId of callerIdList\">\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\"\n (click)=\"showDedicatedPopup = false\">\n <div>\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\n {{callerId?.number}}\n </div>\n <span>{{callerId?.countryName}}</span>\n </li>\n </ng-container>\n </ul>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: ["#dragparent1{position:fixed;left:100px;z-index:9999999;font-family:Lato,sans-serif;display:none}.dialpad-container{width:320px!important;height:600px!important;background:white;margin:auto;border-radius:30px;box-shadow:#00000040 0 54px 55px,#0000001f 0 -12px 30px,#0000001f 0 4px 6px,#0000002b 0 12px 13px,#00000017 0 -3px 5px;display:flex;flex-direction:column;box-sizing:border-box;position:relative;line-height:1.1}.dialpad-alerts{position:absolute;width:calc(100% - 28px);left:14px;top:8px;z-index:1200}.btn-disc{font-size:12px}.dialbox-pop1{font-size:.8rem;z-index:9;padding:8px}.input-error>span{color:#dfdfdf;margin-bottom:2px}.dial-close-btn{cursor:pointer;opacity:.6}.dial-close-btn:hover{opacity:1}.btn-container{display:flex;flex-wrap:wrap;padding:0 18px}.dial-btn{width:50px;height:50px;background-color:#fff;border-radius:4px;text-align:center;box-sizing:border-box;margin:4px 22px;font-size:28px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#2b434d;cursor:pointer;opacity:.8;border:none}.dial-btn:hover{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:focus{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:active{box-shadow:#32325d40 0 30px 60px -12px inset,#0000004d 0 18px 36px -18px inset}.call-btn-container{display:flex;margin-top:8px;justify-content:center;position:relative}.call-btn{display:flex;align-items:center;justify-content:center;width:54px;height:54px;border-radius:27px;background-color:#2ecc71;outline:none;border:none;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;opacity:.8;cursor:pointer}.call-btn:hover{opacity:1}.call-btn:focus{opacity:1}.caller-id-list-container{width:100%;height:auto;position:absolute;bottom:-100%;left:0;border-radius:0 0 30px 30px/0px 0px 30px 30px;padding:8px 12px 32px;box-sizing:border-box;color:#8a8a8a}.visible{animation:slideUp .8s forwards}#callerIdContainer ul{list-style:none;padding-left:0;margin:0}.dialpad-container h4{font-family:Lato,sans-serif;margin:0 0 8px}#callerIdContainer ul li{background-color:#fff;padding:8px;margin-top:7px;display:flex;border-radius:4px;justify-content:space-between;font-size:14px;cursor:pointer}.fi{border-radius:2px;margin-right:2px}@keyframes slideUp{0%{bottom:-100%}to{bottom:0}}.selectedCallerIdClass{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;border:1px solid #e0e0e0;color:#3a3a3a}.toggleBtn{color:gray;border:none;background-color:#e5eef1}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.plusSign{font-weight:600;font-size:14px}.shownCallerId{text-align:center;padding:8px 10px;font-family:Lato,sans-serif;color:#2ecc71;border:1px solid #d7d7d7;background-color:#fff;width:80%;margin:12px auto auto;border-radius:12px;position:relative;cursor:pointer}.no-contact-message{width:100%;margin:auto 16px;color:#fff}.input-box{width:100%;background-color:#fff;padding:4px 10px;border:1px solid rgb(197,197,197);box-sizing:border-box;border-radius:24px;margin-top:12px;display:flex;justify-content:space-between}.input-box:focus-within{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026}.input-box input{font-size:18px;padding:8px 6px;width:100%;box-sizing:border-box;border:none;outline:none;font-weight:600;color:#2b434d}.input-box input::placeholder{font-size:16px;font-weight:500}#input-clear-btn{color:gray;display:flex;align-items:center;cursor:pointer}.contact-card{width:100%;height:54px;display:flex;border-radius:12px;overflow:hidden;margin-top:4px;box-shadow:6px 6px 10px -1px #e6eefc26;cursor:pointer;opacity:0;transform:translateY(20px);animation:slideIn .5s forwards}@keyframes slideIn{to{opacity:1;transform:translateY(0)}}.contact-img{width:50px;display:flex;align-items:center;justify-content:center;border-right:1px solid #bebebe;background-color:#fff}.contact-img img{max-width:50px}.contact-alpha-img{width:50px;display:flex;justify-content:center;align-items:center;font-size:38px;font-weight:600}.contact-details{padding:4px 8px;display:flex;flex-direction:column;justify-content:center}.contact-details p{margin:0;line-height:1;color:#fff}.contact-name{font-weight:600}#topPanel{height:39%;position:relative;margin-bottom:4px;padding:0;border-top-right-radius:30px;border-top-left-radius:30px}.wave-container{position:absolute;bottom:2px}.waves{width:320px;position:relative;margin-bottom:-7px;height:31px;min-height:31px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}app-call-progress{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1000}.mini-dialpad{height:124px!important}.voicemail{line-height:.7;font-size:18px}.dedicated-overlay{position:absolute;width:100%;height:100%;background-color:#2b434d99;display:flex;align-items:center;justify-content:center}.dedicatedNumPopup{width:90%;height:auto;box-sizing:border-box;color:#8a8a8a;background-color:#cbe7df}.chooseDedicatedHeader{padding:.75rem;display:flex;justify-content:space-between}.chooseDedicatedHeader h5{margin-bottom:0}.dedicatedNumList>ul{list-style-type:none;padding:0}.dedicatedNumList>ul li{background-color:#fff;padding:4px;cursor:pointer}@keyframes tilt-shaking{0%{transform:rotate(0)}25%{transform:rotate(5deg)}50%{transform:rotate(0)}75%{transform:rotate(-5deg)}to{transform:rotate(0)}}.tilt-shaking{background-color:#d45858;animation:tilt-shaking .5s infinite;color:#fff}.tilt-shaking h5,.dark .tilt-shaking span,.tilt-shaking span{color:#fff}.no-caller-id-message{display:inline-block;text-align:center;height:10vh;background-color:#fff3cd;color:#000;font-size:.9rem;line-height:1.5;padding:8px}.click-here-link{color:#0f9aee;text-decoration:underline;font-weight:700}.input-info-icon{margin-top:9px;cursor:pointer;color:#2b434d;opacity:.7}::ng-deep .input-tooltip .tooltip-inner{background-color:#000!important}.no-selection-alert{padding:3px 11px;border:1px solid;border-radius:4px;display:flex;justify-content:space-between;color:#721c24;background-color:#f8d7da;border-color:#f5c6cb;align-items:center}.guide{position:relative;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px}.guide:before{content:\"\";position:absolute;top:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid #303030}.guide2{position:absolute;top:-32px;left:24px;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px;pointer-events:none}.guide2:before{content:\"\";position:absolute;bottom:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #303030}.incoming-call-widget{position:absolute;right:-320px;top:30px;width:320px;height:68px;background-color:#3052cd;border-top-right-radius:8px;border-bottom-right-radius:8px;display:flex;align-items:center;padding:4px 12px}.incoming-call-widget h6,.incoming-call-widget p{margin-bottom:0;line-height:1.2;color:#fff}.inc-user-img{width:48px;height:48px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;box-sizing:border-box;margin-right:8px}.inc-user-img img{width:100%}.inc-call-btn{width:40px;height:40px;border-radius:50%;outline:none;border-width:0;display:flex;align-items:center;justify-content:center}.inc-call-btn span{font-size:16px}.inc-accept-btn{background-color:#2ecc71;color:#fff}.inc-reject-btn{background-color:#e14e4e;color:#fff}.inc-user-name{font-weight:600}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;border-radius:50%}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;width:36px;height:36px}.loader{border:4px solid rgb(123 122 122 / 87%);border-left-color:transparent;width:36px;height:36px;animation:spin89345 1s linear infinite;position:absolute;top:50%;left:44%;z-index:100000}.loader-wrapper{width:320px;height:600px;z-index:100000;display:block;position:absolute;border-radius:31px}@keyframes spin89345{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.outgoing-call-loader{display:flex;flex-direction:column;justify-content:center;align-items:center}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto 0;border-radius:100%;border:solid 4px #fff;display:flex;align-items:center;justify-content:center}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.call-animation-play{animation:play 3s linear infinite}.avatar-img{width:94px;height:94px;border-radius:100%}@keyframes play{0%{transform:scale(1)}15%{box-shadow:0 0 0 2px #fff6}25%{box-shadow:0 0 0 4px #fff6,0 0 0 8px #fff3}25%{box-shadow:0 0 0 8px #fff6,0 0 0 16px #fff3}50%{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3}to{box-shadow:0 0 0 10px #fff6,0 0 0 20px #fff3;transform:scale(1.1);opacity:0}}.callerDetails{margin-top:8px;display:flex;flex-direction:column;align-items:center}.callerDetails h1,.callerDetails p{margin-top:8px;color:#fff}.call-action-btns{text-align:center;margin-top:90px}.end-call-btn{background-color:#e14e4e}.end-call-btn span{color:#fff!important}.call-btn span{color:#234de8}.call-sec-btn,.mic-btn{position:relative;box-sizing:border-box;border:1px solid #cccbcb;background-color:transparent;border-radius:25px;padding:12px;box-shadow:6px 6px 10px -1px #bebebe26,-5px -4px 10px -1px #d2d2d226;width:50px;height:50px}.mic-btn{padding:5px;width:37px;height:37px}::ng-deep .swal2-container.swal-reload-on-top{z-index:10000000000000!important}.special-call-modal-wrapper{display:flex;align-items:center;justify-content:center;z-index:100001;background:rgba(0,0,0,.5)}.special-call-modal{background:#ffffff;width:280px;border-radius:18px;padding:24px;text-align:center;box-shadow:0 10px 30px #00000040}.special-call-modal .warning-icon{margin-bottom:12px}.special-call-modal .warning-icon .material-symbols-outlined{font-size:48px;color:#f59e0b}.special-call-modal h3{margin-bottom:12px;font-size:20px;font-weight:600;color:#111827!important}.special-call-modal p{color:#555!important;font-size:14px;line-height:1.5;margin-bottom:24px}.special-call-modal p strong{color:#111827!important}.special-call-modal .warning-actions{display:flex;justify-content:center;gap:12px}.special-call-modal .cancel-btn,.special-call-modal .proceed-btn{border:none;padding:10px 18px;border-radius:8px;cursor:pointer;font-weight:600}.special-call-modal .cancel-btn{background:#e5e7eb;color:#111827}.special-call-modal .proceed-btn{background:#234de8;color:#fff}\n"] }]
6379
6496
  }], ctorParameters: function () { return [{ type: TwilioService }, { type: ExtensionService }, { type: IpAddressService }, { type: ExtensionService }, { type: i0.ChangeDetectorRef }, { type: i4.Router }, { type: IncomeingCallSocketService }]; }, propDecorators: { autoOpenOnIncoming: [{
6380
6497
  type: Input
6381
6498
  }], contactInfo: [{