@vgroup/dialbox 0.8.5 → 0.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/components/call-progress/call-progress.component.mjs +21 -11
- package/esm2020/lib/dialbox.component.mjs +11 -9
- package/fesm2015/vgroup-dialbox.mjs +31 -20
- package/fesm2015/vgroup-dialbox.mjs.map +1 -1
- package/fesm2020/vgroup-dialbox.mjs +30 -18
- package/fesm2020/vgroup-dialbox.mjs.map +1 -1
- package/lib/components/call-progress/call-progress.component.d.ts +1 -0
- package/package.json +1 -1
|
@@ -2314,6 +2314,7 @@ class CallProgressComponent {
|
|
|
2314
2314
|
this.isParticipantPanelLoading = false;
|
|
2315
2315
|
this.pendingNewCallHeldParticipant = null;
|
|
2316
2316
|
this.isCallCancelled = false;
|
|
2317
|
+
this.isNewCallLoader = false;
|
|
2317
2318
|
this.isMinimised = false;
|
|
2318
2319
|
this.showDisconnectModal = false;
|
|
2319
2320
|
this.call = this.twilioService.call;
|
|
@@ -2346,6 +2347,7 @@ class CallProgressComponent {
|
|
|
2346
2347
|
}
|
|
2347
2348
|
else if (((_c = changes['callData'].currentValue) === null || _c === void 0 ? void 0 : _c.displayNum) || ((_d = changes['callData'].currentValue) === null || _d === void 0 ? void 0 : _d.from)) {
|
|
2348
2349
|
this.currentCall = Object.assign(Object.assign({}, changes['callData'].currentValue), { id: '125', img: 'assets/images/user.jpg', isIncomingCall: false, isHold: false, isMute: false, isConference: false, isAcceptCall: true, dial: true, phone: (_e = changes['callData'].currentValue) === null || _e === void 0 ? void 0 : _e.phone, participantId: '121', name: ((_f = changes['callData'].currentValue) === null || _f === void 0 ? void 0 : _f.name) || ((_g = changes['callData'].currentValue) === null || _g === void 0 ? void 0 : _g.fromName) || ((_h = changes['callData'].currentValue) === null || _h === void 0 ? void 0 : _h.toName) || '', time: this.timer });
|
|
2350
|
+
this.isNewCallLoader = true;
|
|
2349
2351
|
this.onAddNewCall(changes['callData'].currentValue);
|
|
2350
2352
|
}
|
|
2351
2353
|
}
|
|
@@ -2656,6 +2658,7 @@ class CallProgressComponent {
|
|
|
2656
2658
|
this.isRinging = false;
|
|
2657
2659
|
this.isConcurrentIncoming = false;
|
|
2658
2660
|
if (this.call) {
|
|
2661
|
+
console.log('call disconnect 566');
|
|
2659
2662
|
this.call.disconnect();
|
|
2660
2663
|
}
|
|
2661
2664
|
this.currentCallList = [];
|
|
@@ -2686,6 +2689,7 @@ class CallProgressComponent {
|
|
|
2686
2689
|
this.deviceNumberList = this.callerIdList.map((res) => res.number);
|
|
2687
2690
|
let data = (_27 = this.newIncomingCallsList.find((item) => { var _a; return (item === null || item === void 0 ? void 0 : item.conferenceId) == ((_a = this.callAction) === null || _a === void 0 ? void 0 : _a.conferenceId); })) === null || _27 === void 0 ? void 0 : _27.participants.find((resData) => resData === null || resData === void 0 ? void 0 : resData.host);
|
|
2688
2691
|
if ((data === null || data === void 0 ? void 0 : data.isLeft) || !data) {
|
|
2692
|
+
this.isNewCallLoader = true;
|
|
2689
2693
|
this.rejoinHost(this.callAction);
|
|
2690
2694
|
}
|
|
2691
2695
|
}
|
|
@@ -2758,9 +2762,11 @@ class CallProgressComponent {
|
|
|
2758
2762
|
clientSid: (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.parameters) === null || _b === void 0 ? void 0 : _b['CallSid'],
|
|
2759
2763
|
recordId: rejoinParticipentInfo === null || rejoinParticipentInfo === void 0 ? void 0 : rejoinParticipentInfo.id
|
|
2760
2764
|
});
|
|
2765
|
+
this.isNewCallLoader = false;
|
|
2761
2766
|
this.conferenceCallIDForParticipantList = rejoinParticipentInfo === null || rejoinParticipentInfo === void 0 ? void 0 : rejoinParticipentInfo.conferenceId;
|
|
2762
2767
|
}
|
|
2763
2768
|
catch (error) {
|
|
2769
|
+
this.isNewCallLoader = false;
|
|
2764
2770
|
console.error('Error in addClientParticipant:', error);
|
|
2765
2771
|
}
|
|
2766
2772
|
};
|
|
@@ -2964,12 +2970,13 @@ class CallProgressComponent {
|
|
|
2964
2970
|
}
|
|
2965
2971
|
this.conferenceId = (_b = response === null || response === void 0 ? void 0 : response.callauth) === null || _b === void 0 ? void 0 : _b.id;
|
|
2966
2972
|
this.isCallCancelled = false;
|
|
2967
|
-
if (response.status == 200) {
|
|
2973
|
+
if ((response === null || response === void 0 ? void 0 : response.status) == 200) {
|
|
2968
2974
|
this.pendingNewCallHeldParticipant = null;
|
|
2969
2975
|
const { id: callAuthId, recordCall, tokenData } = yield this.getCallAuthId(response);
|
|
2970
2976
|
this.recordCall = recordCall; // Store the recordCall value
|
|
2971
2977
|
yield this.connectToDevice(callAuthId, callData, tokenData);
|
|
2972
2978
|
yield this.pollCallStatus(callAuthId);
|
|
2979
|
+
console.log('Call initiated successfully:', response);
|
|
2973
2980
|
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
2974
2981
|
var _c, _d, _e, _f, _g;
|
|
2975
2982
|
try {
|
|
@@ -2997,6 +3004,7 @@ class CallProgressComponent {
|
|
|
2997
3004
|
countrycode: '',
|
|
2998
3005
|
deviceId: this.deviceId,
|
|
2999
3006
|
});
|
|
3007
|
+
this.isNewCallLoader = false;
|
|
3000
3008
|
if (isNewConference) {
|
|
3001
3009
|
this.conferenceCallIDForParticipantList = (_f = response === null || response === void 0 ? void 0 : response.callauth) === null || _f === void 0 ? void 0 : _f.id;
|
|
3002
3010
|
}
|
|
@@ -3005,6 +3013,7 @@ class CallProgressComponent {
|
|
|
3005
3013
|
this.extensionService.isLoadershow.next(false);
|
|
3006
3014
|
this.isLoadershown.emit(false);
|
|
3007
3015
|
}
|
|
3016
|
+
this.showRingAnimation = false;
|
|
3008
3017
|
// this.conferenceCallIDForParticipantList = response?.callauth?.id;
|
|
3009
3018
|
// await this.getAllParticipants(response?.callauth?.id);
|
|
3010
3019
|
}
|
|
@@ -4628,25 +4637,26 @@ class CallProgressComponent {
|
|
|
4628
4637
|
}
|
|
4629
4638
|
}
|
|
4630
4639
|
ngOnDestroy() {
|
|
4640
|
+
var _a, _b, _c;
|
|
4631
4641
|
this.callData.dial = false;
|
|
4632
|
-
setTimeout(() => {
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
}, 1500);
|
|
4642
|
+
// setTimeout(() => {
|
|
4643
|
+
if (!((_a = this.newIncomingCallsList) === null || _a === void 0 ? void 0 : _a.length) && !this.isNewCallLoader) {
|
|
4644
|
+
console.log('Destroying device and disconnecting all calls 2572');
|
|
4645
|
+
(_b = this.twilioService.device) === null || _b === void 0 ? void 0 : _b.disconnectAll();
|
|
4646
|
+
this.call.disconnect();
|
|
4647
|
+
(_c = this.device) === null || _c === void 0 ? void 0 : _c.destroy();
|
|
4648
|
+
}
|
|
4649
|
+
// }, 1500);
|
|
4640
4650
|
if (this.timerSubscription) {
|
|
4641
4651
|
this.timerSubscription.unsubscribe();
|
|
4642
4652
|
}
|
|
4643
4653
|
}
|
|
4644
4654
|
}
|
|
4645
4655
|
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 });
|
|
4646
|
-
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", 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 : ' '}}</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\" (click)=\"toggleMute()\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> 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 : ' '}}</span>\r\n </div>\r\n </div>\r\n <div class=\"conf-actions\">\r\n <button class=\"circle-btn\" [ngClass]=\"{'active': isMute}\" (click)=\"toggleMute(true)\">\r\n <span class=\"material-symbols-outlined\"> {{ isMute ? '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 <p></p>\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\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\" (click)=\"onMuteUser(c)\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"c?.isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!c?.isMute\"> 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\">\r\n <span *ngIf=\"!c?.isHold\" class=\"material-symbols-outlined\" [title]=\"'Hold'\"> phone_paused</span>\r\n <span *ngIf=\"c?.isHold\" class=\"material-symbols-outlined\" [title]=\"'Resume'\"> resume </span>\r\n </button>\r\n </ng-container>\r\n <button class=\"conference-contact\" (click)=\"confirmLeaveParticipant(c)\"\r\n *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>Conference Call Warning</h3>\r\n <p>\r\n Starting a new call will put the current conference 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\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> 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\">▼</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\">▼</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 input{opacity:0;width:0;height: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}.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}\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"] }] });
|
|
4656
|
+
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", 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 : ' '}}</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\" (click)=\"toggleMute()\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> 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 : ' '}}</span>\r\n </div>\r\n </div>\r\n <div class=\"conf-actions\">\r\n <button class=\"circle-btn\" [ngClass]=\"{'active': isMute}\" (click)=\"toggleMute(true)\">\r\n <span class=\"material-symbols-outlined\"> {{ isMute ? '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 <p></p>\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\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\" (click)=\"onMuteUser(c)\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"c?.isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!c?.isMute\"> 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\">\r\n <span *ngIf=\"!c?.isHold\" class=\"material-symbols-outlined\" [title]=\"'Hold'\"> phone_paused</span>\r\n <span *ngIf=\"c?.isHold\" class=\"material-symbols-outlined\" [title]=\"'Resume'\"> resume </span>\r\n </button>\r\n </ng-container>\r\n <button class=\"conference-contact\" (click)=\"confirmLeaveParticipant(c)\"\r\n *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\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> 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\">▼</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\">▼</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 input{opacity:0;width:0;height: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}\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"] }] });
|
|
4647
4657
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CallProgressComponent, decorators: [{
|
|
4648
4658
|
type: Component,
|
|
4649
|
-
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 : ' '}}</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\" (click)=\"toggleMute()\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> 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 : ' '}}</span>\r\n </div>\r\n </div>\r\n <div class=\"conf-actions\">\r\n <button class=\"circle-btn\" [ngClass]=\"{'active': isMute}\" (click)=\"toggleMute(true)\">\r\n <span class=\"material-symbols-outlined\"> {{ isMute ? '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 <p></p>\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\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\" (click)=\"onMuteUser(c)\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"c?.isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!c?.isMute\"> 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\">\r\n <span *ngIf=\"!c?.isHold\" class=\"material-symbols-outlined\" [title]=\"'Hold'\"> phone_paused</span>\r\n <span *ngIf=\"c?.isHold\" class=\"material-symbols-outlined\" [title]=\"'Resume'\"> resume </span>\r\n </button>\r\n </ng-container>\r\n <button class=\"conference-contact\" (click)=\"confirmLeaveParticipant(c)\"\r\n *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>Conference Call Warning</h3>\r\n <p>\r\n Starting a new call will put the current conference 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\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> 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\">▼</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\">▼</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 input{opacity:0;width:0;height: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}.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}\n"] }]
|
|
4659
|
+
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 : ' '}}</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\" (click)=\"toggleMute()\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> 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 : ' '}}</span>\r\n </div>\r\n </div>\r\n <div class=\"conf-actions\">\r\n <button class=\"circle-btn\" [ngClass]=\"{'active': isMute}\" (click)=\"toggleMute(true)\">\r\n <span class=\"material-symbols-outlined\"> {{ isMute ? '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 <p></p>\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\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\" (click)=\"onMuteUser(c)\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"c?.isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!c?.isMute\"> 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\">\r\n <span *ngIf=\"!c?.isHold\" class=\"material-symbols-outlined\" [title]=\"'Hold'\"> phone_paused</span>\r\n <span *ngIf=\"c?.isHold\" class=\"material-symbols-outlined\" [title]=\"'Resume'\"> resume </span>\r\n </button>\r\n </ng-container>\r\n <button class=\"conference-contact\" (click)=\"confirmLeaveParticipant(c)\"\r\n *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\">\r\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\r\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> 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\">▼</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\">▼</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 input{opacity:0;width:0;height: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}\n"] }]
|
|
4650
4660
|
}], ctorParameters: function () { return [{ type: ExtensionService }, { type: i0.ChangeDetectorRef }, { type: TwilioService }, { type: IpAddressService }, { type: IncomeingCallSocketService }]; }, propDecorators: { callData: [{
|
|
4651
4661
|
type: Input
|
|
4652
4662
|
}], selectedCallerId: [{
|
|
@@ -5046,6 +5056,7 @@ class DialboxComponent {
|
|
|
5046
5056
|
this.isCallInProgress = false;
|
|
5047
5057
|
setTimeout(() => {
|
|
5048
5058
|
var _a, _b, _c;
|
|
5059
|
+
console.log('344');
|
|
5049
5060
|
if (!((_a = this.twilioService.acceptedCallList) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
5050
5061
|
(_b = this.twilioService.device) === null || _b === void 0 ? void 0 : _b.disconnectAll();
|
|
5051
5062
|
(_c = this.twilioService.spareDevice) === null || _c === void 0 ? void 0 : _c.disconnectAll();
|
|
@@ -5055,15 +5066,14 @@ class DialboxComponent {
|
|
|
5055
5066
|
}
|
|
5056
5067
|
}
|
|
5057
5068
|
if (!((_e = this.incomingCallsList) === null || _e === void 0 ? void 0 : _e.length)) {
|
|
5058
|
-
setTimeout(() => {
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
}, 2000);
|
|
5069
|
+
// setTimeout(() => {
|
|
5070
|
+
// if(!this.incomingCallsList?.length) {
|
|
5071
|
+
// this.isCallInProgress = false;
|
|
5072
|
+
// this.twilioService.device?.disconnectAll();
|
|
5073
|
+
// this.twilioService.spareDevice?.disconnectAll();
|
|
5074
|
+
// this.twilioService.acceptedCallList = [];
|
|
5075
|
+
// }
|
|
5076
|
+
// }, 5000);
|
|
5067
5077
|
}
|
|
5068
5078
|
}));
|
|
5069
5079
|
this.token = localStorage.getItem('ext_token') || '';
|
|
@@ -6062,6 +6072,7 @@ class DialboxComponent {
|
|
|
6062
6072
|
this.incomingCallsList = [];
|
|
6063
6073
|
// Clean up Twilio device when component is destroyed
|
|
6064
6074
|
if (this.twilioService['device']) {
|
|
6075
|
+
console.log('1402');
|
|
6065
6076
|
this.twilioService['device'].disconnectAll();
|
|
6066
6077
|
this.twilioService['device'].destroy();
|
|
6067
6078
|
}
|