@vgroup/dialbox 0.3.46 → 0.3.48
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.
|
@@ -8,13 +8,13 @@ import * as i1 from '@angular/common/http';
|
|
|
8
8
|
import { HttpHeaders, HttpParams, HttpClientModule } from '@angular/common/http';
|
|
9
9
|
import { catchError, switchMap, map, tap, shareReplay } from 'rxjs/operators';
|
|
10
10
|
import { Device } from '@twilio/voice-sdk';
|
|
11
|
-
import * as i3
|
|
11
|
+
import * as i3 from '@angular/material/dialog';
|
|
12
12
|
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
|
|
13
13
|
import * as i5 from '@angular/router';
|
|
14
14
|
import { RouterLink, RouterModule } from '@angular/router';
|
|
15
|
-
import * as
|
|
15
|
+
import * as i4 from '@angular/common';
|
|
16
16
|
import { CommonModule } from '@angular/common';
|
|
17
|
-
import * as i4 from '@angular/forms';
|
|
17
|
+
import * as i4$1 from '@angular/forms';
|
|
18
18
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
19
19
|
import { BrowserModule } from '@angular/platform-browser';
|
|
20
20
|
|
|
@@ -1710,1181 +1710,1522 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
1710
1710
|
}]
|
|
1711
1711
|
}] });
|
|
1712
1712
|
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
// ];
|
|
1722
|
-
constructor(extensionService, cdr, twilioService) {
|
|
1713
|
+
const GlobalConstant = {
|
|
1714
|
+
ErrorMsg500: "Unable to process request. Please try again later.",
|
|
1715
|
+
isSMSVisible: true,
|
|
1716
|
+
dedicatedNumText: 'C2C Number'
|
|
1717
|
+
};
|
|
1718
|
+
|
|
1719
|
+
class IncomingCallComponent {
|
|
1720
|
+
constructor(extensionService, twilioService, notificationSerivce) {
|
|
1723
1721
|
this.extensionService = extensionService;
|
|
1724
|
-
this.cdr = cdr;
|
|
1725
1722
|
this.twilioService = twilioService;
|
|
1726
|
-
this.
|
|
1727
|
-
this.
|
|
1728
|
-
this.
|
|
1729
|
-
this.
|
|
1730
|
-
this.
|
|
1731
|
-
this.
|
|
1732
|
-
this.showKeypad = false;
|
|
1733
|
-
this.keypadVal = keypad;
|
|
1734
|
-
this.callInput = '';
|
|
1735
|
-
this.isMute = false;
|
|
1736
|
-
this.disbaleEndCallBtn = true;
|
|
1737
|
-
this.showClearBtn = false;
|
|
1738
|
-
this.isCollops = false;
|
|
1739
|
-
// Conference state flag
|
|
1740
|
-
this.isConference = false;
|
|
1741
|
-
this.isOutgoingCall = true;
|
|
1742
|
-
// Incoming call variables
|
|
1743
|
-
this.incomingCallDiv = false;
|
|
1744
|
-
//@Output() showCallProgressEvent: EventEmitter<void> = new EventEmitter<void>();
|
|
1745
|
-
this.incomingCallInitiated = new EventEmitter();
|
|
1723
|
+
this.notificationSerivce = notificationSerivce;
|
|
1724
|
+
this.showRingAnimation = true;
|
|
1725
|
+
this.selectedIncomingCall = {};
|
|
1726
|
+
this.dedicatedNum = '';
|
|
1727
|
+
this.shouldRecordCall = false;
|
|
1728
|
+
this.isClickExpand = false;
|
|
1746
1729
|
this.isRecording = false;
|
|
1747
1730
|
this.isPaused = false;
|
|
1748
|
-
this.
|
|
1749
|
-
this.
|
|
1750
|
-
this.
|
|
1751
|
-
this.
|
|
1752
|
-
this.
|
|
1753
|
-
this.
|
|
1754
|
-
this.
|
|
1755
|
-
this.
|
|
1756
|
-
|
|
1757
|
-
this.isMinimised = false;
|
|
1758
|
-
console.log('Call Progress Component');
|
|
1731
|
+
this.isTwilioConnected = false;
|
|
1732
|
+
this.closeIncomingCallDiv = new EventEmitter();
|
|
1733
|
+
this.incomingCallsNewList = new EventEmitter();
|
|
1734
|
+
this.selectedIncomingCallInfo = new EventEmitter();
|
|
1735
|
+
this.disbaleEndCallBtn = false;
|
|
1736
|
+
this.incomingCallSid = '';
|
|
1737
|
+
this.incomingRecordCall = false;
|
|
1738
|
+
this.timeElapsed = 0;
|
|
1739
|
+
console.log('IncomingCallComponent');
|
|
1759
1740
|
}
|
|
1760
1741
|
ngOnInit() {
|
|
1761
|
-
|
|
1762
|
-
//
|
|
1742
|
+
// this.twilioService.currentCall.subscribe((call: any) => {
|
|
1743
|
+
// if (call) {
|
|
1744
|
+
// this.twilioCallData = call;
|
|
1745
|
+
// this.notificationSerivce.showNotification(call);
|
|
1746
|
+
// // Handle the call UI
|
|
1747
|
+
// }
|
|
1748
|
+
// });
|
|
1749
|
+
console.log('IncomingCallComponent ngOnInit');
|
|
1763
1750
|
try {
|
|
1764
|
-
this.twilioService.currentCall.subscribe(
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
console.log('Current call status:', (_a = this.call) === null || _a === void 0 ? void 0 : _a.status());
|
|
1771
|
-
// If there is an ongoing call, show concurrent incoming banner
|
|
1772
|
-
if (this.call && this.call.status() === 'open') {
|
|
1773
|
-
console.log('Concurrent incoming detected - showing banner');
|
|
1774
|
-
this.isConcurrentIncoming = true;
|
|
1775
|
-
this.incomingCallDiv = true;
|
|
1776
|
-
// Add to list if not present
|
|
1777
|
-
const exists = (this.newIncomingCallsList || []).some((c) => { var _a, _b; return ((_a = c === null || c === void 0 ? void 0 : c.parameters) === null || _a === void 0 ? void 0 : _a.CallSid) === ((_b = incoming === null || incoming === void 0 ? void 0 : incoming.parameters) === null || _b === void 0 ? void 0 : _b.CallSid); });
|
|
1778
|
-
if (!exists) {
|
|
1779
|
-
this.newIncomingCallsList = [...(this.newIncomingCallsList || []), incoming];
|
|
1780
|
-
this.incomingCallsNewInfo.emit(this.newIncomingCallsList);
|
|
1751
|
+
this.twilioService.currentCall.subscribe(call => {
|
|
1752
|
+
if (call) {
|
|
1753
|
+
this.twilioCallData = call;
|
|
1754
|
+
this.twilioAuthId = call.customParameters.get('twilioAuthId');
|
|
1755
|
+
if (!call.parameters) {
|
|
1756
|
+
call.parameters = {};
|
|
1781
1757
|
}
|
|
1782
|
-
this.
|
|
1758
|
+
this.sendIPforIncomingCall(this.twilioAuthId, '');
|
|
1759
|
+
call.on('cancel', () => {
|
|
1760
|
+
if (this.incomingCallData && this.incomingCallData.parameters && this.incomingCallData.parameters.CallSid) {
|
|
1761
|
+
this.newIncomingCallsList = this.newIncomingCallsList.filter((item) => item.parameters && item.parameters.CallSid !== this.incomingCallData.parameters.CallSid);
|
|
1762
|
+
}
|
|
1763
|
+
this.rejectCallFromList(call);
|
|
1764
|
+
});
|
|
1765
|
+
call.on('disconnect', () => {
|
|
1766
|
+
if (this.incomingCallData && this.incomingCallData.parameters && this.incomingCallData.parameters.CallSid) {
|
|
1767
|
+
this.newIncomingCallsList = this.newIncomingCallsList.filter((item) => item.parameters && item.parameters.CallSid !== this.incomingCallData.parameters.CallSid);
|
|
1768
|
+
}
|
|
1769
|
+
this.rejectCallFromList(call);
|
|
1770
|
+
});
|
|
1783
1771
|
}
|
|
1784
1772
|
});
|
|
1785
1773
|
}
|
|
1786
1774
|
catch (e) {
|
|
1787
|
-
console.
|
|
1775
|
+
console.log(e);
|
|
1788
1776
|
}
|
|
1789
1777
|
}
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1778
|
+
acceptCallFromList(data) {
|
|
1779
|
+
if (!data) {
|
|
1780
|
+
return;
|
|
1781
|
+
}
|
|
1782
|
+
// Disconnect any other connected call before accepting this one
|
|
1783
|
+
if (this.newIncomingCallsList && this.newIncomingCallsList.length) {
|
|
1784
|
+
const otherConnected = this.newIncomingCallsList.find((item) => item.isCallConnected && item !== data);
|
|
1785
|
+
if (otherConnected) {
|
|
1786
|
+
try {
|
|
1787
|
+
otherConnected.disconnect();
|
|
1788
|
+
}
|
|
1789
|
+
catch (_a) { }
|
|
1790
|
+
otherConnected.isCallConnected = false;
|
|
1791
|
+
otherConnected.isFirstCall = false;
|
|
1798
1792
|
}
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1793
|
+
}
|
|
1794
|
+
// Accept this call and mark as the active one
|
|
1795
|
+
data.accept();
|
|
1796
|
+
data.isCallConnected = true;
|
|
1797
|
+
data.isFirstCall = true;
|
|
1798
|
+
this.extensionService.setCallSid(this.CallSid, this.recordCall);
|
|
1799
|
+
this.sendIPforIncomingCall(data.customParameters.get('twilioAuthId'), 'answered').then(() => {
|
|
1800
|
+
this.closeIncomingCallWrapper(1);
|
|
1801
|
+
});
|
|
1802
|
+
}
|
|
1803
|
+
rejectCallFromList(data) {
|
|
1804
|
+
if (!data)
|
|
1805
|
+
return;
|
|
1806
|
+
if (data.reject)
|
|
1807
|
+
data.reject();
|
|
1808
|
+
if (data.disconnect)
|
|
1809
|
+
data.disconnect();
|
|
1810
|
+
if (data.parameters) {
|
|
1811
|
+
data.parameters['isCallConnected'] = false; // Should be false when rejecting
|
|
1812
|
+
}
|
|
1813
|
+
if (data.customParameters) {
|
|
1814
|
+
this.sendIPforIncomingCall(data.customParameters.get('twilioAuthId'), 'answered');
|
|
1815
|
+
}
|
|
1816
|
+
if (this.newIncomingCallsList && data && data.parameters && data.parameters.CallSid) {
|
|
1817
|
+
this.newIncomingCallsList = this.newIncomingCallsList.filter((item) => item.parameters && item.parameters.CallSid !== data.parameters.CallSid);
|
|
1818
|
+
this.incomingCallsNewList.emit(this.newIncomingCallsList);
|
|
1819
|
+
if (this.newIncomingCallsList.length == 0) {
|
|
1820
|
+
this.closeIncomingCallDiv.emit({ show: 0, call: data });
|
|
1803
1821
|
}
|
|
1804
1822
|
}
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
//
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1823
|
+
}
|
|
1824
|
+
closeIncomingCallWrapper(val) {
|
|
1825
|
+
this.closeIncomingCallDiv.emit({ show: val, call: this.twilioCallData });
|
|
1826
|
+
}
|
|
1827
|
+
toggleMute(data) {
|
|
1828
|
+
this.isMute = !this.isMute;
|
|
1829
|
+
data.mute(this.isMute);
|
|
1830
|
+
}
|
|
1831
|
+
sendIPforIncomingCall(recordId, callstatus) {
|
|
1832
|
+
console.log('sendIPforIncomingCall');
|
|
1833
|
+
return new Promise((resolve, reject) => {
|
|
1834
|
+
this.extensionService.getIPDetailsForCall(recordId, callstatus, this.deviceId).subscribe((res) => {
|
|
1835
|
+
const resp = res;
|
|
1836
|
+
if (res.status == 200) {
|
|
1837
|
+
if (resp.callAuth) {
|
|
1838
|
+
this.CallSid = resp.callAuth.callSid;
|
|
1839
|
+
this.recordCall = resp.callAuth.recordCall;
|
|
1840
|
+
// Handle the recordCall flag
|
|
1841
|
+
if (resp.callAuth.recordCall) {
|
|
1842
|
+
this.shouldRecordCall = true;
|
|
1843
|
+
}
|
|
1844
|
+
else {
|
|
1845
|
+
this.shouldRecordCall = false;
|
|
1846
|
+
}
|
|
1829
1847
|
}
|
|
1830
1848
|
else {
|
|
1831
|
-
//
|
|
1832
|
-
this.isConcurrentIncoming = false;
|
|
1833
|
-
this.incomingCallDiv = true;
|
|
1834
|
-
this.cdr.detectChanges();
|
|
1849
|
+
// swal("Error", "Missing call authentication details.", "error");
|
|
1835
1850
|
}
|
|
1851
|
+
resolve();
|
|
1836
1852
|
}
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1853
|
+
else {
|
|
1854
|
+
swal("Error", resp.message.join("<br/>"), "error");
|
|
1855
|
+
resolve();
|
|
1856
|
+
}
|
|
1857
|
+
}, (error) => {
|
|
1858
|
+
swal("Error", GlobalConstant.ErrorMsg500, "error");
|
|
1859
|
+
resolve();
|
|
1860
|
+
});
|
|
1861
|
+
});
|
|
1842
1862
|
}
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
// }, 3000);
|
|
1863
|
+
onUserInfoByCallSid() {
|
|
1864
|
+
if (this.selectedIncomingCall && this.selectedIncomingCall.userInfo) {
|
|
1865
|
+
}
|
|
1866
|
+
return this.selectedIncomingCall ? Object.keys(this.selectedIncomingCall).length ? true : false : false;
|
|
1848
1867
|
}
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
console.error('Error fetching contacts:', error);
|
|
1868
|
-
this.contacts = [];
|
|
1869
|
-
});
|
|
1868
|
+
// Check if call has detailed information available for expansion
|
|
1869
|
+
hasDetailedInfo(callData) {
|
|
1870
|
+
if (!callData)
|
|
1871
|
+
return false;
|
|
1872
|
+
// Check if userInfo exists and has meaningful data
|
|
1873
|
+
if (callData.userInfo && callData.userInfo.c2cInformation) {
|
|
1874
|
+
const info = callData.userInfo.c2cInformation;
|
|
1875
|
+
return !!(info.subject && info.subject !== '-' ||
|
|
1876
|
+
info.email && info.email !== '-' ||
|
|
1877
|
+
info.message && info.message !== '-' ||
|
|
1878
|
+
info.pointName && info.pointName !== '-' ||
|
|
1879
|
+
info.sourceName && info.sourceName !== '-' ||
|
|
1880
|
+
info.extension && info.extension !== '-' ||
|
|
1881
|
+
info.url ||
|
|
1882
|
+
info.latitude ||
|
|
1883
|
+
info.longitude);
|
|
1884
|
+
}
|
|
1885
|
+
return false;
|
|
1870
1886
|
}
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
this.getUserInformation(callAuthId);
|
|
1889
|
-
this.recordCall = recordCall; // Store the recordCall value
|
|
1890
|
-
const tokenData = yield this.getOutgoingCallToken(callAuthId);
|
|
1891
|
-
yield this.connectToDevice(tokenData.token, callData);
|
|
1892
|
-
yield this.pollCallStatus(callAuthId);
|
|
1893
|
-
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
1894
|
-
var _b, _c;
|
|
1895
|
-
try {
|
|
1896
|
-
this.addRes = yield this.addParticipantToCall({
|
|
1897
|
-
from: callData === null || callData === void 0 ? void 0 : callData.from,
|
|
1898
|
-
route: "OUTGOING",
|
|
1899
|
-
participantNumber: callData === null || callData === void 0 ? void 0 : callData.phone,
|
|
1900
|
-
conferenceId: this.conferenceId
|
|
1901
|
-
});
|
|
1902
|
-
this.callData = Object.assign(Object.assign({}, callData), { participantId: (_b = this.addRes) === null || _b === void 0 ? void 0 : _b.participantId, isHold: false, isLeft: false, isIncomingCall: false, isConference: false });
|
|
1903
|
-
this.call['callInfo'] = JSON.parse(JSON.stringify(this.callData));
|
|
1904
|
-
console.log('test111111');
|
|
1905
|
-
this.currentCall = Object.assign(Object.assign({}, this.callData), { img: callData.img || 'assets/images/user.jpg' });
|
|
1906
|
-
this.currentCallList.push(Object.assign(Object.assign({}, this.callData), { img: callData.img || 'assets/images/user.jpg' }));
|
|
1907
|
-
console.log('Initial participantId:', (_c = this.addRes) === null || _c === void 0 ? void 0 : _c.participantId);
|
|
1908
|
-
}
|
|
1909
|
-
catch (e) {
|
|
1910
|
-
console.error('Error adding initial participant:', e);
|
|
1911
|
-
}
|
|
1912
|
-
}), 1000);
|
|
1913
|
-
// Poll the status for 30-45 seconds
|
|
1914
|
-
}
|
|
1915
|
-
else if (response.status == 201) {
|
|
1916
|
-
swal("Error", response.message.join("<br/>"), "error");
|
|
1917
|
-
console.log('test2');
|
|
1918
|
-
this.endCall();
|
|
1919
|
-
}
|
|
1887
|
+
onClickExpand(data) {
|
|
1888
|
+
if (this.selectedIncomingCall === data && this.isClickExpand) {
|
|
1889
|
+
this.isClickExpand = false;
|
|
1890
|
+
this.selectedIncomingCall = null;
|
|
1891
|
+
this.selectedIncomingCallInfo.emit({});
|
|
1892
|
+
return;
|
|
1893
|
+
}
|
|
1894
|
+
this.isClickExpand = true;
|
|
1895
|
+
this.selectedIncomingCall = data;
|
|
1896
|
+
if (this.selectedIncomingCall) {
|
|
1897
|
+
this.selectedIncomingCall['isClickExpand'] = true;
|
|
1898
|
+
if (this.newIncomingCallsList && this.newIncomingCallsList.length > 0) {
|
|
1899
|
+
this.newIncomingCallsList.forEach((call) => {
|
|
1900
|
+
if (call !== this.selectedIncomingCall) {
|
|
1901
|
+
call['isClickExpand'] = false;
|
|
1902
|
+
}
|
|
1903
|
+
});
|
|
1920
1904
|
}
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
this.
|
|
1924
|
-
console.log('test3');
|
|
1925
|
-
this.endCall();
|
|
1905
|
+
this.selectedIncomingCallInfo.emit(this.selectedIncomingCall);
|
|
1906
|
+
if (!this.selectedIncomingCall.userInfo || this.selectedIncomingCall.userInfo.status == 201) {
|
|
1907
|
+
this.getUserInformation(this.selectedIncomingCall);
|
|
1926
1908
|
}
|
|
1927
|
-
}
|
|
1909
|
+
}
|
|
1928
1910
|
}
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
this.
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1911
|
+
getUserInformation(incomingCallData) {
|
|
1912
|
+
let data = this.fromEntries(Array.from(incomingCallData.customParameters.entries()));
|
|
1913
|
+
this.extensionService.getUserInformation(data['twilioAuthId']).subscribe(response => {
|
|
1914
|
+
setTimeout(() => {
|
|
1915
|
+
incomingCallData['userInfo'] = response;
|
|
1916
|
+
}, 5000);
|
|
1917
|
+
}, error => {
|
|
1918
|
+
console.error('Error starting recording', error);
|
|
1935
1919
|
});
|
|
1936
|
-
c.hold = !c.hold;
|
|
1937
|
-
this.cdr.detectChanges();
|
|
1938
1920
|
}
|
|
1939
|
-
|
|
1940
|
-
return
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
if ((res === null || res === void 0 ? void 0 : res.status) == 201 && (res === null || res === void 0 ? void 0 : res.message) == 'participant already left') {
|
|
1945
|
-
this.currentCallList = this.currentCallList.filter((item) => item.participantId !== c.participantId);
|
|
1946
|
-
this.currentCall = this.currentCallList.length > 0 ? this.currentCallList[0] : null;
|
|
1947
|
-
this.cdr.detectChanges();
|
|
1948
|
-
}
|
|
1949
|
-
yield this.getAllParticipants(this.conferenceId);
|
|
1950
|
-
});
|
|
1921
|
+
fromEntries(entries) {
|
|
1922
|
+
return entries.reduce((acc, [key, value]) => {
|
|
1923
|
+
acc[key] = value;
|
|
1924
|
+
return acc;
|
|
1925
|
+
}, {});
|
|
1951
1926
|
}
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
}
|
|
1927
|
+
toggleRecording(sid) {
|
|
1928
|
+
if (this.isRecording) {
|
|
1929
|
+
this.stopRecording();
|
|
1930
|
+
}
|
|
1931
|
+
else {
|
|
1932
|
+
this.startRecording();
|
|
1933
|
+
}
|
|
1956
1934
|
}
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1935
|
+
startRecording() {
|
|
1936
|
+
let sid;
|
|
1937
|
+
const details = this.extensionService.getCallSid();
|
|
1938
|
+
this.incomingCallSid = details.callSid;
|
|
1939
|
+
this.incomingRecordCall = details.recordCall;
|
|
1940
|
+
sid = this.incomingCallSid ? this.incomingCallSid : this.CallSid;
|
|
1941
|
+
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
1942
|
+
// return;
|
|
1943
|
+
// }
|
|
1944
|
+
this.extensionService.getCallRecording(sid).subscribe(response => {
|
|
1945
|
+
this.isRecording = true;
|
|
1946
|
+
this.isPaused = false;
|
|
1947
|
+
// this.timeElapsed = 0;
|
|
1948
|
+
this.startTimer1();
|
|
1949
|
+
}, error => {
|
|
1950
|
+
console.error('Error starting recording', error);
|
|
1960
1951
|
});
|
|
1961
1952
|
}
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
}
|
|
1953
|
+
stopRecording() {
|
|
1954
|
+
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
1955
|
+
// return;
|
|
1956
|
+
// }
|
|
1957
|
+
this.isRecording = false;
|
|
1958
|
+
this.isPaused = false;
|
|
1959
|
+
if (this.timerSubscription) {
|
|
1960
|
+
this.timerSubscription.unsubscribe();
|
|
1961
|
+
}
|
|
1966
1962
|
}
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1963
|
+
pauseRecording() {
|
|
1964
|
+
const details = this.extensionService.getCallSid();
|
|
1965
|
+
this.incomingCallSid = details.callSid;
|
|
1966
|
+
this.incomingRecordCall = details.recordCall;
|
|
1967
|
+
const sid = this.incomingCallSid ? this.incomingCallSid : this.CallSid;
|
|
1968
|
+
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
1969
|
+
// return;
|
|
1970
|
+
// }
|
|
1971
|
+
this.extensionService.pauseOrResumeRecording(sid, 'pause').subscribe(response => {
|
|
1972
|
+
// this.stopRecordingTimer();
|
|
1973
|
+
this.isPaused = true;
|
|
1974
|
+
}, error => {
|
|
1975
|
+
console.error('Error pausing recording:', error);
|
|
1976
|
+
// Consider updating the UI to show the error state
|
|
1970
1977
|
});
|
|
1971
1978
|
}
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1979
|
+
resumeRecording(sid) {
|
|
1980
|
+
// let sid;
|
|
1981
|
+
const details = this.extensionService.getCallSid();
|
|
1982
|
+
this.incomingCallSid = details.callSid;
|
|
1983
|
+
this.incomingRecordCall = details.recordCall;
|
|
1984
|
+
sid = this.incomingCallSid ? this.incomingCallSid : this.CallSid;
|
|
1985
|
+
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
1986
|
+
// return; // Skip if recording is not enabled
|
|
1987
|
+
// }
|
|
1988
|
+
this.extensionService.pauseOrResumeRecording(sid, 'resume').subscribe(response => {
|
|
1989
|
+
this.isPaused = false;
|
|
1990
|
+
this.startTimer1();
|
|
1991
|
+
}, error => {
|
|
1992
|
+
console.error('Error resuming recording', error);
|
|
1975
1993
|
});
|
|
1976
1994
|
}
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
id: response.callauth.id,
|
|
1981
|
-
recordCall: response.callauth.recordCall
|
|
1982
|
-
};
|
|
1995
|
+
startTimer1() {
|
|
1996
|
+
this.timerSubscription = interval(1000).subscribe(() => {
|
|
1997
|
+
this.timeElapsed++;
|
|
1983
1998
|
});
|
|
1984
1999
|
}
|
|
1985
|
-
|
|
2000
|
+
stopRecordingTimer() {
|
|
2001
|
+
if (this.timerSubscription) {
|
|
2002
|
+
this.timerSubscription.unsubscribe(); // Pause the timer
|
|
2003
|
+
this.timerSubscription = undefined; // Optionally reset the subscription
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
// device: any;
|
|
2007
|
+
onEndCall() {
|
|
2008
|
+
this.extensionService.getRemoveParticipants(this.incomingCallData.participantId, this.incomingCallData.conferenceId).toPromise();
|
|
2009
|
+
}
|
|
2010
|
+
add(data) {
|
|
1986
2011
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1987
|
-
|
|
2012
|
+
if ((data === null || data === void 0 ? void 0 : data.status) != 'ringing') {
|
|
2013
|
+
let device = yield this.twilioService.connect('');
|
|
2014
|
+
console.log(device, 'callConnect');
|
|
2015
|
+
}
|
|
2016
|
+
else if ((data === null || data === void 0 ? void 0 : data.status) == 'ringing') {
|
|
2017
|
+
this.twilioService.addIncomingParticipant(data === null || data === void 0 ? void 0 : data.id, this.twilioService.conferenceCallInfo.conferenceId).subscribe((data) => {
|
|
2018
|
+
console.log(data, 'bhhhhhhhhhhhhhhhhhhh');
|
|
2019
|
+
});
|
|
2020
|
+
}
|
|
2021
|
+
// this.device = new Device();/
|
|
2022
|
+
// Device.connect({ conferenceName: 'my-conference-room' });
|
|
2023
|
+
// this.device = new Device({ conferenceName: 'my-conference-room' });
|
|
1988
2024
|
});
|
|
1989
2025
|
}
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
const options = {
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
};
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
}
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
});
|
|
2029
|
-
(_e = this.call) === null || _e === void 0 ? void 0 : _e.on('reject', () => {
|
|
2030
|
-
console.log('test5');
|
|
2031
|
-
this.endCall();
|
|
2032
|
-
});
|
|
2033
|
-
(_f = this.call) === null || _f === void 0 ? void 0 : _f.on('accept', () => {
|
|
2034
|
-
this.showRingAnimation = false;
|
|
2035
|
-
this.disbaleEndCallBtn = false;
|
|
2036
|
-
// Start recording if recordCall is true and call is accepted for 30 seconds
|
|
2037
|
-
// if (this.recordCall) {
|
|
2038
|
-
// setTimeout(() => {
|
|
2039
|
-
// if (this.isRecording) return; // If already recording, skip
|
|
2040
|
-
// this.startRecording();
|
|
2041
|
-
// }, 30000);
|
|
2042
|
-
// } else {
|
|
2043
|
-
// this.stopRecording();
|
|
2044
|
-
// }
|
|
2045
|
-
});
|
|
2046
|
-
(_g = this.call) === null || _g === void 0 ? void 0 : _g.on('messageReceived', (message) => {
|
|
2047
|
-
});
|
|
2048
|
-
}
|
|
2049
|
-
startTimer() {
|
|
2050
|
-
let seconds = 0;
|
|
2051
|
-
this.intervalId = setInterval(() => {
|
|
2052
|
-
seconds++;
|
|
2053
|
-
this.timer = this.formatTime(seconds);
|
|
2054
|
-
}, 1000);
|
|
2055
|
-
}
|
|
2056
|
-
stopTimer() {
|
|
2057
|
-
clearInterval(this.intervalId);
|
|
2026
|
+
}
|
|
2027
|
+
IncomingCallComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: IncomingCallComponent, deps: [{ token: ExtensionService }, { token: TwilioService }, { token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2028
|
+
IncomingCallComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: IncomingCallComponent, selector: "lib-incoming-call", inputs: { incomingCallData: "incomingCallData", newIncomingCallsList: "newIncomingCallsList", deviceId: "deviceId" }, outputs: { closeIncomingCallDiv: "closeIncomingCallDiv", incomingCallsNewList: "incomingCallsNewList", selectedIncomingCallInfo: "selectedIncomingCallInfo" }, ngImport: i0, template: "<div class=\"call-container\" *ngIf=\"newIncomingCallsList?.length === 1\">\r\n <div style=\"display: flex; flex-direction: column;\">\r\n <div class=\"callToNum\">Incoming call on <br/><span>{{incomingCallData?.phone || 'Unknown Number'}}</span></div>\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" [src]=\"newIncomingCallsList[0]?.img || incomingCallData?.img\" alt=\"\" width=\"120\" />\r\n </div>\r\n <div class=\"callerDetails\">\r\n <!-- <h1>{{newIncomingCallsList[0]?.userInfo?.c2cInformation?.name || incomingCallData?.name || 'Unknown Number'}}</h1> -->\r\n <!-- <p>{{newIncomingCallsList[0]?.userInfo?.displayNum ? newIncomingCallsList[0]?.userInfo?.c2cInformation?.number : newIncomingCallsList[0]?.userInfo?.c2cInformation?.number || incomingCallData?.displayNum || incomingCallData?.phone}}</p> -->\r\n <h1>{{incomingCallData?.name || 'Unknown Number'}}</h1>\r\n <p>{{incomingCallData?.phone}}</p>\r\n </div>\r\n \r\n <!-- <div class=\"callerDetails\">\r\n <h1 [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{callData.name}}</h1>\r\n <p>{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\r\n <h4 style=\"margin-top: 4px\">{{timer}}</h4>\r\n </div> -->\r\n <div class=\"call-action-btns\">\r\n <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected || incomingCallData\">\r\n <span class=\"material-symbols-outlined\" (click)=\"add(newIncomingCallsList[0])\"> call </span> \r\n </button>\r\n <!-- <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected || incomingCallData\">\r\n <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(newIncomingCallsList[0])\"> call </span>\r\n </button> -->\r\n <button class=\"call-btn mute-btn\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected\" (click)=\"toggleMute(newIncomingCallsList[0])\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container \">\r\n <button class=\"record-btn start-stop\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\r\n <span class=\"recording-icon\"></span>\r\n </button> \r\n <div class=\"\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected && 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=\"newIncomingCallsList[0]?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <!-- <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(newIncomingCallsList[0])\"> call_end </span>\r\n </button> -->\r\n <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"onEndCall()\"> 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\" 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<div class=\"call-container\" style=\"width: 100%;\" *ngIf=\"newIncomingCallsList?.length > 1\" [ngClass]=\"{'call-container-open': selectedIncomingCall?.isClickExpand}\">\r\n <div class=\"collops\">\r\n <div class=\"d-flex w-100\">\r\n <div class=\"d-flex flex-column container-fluid\" >\r\n <div class=\"callToNum\">Incoming call <br/><span>{{dedicatedNum}}</span></div>\r\n <ng-container *ngFor=\"let data of newIncomingCallsList\"> \r\n <div class=\"p-2 \">\r\n <div class=\"call-info-wrapper w-100 d-flex align-items-center\">\r\n <div class=\"img\">\r\n <img class=\"avatar-img-wrapper\" [src]=\"data?.img\" alt=\"\" width=\"45\" />\r\n </div>\r\n <div class=\"d-flex justify-content-between w-100 align-items-center mr-2\">\r\n <div class=\"callerDetails-wrapper\">\r\n <h5 class=\"break-word\">{{data?.userInfo?.c2cInformation?.name || '-'}}</h5>\r\n <p class=\"break-word\">{{data?.userInfo?.displayNum ? data?.userInfo?.c2cInformation?.number : data?.userInfo?.c2cInformation?.number }}</p>\r\n </div> \r\n <div class=\"d-flex align-items-center\">\r\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!data?.isCallConnected\">\r\n <!-- <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(data)\"> call </span> -->\r\n <span class=\"material-symbols-outlined\" (click)=\"add(data)\"> call </span>\r\n </button>\r\n <button class=\"call-btn-wrapper mute-btn\" *ngIf=\"data?.isCallConnected\" (click)=\"toggleMute(data)\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container\">\r\n <button class=\"record-btn start-stop\" *ngIf=\"data?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\r\n <span class=\"recording-icon\"></span>\r\n </button> \r\n <div class=\"\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"data?.isCallConnected && 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=\"data?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <button class=\"call-btn-wrapper reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(data)\"> call_end </span>\r\n </button>\r\n <div class=\"togglearrow-arrow me-2\" id=\"togglearrow\" \r\n (click)=\"hasDetailedInfo(data) ? onClickExpand(data) : null\" \r\n [ngClass]=\"{'disabled': !hasDetailedInfo(data)}\"\r\n [title]=\"hasDetailedInfo(data) ? 'View details' : 'No details available'\">\r\n <i class=\"fa fa-angle-right\"></i>\r\n </div>\r\n <!-- <div *ngIf=\"data?.customParameters?.get('c2cNumber') === true || data?.customParameters?.get('c2cNumber') === 'true'\" class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"onClickExpand(data)\"> \r\n <i class=\"fa fa-angle-right\"></i> \r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div class=\"call-container p-3 text-white model-content\" *ngIf=\"isClickExpand \"> \r\n <div class=\"mb-2\" style=\"width: 100%; height: 100%;\">\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" [src]=\"incomingCallData.img\" alt=\"\" width=\"100\" />\r\n </div>\r\n <div class=\"text-center\">\r\n <h3 class=\"text-white\">{{selectedIncomingCall?.userInfo?.c2cInformation?.name || '-'}}</h3>\r\n </div>\r\n <div class=\"f-13\">\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Subject:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.subject || '-'}}</div>\r\n </div> \r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Email:</div>\r\n <div>{{selectedIncomingCall?.userInfo?.c2cInformation?.email || '-'}}</div>\r\n </div> \r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Number:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.number}}</div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"\">Language:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.language || '-'}}</div>\r\n </div>\r\n </div>\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Extension:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.extension || '-'}}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Image:</div>\r\n <div class=\"text-ellipsis\">\r\n <ng-container *ngIf=\"selectedIncomingCall?.userInfo?.c2cInformation?.image && selectedIncomingCall?.userInfo?.c2cInformation?.image !== '-'; else noImage\">\r\n <img src=\"{{selectedIncomingCall?.userInfo?.c2cInformation?.image}}\" alt=\"\" width=\"42\" height=\"42\" 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\r\n <div class=\" mb-4\">\r\n <div class=\"\">\r\n <div class=\"\">Message:</div>\r\n <div class=\"text-ellipsis\">{{selectedIncomingCall?.userInfo?.c2cInformation?.message || '-'}}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Point Name:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.pointName || '-'}}</div>\r\n </div>\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Source Name:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.sourceName || '-'}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"call-action-btns mt-0\">\r\n <button class=\"call-btn receive-btn\" *ngIf=\"!selectedIncomingCall?.isCallConnected\">\r\n <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(selectedIncomingCall)\"> call </span>\r\n </button>\r\n <button class=\"call-btn mute-btn\" *ngIf=\"selectedIncomingCall?.isCallConnected\" (click)=\"toggleMute(selectedIncomingCall)\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container\">\r\n <button class=\"record-btn start-stop\" *ngIf=\"selectedIncomingCall?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\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=\"selectedIncomingCall?.isCallConnected && 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=\"selectedIncomingCall?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(selectedIncomingCall)\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\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\" [ngStyle]=\"{'width': '756px'}\">\r\n <defs>\r\n <path id=\"gentle-wave\" d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" /> \r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n</div>", styles: [".call-container{width:385px!important;height:646px!important;margin:auto;border-radius:30px;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}.collops{display:flex;flex-direction:column;width:100%;height:100%}.container-fluid{width:400px;height:100%;margin-top:10px}.model-content{background-color:#0d6efd;border-radius:20px;width:395px!important}.call-container-open{width:752px!important}.calls-side-by-side{position:fixed;top:0;width:30%;height:498px;z-index:1050;pointer-events:auto;display:flex;align-items:flex-start;left:-10rem;transform:translate(.2rem);transition:left 1s ease-in-out}.move{left:41vw!important}.f-13{font-size:13px!important}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto;border-radius:100%;border:solid 4px #fff}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.avatar-img-wrapper{border-radius:100%;margin:0 5px}.call-btn-wrapper{height:38px;background-color:#fff;border-radius:30px;margin:0 4px;opacity:.9;width:40px}.call-btn-wrapper span{color:#fff;line-height:unset!important}.hold-btn{background-color:#bebebe26;border:none}.hold-btn span,.mute-btn span{color:#fff!important}.active-hold{background-color:#fff!important}.active-hold span{color:#000!important}.active-mute{background-color:transparent}.call-info-wrapper{border:1px solid white;border-radius:7px;padding:8px 1px!important;word-break:break-all}.call-animation-play{animation:play 3s linear infinite}.avatar-img{width:94px;height:94px;border-radius:100%;position:absolute;left:0;top:0}@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}.callerDetails h1{margin:12px 0 0;color:#fff}.callerDetails-wrapper{margin:0 5px;color:#fff;display:flex;flex-direction:column}.callerDetails-wrapper h3,.callerDetails-wrapper h5{margin:0;color:#fff}.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}.callerDetails h4{margin:0;color:#fff}.callerDetails p,.callerDetails-wrapper p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-btn{position:relative;width:50px;height:50px;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}.call-sec-btn span{color:#cccbcb}.call-btn{width:48px;height:45px;background-color:#fff;border-radius:30px;box-sizing:border-box;margin:0 8px;opacity:.9}.call-btn:hover{opacity:1}.call-btn span{color:#fff;line-height:unset!important}.receive-btn{background-color:#28a745;border:2px solid #28a745}.mute-btn{position:relative;border:none;background-color:#bebebe26}.reject-btn{background-color:#e03131;border:2px solid #e03131}.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}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.call-action-btns{text-align:center;display:flex;justify-content:center;align-items:center;margin-top:240px}#call-input{background-color:transparent;border:none;outline:none;text-align:center;color:#fff}.wave-container{position:absolute;bottom:0}.waves{width:660px;position:relative;margin-bottom:-7px;height:40px;min-height:40px}.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}.callToNum{color:#fff;font-weight:400;text-align:center}.callToNum span{font-weight:600}.text-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;display:block}.record-action-btns{display:flex;flex-direction:column;align-items:center}.record-btn-container{position:relative}.record-btn{border:none;border-radius:50%;width:48px;height:48px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;overflow:hidden}.record-btn-side{border:none;border-radius:50%;width:44px;height:44px;display:flex;align-items:center;justify-content:center;cursor:pointer;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;justify-content:center;width:48px;height:48px;background-color:#fff;border-radius:30px}.record-btn.pause-resume{border:none;border-radius:50%;width:48px;height:48px;background:white;display:flex;align-items:center;justify-content:center}.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%}.togglearrow-arrow.disabled{opacity:.3;cursor:not-allowed;pointer-events:none}.togglearrow-arrow.disabled:hover{opacity:.3;cursor:not-allowed}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
2029
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: IncomingCallComponent, decorators: [{
|
|
2030
|
+
type: Component,
|
|
2031
|
+
args: [{ selector: 'lib-incoming-call', template: "<div class=\"call-container\" *ngIf=\"newIncomingCallsList?.length === 1\">\r\n <div style=\"display: flex; flex-direction: column;\">\r\n <div class=\"callToNum\">Incoming call on <br/><span>{{incomingCallData?.phone || 'Unknown Number'}}</span></div>\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" [src]=\"newIncomingCallsList[0]?.img || incomingCallData?.img\" alt=\"\" width=\"120\" />\r\n </div>\r\n <div class=\"callerDetails\">\r\n <!-- <h1>{{newIncomingCallsList[0]?.userInfo?.c2cInformation?.name || incomingCallData?.name || 'Unknown Number'}}</h1> -->\r\n <!-- <p>{{newIncomingCallsList[0]?.userInfo?.displayNum ? newIncomingCallsList[0]?.userInfo?.c2cInformation?.number : newIncomingCallsList[0]?.userInfo?.c2cInformation?.number || incomingCallData?.displayNum || incomingCallData?.phone}}</p> -->\r\n <h1>{{incomingCallData?.name || 'Unknown Number'}}</h1>\r\n <p>{{incomingCallData?.phone}}</p>\r\n </div>\r\n \r\n <!-- <div class=\"callerDetails\">\r\n <h1 [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{callData.name}}</h1>\r\n <p>{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\r\n <h4 style=\"margin-top: 4px\">{{timer}}</h4>\r\n </div> -->\r\n <div class=\"call-action-btns\">\r\n <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected || incomingCallData\">\r\n <span class=\"material-symbols-outlined\" (click)=\"add(newIncomingCallsList[0])\"> call </span> \r\n </button>\r\n <!-- <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected || incomingCallData\">\r\n <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(newIncomingCallsList[0])\"> call </span>\r\n </button> -->\r\n <button class=\"call-btn mute-btn\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected\" (click)=\"toggleMute(newIncomingCallsList[0])\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container \">\r\n <button class=\"record-btn start-stop\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\r\n <span class=\"recording-icon\"></span>\r\n </button> \r\n <div class=\"\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected && 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=\"newIncomingCallsList[0]?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <!-- <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(newIncomingCallsList[0])\"> call_end </span>\r\n </button> -->\r\n <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"onEndCall()\"> 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\" 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<div class=\"call-container\" style=\"width: 100%;\" *ngIf=\"newIncomingCallsList?.length > 1\" [ngClass]=\"{'call-container-open': selectedIncomingCall?.isClickExpand}\">\r\n <div class=\"collops\">\r\n <div class=\"d-flex w-100\">\r\n <div class=\"d-flex flex-column container-fluid\" >\r\n <div class=\"callToNum\">Incoming call <br/><span>{{dedicatedNum}}</span></div>\r\n <ng-container *ngFor=\"let data of newIncomingCallsList\"> \r\n <div class=\"p-2 \">\r\n <div class=\"call-info-wrapper w-100 d-flex align-items-center\">\r\n <div class=\"img\">\r\n <img class=\"avatar-img-wrapper\" [src]=\"data?.img\" alt=\"\" width=\"45\" />\r\n </div>\r\n <div class=\"d-flex justify-content-between w-100 align-items-center mr-2\">\r\n <div class=\"callerDetails-wrapper\">\r\n <h5 class=\"break-word\">{{data?.userInfo?.c2cInformation?.name || '-'}}</h5>\r\n <p class=\"break-word\">{{data?.userInfo?.displayNum ? data?.userInfo?.c2cInformation?.number : data?.userInfo?.c2cInformation?.number }}</p>\r\n </div> \r\n <div class=\"d-flex align-items-center\">\r\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!data?.isCallConnected\">\r\n <!-- <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(data)\"> call </span> -->\r\n <span class=\"material-symbols-outlined\" (click)=\"add(data)\"> call </span>\r\n </button>\r\n <button class=\"call-btn-wrapper mute-btn\" *ngIf=\"data?.isCallConnected\" (click)=\"toggleMute(data)\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container\">\r\n <button class=\"record-btn start-stop\" *ngIf=\"data?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\r\n <span class=\"recording-icon\"></span>\r\n </button> \r\n <div class=\"\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"data?.isCallConnected && 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=\"data?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <button class=\"call-btn-wrapper reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(data)\"> call_end </span>\r\n </button>\r\n <div class=\"togglearrow-arrow me-2\" id=\"togglearrow\" \r\n (click)=\"hasDetailedInfo(data) ? onClickExpand(data) : null\" \r\n [ngClass]=\"{'disabled': !hasDetailedInfo(data)}\"\r\n [title]=\"hasDetailedInfo(data) ? 'View details' : 'No details available'\">\r\n <i class=\"fa fa-angle-right\"></i>\r\n </div>\r\n <!-- <div *ngIf=\"data?.customParameters?.get('c2cNumber') === true || data?.customParameters?.get('c2cNumber') === 'true'\" class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"onClickExpand(data)\"> \r\n <i class=\"fa fa-angle-right\"></i> \r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div class=\"call-container p-3 text-white model-content\" *ngIf=\"isClickExpand \"> \r\n <div class=\"mb-2\" style=\"width: 100%; height: 100%;\">\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" [src]=\"incomingCallData.img\" alt=\"\" width=\"100\" />\r\n </div>\r\n <div class=\"text-center\">\r\n <h3 class=\"text-white\">{{selectedIncomingCall?.userInfo?.c2cInformation?.name || '-'}}</h3>\r\n </div>\r\n <div class=\"f-13\">\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Subject:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.subject || '-'}}</div>\r\n </div> \r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Email:</div>\r\n <div>{{selectedIncomingCall?.userInfo?.c2cInformation?.email || '-'}}</div>\r\n </div> \r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Number:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.number}}</div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"\">Language:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.language || '-'}}</div>\r\n </div>\r\n </div>\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Extension:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.extension || '-'}}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Image:</div>\r\n <div class=\"text-ellipsis\">\r\n <ng-container *ngIf=\"selectedIncomingCall?.userInfo?.c2cInformation?.image && selectedIncomingCall?.userInfo?.c2cInformation?.image !== '-'; else noImage\">\r\n <img src=\"{{selectedIncomingCall?.userInfo?.c2cInformation?.image}}\" alt=\"\" width=\"42\" height=\"42\" 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\r\n <div class=\" mb-4\">\r\n <div class=\"\">\r\n <div class=\"\">Message:</div>\r\n <div class=\"text-ellipsis\">{{selectedIncomingCall?.userInfo?.c2cInformation?.message || '-'}}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Point Name:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.pointName || '-'}}</div>\r\n </div>\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Source Name:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.sourceName || '-'}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"call-action-btns mt-0\">\r\n <button class=\"call-btn receive-btn\" *ngIf=\"!selectedIncomingCall?.isCallConnected\">\r\n <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(selectedIncomingCall)\"> call </span>\r\n </button>\r\n <button class=\"call-btn mute-btn\" *ngIf=\"selectedIncomingCall?.isCallConnected\" (click)=\"toggleMute(selectedIncomingCall)\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container\">\r\n <button class=\"record-btn start-stop\" *ngIf=\"selectedIncomingCall?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\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=\"selectedIncomingCall?.isCallConnected && 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=\"selectedIncomingCall?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(selectedIncomingCall)\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\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\" [ngStyle]=\"{'width': '756px'}\">\r\n <defs>\r\n <path id=\"gentle-wave\" d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" /> \r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n</div>", styles: [".call-container{width:385px!important;height:646px!important;margin:auto;border-radius:30px;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}.collops{display:flex;flex-direction:column;width:100%;height:100%}.container-fluid{width:400px;height:100%;margin-top:10px}.model-content{background-color:#0d6efd;border-radius:20px;width:395px!important}.call-container-open{width:752px!important}.calls-side-by-side{position:fixed;top:0;width:30%;height:498px;z-index:1050;pointer-events:auto;display:flex;align-items:flex-start;left:-10rem;transform:translate(.2rem);transition:left 1s ease-in-out}.move{left:41vw!important}.f-13{font-size:13px!important}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto;border-radius:100%;border:solid 4px #fff}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.avatar-img-wrapper{border-radius:100%;margin:0 5px}.call-btn-wrapper{height:38px;background-color:#fff;border-radius:30px;margin:0 4px;opacity:.9;width:40px}.call-btn-wrapper span{color:#fff;line-height:unset!important}.hold-btn{background-color:#bebebe26;border:none}.hold-btn span,.mute-btn span{color:#fff!important}.active-hold{background-color:#fff!important}.active-hold span{color:#000!important}.active-mute{background-color:transparent}.call-info-wrapper{border:1px solid white;border-radius:7px;padding:8px 1px!important;word-break:break-all}.call-animation-play{animation:play 3s linear infinite}.avatar-img{width:94px;height:94px;border-radius:100%;position:absolute;left:0;top:0}@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}.callerDetails h1{margin:12px 0 0;color:#fff}.callerDetails-wrapper{margin:0 5px;color:#fff;display:flex;flex-direction:column}.callerDetails-wrapper h3,.callerDetails-wrapper h5{margin:0;color:#fff}.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}.callerDetails h4{margin:0;color:#fff}.callerDetails p,.callerDetails-wrapper p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-btn{position:relative;width:50px;height:50px;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}.call-sec-btn span{color:#cccbcb}.call-btn{width:48px;height:45px;background-color:#fff;border-radius:30px;box-sizing:border-box;margin:0 8px;opacity:.9}.call-btn:hover{opacity:1}.call-btn span{color:#fff;line-height:unset!important}.receive-btn{background-color:#28a745;border:2px solid #28a745}.mute-btn{position:relative;border:none;background-color:#bebebe26}.reject-btn{background-color:#e03131;border:2px solid #e03131}.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}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.call-action-btns{text-align:center;display:flex;justify-content:center;align-items:center;margin-top:240px}#call-input{background-color:transparent;border:none;outline:none;text-align:center;color:#fff}.wave-container{position:absolute;bottom:0}.waves{width:660px;position:relative;margin-bottom:-7px;height:40px;min-height:40px}.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}.callToNum{color:#fff;font-weight:400;text-align:center}.callToNum span{font-weight:600}.text-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;display:block}.record-action-btns{display:flex;flex-direction:column;align-items:center}.record-btn-container{position:relative}.record-btn{border:none;border-radius:50%;width:48px;height:48px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;overflow:hidden}.record-btn-side{border:none;border-radius:50%;width:44px;height:44px;display:flex;align-items:center;justify-content:center;cursor:pointer;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;justify-content:center;width:48px;height:48px;background-color:#fff;border-radius:30px}.record-btn.pause-resume{border:none;border-radius:50%;width:48px;height:48px;background:white;display:flex;align-items:center;justify-content:center}.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%}.togglearrow-arrow.disabled{opacity:.3;cursor:not-allowed;pointer-events:none}.togglearrow-arrow.disabled:hover{opacity:.3;cursor:not-allowed}\n"] }]
|
|
2032
|
+
}], ctorParameters: function () { return [{ type: ExtensionService }, { type: TwilioService }, { type: NotificationService }]; }, propDecorators: { incomingCallData: [{
|
|
2033
|
+
type: Input
|
|
2034
|
+
}], newIncomingCallsList: [{
|
|
2035
|
+
type: Input
|
|
2036
|
+
}], deviceId: [{
|
|
2037
|
+
type: Input
|
|
2038
|
+
}], closeIncomingCallDiv: [{
|
|
2039
|
+
type: Output
|
|
2040
|
+
}], incomingCallsNewList: [{
|
|
2041
|
+
type: Output
|
|
2042
|
+
}], selectedIncomingCallInfo: [{
|
|
2043
|
+
type: Output
|
|
2044
|
+
}] } });
|
|
2045
|
+
|
|
2046
|
+
class CallProgressComponent {
|
|
2047
|
+
// contacts: any[] = [
|
|
2048
|
+
// { name: 'Pamela Cox', title: 'Product Designer', img: 'assets/images/user.jpg' },
|
|
2049
|
+
// { name: 'Roger S. Wood', title: 'JavaScript Programmer', img: 'assets/images/user.jpg' },
|
|
2050
|
+
// { name: 'Victor Blackston', title: 'Database Administrator', img: 'assets/images/user.jpg' },
|
|
2051
|
+
// { name: 'Tammy Rios', title: 'Support', img: 'assets/images/user.jpg' },
|
|
2052
|
+
// { name: 'Carlos Henderson', title: 'Software Architect', img: 'assets/images/user.jpg' },
|
|
2053
|
+
// { name: 'Elizabeth Bailey', title: 'HR', img: 'assets/images/user.jpg' }
|
|
2054
|
+
// ];
|
|
2055
|
+
constructor(extensionService, cdr, twilioService) {
|
|
2056
|
+
this.extensionService = extensionService;
|
|
2057
|
+
this.cdr = cdr;
|
|
2058
|
+
this.twilioService = twilioService;
|
|
2059
|
+
this.newIncomingCallsList = [];
|
|
2060
|
+
this.endCallEvent = new EventEmitter();
|
|
2061
|
+
this.incomingCallsNewInfo = new EventEmitter();
|
|
2062
|
+
this.minimiseEvent = new EventEmitter();
|
|
2063
|
+
this.showRingAnimation = false;
|
|
2058
2064
|
this.timer = '00:00';
|
|
2065
|
+
this.showKeypad = false;
|
|
2066
|
+
this.keypadVal = keypad;
|
|
2067
|
+
this.callInput = '';
|
|
2068
|
+
this.isMute = false;
|
|
2069
|
+
this.disbaleEndCallBtn = true;
|
|
2070
|
+
this.showClearBtn = false;
|
|
2071
|
+
this.isCollops = false;
|
|
2072
|
+
// Conference state flag
|
|
2073
|
+
this.isConference = false;
|
|
2074
|
+
this.isOutgoingCall = true;
|
|
2075
|
+
// Incoming call variables
|
|
2076
|
+
this.incomingCallDiv = false;
|
|
2077
|
+
//@Output() showCallProgressEvent: EventEmitter<void> = new EventEmitter<void>();
|
|
2078
|
+
this.incomingCallInitiated = new EventEmitter();
|
|
2079
|
+
this.isRecording = false;
|
|
2080
|
+
this.isPaused = false;
|
|
2081
|
+
this.timeElapsed = 0; // in seconds
|
|
2082
|
+
this.recordCall = false;
|
|
2083
|
+
this.callStatus = 'ringing';
|
|
2084
|
+
this.showContactsPanel = false;
|
|
2085
|
+
this.isAddRemoveParticipant = false;
|
|
2086
|
+
this.isConcurrentIncoming = false;
|
|
2087
|
+
this.isCallOnHold = false;
|
|
2088
|
+
this.contacts = [];
|
|
2089
|
+
this.currentCallList = [];
|
|
2090
|
+
this.isMinimised = false;
|
|
2091
|
+
console.log('Call Progress Component');
|
|
2059
2092
|
}
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
handleError(error) {
|
|
2069
|
-
swal("Error", error, "error");
|
|
2070
|
-
}
|
|
2071
|
-
// endCall() {
|
|
2072
|
-
// console.log('endCall() called');
|
|
2073
|
-
// console.log('Current call:', this.call?.parameters['From']);
|
|
2074
|
-
// console.log('Held call exists:', !!this.heldCall);
|
|
2075
|
-
// // Disconnect the current active call
|
|
2076
|
-
// if (this.call) {
|
|
2077
|
-
// this.call.disconnect();
|
|
2078
|
-
// this.call = undefined;
|
|
2079
|
-
// }
|
|
2080
|
-
// this.showRingAnimation = false;
|
|
2081
|
-
// this.stopTimer();
|
|
2082
|
-
// // If there's a held call, make it active
|
|
2083
|
-
// if (this.heldCall) {
|
|
2084
|
-
// console.log('Resuming held call:', this.heldCall.parameters['From']);
|
|
2085
|
-
// // Make held call the active call
|
|
2086
|
-
// this.call = this.heldCall;
|
|
2087
|
-
// this.heldCall = undefined;
|
|
2088
|
-
// // this.isCallOnHold = false;
|
|
2089
|
-
// this.isCallOnHold = !!this.heldCall;
|
|
2090
|
-
// // Unmute the resumed call
|
|
2091
|
-
// this.call.mute(false);
|
|
2092
|
-
// // Update UI with the resumed call info
|
|
2093
|
-
// const fromNumber = this.call.parameters['From'];
|
|
2094
|
-
// const callerName = this.call.customParameters?.get('name') || '-';
|
|
2095
|
-
// const callerImg = this.call.customParameters?.get('image') || 'assets/images/user.jpg';
|
|
2096
|
-
// this.callData = {
|
|
2097
|
-
// ...this.callData,
|
|
2098
|
-
// phone: fromNumber,
|
|
2099
|
-
// displayNum: fromNumber,
|
|
2100
|
-
// name: callerName,
|
|
2101
|
-
// img: callerImg
|
|
2102
|
-
// };
|
|
2103
|
-
// // Restart timer for the resumed call
|
|
2104
|
-
// this.startTimer();
|
|
2105
|
-
// this.disbaleEndCallBtn = false;
|
|
2106
|
-
// console.log('Held call is now active:', this.callData);
|
|
2107
|
-
// this.cdr.detectChanges();
|
|
2108
|
-
// } else {
|
|
2109
|
-
// // No held call, completely end
|
|
2110
|
-
// console.log('No held call, ending completely');
|
|
2111
|
-
// this.endCallEvent.emit();
|
|
2112
|
-
// this.maximiseDialpad();
|
|
2113
|
-
// }
|
|
2114
|
-
// }
|
|
2115
|
-
endCall(isAllCallEnd) {
|
|
2116
|
-
var _a, _b;
|
|
2117
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2118
|
-
console.log('endCall() called');
|
|
2119
|
-
console.log('Current call:', (_a = this.call) === null || _a === void 0 ? void 0 : _a.parameters['From']);
|
|
2120
|
-
console.log('Held call exists:', !!this.heldCall);
|
|
2121
|
-
// Leaving conference state when ending current call action
|
|
2122
|
-
this.isConference = false;
|
|
2123
|
-
// if (this.call) {
|
|
2124
|
-
// this.call.disconnect();
|
|
2125
|
-
// this.call.reject();
|
|
2126
|
-
// this.call = undefined;
|
|
2127
|
-
// }
|
|
2128
|
-
this.showRingAnimation = false;
|
|
2129
|
-
this.stopTimer();
|
|
2130
|
-
if (isAllCallEnd) {
|
|
2131
|
-
this.onEndCall({}, isAllCallEnd);
|
|
2132
|
-
this.currentCallList = [];
|
|
2133
|
-
this.endCallEvent.emit();
|
|
2134
|
-
}
|
|
2135
|
-
else {
|
|
2136
|
-
this.onEndCall(this.currentCall, isAllCallEnd);
|
|
2137
|
-
this.currentCallList = this.currentCallList.filter((c) => (c === null || c === void 0 ? void 0 : c.participantId) !== this.currentCall.participantId);
|
|
2138
|
-
if (this.currentCallList.length > 0) {
|
|
2139
|
-
this.currentCallList[0].isHold = false;
|
|
2140
|
-
this.currentCall = this.currentCallList[0];
|
|
2141
|
-
yield this.onholdOrUnholdParticipant({
|
|
2142
|
-
participantId: (_b = this.currentCall) === null || _b === void 0 ? void 0 : _b.participantId,
|
|
2143
|
-
conferenceId: this.conferenceId,
|
|
2144
|
-
hold: false
|
|
2145
|
-
});
|
|
2093
|
+
ngOnInit() {
|
|
2094
|
+
console.log('Call Progress Component ngOnInit');
|
|
2095
|
+
// Subscribe to incoming calls from TwilioService
|
|
2096
|
+
try {
|
|
2097
|
+
this.twilioService.currentCall.subscribe((incoming) => {
|
|
2098
|
+
var _a;
|
|
2099
|
+
if (!incoming) {
|
|
2100
|
+
return;
|
|
2146
2101
|
}
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2102
|
+
console.log('TwilioService.currentCall emitted:', incoming);
|
|
2103
|
+
console.log('Current call status:', (_a = this.call) === null || _a === void 0 ? void 0 : _a.status());
|
|
2104
|
+
// If there is an ongoing call, show concurrent incoming banner
|
|
2105
|
+
if (this.call && this.call.status() === 'open') {
|
|
2106
|
+
console.log('Concurrent incoming detected - showing banner');
|
|
2107
|
+
this.isConcurrentIncoming = true;
|
|
2108
|
+
this.incomingCallDiv = true;
|
|
2109
|
+
// Add to list if not present
|
|
2110
|
+
const exists = (this.newIncomingCallsList || []).some((c) => { var _a, _b; return ((_a = c === null || c === void 0 ? void 0 : c.parameters) === null || _a === void 0 ? void 0 : _a.CallSid) === ((_b = incoming === null || incoming === void 0 ? void 0 : incoming.parameters) === null || _b === void 0 ? void 0 : _b.CallSid); });
|
|
2111
|
+
if (!exists) {
|
|
2112
|
+
this.newIncomingCallsList = [...(this.newIncomingCallsList || []), incoming];
|
|
2113
|
+
this.incomingCallsNewInfo.emit(this.newIncomingCallsList);
|
|
2114
|
+
}
|
|
2115
|
+
this.cdr.detectChanges();
|
|
2151
2116
|
}
|
|
2152
|
-
}
|
|
2153
|
-
}
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
var _a;
|
|
2157
|
-
this.isMute = !this.isMute;
|
|
2158
|
-
(_a = this.call) === null || _a === void 0 ? void 0 : _a.mute(this.isMute);
|
|
2159
|
-
}
|
|
2160
|
-
toggleKeypad() {
|
|
2161
|
-
this.showKeypad = !this.showKeypad;
|
|
2162
|
-
this.callInput = '';
|
|
2163
|
-
}
|
|
2164
|
-
toggleContactsPanel(isRemove) {
|
|
2165
|
-
if (isRemove) {
|
|
2166
|
-
this.showContactsPanel = false;
|
|
2167
|
-
this.isAddRemoveParticipant = !this.isAddRemoveParticipant;
|
|
2168
|
-
}
|
|
2169
|
-
else {
|
|
2170
|
-
this.isAddRemoveParticipant = false;
|
|
2171
|
-
this.showContactsPanel = !this.showContactsPanel;
|
|
2172
|
-
this.GetContactsList();
|
|
2117
|
+
});
|
|
2118
|
+
}
|
|
2119
|
+
catch (e) {
|
|
2120
|
+
console.error('Error subscribing to incoming calls:', e);
|
|
2173
2121
|
}
|
|
2174
2122
|
}
|
|
2175
|
-
|
|
2176
|
-
var _a;
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
if ((data === null || data === void 0 ? void 0 : data.status) != 'ringing') {
|
|
2184
|
-
let device = yield this.twilioService.connect('');
|
|
2185
|
-
console.log(device, 'callConnect');
|
|
2123
|
+
ngOnChanges(changes) {
|
|
2124
|
+
var _a, _b, _c;
|
|
2125
|
+
console.log('Call Progress Component ngOnChanges');
|
|
2126
|
+
if (changes['callData']) {
|
|
2127
|
+
if ((_a = changes['callData'].currentValue) === null || _a === void 0 ? void 0 : _a.isIncomingCall) {
|
|
2128
|
+
this.incomingCallDiv = true;
|
|
2129
|
+
this.call['callInfo'] = JSON.parse(JSON.stringify(this.callData));
|
|
2130
|
+
this.cdr.detectChanges();
|
|
2186
2131
|
}
|
|
2187
|
-
else if ((
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2132
|
+
else if (((_b = changes['callData'].currentValue) === null || _b === void 0 ? void 0 : _b.displayNum) || ((_c = changes['callData'].currentValue) === null || _c === void 0 ? void 0 : _c.from)) {
|
|
2133
|
+
console.log('test-startCall123', changes['callData'].currentValue);
|
|
2134
|
+
this.currentCall = Object.assign(Object.assign({}, changes['callData'].currentValue), { img: 'assets/images/user.jpg' });
|
|
2135
|
+
this.startCall(changes['callData'].currentValue);
|
|
2191
2136
|
}
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2137
|
+
}
|
|
2138
|
+
if (changes['newIncomingCallsList']) {
|
|
2139
|
+
try {
|
|
2140
|
+
if (changes['newIncomingCallsList'].currentValue) {
|
|
2141
|
+
// Check if there's an active ongoing call
|
|
2142
|
+
if (this.call && (this.call.status() == 'open')) {
|
|
2143
|
+
// Concurrent incoming - show banner on top of active call
|
|
2144
|
+
this.isConcurrentIncoming = true;
|
|
2145
|
+
this.incomingCallDiv = true;
|
|
2146
|
+
// const inc = changes['newIncomingCallData'].currentValue;
|
|
2147
|
+
// if (this.newIncomingCallsList && Array.isArray(this.newIncomingCallsList)) {
|
|
2148
|
+
// const exists = this.newIncomingCallsList.some((c: any) => c?.parameters?.CallSid === inc?.parameters?.CallSid);
|
|
2149
|
+
// if (!exists) {
|
|
2150
|
+
// this.newIncomingCallsList = [...this.newIncomingCallsList, inc];
|
|
2151
|
+
// this.incomingCallsNewInfo.emit(this.newIncomingCallsList);
|
|
2152
|
+
// }
|
|
2153
|
+
// } else {
|
|
2154
|
+
// this.newIncomingCallsList = [inc];
|
|
2155
|
+
// this.incomingCallsNewInfo.emit(this.newIncomingCallsList);
|
|
2156
|
+
// }
|
|
2157
|
+
console.log(changes['newIncomingCallsList'].currentValue);
|
|
2158
|
+
this.newIncomingCallsList.forEach((res) => {
|
|
2159
|
+
let data = this.currentCallList.find((item) => item.id == res.callSid);
|
|
2160
|
+
if (!data) {
|
|
2161
|
+
this.currentCallList.push(Object.assign(Object.assign({}, res), { img: 'assets/images/user.jpg', isIncomingCall: true, isHold: false, isMute: false, isConference: false }));
|
|
2162
|
+
}
|
|
2163
|
+
});
|
|
2164
|
+
this.cdr.detectChanges();
|
|
2165
|
+
}
|
|
2166
|
+
else {
|
|
2167
|
+
// Pure incoming - show full incoming UI
|
|
2168
|
+
this.isConcurrentIncoming = false;
|
|
2169
|
+
this.incomingCallDiv = true;
|
|
2170
|
+
this.cdr.detectChanges();
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
else if (changes['newIncomingCallsList'].currentValue.length == 0) {
|
|
2174
|
+
this.isConcurrentIncoming = false;
|
|
2175
|
+
this.incomingCallDiv = false;
|
|
2176
|
+
this.cdr.detectChanges();
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
catch (e) {
|
|
2180
|
+
console.log(e);
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2196
2183
|
}
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
//
|
|
2200
|
-
//
|
|
2201
|
-
// })
|
|
2184
|
+
ngAfterViewInit() {
|
|
2185
|
+
// this.isRecording = false;
|
|
2186
|
+
// setTimeout(() => {
|
|
2187
|
+
// this.isRecording = false;
|
|
2188
|
+
// }, 3000);
|
|
2202
2189
|
}
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
console.log('
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
console.error('No active call');
|
|
2212
|
-
return;
|
|
2190
|
+
GetContactsList() {
|
|
2191
|
+
const token = localStorage.getItem('ext_token') || '';
|
|
2192
|
+
this.extensionService.readContacts(token).subscribe((res) => {
|
|
2193
|
+
console.log('API Response:', res);
|
|
2194
|
+
// Note: Capital B in phoneBook
|
|
2195
|
+
if (res && res.phoneBook) {
|
|
2196
|
+
this.contacts = res.phoneBook;
|
|
2197
|
+
console.log('Contacts array:', this.contacts);
|
|
2213
2198
|
}
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
return;
|
|
2199
|
+
else if (Array.isArray(res)) {
|
|
2200
|
+
this.contacts = res;
|
|
2201
|
+
}
|
|
2202
|
+
else {
|
|
2203
|
+
this.contacts = [];
|
|
2220
2204
|
}
|
|
2205
|
+
console.log('Contacts array:', this.contacts);
|
|
2206
|
+
this.cdr.detectChanges();
|
|
2207
|
+
}, (error) => {
|
|
2208
|
+
console.error('Error fetching contacts:', error);
|
|
2209
|
+
this.contacts = [];
|
|
2210
|
+
});
|
|
2211
|
+
}
|
|
2212
|
+
startCall(callData) {
|
|
2213
|
+
var _a;
|
|
2214
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2215
|
+
console.log(callData, 'callData');
|
|
2221
2216
|
try {
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
console.log("Participant added to conference:", phoneNumber);
|
|
2248
|
-
this.showRingAnimation = false;
|
|
2249
|
-
}
|
|
2250
|
-
else {
|
|
2251
|
-
this.currentCallList.forEach((c) => __awaiter(this, void 0, void 0, function* () {
|
|
2252
|
-
if ((c === null || c === void 0 ? void 0 : c.participantId) && !(c === null || c === void 0 ? void 0 : c.isHold)) {
|
|
2253
|
-
c.isHold = true;
|
|
2254
|
-
yield this.onholdOrUnholdParticipant({
|
|
2255
|
-
participantId: c === null || c === void 0 ? void 0 : c.participantId,
|
|
2256
|
-
conferenceId: this.conferenceId,
|
|
2257
|
-
hold: c === null || c === void 0 ? void 0 : c.isHold
|
|
2217
|
+
this.showRingAnimation = true;
|
|
2218
|
+
const payload = {
|
|
2219
|
+
channelId: environment.channelId,
|
|
2220
|
+
userId: localStorage.getItem('userId'),
|
|
2221
|
+
to: callData.phone,
|
|
2222
|
+
fromNumber: callData.from,
|
|
2223
|
+
scope: 'local',
|
|
2224
|
+
};
|
|
2225
|
+
const response = yield this.initiateCall(payload);
|
|
2226
|
+
this.conferenceId = (_a = response === null || response === void 0 ? void 0 : response.callauth) === null || _a === void 0 ? void 0 : _a.id;
|
|
2227
|
+
if (response.status == 200) {
|
|
2228
|
+
const { id: callAuthId, recordCall } = yield this.getCallAuthId(response);
|
|
2229
|
+
this.getUserInformation(callAuthId);
|
|
2230
|
+
this.recordCall = recordCall; // Store the recordCall value
|
|
2231
|
+
const tokenData = yield this.getOutgoingCallToken(callAuthId);
|
|
2232
|
+
yield this.connectToDevice(tokenData.token, callData);
|
|
2233
|
+
yield this.pollCallStatus(callAuthId);
|
|
2234
|
+
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
2235
|
+
var _b, _c;
|
|
2236
|
+
try {
|
|
2237
|
+
this.addRes = yield this.addParticipantToCall({
|
|
2238
|
+
from: callData === null || callData === void 0 ? void 0 : callData.from,
|
|
2239
|
+
route: "OUTGOING",
|
|
2240
|
+
participantNumber: callData === null || callData === void 0 ? void 0 : callData.phone,
|
|
2241
|
+
conferenceId: this.conferenceId
|
|
2258
2242
|
});
|
|
2243
|
+
this.callData = Object.assign(Object.assign({}, callData), { participantId: (_b = this.addRes) === null || _b === void 0 ? void 0 : _b.participantId, isHold: false, isLeft: false, isIncomingCall: false, isConference: false });
|
|
2244
|
+
this.call['callInfo'] = JSON.parse(JSON.stringify(this.callData));
|
|
2245
|
+
console.log('test111111');
|
|
2246
|
+
this.currentCall = Object.assign(Object.assign({}, this.callData), { img: callData.img || 'assets/images/user.jpg' });
|
|
2247
|
+
this.currentCallList.push(Object.assign(Object.assign({}, this.callData), { img: callData.img || 'assets/images/user.jpg' }));
|
|
2248
|
+
console.log('Initial participantId:', (_c = this.addRes) === null || _c === void 0 ? void 0 : _c.participantId);
|
|
2259
2249
|
}
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
//
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
this.
|
|
2270
|
-
// Update UI to reflect the new outbound leg being dialed
|
|
2271
|
-
const contactName = [contact === null || contact === void 0 ? void 0 : contact.firstName, contact === null || contact === void 0 ? void 0 : contact.middleName, contact === null || contact === void 0 ? void 0 : contact.lastName]
|
|
2272
|
-
.filter(Boolean)
|
|
2273
|
-
.join(' ');
|
|
2274
|
-
// this.call['callInfo'] = JSON.parse(JSON.stringify(this.callData));
|
|
2275
|
-
// Get the conference ID from the current call or use the stored one
|
|
2276
|
-
// const conferenceId = this.conferenceId;
|
|
2277
|
-
if (!this.conferenceId) {
|
|
2278
|
-
console.error("No conferenceId found for active call");
|
|
2279
|
-
swal("Error", "Cannot add participant: conference not found", "error");
|
|
2280
|
-
this.showRingAnimation = false;
|
|
2281
|
-
return;
|
|
2282
|
-
}
|
|
2283
|
-
// Add participant to the conference
|
|
2284
|
-
let data = yield this.addParticipantToCall({
|
|
2285
|
-
from: ((_f = this.callData) === null || _f === void 0 ? void 0 : _f.from) || ((_g = this.selectedCallerId) === null || _g === void 0 ? void 0 : _g.number),
|
|
2286
|
-
route: "OUTGOING",
|
|
2287
|
-
participantNumber: phoneNumber,
|
|
2288
|
-
conferenceId: this.conferenceId
|
|
2289
|
-
});
|
|
2290
|
-
// this.callData = {
|
|
2291
|
-
// ...this.callData,
|
|
2292
|
-
// participantId: ,
|
|
2293
|
-
// }
|
|
2294
|
-
this.callData = {
|
|
2295
|
-
// ...this.callData,
|
|
2296
|
-
phone: phoneNumber,
|
|
2297
|
-
displayNum: phoneNumber,
|
|
2298
|
-
name: (contact === null || contact === void 0 ? void 0 : contact.name) || `${contact === null || contact === void 0 ? void 0 : contact.firstName} ${contact === null || contact === void 0 ? void 0 : contact.lastName}` || phoneNumber,
|
|
2299
|
-
img: (contact === null || contact === void 0 ? void 0 : contact.img) || 'assets/images/user.jpg',
|
|
2300
|
-
participantId: data === null || data === void 0 ? void 0 : data.participantId,
|
|
2301
|
-
from: (_h = this.selectedCallerId) === null || _h === void 0 ? void 0 : _h.number,
|
|
2302
|
-
isIncomingCall: false,
|
|
2303
|
-
isHold: false,
|
|
2304
|
-
isLeft: false,
|
|
2305
|
-
isConference: false
|
|
2306
|
-
};
|
|
2307
|
-
this.cdr.detectChanges();
|
|
2308
|
-
console.log(this.callData, 'this.callData');
|
|
2309
|
-
console.log('test111111');
|
|
2310
|
-
this.currentCall = this.callData;
|
|
2311
|
-
this.currentCallList.push(Object.assign({}, this.callData));
|
|
2312
|
-
console.log("Participant added to conference:", phoneNumber);
|
|
2313
|
-
this.showRingAnimation = false;
|
|
2250
|
+
catch (e) {
|
|
2251
|
+
console.error('Error adding initial participant:', e);
|
|
2252
|
+
}
|
|
2253
|
+
}), 1000);
|
|
2254
|
+
// Poll the status for 30-45 seconds
|
|
2255
|
+
}
|
|
2256
|
+
else if (response.status == 201) {
|
|
2257
|
+
swal("Error", response.message.join("<br/>"), "error");
|
|
2258
|
+
console.log('test2');
|
|
2259
|
+
this.endCall();
|
|
2314
2260
|
}
|
|
2315
2261
|
}
|
|
2316
2262
|
catch (error) {
|
|
2317
|
-
console.error('Error adding participant:', error);
|
|
2318
2263
|
this.showRingAnimation = false;
|
|
2319
|
-
// Restore held call on error
|
|
2320
|
-
if (this.heldCall) {
|
|
2321
|
-
// this.call = this.heldCall;
|
|
2322
|
-
// this.heldCall = undefined;
|
|
2323
|
-
// this.isCallOnHold = false;
|
|
2324
|
-
// this.call.mute(false);
|
|
2325
|
-
}
|
|
2326
2264
|
this.handleError(error);
|
|
2265
|
+
console.log('test3');
|
|
2266
|
+
this.endCall();
|
|
2327
2267
|
}
|
|
2328
2268
|
});
|
|
2329
2269
|
}
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2270
|
+
onHoldCall(c) {
|
|
2271
|
+
console.log(c, 'dsdsdsdsdsdsadsa');
|
|
2272
|
+
this.onholdOrUnholdParticipant({
|
|
2273
|
+
participantId: c.participantId,
|
|
2274
|
+
conferenceId: this.conferenceId,
|
|
2275
|
+
hold: !c.hold
|
|
2333
2276
|
});
|
|
2334
|
-
|
|
2335
|
-
// acceptConcurrentCall(incomingCall: any) {
|
|
2336
|
-
// if (!incomingCall) return;
|
|
2337
|
-
// // Put current call on hold instead of disconnecting
|
|
2338
|
-
// if (this.call) {
|
|
2339
|
-
// this.heldCall = this.call;
|
|
2340
|
-
// this.isCallOnHold = true;
|
|
2341
|
-
// // Mute the held call
|
|
2342
|
-
// this.heldCall.mute(true);
|
|
2343
|
-
// }
|
|
2344
|
-
// incomingCall.accept();
|
|
2345
|
-
// this.call = incomingCall;
|
|
2346
|
-
// this.callData.phone = incomingCall.parameters['From'];
|
|
2347
|
-
// this.callData.name = incomingCall.customParameters?.get('name') || '-';
|
|
2348
|
-
// this.callData.img = incomingCall.customParameters?.get('image') || 'assets/images/user.jpg';
|
|
2349
|
-
// this.isConcurrentIncoming = false;
|
|
2350
|
-
// this.incomingCallDiv = false;
|
|
2351
|
-
// this.disbaleEndCallBtn = false;
|
|
2352
|
-
// // Reset timer for new call
|
|
2353
|
-
// this.stopTimer();
|
|
2354
|
-
// this.startTimer();
|
|
2355
|
-
// this.cdr.detectChanges();
|
|
2356
|
-
// }
|
|
2357
|
-
acceptConcurrentCall(incomingCall) {
|
|
2358
|
-
var _a, _b;
|
|
2359
|
-
if (!incomingCall)
|
|
2360
|
-
return;
|
|
2361
|
-
// Put current call on hold instead of disconnecting
|
|
2362
|
-
// if (this.call) {
|
|
2363
|
-
// this.heldCall = this.call;
|
|
2364
|
-
this.isCallOnHold = true;
|
|
2365
|
-
// // Mute the held call
|
|
2366
|
-
// this.heldCall.mute(true);
|
|
2367
|
-
// }
|
|
2368
|
-
// Accept the new call
|
|
2369
|
-
incomingCall.accept();
|
|
2370
|
-
this.call = incomingCall;
|
|
2371
|
-
this.callData.phone = incomingCall.parameters['From'];
|
|
2372
|
-
this.callData.name = ((_a = incomingCall.customParameters) === null || _a === void 0 ? void 0 : _a.get('name')) || '-';
|
|
2373
|
-
this.callData.img = ((_b = incomingCall.customParameters) === null || _b === void 0 ? void 0 : _b.get('image')) || 'assets/images/user.jpg';
|
|
2374
|
-
this.isConcurrentIncoming = false;
|
|
2375
|
-
this.incomingCallDiv = false;
|
|
2376
|
-
this.disbaleEndCallBtn = false;
|
|
2377
|
-
// 🟢 Remove the accepted call from incoming list
|
|
2378
|
-
this.newIncomingCallsList = (this.newIncomingCallsList || []).filter((c) => { var _a, _b; return ((_a = c === null || c === void 0 ? void 0 : c.parameters) === null || _a === void 0 ? void 0 : _a.CallSid) !== ((_b = incomingCall === null || incomingCall === void 0 ? void 0 : incomingCall.parameters) === null || _b === void 0 ? void 0 : _b.CallSid); });
|
|
2379
|
-
this.incomingCallsNewInfo.emit(this.newIncomingCallsList);
|
|
2380
|
-
// 🕒 Reset timer for new call
|
|
2381
|
-
this.stopTimer();
|
|
2382
|
-
this.startTimer();
|
|
2277
|
+
c.hold = !c.hold;
|
|
2383
2278
|
this.cdr.detectChanges();
|
|
2384
2279
|
}
|
|
2385
|
-
|
|
2386
|
-
var _a, _b, _c;
|
|
2280
|
+
onEndCall(c, isAllCallEnd) {
|
|
2387
2281
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
participantId: c === null || c === void 0 ? void 0 : c.participantId,
|
|
2398
|
-
conferenceId: this.conferenceId,
|
|
2399
|
-
hold: c === null || c === void 0 ? void 0 : c.isHold
|
|
2400
|
-
});
|
|
2401
|
-
}
|
|
2402
|
-
else if ((callInfo === null || callInfo === void 0 ? void 0 : callInfo.isHold) && (c === null || c === void 0 ? void 0 : c.participantId) === (callInfo === null || callInfo === void 0 ? void 0 : callInfo.participantId)) {
|
|
2403
|
-
c.isHold = false;
|
|
2404
|
-
yield this.onholdOrUnholdParticipant({
|
|
2405
|
-
participantId: c === null || c === void 0 ? void 0 : c.participantId,
|
|
2406
|
-
conferenceId: this.conferenceId,
|
|
2407
|
-
hold: c === null || c === void 0 ? void 0 : c.isHold
|
|
2408
|
-
});
|
|
2409
|
-
this.currentCall = c;
|
|
2410
|
-
}
|
|
2411
|
-
}));
|
|
2412
|
-
// await this.onholdOrUnholdParticipant({
|
|
2413
|
-
// participantId: this.call?.callInfo?.participantId,
|
|
2414
|
-
// conferenceId: this.conferenceId,
|
|
2415
|
-
// hold: true
|
|
2416
|
-
// });
|
|
2417
|
-
// await this.onholdOrUnholdParticipant({
|
|
2418
|
-
// participantId: this.heldCall?.callInfo?.participantId,
|
|
2419
|
-
// conferenceId: this.conferenceId,
|
|
2420
|
-
// hold: false
|
|
2421
|
-
// });
|
|
2422
|
-
console.log('Swapping calls...');
|
|
2423
|
-
console.log('Before swap - Active call:', this.call.parameters['From']);
|
|
2424
|
-
console.log('Before swap - Held call:', this.heldCall.parameters['From']);
|
|
2425
|
-
// Swap the calls
|
|
2426
|
-
// const temp = this.call;
|
|
2427
|
-
// this.call = this.heldCall;
|
|
2428
|
-
// this.heldCall = temp;
|
|
2429
|
-
// this.call.mute(false);
|
|
2430
|
-
// this.heldCall.mute(true);
|
|
2431
|
-
// Update UI with active call info - extract from call parameters
|
|
2432
|
-
const fromNumber = this.call.parameters['From'];
|
|
2433
|
-
const callerName = ((_a = this.call.customParameters) === null || _a === void 0 ? void 0 : _a.get('name')) || '-';
|
|
2434
|
-
const callerImg = ((_b = this.call.customParameters) === null || _b === void 0 ? void 0 : _b.get('image')) || 'assets/images/user.jpg';
|
|
2435
|
-
const displayNumber = ((_c = this.call.customParameters) === null || _c === void 0 ? void 0 : _c.get('displayNumber')) || '-';
|
|
2436
|
-
// Update callData to refresh the main UI
|
|
2437
|
-
// this.callData = {
|
|
2438
|
-
// ...this.callData,
|
|
2439
|
-
// phone: fromNumber,
|
|
2440
|
-
// displayNum: (displayNumber && displayNumber !== '-') ? displayNumber : fromNumber,
|
|
2441
|
-
// name: (callerName && callerName !== '-') ? callerName : (this.callData?.name || fromNumber),
|
|
2442
|
-
// img: callerImg || this.callData?.img || 'assets/images/user.jpg'
|
|
2443
|
-
// };
|
|
2444
|
-
// console.log('After swap - Active call:', this.call.parameters['From']);
|
|
2445
|
-
// console.log('After swap - Held call:', this.heldCall.parameters['From']);
|
|
2446
|
-
// console.log('Updated callData:', this.callData);
|
|
2447
|
-
console.log('this.currentCallList after swap', this.currentCallList);
|
|
2448
|
-
this.cdr.detectChanges();
|
|
2282
|
+
console.log(c, 'dsdsdsdsdsdsadsa');
|
|
2283
|
+
let participantId = isAllCallEnd ? 'all' : c.participantId || c.participantId;
|
|
2284
|
+
let res = yield this.getRemoveParticipants(participantId, this.conferenceId);
|
|
2285
|
+
if ((res === null || res === void 0 ? void 0 : res.status) == 201 && (res === null || res === void 0 ? void 0 : res.message) == 'participant already left') {
|
|
2286
|
+
this.currentCallList = this.currentCallList.filter((item) => item.participantId !== c.participantId);
|
|
2287
|
+
this.currentCall = this.currentCallList.length > 0 ? this.currentCallList[0] : null;
|
|
2288
|
+
this.cdr.detectChanges();
|
|
2289
|
+
}
|
|
2290
|
+
yield this.getAllParticipants(this.conferenceId);
|
|
2449
2291
|
});
|
|
2450
2292
|
}
|
|
2451
|
-
|
|
2293
|
+
initiateCall(payload) {
|
|
2452
2294
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2453
|
-
|
|
2454
|
-
if (this.currentCallList.length > 1) {
|
|
2455
|
-
this.currentCallList.forEach((c) => __awaiter(this, void 0, void 0, function* () {
|
|
2456
|
-
if ((c === null || c === void 0 ? void 0 : c.participantId) && (c === null || c === void 0 ? void 0 : c.isHold)) {
|
|
2457
|
-
c.isHold = false;
|
|
2458
|
-
yield this.onholdOrUnholdParticipant({
|
|
2459
|
-
participantId: c === null || c === void 0 ? void 0 : c.participantId,
|
|
2460
|
-
conferenceId: this.conferenceId,
|
|
2461
|
-
hold: false
|
|
2462
|
-
});
|
|
2463
|
-
}
|
|
2464
|
-
c.isConference = true;
|
|
2465
|
-
}));
|
|
2466
|
-
// await this.onholdOrUnholdParticipant({
|
|
2467
|
-
// participantId: this.heldCall?.callInfo?.participantId,
|
|
2468
|
-
// conferenceId: this.conferenceId,
|
|
2469
|
-
// hold: false
|
|
2470
|
-
// });
|
|
2471
|
-
// this.heldCall.mute(false);
|
|
2472
|
-
// this.call.mute(false);
|
|
2473
|
-
this.isCallOnHold = false;
|
|
2474
|
-
this.isConference = true;
|
|
2475
|
-
this.cdr.detectChanges();
|
|
2476
|
-
}
|
|
2295
|
+
return yield this.extensionService.initiateCall(payload).toPromise();
|
|
2477
2296
|
});
|
|
2478
2297
|
}
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
// this.isCallOnHold = false;
|
|
2484
|
-
// this.cdr.detectChanges();
|
|
2485
|
-
// }
|
|
2298
|
+
onholdOrUnholdParticipant(payload) {
|
|
2299
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2300
|
+
return yield this.extensionService.holdParticipant(payload).toPromise();
|
|
2301
|
+
});
|
|
2486
2302
|
}
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
return;
|
|
2490
|
-
|
|
2491
|
-
incomingCall.reject();
|
|
2492
|
-
}
|
|
2493
|
-
if (incomingCall.disconnect)
|
|
2494
|
-
incomingCall.disconnect();
|
|
2495
|
-
// Remove from list
|
|
2496
|
-
this.newIncomingCallsList = (this.newIncomingCallsList || []).filter((c) => { var _a, _b; return ((_a = c === null || c === void 0 ? void 0 : c.parameters) === null || _a === void 0 ? void 0 : _a.CallSid) !== ((_b = incomingCall === null || incomingCall === void 0 ? void 0 : incomingCall.parameters) === null || _b === void 0 ? void 0 : _b.CallSid); });
|
|
2497
|
-
this.incomingCallsNewInfo.emit(this.newIncomingCallsList);
|
|
2498
|
-
// If no more incoming, hide banner
|
|
2499
|
-
if (!this.newIncomingCallsList || this.newIncomingCallsList.length === 0) {
|
|
2500
|
-
this.isConcurrentIncoming = false;
|
|
2501
|
-
this.incomingCallDiv = false;
|
|
2502
|
-
}
|
|
2503
|
-
this.cdr.detectChanges();
|
|
2303
|
+
addParticipantToCall(payload) {
|
|
2304
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2305
|
+
return yield this.extensionService.addParticipant(payload).toPromise();
|
|
2306
|
+
});
|
|
2504
2307
|
}
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
if (num == '#') {
|
|
2510
|
-
new Audio(`/assets/dial-tones/dtmf/dtmf-hash-.mp3`).play();
|
|
2511
|
-
}
|
|
2512
|
-
else if (num == '*') {
|
|
2513
|
-
new Audio(`/assets/dial-tones/dtmf/dtmf-star-.mp3`).play();
|
|
2514
|
-
}
|
|
2515
|
-
else {
|
|
2516
|
-
new Audio(`/assets/dial-tones/dtmf/dtmf-${num}-.mp3`).play();
|
|
2517
|
-
}
|
|
2518
|
-
this.callInput = this.callInput + String(num);
|
|
2519
|
-
this.showClearBtn = true;
|
|
2520
|
-
}
|
|
2521
|
-
let str = String(num);
|
|
2522
|
-
(_a = this.call) === null || _a === void 0 ? void 0 : _a.sendDigits(str);
|
|
2523
|
-
}
|
|
2524
|
-
catch (e) {
|
|
2525
|
-
console.log(e);
|
|
2526
|
-
}
|
|
2308
|
+
getCallStatusOfParticipants(participantId) {
|
|
2309
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2310
|
+
return yield this.extensionService.getCallStatusOfParticipants(participantId).toPromise();
|
|
2311
|
+
});
|
|
2527
2312
|
}
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
}
|
|
2533
|
-
catch (e) {
|
|
2534
|
-
console.log(e);
|
|
2535
|
-
}
|
|
2313
|
+
getRemoveParticipants(participantId, conferenceId) {
|
|
2314
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2315
|
+
return yield this.extensionService.getRemoveParticipants(participantId, conferenceId).toPromise();
|
|
2316
|
+
});
|
|
2536
2317
|
}
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
this.disbaleEndCallBtn = false;
|
|
2544
|
-
this.call = data.call;
|
|
2545
|
-
this.isConcurrentIncoming = false;
|
|
2546
|
-
this.incomingCallDiv = false;
|
|
2547
|
-
const incomingDetail = this.extensionService.getCallSid();
|
|
2548
|
-
this.incomingRecordCall = incomingDetail.recordCall;
|
|
2549
|
-
if (this.incomingRecordCall) {
|
|
2550
|
-
this.startRecording();
|
|
2551
|
-
}
|
|
2552
|
-
else {
|
|
2553
|
-
this.isRecording = false;
|
|
2554
|
-
}
|
|
2555
|
-
this.cdr.detectChanges();
|
|
2556
|
-
}
|
|
2557
|
-
else {
|
|
2558
|
-
// incoming call rejected or auto-cancelled
|
|
2559
|
-
this.isConcurrentIncoming = false;
|
|
2560
|
-
this.incomingCallDiv = false;
|
|
2561
|
-
// If there is NO active call, then propagate end. Otherwise keep ongoing UI.
|
|
2562
|
-
if (!this.call || this.call.status() !== 'open') {
|
|
2563
|
-
console.log('test7');
|
|
2564
|
-
this.endCallEvent.emit();
|
|
2565
|
-
}
|
|
2566
|
-
}
|
|
2567
|
-
}
|
|
2568
|
-
clearInputs() {
|
|
2569
|
-
this.callInput = this.callInput.slice(0, -1);
|
|
2570
|
-
}
|
|
2571
|
-
minimiseDialpad() {
|
|
2572
|
-
this.minimiseEvent.emit(true);
|
|
2573
|
-
this.isMinimised = true;
|
|
2574
|
-
}
|
|
2575
|
-
maximiseDialpad() {
|
|
2576
|
-
this.minimiseEvent.emit(false);
|
|
2577
|
-
this.isMinimised = false;
|
|
2578
|
-
}
|
|
2579
|
-
toggleRecording() {
|
|
2580
|
-
if (this.isRecording) {
|
|
2581
|
-
this.stopRecording();
|
|
2582
|
-
}
|
|
2583
|
-
else {
|
|
2584
|
-
this.startRecording();
|
|
2585
|
-
}
|
|
2586
|
-
}
|
|
2587
|
-
startRecording() {
|
|
2588
|
-
var _a;
|
|
2589
|
-
let sid;
|
|
2590
|
-
const details = this.extensionService.getCallSid();
|
|
2591
|
-
this.incomingCallSid = details.callSid;
|
|
2592
|
-
this.incomingRecordCall = details.recordCall;
|
|
2593
|
-
sid = this.incomingCallSid ? this.incomingCallSid : this.callSid || ((_a = this.addRes) === null || _a === void 0 ? void 0 : _a.conferenceSid);
|
|
2594
|
-
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
2595
|
-
// return;
|
|
2596
|
-
// }
|
|
2597
|
-
this.extensionService.getCallRecording(sid).subscribe(response => {
|
|
2598
|
-
this.isRecording = true;
|
|
2599
|
-
this.isPaused = false;
|
|
2600
|
-
this.timeElapsed = 0;
|
|
2601
|
-
this.startTimer1();
|
|
2602
|
-
}, error => {
|
|
2603
|
-
console.error('Error starting recording', error);
|
|
2318
|
+
getCallAuthId(response) {
|
|
2319
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2320
|
+
return {
|
|
2321
|
+
id: response.callauth.id,
|
|
2322
|
+
recordCall: response.callauth.recordCall
|
|
2323
|
+
};
|
|
2604
2324
|
});
|
|
2605
2325
|
}
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
// }
|
|
2610
|
-
this.isRecording = false;
|
|
2611
|
-
this.isPaused = false;
|
|
2612
|
-
if (this.timerSubscription) {
|
|
2613
|
-
this.timerSubscription.unsubscribe();
|
|
2614
|
-
}
|
|
2615
|
-
}
|
|
2616
|
-
pauseRecording() {
|
|
2617
|
-
const details = this.extensionService.getCallSid();
|
|
2618
|
-
this.incomingCallSid = details.callSid;
|
|
2619
|
-
this.incomingRecordCall = details.recordCall;
|
|
2620
|
-
const sid = this.incomingCallSid ? this.incomingCallSid : this.callSid;
|
|
2621
|
-
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
2622
|
-
// return;
|
|
2623
|
-
// }
|
|
2624
|
-
this.extensionService.pauseOrResumeRecording(sid, 'pause').subscribe(response => {
|
|
2625
|
-
this.stopRecordingTimer();
|
|
2626
|
-
this.isPaused = true;
|
|
2627
|
-
}, (error) => {
|
|
2628
|
-
console.error('Error pausing recording:', error);
|
|
2629
|
-
// Consider updating the UI to show the error state
|
|
2326
|
+
getOutgoingCallToken(callAuthId) {
|
|
2327
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2328
|
+
return yield this.extensionService.getConferenceCallToken({ authId: callAuthId }).toPromise();
|
|
2630
2329
|
});
|
|
2631
2330
|
}
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2331
|
+
connectToDevice(token, callData) {
|
|
2332
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2333
|
+
const options = {
|
|
2334
|
+
codecPreferences: ['opus', 'pcmu'],
|
|
2335
|
+
closeProtection: true,
|
|
2336
|
+
};
|
|
2337
|
+
this.device = new Device(token.value, options);
|
|
2338
|
+
this.call = yield this.device.connect({
|
|
2339
|
+
params: {
|
|
2340
|
+
From: callData.from,
|
|
2341
|
+
To: callData.phone,
|
|
2342
|
+
Env: environment.abb,
|
|
2343
|
+
Token: token.id,
|
|
2344
|
+
Ext: callData.extNum
|
|
2345
|
+
},
|
|
2346
|
+
rtcConstraints: { audio: { deviceId: 'default' } },
|
|
2347
|
+
});
|
|
2348
|
+
this.call['callInfo'] = JSON.parse(JSON.stringify(callData));
|
|
2349
|
+
this.setupEventListeners();
|
|
2646
2350
|
});
|
|
2647
2351
|
}
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2352
|
+
setupEventListeners() {
|
|
2353
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
2354
|
+
this.startTimer();
|
|
2355
|
+
(_a = this.device) === null || _a === void 0 ? void 0 : _a.on('error', (err) => {
|
|
2356
|
+
console.log(err);
|
|
2357
|
+
this.showRingAnimation = false;
|
|
2358
|
+
this.stopTimer();
|
|
2359
|
+
});
|
|
2360
|
+
(_b = this.call) === null || _b === void 0 ? void 0 : _b.on('error', (error) => {
|
|
2361
|
+
this.showRingAnimation = false;
|
|
2362
|
+
this.stopTimer();
|
|
2363
|
+
});
|
|
2364
|
+
(_c = this.call) === null || _c === void 0 ? void 0 : _c.on('disconnect', (item) => {
|
|
2365
|
+
console.log('test-disconnect');
|
|
2366
|
+
// this.endCall();
|
|
2367
|
+
});
|
|
2368
|
+
(_d = this.call) === null || _d === void 0 ? void 0 : _d.on('ringing', () => {
|
|
2369
|
+
});
|
|
2370
|
+
(_e = this.call) === null || _e === void 0 ? void 0 : _e.on('reject', () => {
|
|
2371
|
+
console.log('test5');
|
|
2372
|
+
this.endCall();
|
|
2373
|
+
});
|
|
2374
|
+
(_f = this.call) === null || _f === void 0 ? void 0 : _f.on('accept', () => {
|
|
2375
|
+
this.showRingAnimation = false;
|
|
2376
|
+
this.disbaleEndCallBtn = false;
|
|
2377
|
+
// Start recording if recordCall is true and call is accepted for 30 seconds
|
|
2378
|
+
// if (this.recordCall) {
|
|
2379
|
+
// setTimeout(() => {
|
|
2380
|
+
// if (this.isRecording) return; // If already recording, skip
|
|
2381
|
+
// this.startRecording();
|
|
2382
|
+
// }, 30000);
|
|
2383
|
+
// } else {
|
|
2384
|
+
// this.stopRecording();
|
|
2385
|
+
// }
|
|
2386
|
+
});
|
|
2387
|
+
(_g = this.call) === null || _g === void 0 ? void 0 : _g.on('messageReceived', (message) => {
|
|
2651
2388
|
});
|
|
2652
2389
|
}
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
getFormattedTime() {
|
|
2660
|
-
const minutes = Math.floor(this.timeElapsed / 60);
|
|
2661
|
-
const seconds = this.timeElapsed % 60;
|
|
2662
|
-
return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
|
|
2663
|
-
}
|
|
2664
|
-
pollCallStatus(callAuthId) {
|
|
2665
|
-
const maxTime = 30000; // Poll for up to 30 seconds
|
|
2666
|
-
const pollInterval = 3000; // Poll every 3 seconds
|
|
2667
|
-
let elapsedTime = 0;
|
|
2668
|
-
const intervalId = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
2669
|
-
elapsedTime += pollInterval;
|
|
2670
|
-
try {
|
|
2671
|
-
const statusResponse = yield this.extensionService.getCallStatus(callAuthId).toPromise();
|
|
2672
|
-
if (statusResponse && statusResponse.callDetails) {
|
|
2673
|
-
this.callStatus = statusResponse.callDetails.callStatus;
|
|
2674
|
-
if (this.callStatus === 'in-progress') {
|
|
2675
|
-
this.callSid = statusResponse.callDetails.callSid;
|
|
2676
|
-
if (this.recordCall && !this.isRecording) {
|
|
2677
|
-
this.startRecording();
|
|
2678
|
-
}
|
|
2679
|
-
clearInterval(intervalId);
|
|
2680
|
-
}
|
|
2681
|
-
else if (this.callStatus === 'completed') {
|
|
2682
|
-
clearInterval(intervalId);
|
|
2683
|
-
console.log('test1');
|
|
2684
|
-
this.endCall();
|
|
2685
|
-
this.stopRecording();
|
|
2686
|
-
}
|
|
2687
|
-
else if (this.callStatus === 'ringing') {
|
|
2688
|
-
// Continue polling; do not clear the interval yet
|
|
2689
|
-
}
|
|
2690
|
-
}
|
|
2691
|
-
}
|
|
2692
|
-
catch (error) {
|
|
2693
|
-
clearInterval(intervalId);
|
|
2694
|
-
}
|
|
2695
|
-
if (elapsedTime >= maxTime) {
|
|
2696
|
-
// console.log('Max polling time reached. Stopping poll.');
|
|
2697
|
-
clearInterval(intervalId);
|
|
2698
|
-
}
|
|
2699
|
-
}), pollInterval);
|
|
2390
|
+
startTimer() {
|
|
2391
|
+
let seconds = 0;
|
|
2392
|
+
this.intervalId = setInterval(() => {
|
|
2393
|
+
seconds++;
|
|
2394
|
+
this.timer = this.formatTime(seconds);
|
|
2395
|
+
}, 1000);
|
|
2700
2396
|
}
|
|
2701
|
-
|
|
2702
|
-
this.
|
|
2703
|
-
|
|
2704
|
-
}, error => {
|
|
2705
|
-
console.error('Error starting recording', error);
|
|
2706
|
-
});
|
|
2397
|
+
stopTimer() {
|
|
2398
|
+
clearInterval(this.intervalId);
|
|
2399
|
+
this.timer = '00:00';
|
|
2707
2400
|
}
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
this.
|
|
2401
|
+
formatTime(totalSeconds) {
|
|
2402
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
2403
|
+
const seconds = totalSeconds % 60;
|
|
2404
|
+
return `${this.pad(minutes)}:${this.pad(seconds)}`;
|
|
2712
2405
|
}
|
|
2713
|
-
|
|
2714
|
-
|
|
2406
|
+
pad(value) {
|
|
2407
|
+
return value < 10 ? `0${value}` : `${value}`;
|
|
2715
2408
|
}
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
if (this.timerSubscription) {
|
|
2719
|
-
this.timerSubscription.unsubscribe();
|
|
2720
|
-
}
|
|
2409
|
+
handleError(error) {
|
|
2410
|
+
swal("Error", error, "error");
|
|
2721
2411
|
}
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
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", deviceId: "deviceId" }, outputs: { endCallEvent: "endCallEvent", incomingCallsNewInfo: "incomingCallsNewInfo", minimiseEvent: "minimiseEvent", incomingCallInitiated: "incomingCallInitiated" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"call-container\" *ngIf=\"!isMinimised\"\n [ngClass]=\"{'collops': isCollops, 'incoming-call-container': selectedIncomingCall?.isClickExpand, 'contacts-open': showContactsPanel }\">\n <!-- <div id=\"minimize-btn-div\">\n <span class=\"material-symbols-outlined minimize-btn\" (click)=\"minimiseDialpad()\">\n minimize\n </span>\n </div> -->\n <!-- <lib-incoming-call *ngIf=\"incomingCallDiv && !isConcurrentIncoming\" [incomingCallData]=\"callData\"\n [deviceId]=\"deviceId\" [newIncomingCallsList]=\"newIncomingCallsList\"\n (closeIncomingCallDiv)=\"closeIncomingCall($event)\" (incomingCallsNewList)=\"incomingCallsNewList($event)\"\n (selectedIncomingCallInfo)=\"selectedIncomingCallInfo($event)\"></lib-incoming-call> -->\n\n <ng-container *ngIf=\"!incomingCallDiv || isConcurrentIncoming\">\n <div class=\"held-call-banner\" *ngIf=\"isCallOnHold\">\n <ng-container *ngFor=\"let heldCall of currentCallList\">\n <div class=\"held-call-content\" *ngIf=\"heldCall?.isHold\">\n <div class=\"held-info\">\n <span class=\"material-symbols-outlined hold-icon\">pause_circle</span>\n <div class=\"held-caller\">\n <span class=\"held-label\">Hold</span>\n <span class=\"held-name\">{{heldCall?.name || 'Unknown number'}}</span>\n <span class=\"held-number\">{{heldCall?.phone || ''}}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <button class=\"held-btn swap-btn\" (click)=\"swapCalls(heldCall)\" title=\"Swap calls\">\n <span>Swap</span>\n </button>\n </div>\n </div>\n <div class=\"held-call-content\" *ngIf=\"heldCall?.isIncomingCall\">\n <div class=\"held-info\">\n <span class=\"material-symbols-outlined hold-icon\">phone_callback</span>\n <div class=\"held-caller\">\n <span class=\"held-label\">Incoming Call</span>\n <span class=\"held-name\">{{heldCall?.name || 'Unknown number'}}</span>\n <span class=\"held-number\">{{heldCall?.phone || ''}}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!heldCall?.isCallConnected\">\n <span class=\"material-symbols-outlined\" (click)=\"add(heldCall)\"> call </span>\n </button>\n <button class=\"call-btn-wrapper reject-btn\">\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(heldCall)\"> call_end </span>\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Compact banners for concurrent incoming (one per call) -->\n <ng-container>\n <div class=\"incoming-banners-container\" *ngIf=\"!isConference\">\n <div class=\"incoming-banner\" *ngFor=\"let inc of newIncomingCallsList; let i = index\"\n [ngStyle]=\"{ top: ((isCallOnHold && heldCall) ? 64 : 0) + (i * 80) + 'px' }\">\n <div class=\"incoming-banner-content\">\n <div class=\"incoming-info\">\n <span class=\"incom ing-label\">Incoming call</span>\n <div class=\"incoming-caller\">\n <span class=\"caller-name\">{{ inc?.userInfo?.c2cInformation?.name ||\n inc?.customParameters?.get('name') || '-' }}</span>\n <span class=\"caller-number\">{{ inc?.userInfo?.c2cInformation?.number ||\n inc?.parameters?.From || '' }}</span>\n </div>\n </div>\n <div class=\"incoming-actions\">\n <button class=\"banner-btn accept-btn\" (click)=\"acceptConcurrentCall(inc)\">\n <span class=\"material-symbols-outlined\">call</span>\n </button>\n <button class=\"banner-btn reject-btn\" (click)=\"rejectConcurrentCall(inc)\">\n <span class=\"material-symbols-outlined\">call_end</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <div *ngIf=\"!isConference\" [ngStyle]=\"{'display': 'flex', 'flex-direction': 'column', 'position': 'relative'}\">\n\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\n <img class=\"avatar-img\" [src]=\"currentCall.img\" alt=\"\" width=\"120\" />\n </div>\n <div class=\"callerDetails\">\n <h1 [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall.name || 'Unknown number'}}</h1>\n <p>{{currentCall.displayNum ? currentCall.displayNum : currentCall.phone }}</p>\n <h4 style=\"margin-top: 4px\">{{timer}}</h4>\n </div>\n\n <div class=\"record-action-btns\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\">\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\"\n (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n <div *ngIf=\"showKeypad\" class=\"sendDigit\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\"\n (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\"\n (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : ' '}}</span>\n </div>\n </div>\n\n <div class=\"call-action-btns\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '110px'}\">\n <div class=\"mb-3\" *ngIf=\"!incomingCallDiv || isConcurrentIncoming\">\n <button class=\"held-btn merge-btn\" (click)=\"mergeCalls()\" title=\"Merge calls\"\n [disabled]=\"currentCallList.length < 2\">\n <span>Merge</span>\n </button>\n </div>\n <div class=\"flex align-items-center justify-content-evenly mb-3\">\n <button class=\"call-sec-btn mr-3\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleMute()\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> mic </span>\n\n </button>\n <button class=\"call-sec-btn mr-3\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\" (click)=\"toggleKeypad()\"> transition_dissolve </span>\n </button>\n <button class=\"call-sec-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleContactsPanel()\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n </div>\n\n <div>\n <button class=\"call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n\n\n <!-- <div class=\"contacts-panel\" *ngIf=\"showContactsPanel\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel()\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of contacts\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c.firstName}} {{c.middleName}} {{c.lastName}}</div>\n <div class=\"contact-title\">{{ (c.numbersList && c.numbersList[0]?.number)}}</div>\n </div>\n <button class=\"contact-call-btn\" (click)=\"callContact(c)\">\n <span class=\"material-symbols-outlined\"> call </span>\n <span class=\"label\">Call</span>\n </button>\n </div>\n </div>\n </div> -->\n\n\n <!-- <div class=\"mt-2 px-3 call-info-wrapper \" [ngClass]=\"{'open-collops': isCollops}\">\n <div class=\"text-center\" >\n <i class=\"fa fa-angle-down\" *ngIf=\"isCollops\" (click)=\"isCollops = !isCollops\"></i>\n <i class=\"fa fa-angle-up\" *ngIf=\"!isCollops\" (click)=\"isCollops = !isCollops\"></i>\n </div>\n <ng-container *ngIf=\"isCollops\">\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div >First Name:</div>\n <div >test ttttt</div>\n </div>\n <div class=\"col-6\">\n <div>Last Name:</div>\n <div>tetst test </div>\n </div>\n </div>\n <div class=\"mb-2\">\n <div class=\"\">Email:</div>\n <div class=\"\">abcdeft@vgroup.com</div>\n </div>\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div class=\"\">Number:</div>\n <div class=\"\">63545985264225</div>\n </div>\n <div class=\"col-6\">\n <div class=\"\">Language:</div>\n <div class=\"\">English</div>\n </div>\n </div>\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div class=\"\">Image :</div>\n <div class=\"\">test.jpg </div>\n </div>\n <div class=\"col-6\">\n <div class=\"\">Extension :</div>\n <div class=\"\">4596</div>\n </div>\n </div>\n <div class=\" mb-2\">\n <div class=\"\">Note :</div>\n <div class=\"\">tes test test </div>\n </div>\n <div class=\" mb-2\">\n <div class=\"\">\n <div class=\"\">Subject:</div>\n <div class=\"\">hello world | test</div>\n </div>\n </div>\n <div class=\" mb-4\">\n <div class=\"\">\n <div class=\"\">Message:</div>\n <div class=\"\">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>\n </div>\n </div>\n </ng-container>\n </div> -->\n </div>\n <div class=\"contacts-panel\" *ngIf=\"showContactsPanel\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel()\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of contacts\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c.firstName}} {{c.middleName}} {{c.lastName}}</div>\n <div class=\"contact-title\">{{ (c.numbersList && c.numbersList[0]?.number)}}</div>\n </div>\n <button class=\"contact-call-btn\" (click)=\"callContact(c)\">\n <span class=\"material-symbols-outlined\"> call </span>\n <span class=\"label\">Call</span>\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"conference-call-view\" *ngIf=\"isConference\">\n <div class=\"conf-heading\">\n <span class=\"conf-icon material-symbols-outlined\"> groups </span>\n <span class=\"conf-title\">Conference Call</span>\n </div>\n\n <div class=\"conf-name\">\n <!-- {{ (callData?.name || callData?.displayNum || callData?.phone || '-') }} &\n {{ (newIncomingCallsList?.[0]?.userInfo?.c2cInformation?.name\n || newIncomingCallsList?.[0]?.userInfo?.c2cInformation?.number\n || newIncomingCallsList?.[0]?.parameters?.From\n || heldCall?.customParameters?.get('displayNumber')\n || '-') }} -->\n {{currentCallList?.[0]?.name || 'Unknown number'}} & {{currentCallList?.[1]?.name || 'Unknown number'}}\n </div>\n <div class=\"conf-timer\">{{ timer }}</div>\n <!-- <div class=\"conf-record\">\n <button class=\"record-stop-btn\" *ngIf=\"isRecording\" (click)=\"toggleRecording()\" title=\"Stop Recording\">\n <span class=\"material-symbols-outlined\"> stop_circle </span>\n </button>\n </div> -->\n\n <div class=\"record-action-btns mt-auto\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\">\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\"\n (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n\n <div *ngIf=\"showKeypad\" class=\"sendDigit mt-2\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\"\n (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\"\n (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : ' '}}</span>\n </div>\n </div>\n\n <div class=\"conf-remove\" >\n <button class=\"remove-btn\" (click)=\"addRemoveParticipant()\">Remove</button>\n </div>\n\n <div class=\"conf-actions\">\n <button class=\"circle-btn\" [ngClass]=\"{'active': isMute}\" (click)=\"toggleMute()\"\n [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> {{ isMute ? 'mic_off' : 'mic' }} </span>\n </button>\n <button class=\"circle-btn\" (click)=\"toggleKeypad()\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> transition_dissolve </span>\n </button>\n <button class=\"circle-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleContactsPanel()\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n </div>\n\n <div class=\"conf-end\">\n <button class=\"circle-btn danger\" (click)=\"endCall(true)\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n\n\n <div class=\"contacts-panel\" *ngIf=\"isAddRemoveParticipant\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel(true)\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of allParticipentList\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c?.toName || 'Unknown'}}</div>\n <div class=\"contact-title\">{{ c?.to || 'Unknown'}}</div>\n </div>\n <button class=\"conference-hold-contact mr-2\" [ngClass]=\"{ 'on-hold': c.hold }\" (click)=\"onHoldCall(c)\">\n <span class=\"material-symbols-outlined\" title=\"Hold\"> phone_paused </span>\n <!-- <span class=\"label\">Hold</span> -->\n </button>\n <button class=\"conference-contact\" (click)=\"onEndCall(c)\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n <!-- <span class=\"label\">End</span> -->\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"wave-container\">\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\n <defs>\n <path id=\"gentle-wave\"\n d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\n </defs>\n <g class=\"parallax\">\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\n <!-- <use\n xlink:href=\"#gentle-wave\"\n x=\"48\"\n y=\"5\"\n fill=\"rgba(255,255,255,0.3)\"\n /> -->\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\n </g>\n </svg>\n </div>\n </ng-container>\n</div>\n\n<div class=\"min-call-container\" *ngIf=\"isMinimised\">\n <span class=\"material-symbols-outlined fullscreen\" (click)=\"maximiseDialpad()\"> open_in_full </span>\n <div style=\"display: flex; width: 100%\">\n <div>\n <div class=\"min-call-animation\" id=\"call-avatar\">\n <img class=\"min-avatar-img\" [src]=\"callData.img\" alt=\"\" />\n </div>\n </div>\n <div>\n <div class=\"min-callerDetails\">\n <div class=\"name\">\n {{callData.name}}\n </div>\n <p style=\"margin: 0\">{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\n </div>\n </div>\n </div>\n <div class=\"min-btn-container\">\n <div class=\"min-timer\">{{timer}}</div>\n <button class=\"min-call-sec-btn\" (click)=\"toggleMute()\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> mic </span>\n </button>\n <button class=\"min-call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n</div>", styles: [".call-container{width:385px;height:646px!important;margin:auto;border-radius:30px;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:100000;flex-flow:column}.collops{height:660px!important}.incoming-call-container{flex-flow:row!important;width:752px!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}.callerDetails h1{width:230px;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}.callerDetails p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-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}.receive-btn{background-color:#28a745;border:2px solid #28a745}.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;background:linear-gradient(135deg,#0f172a 0%,#1e293b 100%);padding:10px 16px;z-index:2100;box-shadow:0 4px 12px #0000004d;border-radius:0 0 16px 16px}.held-call-content{display:flex;align-items:center;justify-content:space-between;gap:12px}.held-info{display:flex;align-items:center;gap:10px;flex:1}.hold-icon{font-size:24px;color:#fbbf24}.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{display:flex;flex-direction:column;gap:8px;width:100%}.incoming-banner{position:absolute;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:0 0 16px 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:1000}.contacts-header{height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;border-bottom:1px solid #f0f0f0}.contacts-header .title{font-weight:600}.contacts-header .back,.contacts-header .search{color:#9aa0a6;cursor:pointer}.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:44px;height:44px;border-radius:50%;object-fit:cover;margin-right:12px}.contact-info{flex:1}.contact-name{font-weight:600;color:#111827}.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:6px 10px;cursor:pointer}.conference-hold-contact{display:inline-flex;align-items:center;gap:6px;background:#727070;color:#fff;border:none;border-radius:50%;padding:8px 9px;cursor:pointer}.conference-hold-contact.on-hold{background:#28a745!important;color:#fff}.conference-contact{display:inline-flex;align-items:center;gap:6px;background:#f80909;color:#fff;border:none;border-radius:50%;padding:8px 9px;cursor:pointer}.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:30px;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}.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}.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%}.conference-call-view{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;width:100%;padding:12px 16px 24px;color:#fff;height:100%}.conf-heading{display:flex;align-items:center;gap:8px;margin-top:8px}.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}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
args: [{ selector: 'lib-call-progress', template: "<div class=\"call-container\" *ngIf=\"!isMinimised\"\n [ngClass]=\"{'collops': isCollops, 'incoming-call-container': selectedIncomingCall?.isClickExpand, 'contacts-open': showContactsPanel }\">\n <!-- <div id=\"minimize-btn-div\">\n <span class=\"material-symbols-outlined minimize-btn\" (click)=\"minimiseDialpad()\">\n minimize\n </span>\n </div> -->\n <!-- <lib-incoming-call *ngIf=\"incomingCallDiv && !isConcurrentIncoming\" [incomingCallData]=\"callData\"\n [deviceId]=\"deviceId\" [newIncomingCallsList]=\"newIncomingCallsList\"\n (closeIncomingCallDiv)=\"closeIncomingCall($event)\" (incomingCallsNewList)=\"incomingCallsNewList($event)\"\n (selectedIncomingCallInfo)=\"selectedIncomingCallInfo($event)\"></lib-incoming-call> -->\n\n <ng-container *ngIf=\"!incomingCallDiv || isConcurrentIncoming\">\n <div class=\"held-call-banner\" *ngIf=\"isCallOnHold\">\n <ng-container *ngFor=\"let heldCall of currentCallList\">\n <div class=\"held-call-content\" *ngIf=\"heldCall?.isHold\">\n <div class=\"held-info\">\n <span class=\"material-symbols-outlined hold-icon\">pause_circle</span>\n <div class=\"held-caller\">\n <span class=\"held-label\">Hold</span>\n <span class=\"held-name\">{{heldCall?.name || 'Unknown number'}}</span>\n <span class=\"held-number\">{{heldCall?.phone || ''}}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <button class=\"held-btn swap-btn\" (click)=\"swapCalls(heldCall)\" title=\"Swap calls\">\n <span>Swap</span>\n </button>\n </div>\n </div>\n <div class=\"held-call-content\" *ngIf=\"heldCall?.isIncomingCall\">\n <div class=\"held-info\">\n <span class=\"material-symbols-outlined hold-icon\">phone_callback</span>\n <div class=\"held-caller\">\n <span class=\"held-label\">Incoming Call</span>\n <span class=\"held-name\">{{heldCall?.name || 'Unknown number'}}</span>\n <span class=\"held-number\">{{heldCall?.phone || ''}}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!heldCall?.isCallConnected\">\n <span class=\"material-symbols-outlined\" (click)=\"add(heldCall)\"> call </span>\n </button>\n <button class=\"call-btn-wrapper reject-btn\">\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(heldCall)\"> call_end </span>\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Compact banners for concurrent incoming (one per call) -->\n <ng-container>\n <div class=\"incoming-banners-container\" *ngIf=\"!isConference\">\n <div class=\"incoming-banner\" *ngFor=\"let inc of newIncomingCallsList; let i = index\"\n [ngStyle]=\"{ top: ((isCallOnHold && heldCall) ? 64 : 0) + (i * 80) + 'px' }\">\n <div class=\"incoming-banner-content\">\n <div class=\"incoming-info\">\n <span class=\"incom ing-label\">Incoming call</span>\n <div class=\"incoming-caller\">\n <span class=\"caller-name\">{{ inc?.userInfo?.c2cInformation?.name ||\n inc?.customParameters?.get('name') || '-' }}</span>\n <span class=\"caller-number\">{{ inc?.userInfo?.c2cInformation?.number ||\n inc?.parameters?.From || '' }}</span>\n </div>\n </div>\n <div class=\"incoming-actions\">\n <button class=\"banner-btn accept-btn\" (click)=\"acceptConcurrentCall(inc)\">\n <span class=\"material-symbols-outlined\">call</span>\n </button>\n <button class=\"banner-btn reject-btn\" (click)=\"rejectConcurrentCall(inc)\">\n <span class=\"material-symbols-outlined\">call_end</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <div *ngIf=\"!isConference\" [ngStyle]=\"{'display': 'flex', 'flex-direction': 'column', 'position': 'relative'}\">\n\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\n <img class=\"avatar-img\" [src]=\"currentCall.img\" alt=\"\" width=\"120\" />\n </div>\n <div class=\"callerDetails\">\n <h1 [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall.name || 'Unknown number'}}</h1>\n <p>{{currentCall.displayNum ? currentCall.displayNum : currentCall.phone }}</p>\n <h4 style=\"margin-top: 4px\">{{timer}}</h4>\n </div>\n\n <div class=\"record-action-btns\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\">\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\"\n (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n <div *ngIf=\"showKeypad\" class=\"sendDigit\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\"\n (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\"\n (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : ' '}}</span>\n </div>\n </div>\n\n <div class=\"call-action-btns\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '110px'}\">\n <div class=\"mb-3\" *ngIf=\"!incomingCallDiv || isConcurrentIncoming\">\n <button class=\"held-btn merge-btn\" (click)=\"mergeCalls()\" title=\"Merge calls\"\n [disabled]=\"currentCallList.length < 2\">\n <span>Merge</span>\n </button>\n </div>\n <div class=\"flex align-items-center justify-content-evenly mb-3\">\n <button class=\"call-sec-btn mr-3\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleMute()\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> mic </span>\n\n </button>\n <button class=\"call-sec-btn mr-3\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\" (click)=\"toggleKeypad()\"> transition_dissolve </span>\n </button>\n <button class=\"call-sec-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleContactsPanel()\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n </div>\n\n <div>\n <button class=\"call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n\n\n <!-- <div class=\"contacts-panel\" *ngIf=\"showContactsPanel\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel()\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of contacts\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c.firstName}} {{c.middleName}} {{c.lastName}}</div>\n <div class=\"contact-title\">{{ (c.numbersList && c.numbersList[0]?.number)}}</div>\n </div>\n <button class=\"contact-call-btn\" (click)=\"callContact(c)\">\n <span class=\"material-symbols-outlined\"> call </span>\n <span class=\"label\">Call</span>\n </button>\n </div>\n </div>\n </div> -->\n\n\n <!-- <div class=\"mt-2 px-3 call-info-wrapper \" [ngClass]=\"{'open-collops': isCollops}\">\n <div class=\"text-center\" >\n <i class=\"fa fa-angle-down\" *ngIf=\"isCollops\" (click)=\"isCollops = !isCollops\"></i>\n <i class=\"fa fa-angle-up\" *ngIf=\"!isCollops\" (click)=\"isCollops = !isCollops\"></i>\n </div>\n <ng-container *ngIf=\"isCollops\">\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div >First Name:</div>\n <div >test ttttt</div>\n </div>\n <div class=\"col-6\">\n <div>Last Name:</div>\n <div>tetst test </div>\n </div>\n </div>\n <div class=\"mb-2\">\n <div class=\"\">Email:</div>\n <div class=\"\">abcdeft@vgroup.com</div>\n </div>\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div class=\"\">Number:</div>\n <div class=\"\">63545985264225</div>\n </div>\n <div class=\"col-6\">\n <div class=\"\">Language:</div>\n <div class=\"\">English</div>\n </div>\n </div>\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div class=\"\">Image :</div>\n <div class=\"\">test.jpg </div>\n </div>\n <div class=\"col-6\">\n <div class=\"\">Extension :</div>\n <div class=\"\">4596</div>\n </div>\n </div>\n <div class=\" mb-2\">\n <div class=\"\">Note :</div>\n <div class=\"\">tes test test </div>\n </div>\n <div class=\" mb-2\">\n <div class=\"\">\n <div class=\"\">Subject:</div>\n <div class=\"\">hello world | test</div>\n </div>\n </div>\n <div class=\" mb-4\">\n <div class=\"\">\n <div class=\"\">Message:</div>\n <div class=\"\">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>\n </div>\n </div>\n </ng-container>\n </div> -->\n </div>\n <div class=\"contacts-panel\" *ngIf=\"showContactsPanel\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel()\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of contacts\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c.firstName}} {{c.middleName}} {{c.lastName}}</div>\n <div class=\"contact-title\">{{ (c.numbersList && c.numbersList[0]?.number)}}</div>\n </div>\n <button class=\"contact-call-btn\" (click)=\"callContact(c)\">\n <span class=\"material-symbols-outlined\"> call </span>\n <span class=\"label\">Call</span>\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"conference-call-view\" *ngIf=\"isConference\">\n <div class=\"conf-heading\">\n <span class=\"conf-icon material-symbols-outlined\"> groups </span>\n <span class=\"conf-title\">Conference Call</span>\n </div>\n\n <div class=\"conf-name\">\n <!-- {{ (callData?.name || callData?.displayNum || callData?.phone || '-') }} &\n {{ (newIncomingCallsList?.[0]?.userInfo?.c2cInformation?.name\n || newIncomingCallsList?.[0]?.userInfo?.c2cInformation?.number\n || newIncomingCallsList?.[0]?.parameters?.From\n || heldCall?.customParameters?.get('displayNumber')\n || '-') }} -->\n {{currentCallList?.[0]?.name || 'Unknown number'}} & {{currentCallList?.[1]?.name || 'Unknown number'}}\n </div>\n <div class=\"conf-timer\">{{ timer }}</div>\n <!-- <div class=\"conf-record\">\n <button class=\"record-stop-btn\" *ngIf=\"isRecording\" (click)=\"toggleRecording()\" title=\"Stop Recording\">\n <span class=\"material-symbols-outlined\"> stop_circle </span>\n </button>\n </div> -->\n\n <div class=\"record-action-btns mt-auto\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\">\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\"\n (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n\n <div *ngIf=\"showKeypad\" class=\"sendDigit mt-2\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\"\n (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\"\n (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : ' '}}</span>\n </div>\n </div>\n\n <div class=\"conf-remove\" >\n <button class=\"remove-btn\" (click)=\"addRemoveParticipant()\">Remove</button>\n </div>\n\n <div class=\"conf-actions\">\n <button class=\"circle-btn\" [ngClass]=\"{'active': isMute}\" (click)=\"toggleMute()\"\n [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> {{ isMute ? 'mic_off' : 'mic' }} </span>\n </button>\n <button class=\"circle-btn\" (click)=\"toggleKeypad()\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> transition_dissolve </span>\n </button>\n <button class=\"circle-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleContactsPanel()\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n </div>\n\n <div class=\"conf-end\">\n <button class=\"circle-btn danger\" (click)=\"endCall(true)\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n\n\n <div class=\"contacts-panel\" *ngIf=\"isAddRemoveParticipant\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel(true)\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of allParticipentList\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c?.toName || 'Unknown'}}</div>\n <div class=\"contact-title\">{{ c?.to || 'Unknown'}}</div>\n </div>\n <button class=\"conference-hold-contact mr-2\" [ngClass]=\"{ 'on-hold': c.hold }\" (click)=\"onHoldCall(c)\">\n <span class=\"material-symbols-outlined\" title=\"Hold\"> phone_paused </span>\n <!-- <span class=\"label\">Hold</span> -->\n </button>\n <button class=\"conference-contact\" (click)=\"onEndCall(c)\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n <!-- <span class=\"label\">End</span> -->\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"wave-container\">\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\n <defs>\n <path id=\"gentle-wave\"\n d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\n </defs>\n <g class=\"parallax\">\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\n <!-- <use\n xlink:href=\"#gentle-wave\"\n x=\"48\"\n y=\"5\"\n fill=\"rgba(255,255,255,0.3)\"\n /> -->\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\n </g>\n </svg>\n </div>\n </ng-container>\n</div>\n\n<div class=\"min-call-container\" *ngIf=\"isMinimised\">\n <span class=\"material-symbols-outlined fullscreen\" (click)=\"maximiseDialpad()\"> open_in_full </span>\n <div style=\"display: flex; width: 100%\">\n <div>\n <div class=\"min-call-animation\" id=\"call-avatar\">\n <img class=\"min-avatar-img\" [src]=\"callData.img\" alt=\"\" />\n </div>\n </div>\n <div>\n <div class=\"min-callerDetails\">\n <div class=\"name\">\n {{callData.name}}\n </div>\n <p style=\"margin: 0\">{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\n </div>\n </div>\n </div>\n <div class=\"min-btn-container\">\n <div class=\"min-timer\">{{timer}}</div>\n <button class=\"min-call-sec-btn\" (click)=\"toggleMute()\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> mic </span>\n </button>\n <button class=\"min-call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n</div>", styles: [".call-container{width:385px;height:646px!important;margin:auto;border-radius:30px;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:100000;flex-flow:column}.collops{height:660px!important}.incoming-call-container{flex-flow:row!important;width:752px!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}.callerDetails h1{width:230px;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}.callerDetails p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-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}.receive-btn{background-color:#28a745;border:2px solid #28a745}.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;background:linear-gradient(135deg,#0f172a 0%,#1e293b 100%);padding:10px 16px;z-index:2100;box-shadow:0 4px 12px #0000004d;border-radius:0 0 16px 16px}.held-call-content{display:flex;align-items:center;justify-content:space-between;gap:12px}.held-info{display:flex;align-items:center;gap:10px;flex:1}.hold-icon{font-size:24px;color:#fbbf24}.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{display:flex;flex-direction:column;gap:8px;width:100%}.incoming-banner{position:absolute;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:0 0 16px 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:1000}.contacts-header{height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;border-bottom:1px solid #f0f0f0}.contacts-header .title{font-weight:600}.contacts-header .back,.contacts-header .search{color:#9aa0a6;cursor:pointer}.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:44px;height:44px;border-radius:50%;object-fit:cover;margin-right:12px}.contact-info{flex:1}.contact-name{font-weight:600;color:#111827}.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:6px 10px;cursor:pointer}.conference-hold-contact{display:inline-flex;align-items:center;gap:6px;background:#727070;color:#fff;border:none;border-radius:50%;padding:8px 9px;cursor:pointer}.conference-hold-contact.on-hold{background:#28a745!important;color:#fff}.conference-contact{display:inline-flex;align-items:center;gap:6px;background:#f80909;color:#fff;border:none;border-radius:50%;padding:8px 9px;cursor:pointer}.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:30px;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}.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}.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%}.conference-call-view{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;width:100%;padding:12px 16px 24px;color:#fff;height:100%}.conf-heading{display:flex;align-items:center;gap:8px;margin-top:8px}.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}\n"] }]
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2412
|
+
// endCall() {
|
|
2413
|
+
// console.log('endCall() called');
|
|
2414
|
+
// console.log('Current call:', this.call?.parameters['From']);
|
|
2415
|
+
// console.log('Held call exists:', !!this.heldCall);
|
|
2416
|
+
// // Disconnect the current active call
|
|
2417
|
+
// if (this.call) {
|
|
2418
|
+
// this.call.disconnect();
|
|
2419
|
+
// this.call = undefined;
|
|
2420
|
+
// }
|
|
2421
|
+
// this.showRingAnimation = false;
|
|
2422
|
+
// this.stopTimer();
|
|
2423
|
+
// // If there's a held call, make it active
|
|
2424
|
+
// if (this.heldCall) {
|
|
2425
|
+
// console.log('Resuming held call:', this.heldCall.parameters['From']);
|
|
2426
|
+
// // Make held call the active call
|
|
2427
|
+
// this.call = this.heldCall;
|
|
2428
|
+
// this.heldCall = undefined;
|
|
2429
|
+
// // this.isCallOnHold = false;
|
|
2430
|
+
// this.isCallOnHold = !!this.heldCall;
|
|
2431
|
+
// // Unmute the resumed call
|
|
2432
|
+
// this.call.mute(false);
|
|
2433
|
+
// // Update UI with the resumed call info
|
|
2434
|
+
// const fromNumber = this.call.parameters['From'];
|
|
2435
|
+
// const callerName = this.call.customParameters?.get('name') || '-';
|
|
2436
|
+
// const callerImg = this.call.customParameters?.get('image') || 'assets/images/user.jpg';
|
|
2437
|
+
// this.callData = {
|
|
2438
|
+
// ...this.callData,
|
|
2439
|
+
// phone: fromNumber,
|
|
2440
|
+
// displayNum: fromNumber,
|
|
2441
|
+
// name: callerName,
|
|
2442
|
+
// img: callerImg
|
|
2443
|
+
// };
|
|
2444
|
+
// // Restart timer for the resumed call
|
|
2445
|
+
// this.startTimer();
|
|
2446
|
+
// this.disbaleEndCallBtn = false;
|
|
2447
|
+
// console.log('Held call is now active:', this.callData);
|
|
2448
|
+
// this.cdr.detectChanges();
|
|
2449
|
+
// } else {
|
|
2450
|
+
// // No held call, completely end
|
|
2451
|
+
// console.log('No held call, ending completely');
|
|
2452
|
+
// this.endCallEvent.emit();
|
|
2453
|
+
// this.maximiseDialpad();
|
|
2454
|
+
// }
|
|
2455
|
+
// }
|
|
2456
|
+
endCall(isAllCallEnd) {
|
|
2457
|
+
var _a, _b;
|
|
2458
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2459
|
+
console.log('endCall() called');
|
|
2460
|
+
console.log('Current call:', (_a = this.call) === null || _a === void 0 ? void 0 : _a.parameters['From']);
|
|
2461
|
+
console.log('Held call exists:', !!this.heldCall);
|
|
2462
|
+
// Leaving conference state when ending current call action
|
|
2463
|
+
this.isConference = false;
|
|
2464
|
+
// if (this.call) {
|
|
2465
|
+
// this.call.disconnect();
|
|
2466
|
+
// this.call.reject();
|
|
2467
|
+
// this.call = undefined;
|
|
2468
|
+
// }
|
|
2469
|
+
this.showRingAnimation = false;
|
|
2470
|
+
this.stopTimer();
|
|
2471
|
+
if (isAllCallEnd) {
|
|
2472
|
+
this.onEndCall({}, isAllCallEnd);
|
|
2473
|
+
this.currentCallList = [];
|
|
2474
|
+
this.endCallEvent.emit();
|
|
2475
|
+
}
|
|
2476
|
+
else {
|
|
2477
|
+
this.onEndCall(this.currentCall, isAllCallEnd);
|
|
2478
|
+
this.currentCallList = this.currentCallList.filter((c) => (c === null || c === void 0 ? void 0 : c.participantId) !== this.currentCall.participantId);
|
|
2479
|
+
if (this.currentCallList.length > 0) {
|
|
2480
|
+
this.currentCallList[0].isHold = false;
|
|
2481
|
+
this.currentCall = this.currentCallList[0];
|
|
2482
|
+
yield this.onholdOrUnholdParticipant({
|
|
2483
|
+
participantId: (_b = this.currentCall) === null || _b === void 0 ? void 0 : _b.participantId,
|
|
2484
|
+
conferenceId: this.conferenceId,
|
|
2485
|
+
hold: false
|
|
2486
|
+
});
|
|
2487
|
+
}
|
|
2488
|
+
else {
|
|
2489
|
+
this.currentCall = null;
|
|
2490
|
+
this.currentCallList = [];
|
|
2491
|
+
this.endCallEvent.emit();
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
});
|
|
2755
2495
|
}
|
|
2756
|
-
|
|
2757
|
-
|
|
2496
|
+
toggleMute() {
|
|
2497
|
+
var _a;
|
|
2498
|
+
this.isMute = !this.isMute;
|
|
2499
|
+
(_a = this.call) === null || _a === void 0 ? void 0 : _a.mute(this.isMute);
|
|
2758
2500
|
}
|
|
2759
|
-
|
|
2760
|
-
this.
|
|
2761
|
-
this.
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
this.callInitiated = new EventEmitter();
|
|
2773
|
-
this.endCallEvent = new EventEmitter();
|
|
2774
|
-
this.minimiseEvent = new EventEmitter();
|
|
2775
|
-
this.incomingCallsNewInfoEvent = new EventEmitter();
|
|
2776
|
-
this.incomingCallInitiated = new EventEmitter();
|
|
2777
|
-
this.numberDialed = new EventEmitter();
|
|
2778
|
-
this.isCallInProgress = false;
|
|
2779
|
-
this.keypadVal = keypad;
|
|
2780
|
-
this.showInputClearBtn = false;
|
|
2781
|
-
this.dialedNumber = '';
|
|
2782
|
-
this.contactList = [];
|
|
2783
|
-
this.filteredContactList = [];
|
|
2784
|
-
this.callerIdList = [];
|
|
2785
|
-
this.isCallerIdHidden = true;
|
|
2786
|
-
this.isTrialPeriodOver = false;
|
|
2787
|
-
this.isPaymentDue = false;
|
|
2788
|
-
this.terminateCall = false;
|
|
2789
|
-
this.toastTimeout = 7000;
|
|
2790
|
-
this.callNumberToast = {
|
|
2791
|
-
show: false,
|
|
2792
|
-
type: 'alert-success',
|
|
2793
|
-
number: '',
|
|
2794
|
-
displayNum: ''
|
|
2795
|
-
};
|
|
2796
|
-
this.callData = {
|
|
2797
|
-
phone: '',
|
|
2798
|
-
displayNum: '',
|
|
2799
|
-
dial: false,
|
|
2800
|
-
name: '',
|
|
2801
|
-
img: 'assets/images/user.jpg',
|
|
2802
|
-
isIncomingCall: false,
|
|
2803
|
-
extNum: ''
|
|
2804
|
-
};
|
|
2805
|
-
this.lastDialed = null;
|
|
2806
|
-
this.dialAlert = {
|
|
2807
|
-
msg: '',
|
|
2808
|
-
show: false
|
|
2809
|
-
};
|
|
2810
|
-
this.showDedicatedPopup = false;
|
|
2811
|
-
this.newIncomingCalls = [];
|
|
2812
|
-
this.incomingCallsList = [];
|
|
2813
|
-
this.subscriptions = new Subscription();
|
|
2814
|
-
this.shakeDedicatedBtn = false;
|
|
2815
|
-
this.isSmartDialCall = false;
|
|
2816
|
-
this.isInitialized = false;
|
|
2817
|
-
this.isMinimised = false;
|
|
2818
|
-
// Initialize if dialpad is visible by default
|
|
2819
|
-
if (!this.isDialpadHidden) {
|
|
2820
|
-
console.log('sfsdfdsf');
|
|
2821
|
-
this.initializeTwilio();
|
|
2501
|
+
toggleKeypad() {
|
|
2502
|
+
this.showKeypad = !this.showKeypad;
|
|
2503
|
+
this.callInput = '';
|
|
2504
|
+
}
|
|
2505
|
+
toggleContactsPanel(isRemove) {
|
|
2506
|
+
if (isRemove) {
|
|
2507
|
+
this.showContactsPanel = false;
|
|
2508
|
+
this.isAddRemoveParticipant = !this.isAddRemoveParticipant;
|
|
2509
|
+
}
|
|
2510
|
+
else {
|
|
2511
|
+
this.isAddRemoveParticipant = false;
|
|
2512
|
+
this.showContactsPanel = !this.showContactsPanel;
|
|
2513
|
+
this.GetContactsList();
|
|
2822
2514
|
}
|
|
2823
|
-
console.log('DialboxComponent constructor');
|
|
2824
2515
|
}
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2516
|
+
addRemoveParticipant() {
|
|
2517
|
+
var _a;
|
|
2518
|
+
const conferenceSId = (_a = this.addRes) === null || _a === void 0 ? void 0 : _a.conferenceSid;
|
|
2519
|
+
this.isAddRemoveParticipant = !this.isAddRemoveParticipant;
|
|
2520
|
+
this.allParticipentList = this.getAllParticipants(conferenceSId);
|
|
2521
|
+
}
|
|
2522
|
+
add(data) {
|
|
2523
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2524
|
+
if ((data === null || data === void 0 ? void 0 : data.status) != 'ringing') {
|
|
2525
|
+
let device = yield this.twilioService.connect('');
|
|
2526
|
+
console.log(device, 'callConnect');
|
|
2832
2527
|
}
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2528
|
+
else if ((data === null || data === void 0 ? void 0 : data.status) == 'ringing') {
|
|
2529
|
+
this.twilioService.addIncomingParticipant(data === null || data === void 0 ? void 0 : data.id, this.twilioService.conferenceCallInfo.conferenceId).subscribe((data) => {
|
|
2530
|
+
console.log(data, 'bhhhhhhhhhhhhhhhhhhh');
|
|
2531
|
+
});
|
|
2532
|
+
}
|
|
2533
|
+
// this.device = new Device();/
|
|
2534
|
+
// Device.connect({ conferenceName: 'my-conference-room' });
|
|
2535
|
+
// this.device = new Device({ conferenceName: 'my-conference-room' });
|
|
2536
|
+
});
|
|
2837
2537
|
}
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2538
|
+
rejectCallFromList(data) {
|
|
2539
|
+
console.log(data, '266565655');
|
|
2540
|
+
// this.twilioService.rejectIncomingParticipant(data?.id, this.twilioService.conferenceCallInfo.conferenceId).subscribe((data: any) => {
|
|
2541
|
+
// console.log(data,'bhhhhhhhhhhhhhhhhhhh')
|
|
2542
|
+
// })
|
|
2543
|
+
}
|
|
2544
|
+
callContact(contact) {
|
|
2545
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2546
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2547
|
+
console.log('Adding participant:', contact);
|
|
2548
|
+
console.log('this.call', this.call);
|
|
2549
|
+
console.log('this.call', this.call.status());
|
|
2550
|
+
// Check if there's an active call
|
|
2551
|
+
if (!this.call || this.call.status() !== 'open') {
|
|
2552
|
+
console.error('No active call');
|
|
2553
|
+
return;
|
|
2554
|
+
}
|
|
2555
|
+
// Get the phone number from the contact
|
|
2556
|
+
const phoneNumber = (_b = (_a = contact === null || contact === void 0 ? void 0 : contact.numbersList) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.number;
|
|
2557
|
+
const currentCall = this.currentCallList.find((c) => (c === null || c === void 0 ? void 0 : c.phone) === phoneNumber);
|
|
2558
|
+
if (!phoneNumber || currentCall) {
|
|
2559
|
+
console.error('No phone number found for contact');
|
|
2560
|
+
return;
|
|
2561
|
+
}
|
|
2562
|
+
try {
|
|
2563
|
+
if (this.isConference) {
|
|
2564
|
+
let data = yield this.addParticipantToCall({
|
|
2565
|
+
from: ((_c = this.callData) === null || _c === void 0 ? void 0 : _c.from) || ((_d = this.selectedCallerId) === null || _d === void 0 ? void 0 : _d.number),
|
|
2566
|
+
route: "OUTGOING",
|
|
2567
|
+
participantNumber: phoneNumber,
|
|
2568
|
+
conferenceId: this.conferenceId
|
|
2569
|
+
});
|
|
2570
|
+
this.callData = {
|
|
2571
|
+
// ...this.callData,
|
|
2572
|
+
phone: phoneNumber,
|
|
2573
|
+
displayNum: phoneNumber,
|
|
2574
|
+
name: (contact === null || contact === void 0 ? void 0 : contact.name) || `${contact === null || contact === void 0 ? void 0 : contact.firstName} ${contact === null || contact === void 0 ? void 0 : contact.lastName}` || phoneNumber,
|
|
2575
|
+
img: (contact === null || contact === void 0 ? void 0 : contact.img) || 'assets/images/user.jpg',
|
|
2576
|
+
participantId: data === null || data === void 0 ? void 0 : data.participantId,
|
|
2577
|
+
from: (_e = this.selectedCallerId) === null || _e === void 0 ? void 0 : _e.number,
|
|
2578
|
+
isIncomingCall: false,
|
|
2579
|
+
isHold: false,
|
|
2580
|
+
isLeft: false,
|
|
2581
|
+
isConference: true
|
|
2582
|
+
};
|
|
2583
|
+
this.cdr.detectChanges();
|
|
2584
|
+
console.log(this.callData, 'this.callData5656');
|
|
2585
|
+
console.log('test1111115555555555');
|
|
2586
|
+
this.currentCall = this.callData;
|
|
2587
|
+
this.currentCallList.push(Object.assign({}, this.callData));
|
|
2588
|
+
console.log("Participant added to conference:", phoneNumber);
|
|
2589
|
+
this.showRingAnimation = false;
|
|
2590
|
+
}
|
|
2591
|
+
else {
|
|
2592
|
+
this.currentCallList.forEach((c) => __awaiter(this, void 0, void 0, function* () {
|
|
2593
|
+
if ((c === null || c === void 0 ? void 0 : c.participantId) && !(c === null || c === void 0 ? void 0 : c.isHold)) {
|
|
2594
|
+
c.isHold = true;
|
|
2595
|
+
yield this.onholdOrUnholdParticipant({
|
|
2596
|
+
participantId: c === null || c === void 0 ? void 0 : c.participantId,
|
|
2597
|
+
conferenceId: this.conferenceId,
|
|
2598
|
+
hold: c === null || c === void 0 ? void 0 : c.isHold
|
|
2599
|
+
});
|
|
2600
|
+
}
|
|
2601
|
+
}));
|
|
2602
|
+
// Put current call on hold
|
|
2603
|
+
// this.heldCall = this.call;
|
|
2604
|
+
this.isCallOnHold = true;
|
|
2605
|
+
// this.heldCall.mute(true);
|
|
2606
|
+
// this.heldCall['parameters']['caller_name'] = { ...this.callData }
|
|
2607
|
+
// this.call=null
|
|
2608
|
+
// Close contacts panel and show ring animation
|
|
2609
|
+
this.showContactsPanel = false;
|
|
2610
|
+
this.showRingAnimation = true;
|
|
2611
|
+
// Update UI to reflect the new outbound leg being dialed
|
|
2612
|
+
const contactName = [contact === null || contact === void 0 ? void 0 : contact.firstName, contact === null || contact === void 0 ? void 0 : contact.middleName, contact === null || contact === void 0 ? void 0 : contact.lastName]
|
|
2613
|
+
.filter(Boolean)
|
|
2614
|
+
.join(' ');
|
|
2615
|
+
// this.call['callInfo'] = JSON.parse(JSON.stringify(this.callData));
|
|
2616
|
+
// Get the conference ID from the current call or use the stored one
|
|
2617
|
+
// const conferenceId = this.conferenceId;
|
|
2618
|
+
if (!this.conferenceId) {
|
|
2619
|
+
console.error("No conferenceId found for active call");
|
|
2620
|
+
swal("Error", "Cannot add participant: conference not found", "error");
|
|
2621
|
+
this.showRingAnimation = false;
|
|
2622
|
+
return;
|
|
2623
|
+
}
|
|
2624
|
+
// Add participant to the conference
|
|
2625
|
+
let data = yield this.addParticipantToCall({
|
|
2626
|
+
from: ((_f = this.callData) === null || _f === void 0 ? void 0 : _f.from) || ((_g = this.selectedCallerId) === null || _g === void 0 ? void 0 : _g.number),
|
|
2627
|
+
route: "OUTGOING",
|
|
2628
|
+
participantNumber: phoneNumber,
|
|
2629
|
+
conferenceId: this.conferenceId
|
|
2630
|
+
});
|
|
2631
|
+
// this.callData = {
|
|
2632
|
+
// ...this.callData,
|
|
2633
|
+
// participantId: ,
|
|
2634
|
+
// }
|
|
2635
|
+
this.callData = {
|
|
2636
|
+
// ...this.callData,
|
|
2637
|
+
phone: phoneNumber,
|
|
2638
|
+
displayNum: phoneNumber,
|
|
2639
|
+
name: (contact === null || contact === void 0 ? void 0 : contact.name) || `${contact === null || contact === void 0 ? void 0 : contact.firstName} ${contact === null || contact === void 0 ? void 0 : contact.lastName}` || phoneNumber,
|
|
2640
|
+
img: (contact === null || contact === void 0 ? void 0 : contact.img) || 'assets/images/user.jpg',
|
|
2641
|
+
participantId: data === null || data === void 0 ? void 0 : data.participantId,
|
|
2642
|
+
from: (_h = this.selectedCallerId) === null || _h === void 0 ? void 0 : _h.number,
|
|
2643
|
+
isIncomingCall: false,
|
|
2644
|
+
isHold: false,
|
|
2645
|
+
isLeft: false,
|
|
2646
|
+
isConference: false
|
|
2647
|
+
};
|
|
2648
|
+
this.cdr.detectChanges();
|
|
2649
|
+
console.log(this.callData, 'this.callData');
|
|
2650
|
+
console.log('test111111');
|
|
2651
|
+
this.currentCall = this.callData;
|
|
2652
|
+
this.currentCallList.push(Object.assign({}, this.callData));
|
|
2653
|
+
console.log("Participant added to conference:", phoneNumber);
|
|
2654
|
+
this.showRingAnimation = false;
|
|
2655
|
+
}
|
|
2656
|
+
}
|
|
2657
|
+
catch (error) {
|
|
2658
|
+
console.error('Error adding participant:', error);
|
|
2659
|
+
this.showRingAnimation = false;
|
|
2660
|
+
// Restore held call on error
|
|
2661
|
+
if (this.heldCall) {
|
|
2662
|
+
// this.call = this.heldCall;
|
|
2663
|
+
// this.heldCall = undefined;
|
|
2664
|
+
// this.isCallOnHold = false;
|
|
2665
|
+
// this.call.mute(false);
|
|
2666
|
+
}
|
|
2667
|
+
this.handleError(error);
|
|
2668
|
+
}
|
|
2669
|
+
});
|
|
2670
|
+
}
|
|
2671
|
+
getAllParticipants(conferenceSid) {
|
|
2672
|
+
this.extensionService.getAllParticipants(conferenceSid).subscribe((res) => {
|
|
2673
|
+
this.allParticipentList = res.participants;
|
|
2674
|
+
});
|
|
2675
|
+
}
|
|
2676
|
+
// acceptConcurrentCall(incomingCall: any) {
|
|
2677
|
+
// if (!incomingCall) return;
|
|
2678
|
+
// // Put current call on hold instead of disconnecting
|
|
2679
|
+
// if (this.call) {
|
|
2680
|
+
// this.heldCall = this.call;
|
|
2681
|
+
// this.isCallOnHold = true;
|
|
2682
|
+
// // Mute the held call
|
|
2683
|
+
// this.heldCall.mute(true);
|
|
2684
|
+
// }
|
|
2685
|
+
// incomingCall.accept();
|
|
2686
|
+
// this.call = incomingCall;
|
|
2687
|
+
// this.callData.phone = incomingCall.parameters['From'];
|
|
2688
|
+
// this.callData.name = incomingCall.customParameters?.get('name') || '-';
|
|
2689
|
+
// this.callData.img = incomingCall.customParameters?.get('image') || 'assets/images/user.jpg';
|
|
2690
|
+
// this.isConcurrentIncoming = false;
|
|
2691
|
+
// this.incomingCallDiv = false;
|
|
2692
|
+
// this.disbaleEndCallBtn = false;
|
|
2693
|
+
// // Reset timer for new call
|
|
2694
|
+
// this.stopTimer();
|
|
2695
|
+
// this.startTimer();
|
|
2696
|
+
// this.cdr.detectChanges();
|
|
2697
|
+
// }
|
|
2698
|
+
acceptConcurrentCall(incomingCall) {
|
|
2699
|
+
var _a, _b;
|
|
2700
|
+
if (!incomingCall)
|
|
2701
|
+
return;
|
|
2702
|
+
// Put current call on hold instead of disconnecting
|
|
2703
|
+
// if (this.call) {
|
|
2704
|
+
// this.heldCall = this.call;
|
|
2705
|
+
this.isCallOnHold = true;
|
|
2706
|
+
// // Mute the held call
|
|
2707
|
+
// this.heldCall.mute(true);
|
|
2708
|
+
// }
|
|
2709
|
+
// Accept the new call
|
|
2710
|
+
incomingCall.accept();
|
|
2711
|
+
this.call = incomingCall;
|
|
2712
|
+
this.callData.phone = incomingCall.parameters['From'];
|
|
2713
|
+
this.callData.name = ((_a = incomingCall.customParameters) === null || _a === void 0 ? void 0 : _a.get('name')) || '-';
|
|
2714
|
+
this.callData.img = ((_b = incomingCall.customParameters) === null || _b === void 0 ? void 0 : _b.get('image')) || 'assets/images/user.jpg';
|
|
2715
|
+
this.isConcurrentIncoming = false;
|
|
2716
|
+
this.incomingCallDiv = false;
|
|
2717
|
+
this.disbaleEndCallBtn = false;
|
|
2718
|
+
// 🟢 Remove the accepted call from incoming list
|
|
2719
|
+
this.newIncomingCallsList = (this.newIncomingCallsList || []).filter((c) => { var _a, _b; return ((_a = c === null || c === void 0 ? void 0 : c.parameters) === null || _a === void 0 ? void 0 : _a.CallSid) !== ((_b = incomingCall === null || incomingCall === void 0 ? void 0 : incomingCall.parameters) === null || _b === void 0 ? void 0 : _b.CallSid); });
|
|
2720
|
+
this.incomingCallsNewInfo.emit(this.newIncomingCallsList);
|
|
2721
|
+
// 🕒 Reset timer for new call
|
|
2722
|
+
this.stopTimer();
|
|
2723
|
+
this.startTimer();
|
|
2724
|
+
this.cdr.detectChanges();
|
|
2725
|
+
}
|
|
2726
|
+
swapCalls(callInfo) {
|
|
2727
|
+
var _a, _b, _c;
|
|
2728
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2729
|
+
// if (!this.heldCall || !this.call) return;
|
|
2730
|
+
console.log(this.call, 'this.call');
|
|
2731
|
+
console.log(this.heldCall, 'this.heldCall');
|
|
2732
|
+
console.log(this.currentCallList, 'this.currentCallList');
|
|
2733
|
+
console.log(callInfo, 'callInfo for swapCalls');
|
|
2734
|
+
this.currentCallList.forEach((c) => __awaiter(this, void 0, void 0, function* () {
|
|
2735
|
+
if ((c === null || c === void 0 ? void 0 : c.participantId) && !(c === null || c === void 0 ? void 0 : c.isHold)) {
|
|
2736
|
+
c.isHold = true;
|
|
2737
|
+
yield this.onholdOrUnholdParticipant({
|
|
2738
|
+
participantId: c === null || c === void 0 ? void 0 : c.participantId,
|
|
2739
|
+
conferenceId: this.conferenceId,
|
|
2740
|
+
hold: c === null || c === void 0 ? void 0 : c.isHold
|
|
2741
|
+
});
|
|
2742
|
+
}
|
|
2743
|
+
else if ((callInfo === null || callInfo === void 0 ? void 0 : callInfo.isHold) && (c === null || c === void 0 ? void 0 : c.participantId) === (callInfo === null || callInfo === void 0 ? void 0 : callInfo.participantId)) {
|
|
2744
|
+
c.isHold = false;
|
|
2745
|
+
yield this.onholdOrUnholdParticipant({
|
|
2746
|
+
participantId: c === null || c === void 0 ? void 0 : c.participantId,
|
|
2747
|
+
conferenceId: this.conferenceId,
|
|
2748
|
+
hold: c === null || c === void 0 ? void 0 : c.isHold
|
|
2749
|
+
});
|
|
2750
|
+
this.currentCall = c;
|
|
2751
|
+
}
|
|
2752
|
+
}));
|
|
2753
|
+
// await this.onholdOrUnholdParticipant({
|
|
2754
|
+
// participantId: this.call?.callInfo?.participantId,
|
|
2755
|
+
// conferenceId: this.conferenceId,
|
|
2756
|
+
// hold: true
|
|
2757
|
+
// });
|
|
2758
|
+
// await this.onholdOrUnholdParticipant({
|
|
2759
|
+
// participantId: this.heldCall?.callInfo?.participantId,
|
|
2760
|
+
// conferenceId: this.conferenceId,
|
|
2761
|
+
// hold: false
|
|
2762
|
+
// });
|
|
2763
|
+
console.log('Swapping calls...');
|
|
2764
|
+
console.log('Before swap - Active call:', this.call.parameters['From']);
|
|
2765
|
+
console.log('Before swap - Held call:', this.heldCall.parameters['From']);
|
|
2766
|
+
// Swap the calls
|
|
2767
|
+
// const temp = this.call;
|
|
2768
|
+
// this.call = this.heldCall;
|
|
2769
|
+
// this.heldCall = temp;
|
|
2770
|
+
// this.call.mute(false);
|
|
2771
|
+
// this.heldCall.mute(true);
|
|
2772
|
+
// Update UI with active call info - extract from call parameters
|
|
2773
|
+
const fromNumber = this.call.parameters['From'];
|
|
2774
|
+
const callerName = ((_a = this.call.customParameters) === null || _a === void 0 ? void 0 : _a.get('name')) || '-';
|
|
2775
|
+
const callerImg = ((_b = this.call.customParameters) === null || _b === void 0 ? void 0 : _b.get('image')) || 'assets/images/user.jpg';
|
|
2776
|
+
const displayNumber = ((_c = this.call.customParameters) === null || _c === void 0 ? void 0 : _c.get('displayNumber')) || '-';
|
|
2777
|
+
// Update callData to refresh the main UI
|
|
2778
|
+
// this.callData = {
|
|
2779
|
+
// ...this.callData,
|
|
2780
|
+
// phone: fromNumber,
|
|
2781
|
+
// displayNum: (displayNumber && displayNumber !== '-') ? displayNumber : fromNumber,
|
|
2782
|
+
// name: (callerName && callerName !== '-') ? callerName : (this.callData?.name || fromNumber),
|
|
2783
|
+
// img: callerImg || this.callData?.img || 'assets/images/user.jpg'
|
|
2784
|
+
// };
|
|
2785
|
+
// console.log('After swap - Active call:', this.call.parameters['From']);
|
|
2786
|
+
// console.log('After swap - Held call:', this.heldCall.parameters['From']);
|
|
2787
|
+
// console.log('Updated callData:', this.callData);
|
|
2788
|
+
console.log('this.currentCallList after swap', this.currentCallList);
|
|
2789
|
+
this.cdr.detectChanges();
|
|
2790
|
+
});
|
|
2791
|
+
}
|
|
2792
|
+
mergeCalls() {
|
|
2793
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2794
|
+
// Merge functionality - unmute both calls for conference
|
|
2795
|
+
if (this.currentCallList.length > 1) {
|
|
2796
|
+
this.currentCallList.forEach((c) => __awaiter(this, void 0, void 0, function* () {
|
|
2797
|
+
if ((c === null || c === void 0 ? void 0 : c.participantId) && (c === null || c === void 0 ? void 0 : c.isHold)) {
|
|
2798
|
+
c.isHold = false;
|
|
2799
|
+
yield this.onholdOrUnholdParticipant({
|
|
2800
|
+
participantId: c === null || c === void 0 ? void 0 : c.participantId,
|
|
2801
|
+
conferenceId: this.conferenceId,
|
|
2802
|
+
hold: false
|
|
2803
|
+
});
|
|
2804
|
+
}
|
|
2805
|
+
c.isConference = true;
|
|
2806
|
+
}));
|
|
2807
|
+
// await this.onholdOrUnholdParticipant({
|
|
2808
|
+
// participantId: this.heldCall?.callInfo?.participantId,
|
|
2809
|
+
// conferenceId: this.conferenceId,
|
|
2810
|
+
// hold: false
|
|
2811
|
+
// });
|
|
2812
|
+
// this.heldCall.mute(false);
|
|
2813
|
+
// this.call.mute(false);
|
|
2814
|
+
this.isCallOnHold = false;
|
|
2815
|
+
this.isConference = true;
|
|
2816
|
+
this.cdr.detectChanges();
|
|
2817
|
+
}
|
|
2818
|
+
});
|
|
2819
|
+
}
|
|
2820
|
+
endHeldCall() {
|
|
2821
|
+
// if (this.heldCall) {
|
|
2822
|
+
// this.heldCall.disconnect();
|
|
2823
|
+
// this.heldCall = undefined;
|
|
2824
|
+
// this.isCallOnHold = false;
|
|
2825
|
+
// this.cdr.detectChanges();
|
|
2826
|
+
// }
|
|
2827
|
+
}
|
|
2828
|
+
rejectConcurrentCall(incomingCall) {
|
|
2829
|
+
if (!incomingCall)
|
|
2830
|
+
return;
|
|
2831
|
+
if (incomingCall.reject) {
|
|
2832
|
+
incomingCall.reject();
|
|
2833
|
+
}
|
|
2834
|
+
if (incomingCall.disconnect)
|
|
2835
|
+
incomingCall.disconnect();
|
|
2836
|
+
// Remove from list
|
|
2837
|
+
this.newIncomingCallsList = (this.newIncomingCallsList || []).filter((c) => { var _a, _b; return ((_a = c === null || c === void 0 ? void 0 : c.parameters) === null || _a === void 0 ? void 0 : _a.CallSid) !== ((_b = incomingCall === null || incomingCall === void 0 ? void 0 : incomingCall.parameters) === null || _b === void 0 ? void 0 : _b.CallSid); });
|
|
2838
|
+
this.incomingCallsNewInfo.emit(this.newIncomingCallsList);
|
|
2839
|
+
// If no more incoming, hide banner
|
|
2840
|
+
if (!this.newIncomingCallsList || this.newIncomingCallsList.length === 0) {
|
|
2841
|
+
this.isConcurrentIncoming = false;
|
|
2842
|
+
this.incomingCallDiv = false;
|
|
2843
|
+
}
|
|
2844
|
+
this.cdr.detectChanges();
|
|
2845
|
+
}
|
|
2846
|
+
onCallInputs(num) {
|
|
2847
|
+
var _a;
|
|
2848
|
+
try {
|
|
2849
|
+
if (Number.isInteger(num) || num == '+' || num == '*' || num == '#') {
|
|
2850
|
+
if (num == '#') {
|
|
2851
|
+
new Audio(`/assets/dial-tones/dtmf/dtmf-hash-.mp3`).play();
|
|
2852
|
+
}
|
|
2853
|
+
else if (num == '*') {
|
|
2854
|
+
new Audio(`/assets/dial-tones/dtmf/dtmf-star-.mp3`).play();
|
|
2855
|
+
}
|
|
2856
|
+
else {
|
|
2857
|
+
new Audio(`/assets/dial-tones/dtmf/dtmf-${num}-.mp3`).play();
|
|
2858
|
+
}
|
|
2859
|
+
this.callInput = this.callInput + String(num);
|
|
2860
|
+
this.showClearBtn = true;
|
|
2861
|
+
}
|
|
2862
|
+
let str = String(num);
|
|
2863
|
+
(_a = this.call) === null || _a === void 0 ? void 0 : _a.sendDigits(str);
|
|
2864
|
+
}
|
|
2865
|
+
catch (e) {
|
|
2866
|
+
console.log(e);
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
onCallInputEnter(ev) {
|
|
2870
|
+
var _a;
|
|
2871
|
+
try {
|
|
2872
|
+
(_a = this.call) === null || _a === void 0 ? void 0 : _a.sendDigits(String(ev.key));
|
|
2873
|
+
}
|
|
2874
|
+
catch (e) {
|
|
2875
|
+
console.log(e);
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
closeIncomingCall(data) {
|
|
2879
|
+
// this.incomingCallDiv = false;
|
|
2880
|
+
if (data.show) {
|
|
2881
|
+
//this.showCallProgressEvent.emit()
|
|
2882
|
+
// handle incoming call accepted
|
|
2883
|
+
this.startTimer();
|
|
2884
|
+
this.disbaleEndCallBtn = false;
|
|
2885
|
+
this.call = data.call;
|
|
2886
|
+
this.isConcurrentIncoming = false;
|
|
2887
|
+
this.incomingCallDiv = false;
|
|
2888
|
+
const incomingDetail = this.extensionService.getCallSid();
|
|
2889
|
+
this.incomingRecordCall = incomingDetail.recordCall;
|
|
2890
|
+
if (this.incomingRecordCall) {
|
|
2891
|
+
this.startRecording();
|
|
2892
|
+
}
|
|
2893
|
+
else {
|
|
2894
|
+
this.isRecording = false;
|
|
2895
|
+
}
|
|
2896
|
+
this.cdr.detectChanges();
|
|
2897
|
+
}
|
|
2898
|
+
else {
|
|
2899
|
+
// incoming call rejected or auto-cancelled
|
|
2900
|
+
this.isConcurrentIncoming = false;
|
|
2901
|
+
this.incomingCallDiv = false;
|
|
2902
|
+
// If there is NO active call, then propagate end. Otherwise keep ongoing UI.
|
|
2903
|
+
if (!this.call || this.call.status() !== 'open') {
|
|
2904
|
+
console.log('test7');
|
|
2905
|
+
this.endCallEvent.emit();
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
clearInputs() {
|
|
2910
|
+
this.callInput = this.callInput.slice(0, -1);
|
|
2911
|
+
}
|
|
2912
|
+
minimiseDialpad() {
|
|
2913
|
+
this.minimiseEvent.emit(true);
|
|
2914
|
+
this.isMinimised = true;
|
|
2915
|
+
}
|
|
2916
|
+
maximiseDialpad() {
|
|
2917
|
+
this.minimiseEvent.emit(false);
|
|
2918
|
+
this.isMinimised = false;
|
|
2919
|
+
}
|
|
2920
|
+
toggleRecording() {
|
|
2921
|
+
if (this.isRecording) {
|
|
2922
|
+
this.stopRecording();
|
|
2923
|
+
}
|
|
2924
|
+
else {
|
|
2925
|
+
this.startRecording();
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
startRecording() {
|
|
2929
|
+
var _a;
|
|
2930
|
+
let sid;
|
|
2931
|
+
const details = this.extensionService.getCallSid();
|
|
2932
|
+
this.incomingCallSid = details.callSid;
|
|
2933
|
+
this.incomingRecordCall = details.recordCall;
|
|
2934
|
+
sid = this.incomingCallSid ? this.incomingCallSid : this.callSid || ((_a = this.addRes) === null || _a === void 0 ? void 0 : _a.conferenceSid);
|
|
2935
|
+
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
2936
|
+
// return;
|
|
2937
|
+
// }
|
|
2938
|
+
this.extensionService.getCallRecording(sid).subscribe(response => {
|
|
2939
|
+
this.isRecording = true;
|
|
2940
|
+
this.isPaused = false;
|
|
2941
|
+
this.timeElapsed = 0;
|
|
2942
|
+
this.startTimer1();
|
|
2943
|
+
}, error => {
|
|
2944
|
+
console.error('Error starting recording', error);
|
|
2945
|
+
});
|
|
2946
|
+
}
|
|
2947
|
+
stopRecording() {
|
|
2948
|
+
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
2949
|
+
// return;
|
|
2950
|
+
// }
|
|
2951
|
+
this.isRecording = false;
|
|
2952
|
+
this.isPaused = false;
|
|
2953
|
+
if (this.timerSubscription) {
|
|
2954
|
+
this.timerSubscription.unsubscribe();
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
pauseRecording() {
|
|
2958
|
+
const details = this.extensionService.getCallSid();
|
|
2959
|
+
this.incomingCallSid = details.callSid;
|
|
2960
|
+
this.incomingRecordCall = details.recordCall;
|
|
2961
|
+
const sid = this.incomingCallSid ? this.incomingCallSid : this.callSid;
|
|
2962
|
+
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
2963
|
+
// return;
|
|
2964
|
+
// }
|
|
2965
|
+
this.extensionService.pauseOrResumeRecording(sid, 'pause').subscribe(response => {
|
|
2966
|
+
this.stopRecordingTimer();
|
|
2967
|
+
this.isPaused = true;
|
|
2968
|
+
}, (error) => {
|
|
2969
|
+
console.error('Error pausing recording:', error);
|
|
2970
|
+
// Consider updating the UI to show the error state
|
|
2971
|
+
});
|
|
2972
|
+
}
|
|
2973
|
+
resumeRecording() {
|
|
2974
|
+
let sid;
|
|
2975
|
+
const details = this.extensionService.getCallSid();
|
|
2976
|
+
this.incomingCallSid = details.callSid;
|
|
2977
|
+
this.incomingRecordCall = details.recordCall;
|
|
2978
|
+
sid = this.incomingCallSid ? this.incomingCallSid : this.callSid;
|
|
2979
|
+
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
2980
|
+
// return; // Skip if recording is not enabled
|
|
2981
|
+
// }
|
|
2982
|
+
this.extensionService.pauseOrResumeRecording(sid, 'resume').subscribe(response => {
|
|
2983
|
+
this.isPaused = false;
|
|
2984
|
+
this.startTimer1();
|
|
2985
|
+
}, error => {
|
|
2986
|
+
console.error('Error resuming recording', error);
|
|
2987
|
+
});
|
|
2988
|
+
}
|
|
2989
|
+
startTimer1() {
|
|
2990
|
+
this.timerSubscription = interval(1000).subscribe(() => {
|
|
2991
|
+
this.timeElapsed++;
|
|
2992
|
+
});
|
|
2993
|
+
}
|
|
2994
|
+
stopRecordingTimer() {
|
|
2995
|
+
if (this.timerSubscription) {
|
|
2996
|
+
this.timerSubscription.unsubscribe(); // Pause the timer
|
|
2997
|
+
this.timerSubscription = undefined; // Optionally reset the subscription
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
3000
|
+
getFormattedTime() {
|
|
3001
|
+
const minutes = Math.floor(this.timeElapsed / 60);
|
|
3002
|
+
const seconds = this.timeElapsed % 60;
|
|
3003
|
+
return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
|
|
3004
|
+
}
|
|
3005
|
+
pollCallStatus(callAuthId) {
|
|
3006
|
+
const maxTime = 30000; // Poll for up to 30 seconds
|
|
3007
|
+
const pollInterval = 3000; // Poll every 3 seconds
|
|
3008
|
+
let elapsedTime = 0;
|
|
3009
|
+
const intervalId = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
3010
|
+
elapsedTime += pollInterval;
|
|
3011
|
+
try {
|
|
3012
|
+
const statusResponse = yield this.extensionService.getCallStatus(callAuthId).toPromise();
|
|
3013
|
+
if (statusResponse && statusResponse.callDetails) {
|
|
3014
|
+
this.callStatus = statusResponse.callDetails.callStatus;
|
|
3015
|
+
if (this.callStatus === 'in-progress') {
|
|
3016
|
+
this.callSid = statusResponse.callDetails.callSid;
|
|
3017
|
+
if (this.recordCall && !this.isRecording) {
|
|
3018
|
+
this.startRecording();
|
|
3019
|
+
}
|
|
3020
|
+
clearInterval(intervalId);
|
|
3021
|
+
}
|
|
3022
|
+
else if (this.callStatus === 'completed') {
|
|
3023
|
+
clearInterval(intervalId);
|
|
3024
|
+
console.log('test1');
|
|
3025
|
+
this.endCall();
|
|
3026
|
+
this.stopRecording();
|
|
3027
|
+
}
|
|
3028
|
+
else if (this.callStatus === 'ringing') {
|
|
3029
|
+
// Continue polling; do not clear the interval yet
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
3032
|
+
}
|
|
3033
|
+
catch (error) {
|
|
3034
|
+
clearInterval(intervalId);
|
|
3035
|
+
}
|
|
3036
|
+
if (elapsedTime >= maxTime) {
|
|
3037
|
+
// console.log('Max polling time reached. Stopping poll.');
|
|
3038
|
+
clearInterval(intervalId);
|
|
3039
|
+
}
|
|
3040
|
+
}), pollInterval);
|
|
3041
|
+
}
|
|
3042
|
+
getUserInformation(id) {
|
|
3043
|
+
this.extensionService.getUserInformation(id).subscribe(response => {
|
|
3044
|
+
console.log(response);
|
|
3045
|
+
}, error => {
|
|
3046
|
+
console.error('Error starting recording', error);
|
|
3047
|
+
});
|
|
3048
|
+
}
|
|
3049
|
+
incomingCallsNewList(data) {
|
|
3050
|
+
console.log(data, 'newIncomingCallsListOUR');
|
|
3051
|
+
this.newIncomingCallsList = data;
|
|
3052
|
+
this.incomingCallsNewInfo.emit(this.newIncomingCallsList);
|
|
3053
|
+
}
|
|
3054
|
+
selectedIncomingCallInfo(data) {
|
|
3055
|
+
this.selectedIncomingCall = data;
|
|
3056
|
+
}
|
|
3057
|
+
ngOnDestroy() {
|
|
3058
|
+
this.callData.dial = false;
|
|
3059
|
+
if (this.timerSubscription) {
|
|
3060
|
+
this.timerSubscription.unsubscribe();
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
CallProgressComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CallProgressComponent, deps: [{ token: ExtensionService }, { token: i0.ChangeDetectorRef }, { token: TwilioService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3065
|
+
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", deviceId: "deviceId" }, outputs: { endCallEvent: "endCallEvent", incomingCallsNewInfo: "incomingCallsNewInfo", minimiseEvent: "minimiseEvent", incomingCallInitiated: "incomingCallInitiated" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"call-container\" *ngIf=\"!isMinimised\"\n [ngClass]=\"{'collops': isCollops, 'incoming-call-container': selectedIncomingCall?.isClickExpand, 'contacts-open': showContactsPanel }\">\n <!-- <div id=\"minimize-btn-div\">\n <span class=\"material-symbols-outlined minimize-btn\" (click)=\"minimiseDialpad()\">\n minimize\n </span>\n </div> -->\n <lib-incoming-call *ngIf=\"incomingCallDiv && !isConcurrentIncoming\" [incomingCallData]=\"callData\"\n [deviceId]=\"deviceId\" [newIncomingCallsList]=\"newIncomingCallsList\"\n (closeIncomingCallDiv)=\"closeIncomingCall($event)\" (incomingCallsNewList)=\"incomingCallsNewList($event)\"\n (selectedIncomingCallInfo)=\"selectedIncomingCallInfo($event)\"></lib-incoming-call>\n\n <ng-container *ngIf=\"!incomingCallDiv || isConcurrentIncoming\">\n <div class=\"held-call-banner\" *ngIf=\"isCallOnHold\">\n <ng-container *ngFor=\"let heldCall of currentCallList\">\n <div class=\"held-call-content\" *ngIf=\"heldCall?.isHold\">\n <div class=\"held-info\">\n <span class=\"material-symbols-outlined hold-icon\">pause_circle</span>\n <div class=\"held-caller\">\n <span class=\"held-label\">Hold</span>\n <span class=\"held-name\">{{heldCall?.name || 'Unknown number'}}</span>\n <span class=\"held-number\">{{heldCall?.phone || ''}}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <button class=\"held-btn swap-btn\" (click)=\"swapCalls(heldCall)\" title=\"Swap calls\">\n <span>Swap</span>\n </button>\n </div>\n </div>\n <div class=\"held-call-content\" *ngIf=\"heldCall?.isIncomingCall\">\n <div class=\"held-info\">\n <span class=\"material-symbols-outlined hold-icon\">phone_callback</span>\n <div class=\"held-caller\">\n <span class=\"held-label\">Incoming Call</span>\n <span class=\"held-name\">{{heldCall?.name || 'Unknown number'}}</span>\n <span class=\"held-number\">{{heldCall?.phone || ''}}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!heldCall?.isCallConnected\">\n <span class=\"material-symbols-outlined\" (click)=\"add(heldCall)\"> call </span>\n </button>\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!heldCall?.isCallConnected\">\n <span class=\"material-symbols-outlined\"> call_merge </span>\n </button>\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!heldCall?.isCallConnected\">\n <span class=\"material-symbols-outlined\"> swap_vert </span>\n </button>\n <button class=\"call-btn-wrapper reject-btn\">\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(heldCall)\"> call_end </span>\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Compact banners for concurrent incoming (one per call) -->\n <ng-container>\n <div class=\"incoming-banners-container\" *ngIf=\"!isConference\">\n <div class=\"incoming-banner\" *ngFor=\"let inc of newIncomingCallsList; let i = index\"\n [ngStyle]=\"{ top: ((isCallOnHold && heldCall) ? 64 : 0) + (i * 80) + 'px' }\">\n <div class=\"incoming-banner-content\">\n <div class=\"incoming-info\">\n <span class=\"incom ing-label\">Incoming call</span>\n <div class=\"incoming-caller\">\n <span class=\"caller-name\">{{ inc?.userInfo?.c2cInformation?.name ||\n inc?.customParameters?.get('name') || '-' }}</span>\n <span class=\"caller-number\">{{ inc?.userInfo?.c2cInformation?.number ||\n inc?.parameters?.From || '' }}</span>\n </div>\n </div>\n <div class=\"incoming-actions\">\n <button class=\"banner-btn accept-btn\" (click)=\"acceptConcurrentCall(inc)\">\n <span class=\"material-symbols-outlined\">call</span>\n </button>\n <button class=\"banner-btn reject-btn\" (click)=\"rejectConcurrentCall(inc)\">\n <span class=\"material-symbols-outlined\">call_end</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <div *ngIf=\"!isConference\" [ngStyle]=\"{'display': 'flex', 'flex-direction': 'column', 'position': 'relative'}\">\n\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\n <img class=\"avatar-img\" [src]=\"currentCall.img\" alt=\"\" width=\"120\" />\n </div>\n <div class=\"callerDetails\">\n <h1 [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall.name || 'Unknown number'}}</h1>\n <p>{{currentCall.displayNum ? currentCall.displayNum : currentCall.phone }}</p>\n <h4 style=\"margin-top: 4px\">{{timer}}</h4>\n </div>\n\n <div class=\"record-action-btns\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\">\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\"\n (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n <div *ngIf=\"showKeypad\" class=\"sendDigit\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\"\n (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\"\n (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : ' '}}</span>\n </div>\n </div>\n\n <div class=\"call-action-btns\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '110px'}\">\n <div class=\"mb-3\" *ngIf=\"!incomingCallDiv || isConcurrentIncoming\">\n <button class=\"held-btn merge-btn\" (click)=\"mergeCalls()\" title=\"Merge calls\"\n [disabled]=\"currentCallList.length < 2\">\n <span>Merge</span>\n </button>\n </div>\n <div class=\"flex align-items-center justify-content-evenly mb-3\">\n <button class=\"call-sec-btn mr-3\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleMute()\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> mic </span>\n\n </button>\n <button class=\"call-sec-btn mr-3\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\" (click)=\"toggleKeypad()\"> transition_dissolve </span>\n </button>\n <button class=\"call-sec-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleContactsPanel()\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n </div>\n\n <div>\n <button class=\"call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n\n\n <!-- <div class=\"contacts-panel\" *ngIf=\"showContactsPanel\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel()\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of contacts\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c.firstName}} {{c.middleName}} {{c.lastName}}</div>\n <div class=\"contact-title\">{{ (c.numbersList && c.numbersList[0]?.number)}}</div>\n </div>\n <button class=\"contact-call-btn\" (click)=\"callContact(c)\">\n <span class=\"material-symbols-outlined\"> call </span>\n <span class=\"label\">Call</span>\n </button>\n </div>\n </div>\n </div> -->\n\n\n <!-- <div class=\"mt-2 px-3 call-info-wrapper \" [ngClass]=\"{'open-collops': isCollops}\">\n <div class=\"text-center\" >\n <i class=\"fa fa-angle-down\" *ngIf=\"isCollops\" (click)=\"isCollops = !isCollops\"></i>\n <i class=\"fa fa-angle-up\" *ngIf=\"!isCollops\" (click)=\"isCollops = !isCollops\"></i>\n </div>\n <ng-container *ngIf=\"isCollops\">\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div >First Name:</div>\n <div >test ttttt</div>\n </div>\n <div class=\"col-6\">\n <div>Last Name:</div>\n <div>tetst test </div>\n </div>\n </div>\n <div class=\"mb-2\">\n <div class=\"\">Email:</div>\n <div class=\"\">abcdeft@vgroup.com</div>\n </div>\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div class=\"\">Number:</div>\n <div class=\"\">63545985264225</div>\n </div>\n <div class=\"col-6\">\n <div class=\"\">Language:</div>\n <div class=\"\">English</div>\n </div>\n </div>\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div class=\"\">Image :</div>\n <div class=\"\">test.jpg </div>\n </div>\n <div class=\"col-6\">\n <div class=\"\">Extension :</div>\n <div class=\"\">4596</div>\n </div>\n </div>\n <div class=\" mb-2\">\n <div class=\"\">Note :</div>\n <div class=\"\">tes test test </div>\n </div>\n <div class=\" mb-2\">\n <div class=\"\">\n <div class=\"\">Subject:</div>\n <div class=\"\">hello world | test</div>\n </div>\n </div>\n <div class=\" mb-4\">\n <div class=\"\">\n <div class=\"\">Message:</div>\n <div class=\"\">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>\n </div>\n </div>\n </ng-container>\n </div> -->\n </div>\n <div class=\"contacts-panel\" *ngIf=\"showContactsPanel\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel()\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of contacts\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c.firstName}} {{c.middleName}} {{c.lastName}}</div>\n <div class=\"contact-title\">{{ (c.numbersList && c.numbersList[0]?.number)}}</div>\n </div>\n <button class=\"contact-call-btn\" (click)=\"callContact(c)\">\n <span class=\"material-symbols-outlined\"> call </span>\n <span class=\"label\">Call</span>\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"conference-call-view\" *ngIf=\"isConference\">\n <div class=\"conf-heading\">\n <span class=\"conf-icon material-symbols-outlined\"> groups </span>\n <span class=\"conf-title\">Conference Call</span>\n </div>\n\n <div class=\"conf-name\">\n <!-- {{ (callData?.name || callData?.displayNum || callData?.phone || '-') }} &\n {{ (newIncomingCallsList?.[0]?.userInfo?.c2cInformation?.name\n || newIncomingCallsList?.[0]?.userInfo?.c2cInformation?.number\n || newIncomingCallsList?.[0]?.parameters?.From\n || heldCall?.customParameters?.get('displayNumber')\n || '-') }} -->\n {{currentCallList?.[0]?.name || 'Unknown number'}} & {{currentCallList?.[1]?.name || 'Unknown number'}}\n </div>\n <div class=\"conf-timer\">{{ timer }}</div>\n <!-- <div class=\"conf-record\">\n <button class=\"record-stop-btn\" *ngIf=\"isRecording\" (click)=\"toggleRecording()\" title=\"Stop Recording\">\n <span class=\"material-symbols-outlined\"> stop_circle </span>\n </button>\n </div> -->\n\n <div class=\"record-action-btns mt-auto\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\">\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\"\n (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n\n <div *ngIf=\"showKeypad\" class=\"sendDigit mt-2\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\"\n (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\"\n (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : ' '}}</span>\n </div>\n </div>\n\n <div class=\"conf-remove\" >\n <button class=\"remove-btn\" (click)=\"addRemoveParticipant()\">Remove</button>\n </div>\n\n <div class=\"conf-actions\">\n <button class=\"circle-btn\" [ngClass]=\"{'active': isMute}\" (click)=\"toggleMute()\"\n [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> {{ isMute ? 'mic_off' : 'mic' }} </span>\n </button>\n <button class=\"circle-btn\" (click)=\"toggleKeypad()\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> transition_dissolve </span>\n </button>\n <button class=\"circle-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleContactsPanel()\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n </div>\n\n <div class=\"conf-end\">\n <button class=\"circle-btn danger\" (click)=\"endCall(true)\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n\n\n <div class=\"contacts-panel\" *ngIf=\"isAddRemoveParticipant\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel(true)\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of allParticipentList\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c?.toName || 'Unknown'}}</div>\n <div class=\"contact-title\">{{ c?.to || 'Unknown'}}</div>\n </div>\n <button class=\"conference-hold-contact mr-2\" [ngClass]=\"{ 'on-hold': c.hold }\" (click)=\"onHoldCall(c)\">\n <span class=\"material-symbols-outlined\" title=\"Hold\"> phone_paused </span>\n <!-- <span class=\"label\">Hold</span> -->\n </button>\n <button class=\"conference-contact\" (click)=\"onEndCall(c)\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n <!-- <span class=\"label\">End</span> -->\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"wave-container\">\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\n <defs>\n <path id=\"gentle-wave\"\n d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\n </defs>\n <g class=\"parallax\">\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\n <!-- <use\n xlink:href=\"#gentle-wave\"\n x=\"48\"\n y=\"5\"\n fill=\"rgba(255,255,255,0.3)\"\n /> -->\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\n </g>\n </svg>\n </div>\n </ng-container>\n</div>\n\n<div class=\"min-call-container\" *ngIf=\"isMinimised\">\n <span class=\"material-symbols-outlined fullscreen\" (click)=\"maximiseDialpad()\"> open_in_full </span>\n <div style=\"display: flex; width: 100%\">\n <div>\n <div class=\"min-call-animation\" id=\"call-avatar\">\n <img class=\"min-avatar-img\" [src]=\"callData.img\" alt=\"\" />\n </div>\n </div>\n <div>\n <div class=\"min-callerDetails\">\n <div class=\"name\">\n {{callData.name}}\n </div>\n <p style=\"margin: 0\">{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\n </div>\n </div>\n </div>\n <div class=\"min-btn-container\">\n <div class=\"min-timer\">{{timer}}</div>\n <button class=\"min-call-sec-btn\" (click)=\"toggleMute()\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> mic </span>\n </button>\n <button class=\"min-call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n</div>", styles: [".call-container{width:385px;height:646px!important;margin:auto;border-radius:30px;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:100000;flex-flow:column}.collops{height:660px!important}.incoming-call-container{flex-flow:row!important;width:752px!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}.callerDetails h1{width:230px;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}.callerDetails p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-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}.receive-btn{background-color:#28a745;border:2px solid #28a745}.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;background:linear-gradient(135deg,#0f172a 0%,#1e293b 100%);padding:10px 16px;z-index:2100;box-shadow:0 4px 12px #0000004d;border-radius:0 0 16px 16px}.held-call-content{display:flex;align-items:center;justify-content:space-between;gap:12px}.held-info{display:flex;align-items:center;gap:10px;flex:1}.hold-icon{font-size:24px;color:#fbbf24}.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{display:flex;flex-direction:column;gap:8px;width:100%}.incoming-banner{position:absolute;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:0 0 16px 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:1000}.contacts-header{height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;border-bottom:1px solid #f0f0f0}.contacts-header .title{font-weight:600}.contacts-header .back,.contacts-header .search{color:#9aa0a6;cursor:pointer}.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:44px;height:44px;border-radius:50%;object-fit:cover;margin-right:12px}.contact-info{flex:1}.contact-name{font-weight:600;color:#111827}.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:6px 10px;cursor:pointer}.conference-hold-contact{display:inline-flex;align-items:center;gap:6px;background:#727070;color:#fff;border:none;border-radius:50%;padding:8px 9px;cursor:pointer}.conference-hold-contact.on-hold{background:#28a745!important;color:#fff}.conference-contact{display:inline-flex;align-items:center;gap:6px;background:#f80909;color:#fff;border:none;border-radius:50%;padding:8px 9px;cursor:pointer}.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:30px;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}.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}.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%}.conference-call-view{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;width:100%;padding:12px 16px 24px;color:#fff;height:100%}.conf-heading{display:flex;align-items:center;gap:8px;margin-top:8px}.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}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i4$1.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: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: IncomingCallComponent, selector: "lib-incoming-call", inputs: ["incomingCallData", "newIncomingCallsList", "deviceId"], outputs: ["closeIncomingCallDiv", "incomingCallsNewList", "selectedIncomingCallInfo"] }] });
|
|
3066
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CallProgressComponent, decorators: [{
|
|
3067
|
+
type: Component,
|
|
3068
|
+
args: [{ selector: 'lib-call-progress', template: "<div class=\"call-container\" *ngIf=\"!isMinimised\"\n [ngClass]=\"{'collops': isCollops, 'incoming-call-container': selectedIncomingCall?.isClickExpand, 'contacts-open': showContactsPanel }\">\n <!-- <div id=\"minimize-btn-div\">\n <span class=\"material-symbols-outlined minimize-btn\" (click)=\"minimiseDialpad()\">\n minimize\n </span>\n </div> -->\n <lib-incoming-call *ngIf=\"incomingCallDiv && !isConcurrentIncoming\" [incomingCallData]=\"callData\"\n [deviceId]=\"deviceId\" [newIncomingCallsList]=\"newIncomingCallsList\"\n (closeIncomingCallDiv)=\"closeIncomingCall($event)\" (incomingCallsNewList)=\"incomingCallsNewList($event)\"\n (selectedIncomingCallInfo)=\"selectedIncomingCallInfo($event)\"></lib-incoming-call>\n\n <ng-container *ngIf=\"!incomingCallDiv || isConcurrentIncoming\">\n <div class=\"held-call-banner\" *ngIf=\"isCallOnHold\">\n <ng-container *ngFor=\"let heldCall of currentCallList\">\n <div class=\"held-call-content\" *ngIf=\"heldCall?.isHold\">\n <div class=\"held-info\">\n <span class=\"material-symbols-outlined hold-icon\">pause_circle</span>\n <div class=\"held-caller\">\n <span class=\"held-label\">Hold</span>\n <span class=\"held-name\">{{heldCall?.name || 'Unknown number'}}</span>\n <span class=\"held-number\">{{heldCall?.phone || ''}}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <button class=\"held-btn swap-btn\" (click)=\"swapCalls(heldCall)\" title=\"Swap calls\">\n <span>Swap</span>\n </button>\n </div>\n </div>\n <div class=\"held-call-content\" *ngIf=\"heldCall?.isIncomingCall\">\n <div class=\"held-info\">\n <span class=\"material-symbols-outlined hold-icon\">phone_callback</span>\n <div class=\"held-caller\">\n <span class=\"held-label\">Incoming Call</span>\n <span class=\"held-name\">{{heldCall?.name || 'Unknown number'}}</span>\n <span class=\"held-number\">{{heldCall?.phone || ''}}</span>\n </div>\n </div>\n <div class=\"held-actions\">\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!heldCall?.isCallConnected\">\n <span class=\"material-symbols-outlined\" (click)=\"add(heldCall)\"> call </span>\n </button>\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!heldCall?.isCallConnected\">\n <span class=\"material-symbols-outlined\"> call_merge </span>\n </button>\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!heldCall?.isCallConnected\">\n <span class=\"material-symbols-outlined\"> swap_vert </span>\n </button>\n <button class=\"call-btn-wrapper reject-btn\">\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(heldCall)\"> call_end </span>\n </button>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Compact banners for concurrent incoming (one per call) -->\n <ng-container>\n <div class=\"incoming-banners-container\" *ngIf=\"!isConference\">\n <div class=\"incoming-banner\" *ngFor=\"let inc of newIncomingCallsList; let i = index\"\n [ngStyle]=\"{ top: ((isCallOnHold && heldCall) ? 64 : 0) + (i * 80) + 'px' }\">\n <div class=\"incoming-banner-content\">\n <div class=\"incoming-info\">\n <span class=\"incom ing-label\">Incoming call</span>\n <div class=\"incoming-caller\">\n <span class=\"caller-name\">{{ inc?.userInfo?.c2cInformation?.name ||\n inc?.customParameters?.get('name') || '-' }}</span>\n <span class=\"caller-number\">{{ inc?.userInfo?.c2cInformation?.number ||\n inc?.parameters?.From || '' }}</span>\n </div>\n </div>\n <div class=\"incoming-actions\">\n <button class=\"banner-btn accept-btn\" (click)=\"acceptConcurrentCall(inc)\">\n <span class=\"material-symbols-outlined\">call</span>\n </button>\n <button class=\"banner-btn reject-btn\" (click)=\"rejectConcurrentCall(inc)\">\n <span class=\"material-symbols-outlined\">call_end</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <div *ngIf=\"!isConference\" [ngStyle]=\"{'display': 'flex', 'flex-direction': 'column', 'position': 'relative'}\">\n\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\n <img class=\"avatar-img\" [src]=\"currentCall.img\" alt=\"\" width=\"120\" />\n </div>\n <div class=\"callerDetails\">\n <h1 [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{currentCall.name || 'Unknown number'}}</h1>\n <p>{{currentCall.displayNum ? currentCall.displayNum : currentCall.phone }}</p>\n <h4 style=\"margin-top: 4px\">{{timer}}</h4>\n </div>\n\n <div class=\"record-action-btns\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\">\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\"\n (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n <div *ngIf=\"showKeypad\" class=\"sendDigit\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\"\n (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\"\n (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : ' '}}</span>\n </div>\n </div>\n\n <div class=\"call-action-btns\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '110px'}\">\n <div class=\"mb-3\" *ngIf=\"!incomingCallDiv || isConcurrentIncoming\">\n <button class=\"held-btn merge-btn\" (click)=\"mergeCalls()\" title=\"Merge calls\"\n [disabled]=\"currentCallList.length < 2\">\n <span>Merge</span>\n </button>\n </div>\n <div class=\"flex align-items-center justify-content-evenly mb-3\">\n <button class=\"call-sec-btn mr-3\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleMute()\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> mic </span>\n\n </button>\n <button class=\"call-sec-btn mr-3\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\" (click)=\"toggleKeypad()\"> transition_dissolve </span>\n </button>\n <button class=\"call-sec-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleContactsPanel()\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n </div>\n\n <div>\n <button class=\"call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n\n\n <!-- <div class=\"contacts-panel\" *ngIf=\"showContactsPanel\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel()\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of contacts\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c.firstName}} {{c.middleName}} {{c.lastName}}</div>\n <div class=\"contact-title\">{{ (c.numbersList && c.numbersList[0]?.number)}}</div>\n </div>\n <button class=\"contact-call-btn\" (click)=\"callContact(c)\">\n <span class=\"material-symbols-outlined\"> call </span>\n <span class=\"label\">Call</span>\n </button>\n </div>\n </div>\n </div> -->\n\n\n <!-- <div class=\"mt-2 px-3 call-info-wrapper \" [ngClass]=\"{'open-collops': isCollops}\">\n <div class=\"text-center\" >\n <i class=\"fa fa-angle-down\" *ngIf=\"isCollops\" (click)=\"isCollops = !isCollops\"></i>\n <i class=\"fa fa-angle-up\" *ngIf=\"!isCollops\" (click)=\"isCollops = !isCollops\"></i>\n </div>\n <ng-container *ngIf=\"isCollops\">\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div >First Name:</div>\n <div >test ttttt</div>\n </div>\n <div class=\"col-6\">\n <div>Last Name:</div>\n <div>tetst test </div>\n </div>\n </div>\n <div class=\"mb-2\">\n <div class=\"\">Email:</div>\n <div class=\"\">abcdeft@vgroup.com</div>\n </div>\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div class=\"\">Number:</div>\n <div class=\"\">63545985264225</div>\n </div>\n <div class=\"col-6\">\n <div class=\"\">Language:</div>\n <div class=\"\">English</div>\n </div>\n </div>\n <div class=\"row mb-2\">\n <div class=\"col-6\">\n <div class=\"\">Image :</div>\n <div class=\"\">test.jpg </div>\n </div>\n <div class=\"col-6\">\n <div class=\"\">Extension :</div>\n <div class=\"\">4596</div>\n </div>\n </div>\n <div class=\" mb-2\">\n <div class=\"\">Note :</div>\n <div class=\"\">tes test test </div>\n </div>\n <div class=\" mb-2\">\n <div class=\"\">\n <div class=\"\">Subject:</div>\n <div class=\"\">hello world | test</div>\n </div>\n </div>\n <div class=\" mb-4\">\n <div class=\"\">\n <div class=\"\">Message:</div>\n <div class=\"\">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>\n </div>\n </div>\n </ng-container>\n </div> -->\n </div>\n <div class=\"contacts-panel\" *ngIf=\"showContactsPanel\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel()\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of contacts\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c.firstName}} {{c.middleName}} {{c.lastName}}</div>\n <div class=\"contact-title\">{{ (c.numbersList && c.numbersList[0]?.number)}}</div>\n </div>\n <button class=\"contact-call-btn\" (click)=\"callContact(c)\">\n <span class=\"material-symbols-outlined\"> call </span>\n <span class=\"label\">Call</span>\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"conference-call-view\" *ngIf=\"isConference\">\n <div class=\"conf-heading\">\n <span class=\"conf-icon material-symbols-outlined\"> groups </span>\n <span class=\"conf-title\">Conference Call</span>\n </div>\n\n <div class=\"conf-name\">\n <!-- {{ (callData?.name || callData?.displayNum || callData?.phone || '-') }} &\n {{ (newIncomingCallsList?.[0]?.userInfo?.c2cInformation?.name\n || newIncomingCallsList?.[0]?.userInfo?.c2cInformation?.number\n || newIncomingCallsList?.[0]?.parameters?.From\n || heldCall?.customParameters?.get('displayNumber')\n || '-') }} -->\n {{currentCallList?.[0]?.name || 'Unknown number'}} & {{currentCallList?.[1]?.name || 'Unknown number'}}\n </div>\n <div class=\"conf-timer\">{{ timer }}</div>\n <!-- <div class=\"conf-record\">\n <button class=\"record-stop-btn\" *ngIf=\"isRecording\" (click)=\"toggleRecording()\" title=\"Stop Recording\">\n <span class=\"material-symbols-outlined\"> stop_circle </span>\n </button>\n </div> -->\n\n <div class=\"record-action-btns mt-auto\" *ngIf=\"!showKeypad\" [ngStyle]=\"{'margin-top': showKeypad ? '0': '20px'}\">\n <div class=\"record-btn-container\">\n <button class=\"record-btn start-stop\" *ngIf=\"!isRecording\"\n [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording()\"\n [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"recording-icon\"></span>\n </button>\n <div class=\"pause-resume-btns\">\n <button class=\"record-btn pause-resume\" *ngIf=\"isRecording && !isPaused\"\n (click)=\"pauseRecording()\">\n <span class=\"material-symbols-outlined\"> pause </span>\n </button>\n <button class=\"record-btn pause-resume\" *ngIf=\"isPaused\" (click)=\"resumeRecording()\">\n <span class=\"material-symbols-outlined\"> play_arrow </span>\n </button>\n </div>\n </div>\n <div *ngIf=\"isRecording\" class=\"timer-display\">\n {{ getFormattedTime() }}\n </div>\n </div>\n\n <div *ngIf=\"showKeypad\" class=\"sendDigit mt-2\">\n <input type=\"text\" name=\"call-inputs\" id=\"call-input\" [(ngModel)]=\"callInput\"\n (keyup)=\"onCallInputEnter($event)\">\n <span class=\"material-symbols-outlined input-clear-btn\" *ngIf=\"callInput\"\n (click)=\"clearInputs()\">close_small</span>\n </div>\n <div class=\"btn-container justify-content-center\" *ngIf=\"showKeypad\">\n <div class=\"key-btn\" *ngFor=\"let key of keypadVal\" (click)=\"onCallInputs(key.num)\">\n {{key.num}}\n <span class=\"btn-albhabets\">{{key.text ? key.text : ' '}}</span>\n </div>\n </div>\n\n <div class=\"conf-remove\" >\n <button class=\"remove-btn\" (click)=\"addRemoveParticipant()\">Remove</button>\n </div>\n\n <div class=\"conf-actions\">\n <button class=\"circle-btn\" [ngClass]=\"{'active': isMute}\" (click)=\"toggleMute()\"\n [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> {{ isMute ? 'mic_off' : 'mic' }} </span>\n </button>\n <button class=\"circle-btn\" (click)=\"toggleKeypad()\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> transition_dissolve </span>\n </button>\n <button class=\"circle-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"toggleContactsPanel()\">\n <span class=\"material-symbols-outlined\"> add </span>\n </button>\n </div>\n\n <div class=\"conf-end\">\n <button class=\"circle-btn danger\" (click)=\"endCall(true)\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n </div>\n\n\n <div class=\"contacts-panel\" *ngIf=\"isAddRemoveParticipant\">\n <div class=\"contacts-header\">\n <span class=\"material-symbols-outlined back\" (click)=\"toggleContactsPanel(true)\"> chevron_left </span>\n <div class=\"title\">Contacts</div>\n <span class=\"material-symbols-outlined search\"> search </span>\n </div>\n <div class=\"contacts-list\">\n <div class=\"contact-item\" *ngFor=\"let c of allParticipentList\">\n <img class=\"contact-avatar\" [src]=\"c.img || 'assets/images/user.jpg'\" alt=\"\" />\n <div class=\"contact-info\">\n <div class=\"contact-name\">{{c?.toName || 'Unknown'}}</div>\n <div class=\"contact-title\">{{ c?.to || 'Unknown'}}</div>\n </div>\n <button class=\"conference-hold-contact mr-2\" [ngClass]=\"{ 'on-hold': c.hold }\" (click)=\"onHoldCall(c)\">\n <span class=\"material-symbols-outlined\" title=\"Hold\"> phone_paused </span>\n <!-- <span class=\"label\">Hold</span> -->\n </button>\n <button class=\"conference-contact\" (click)=\"onEndCall(c)\">\n <span class=\"material-symbols-outlined\" title=\"Call End\"> call_end </span>\n <!-- <span class=\"label\">End</span> -->\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"wave-container\">\n <svg class=\"waves\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n viewBox=\"0 24 150 28\" preserveAspectRatio=\"none\" shape-rendering=\"auto\">\n <defs>\n <path id=\"gentle-wave\"\n d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\n </defs>\n <g class=\"parallax\">\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" />\n <!-- <use\n xlink:href=\"#gentle-wave\"\n x=\"48\"\n y=\"5\"\n fill=\"rgba(255,255,255,0.3)\"\n /> -->\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\n </g>\n </svg>\n </div>\n </ng-container>\n</div>\n\n<div class=\"min-call-container\" *ngIf=\"isMinimised\">\n <span class=\"material-symbols-outlined fullscreen\" (click)=\"maximiseDialpad()\"> open_in_full </span>\n <div style=\"display: flex; width: 100%\">\n <div>\n <div class=\"min-call-animation\" id=\"call-avatar\">\n <img class=\"min-avatar-img\" [src]=\"callData.img\" alt=\"\" />\n </div>\n </div>\n <div>\n <div class=\"min-callerDetails\">\n <div class=\"name\">\n {{callData.name}}\n </div>\n <p style=\"margin: 0\">{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\n </div>\n </div>\n </div>\n <div class=\"min-btn-container\">\n <div class=\"min-timer\">{{timer}}</div>\n <button class=\"min-call-sec-btn\" (click)=\"toggleMute()\" [disabled]=\"disbaleEndCallBtn\">\n <span class=\"material-symbols-outlined\" *ngIf=\"isMute\"> mic_off </span>\n <span class=\"material-symbols-outlined\" *ngIf=\"!isMute\"> mic </span>\n </button>\n <button class=\"min-call-btn end-call-btn\" [disabled]=\"disbaleEndCallBtn\" (click)=\"endCall()\">\n <span class=\"material-symbols-outlined\"> call_end </span>\n </button>\n </div>\n</div>", styles: [".call-container{width:385px;height:646px!important;margin:auto;border-radius:30px;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:100000;flex-flow:column}.collops{height:660px!important}.incoming-call-container{flex-flow:row!important;width:752px!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}.callerDetails h1{width:230px;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}.callerDetails p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-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}.receive-btn{background-color:#28a745;border:2px solid #28a745}.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;background:linear-gradient(135deg,#0f172a 0%,#1e293b 100%);padding:10px 16px;z-index:2100;box-shadow:0 4px 12px #0000004d;border-radius:0 0 16px 16px}.held-call-content{display:flex;align-items:center;justify-content:space-between;gap:12px}.held-info{display:flex;align-items:center;gap:10px;flex:1}.hold-icon{font-size:24px;color:#fbbf24}.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{display:flex;flex-direction:column;gap:8px;width:100%}.incoming-banner{position:absolute;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:0 0 16px 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:1000}.contacts-header{height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;border-bottom:1px solid #f0f0f0}.contacts-header .title{font-weight:600}.contacts-header .back,.contacts-header .search{color:#9aa0a6;cursor:pointer}.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:44px;height:44px;border-radius:50%;object-fit:cover;margin-right:12px}.contact-info{flex:1}.contact-name{font-weight:600;color:#111827}.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:6px 10px;cursor:pointer}.conference-hold-contact{display:inline-flex;align-items:center;gap:6px;background:#727070;color:#fff;border:none;border-radius:50%;padding:8px 9px;cursor:pointer}.conference-hold-contact.on-hold{background:#28a745!important;color:#fff}.conference-contact{display:inline-flex;align-items:center;gap:6px;background:#f80909;color:#fff;border:none;border-radius:50%;padding:8px 9px;cursor:pointer}.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:30px;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}.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}.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%}.conference-call-view{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;width:100%;padding:12px 16px 24px;color:#fff;height:100%}.conf-heading{display:flex;align-items:center;gap:8px;margin-top:8px}.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}\n"] }]
|
|
3069
|
+
}], ctorParameters: function () { return [{ type: ExtensionService }, { type: i0.ChangeDetectorRef }, { type: TwilioService }]; }, propDecorators: { callData: [{
|
|
3070
|
+
type: Input
|
|
3071
|
+
}], selectedCallerId: [{
|
|
3072
|
+
type: Input
|
|
3073
|
+
}], newIncomingCallData: [{
|
|
3074
|
+
type: Input
|
|
3075
|
+
}], newIncomingCallsList: [{
|
|
3076
|
+
type: Input
|
|
3077
|
+
}], deviceId: [{
|
|
3078
|
+
type: Input
|
|
3079
|
+
}], endCallEvent: [{
|
|
3080
|
+
type: Output
|
|
3081
|
+
}], incomingCallsNewInfo: [{
|
|
3082
|
+
type: Output
|
|
3083
|
+
}], minimiseEvent: [{
|
|
3084
|
+
type: Output
|
|
3085
|
+
}], incomingCallInitiated: [{
|
|
3086
|
+
type: Output
|
|
3087
|
+
}] } });
|
|
3088
|
+
|
|
3089
|
+
class DialboxComponent {
|
|
3090
|
+
set isDialpadHidden(value) {
|
|
3091
|
+
this._isDialpadHidden = value;
|
|
3092
|
+
if (!value) {
|
|
3093
|
+
// When dialpad becomes visible, ensure Twilio is initialized
|
|
3094
|
+
this.initializeTwilio();
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
get isDialpadHidden() {
|
|
3098
|
+
return this._isDialpadHidden;
|
|
3099
|
+
}
|
|
3100
|
+
constructor(twilioService, extService, dialog, ipService, extensionService, cdk, router, incomeingCallSocketService) {
|
|
3101
|
+
this.twilioService = twilioService;
|
|
3102
|
+
this.extService = extService;
|
|
3103
|
+
this.dialog = dialog;
|
|
3104
|
+
this.ipService = ipService;
|
|
3105
|
+
this.extensionService = extensionService;
|
|
3106
|
+
this.cdk = cdk;
|
|
3107
|
+
this.router = router;
|
|
3108
|
+
this.incomeingCallSocketService = incomeingCallSocketService;
|
|
3109
|
+
this._isDialpadHidden = true;
|
|
3110
|
+
// Let the library decide to auto-open on incoming call without host wiring
|
|
3111
|
+
this.autoOpenOnIncoming = true;
|
|
3112
|
+
this.closeDialpadEvent = new EventEmitter();
|
|
3113
|
+
this.callInitiated = new EventEmitter();
|
|
3114
|
+
this.endCallEvent = new EventEmitter();
|
|
3115
|
+
this.minimiseEvent = new EventEmitter();
|
|
3116
|
+
this.incomingCallsNewInfoEvent = new EventEmitter();
|
|
3117
|
+
this.incomingCallInitiated = new EventEmitter();
|
|
3118
|
+
this.numberDialed = new EventEmitter();
|
|
3119
|
+
this.isCallInProgress = false;
|
|
3120
|
+
this.keypadVal = keypad;
|
|
3121
|
+
this.showInputClearBtn = false;
|
|
3122
|
+
this.dialedNumber = '';
|
|
3123
|
+
this.contactList = [];
|
|
3124
|
+
this.filteredContactList = [];
|
|
3125
|
+
this.callerIdList = [];
|
|
3126
|
+
this.isCallerIdHidden = true;
|
|
3127
|
+
this.isTrialPeriodOver = false;
|
|
3128
|
+
this.isPaymentDue = false;
|
|
3129
|
+
this.terminateCall = false;
|
|
3130
|
+
this.toastTimeout = 7000;
|
|
3131
|
+
this.callNumberToast = {
|
|
3132
|
+
show: false,
|
|
3133
|
+
type: 'alert-success',
|
|
3134
|
+
number: '',
|
|
3135
|
+
displayNum: ''
|
|
3136
|
+
};
|
|
3137
|
+
this.callData = {
|
|
3138
|
+
phone: '',
|
|
3139
|
+
displayNum: '',
|
|
3140
|
+
dial: false,
|
|
3141
|
+
name: '',
|
|
3142
|
+
img: 'assets/images/user.jpg',
|
|
3143
|
+
isIncomingCall: false,
|
|
3144
|
+
extNum: ''
|
|
3145
|
+
};
|
|
3146
|
+
this.lastDialed = null;
|
|
3147
|
+
this.dialAlert = {
|
|
3148
|
+
msg: '',
|
|
3149
|
+
show: false
|
|
3150
|
+
};
|
|
3151
|
+
this.showDedicatedPopup = false;
|
|
3152
|
+
this.newIncomingCalls = [];
|
|
3153
|
+
this.incomingCallsList = [];
|
|
3154
|
+
this.subscriptions = new Subscription();
|
|
3155
|
+
this.shakeDedicatedBtn = false;
|
|
3156
|
+
this.isSmartDialCall = false;
|
|
3157
|
+
this.isInitialized = false;
|
|
3158
|
+
this.isMinimised = false;
|
|
3159
|
+
// Initialize if dialpad is visible by default
|
|
3160
|
+
if (!this.isDialpadHidden) {
|
|
3161
|
+
console.log('sfsdfdsf');
|
|
3162
|
+
this.initializeTwilio();
|
|
3163
|
+
}
|
|
3164
|
+
console.log('DialboxComponent constructor');
|
|
3165
|
+
}
|
|
3166
|
+
initializeTwilio() {
|
|
3167
|
+
console.log('initializeTwilio');
|
|
3168
|
+
if (!this.isInitialized) {
|
|
3169
|
+
this.token = localStorage.getItem('ext_token') || '';
|
|
3170
|
+
if (!this.token) {
|
|
3171
|
+
console.error('No authentication token found');
|
|
3172
|
+
return;
|
|
3173
|
+
}
|
|
3174
|
+
this.isInitialized = true;
|
|
3175
|
+
// Initialize Twilio service
|
|
3176
|
+
this.twilioService.initializeTwilioDevice(this.deviceId);
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3179
|
+
// ngOnChange() {
|
|
3180
|
+
// this.initializeTwilio();
|
|
3181
|
+
// }
|
|
3182
|
+
// ngOnInit() {
|
|
3183
|
+
// try {
|
|
3184
|
+
// this.getContactList();
|
|
3185
|
+
// this.getUserCallSetting();
|
|
3186
|
+
// // Subscribe to dial number events
|
|
3187
|
+
// const sub1 = this.twilioService.dialNumberFromOtherModule.subscribe((contact: any) => {
|
|
3188
|
+
// if (contact.number) {
|
|
3189
|
+
// this.isSmartDialCall = false;
|
|
3190
|
+
// if (contact.isDialFromHistory) {
|
|
3191
|
+
// //handle dialing from history page
|
|
3192
|
+
// if(contact.callerId == 'smartDialing'){
|
|
3193
|
+
// this.selectedCallerId = { number: contact.from };
|
|
3194
|
+
// this.isSmartDialCall = true;
|
|
3195
|
+
// setTimeout(() => {
|
|
3196
|
+
// this.isDialpadHidden = false;
|
|
3197
|
+
// }, 2000);
|
|
3198
|
+
// this.callData.phone = contact.number;
|
|
3199
|
+
// this.callData.name = contact.name;
|
|
3200
|
+
// this.callData.img = contact.img;
|
|
3201
|
+
// this.callData.from = contact.from;
|
|
3202
|
+
// this.sanitizedNum = contact.number;
|
|
3203
|
+
// this.getUserInformation(contact);
|
|
3204
|
+
// // this.incomingCallsList.push(contact)
|
|
3205
|
+
// this.initiateCall();
|
|
3206
|
+
// }else{
|
|
3207
|
+
// this.getUserCallSetting();
|
|
3208
|
+
// setTimeout(() => {
|
|
3209
|
+
// this.isDialpadHidden = false;
|
|
3210
|
+
// }, 1000);
|
|
3211
|
+
// this.getUserInformation(contact);
|
|
3212
|
+
// // this.incomingCallsList.push(contact)
|
|
3213
|
+
// this.dialedNumber = contact.number;
|
|
3214
|
+
// this.sanitizedNum = contact.number;
|
|
3215
|
+
// }
|
|
3216
|
+
// } else {
|
|
3217
|
+
// if (contact.callerId == 'alwaysAsk' || contact.callerId == 'smartDialing') {
|
|
3218
|
+
// this.getUserCallSetting();
|
|
3219
|
+
// setTimeout(() => {
|
|
3220
|
+
// this.isDialpadHidden = false;
|
|
3221
|
+
// }, 1000);
|
|
3222
|
+
// this.dialedNumber = contact.number;
|
|
3223
|
+
// this.sanitizedNum = contact.number;
|
|
3224
|
+
// } else {
|
|
3225
|
+
// setTimeout(() => {
|
|
3226
|
+
// this.isDialpadHidden = false;
|
|
3227
|
+
// }, 2000);
|
|
3228
|
+
// this.callData.phone = contact.number;
|
|
2888
3229
|
// this.callData.name = contact.name;
|
|
2889
3230
|
// this.callData.img = contact.img;
|
|
2890
3231
|
// this.sanitizedNum = contact.number;
|
|
@@ -3684,703 +4025,370 @@ class DialboxComponent {
|
|
|
3684
4025
|
// // } else {
|
|
3685
4026
|
// // swal('Error', 'Trial period is over. Please setup payment method to continue services')
|
|
3686
4027
|
// // }
|
|
3687
|
-
// }catch(e){
|
|
3688
|
-
// console.error('Error in initiateCall:', e);
|
|
3689
|
-
// this.showDialAlert('Failed to initiate call. Please try again.');
|
|
3690
|
-
// this.isCallInProgress = false;
|
|
3691
|
-
// return false;
|
|
3692
|
-
// }
|
|
3693
|
-
// }
|
|
3694
|
-
initiateCall() {
|
|
3695
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3696
|
-
try {
|
|
3697
|
-
if (!this.dialedNumber && this.lastDialed) {
|
|
3698
|
-
this.sanitizedNum = this.lastDialed.number;
|
|
3699
|
-
}
|
|
3700
|
-
const isInvalid = yield this.isInvalidNumber();
|
|
3701
|
-
if (isInvalid) {
|
|
3702
|
-
return false;
|
|
3703
|
-
}
|
|
3704
|
-
this.saveLastDialed();
|
|
3705
|
-
this.isSavedContactDialled();
|
|
3706
|
-
this.isPaymentDue = localStorage.getItem('paymentDue') === 'false' ? false : true;
|
|
3707
|
-
if (this.isPaymentDue) {
|
|
3708
|
-
swal('Warning', 'Please note that your payment is due, To continue on your services kindly subscribe to use uninterrupted services.');
|
|
3709
|
-
return false;
|
|
3710
|
-
}
|
|
3711
|
-
this.isTrialPeriodOver = localStorage.getItem('trialOver') === 'false' ? false : true;
|
|
3712
|
-
if (this.sanitizedNum === localStorage.getItem('twilioNumber')) {
|
|
3713
|
-
swal('Error', 'You can not dial this number');
|
|
3714
|
-
return false;
|
|
3715
|
-
}
|
|
3716
|
-
const hasPermission = yield this.checkMicrophonePermission();
|
|
3717
|
-
if (!hasPermission) {
|
|
3718
|
-
yield this.askForMicrophonePermission();
|
|
3719
|
-
return false;
|
|
3720
|
-
}
|
|
3721
|
-
if (!this.selectedCallerId) {
|
|
3722
|
-
this.shakeDedicatedBtn = true;
|
|
3723
|
-
this.showDialAlert('Select a C2C number to call');
|
|
3724
|
-
setTimeout(() => {
|
|
3725
|
-
this.shakeDedicatedBtn = false;
|
|
3726
|
-
}, 3000);
|
|
3727
|
-
return false;
|
|
3728
|
-
}
|
|
3729
|
-
// Clear displayNum if value is bound from previous call
|
|
3730
|
-
this.callData.displayNum = '';
|
|
3731
|
-
// Get number to be dialed from backend
|
|
3732
|
-
yield this.getToNumber(this.sanitizedNum);
|
|
3733
|
-
if (this.terminateCall) {
|
|
3734
|
-
this.terminateCall = false;
|
|
3735
|
-
return;
|
|
3736
|
-
}
|
|
3737
|
-
// Update call data in a single operation
|
|
3738
|
-
this.callData = Object.assign(Object.assign({}, this.callData), { phone: this.sanitizedNum, isIncomingCall: false, dial: true, from: this.isSmartDialCall ? this.callData.from : this.selectedCallerId.number, timestamp: new Date().toISOString() });
|
|
3739
|
-
// console.log('Initiating call with data:', this.callData);
|
|
3740
|
-
console.log('dd10');
|
|
3741
|
-
this.isCallInProgress = true;
|
|
3742
|
-
this.callInitiated.emit(Object.assign({}, this.callData));
|
|
3743
|
-
return true;
|
|
3744
|
-
}
|
|
3745
|
-
catch (e) {
|
|
3746
|
-
// console.error('Error in initiateCall:', e);
|
|
3747
|
-
this.showDialAlert('Failed to initiate call. Please try again.');
|
|
3748
|
-
console.log('dd11');
|
|
3749
|
-
this.isCallInProgress = false;
|
|
3750
|
-
return false;
|
|
3751
|
-
}
|
|
3752
|
-
});
|
|
3753
|
-
}
|
|
3754
|
-
isInvalidNumber() {
|
|
3755
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3756
|
-
try {
|
|
3757
|
-
if (this.sanitizedNum == '') {
|
|
3758
|
-
this.showDialAlert('Invalid Number');
|
|
3759
|
-
return true;
|
|
3760
|
-
}
|
|
3761
|
-
const validNumberPattern = /^[+\d\s()-]*$/; // Regular expression to match valid characters
|
|
3762
|
-
const phoneNumber = this.sanitizedNum;
|
|
3763
|
-
if (!validNumberPattern.test(phoneNumber)) {
|
|
3764
|
-
this.showDialAlert('Invalid Number');
|
|
3765
|
-
return true;
|
|
3766
|
-
}
|
|
3767
|
-
return false;
|
|
3768
|
-
}
|
|
3769
|
-
catch (error) {
|
|
3770
|
-
this.showDialAlert('Invalid Number');
|
|
3771
|
-
return true; // Return true if an error occurred, meaning the number is invalid
|
|
3772
|
-
}
|
|
3773
|
-
});
|
|
3774
|
-
}
|
|
3775
|
-
saveLastDialed() {
|
|
3776
|
-
const contact = this.filteredContactList.find((c) => c.numbersList.some((n) => n.number === this.dialedNumber));
|
|
3777
|
-
if (contact) {
|
|
3778
|
-
this.lastDialed = {
|
|
3779
|
-
name: contact.name,
|
|
3780
|
-
image: contact.image,
|
|
3781
|
-
number: this.dialedNumber
|
|
3782
|
-
};
|
|
3783
|
-
}
|
|
3784
|
-
else {
|
|
3785
|
-
if (this.dialedNumber) {
|
|
3786
|
-
this.lastDialed = { number: this.dialedNumber };
|
|
3787
|
-
}
|
|
3788
|
-
}
|
|
3789
|
-
}
|
|
3790
|
-
isSavedContactDialled() {
|
|
3791
|
-
let phoneNum = this.sanitizedNum.replace(/\s+/g, '');
|
|
3792
|
-
let contact = this.contactList.filter((contact) => {
|
|
3793
|
-
return contact.numbersList.some((num) => num.number === phoneNum);
|
|
3794
|
-
});
|
|
3795
|
-
if (contact.length) {
|
|
3796
|
-
this.callData.name = `${contact[0].firstName} ${contact[0].middleName} ${contact[0].lastName}`.toLowerCase();
|
|
3797
|
-
this.callData.img = contact[0].image || 'assets/images/user.jpg';
|
|
3798
|
-
this.callData.phone = this.sanitizedNum;
|
|
3799
|
-
return true;
|
|
3800
|
-
}
|
|
3801
|
-
return false;
|
|
3802
|
-
}
|
|
3803
|
-
showDialAlert(message) {
|
|
3804
|
-
this.dialAlert = {
|
|
3805
|
-
msg: message,
|
|
3806
|
-
show: true
|
|
3807
|
-
};
|
|
3808
|
-
setTimeout(() => {
|
|
3809
|
-
this.dialAlert.show = false;
|
|
3810
|
-
}, 3000);
|
|
3811
|
-
}
|
|
3812
|
-
isCallerIdSet() {
|
|
3813
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3814
|
-
try {
|
|
3815
|
-
const tkn = localStorage.getItem('ext_token');
|
|
3816
|
-
const res = yield this.extService.fetchCallerId(tkn || '').toPromise();
|
|
3817
|
-
if (res.status == 200) {
|
|
3818
|
-
localStorage.setItem('trialOver', res.trialOver);
|
|
3819
|
-
this.twilioService.isTrialOver.next(res.trialOver);
|
|
3820
|
-
localStorage.setItem('paymentDue', res.paymentDue);
|
|
3821
|
-
this.twilioService.isPaymentDue.next(res.paymentDue);
|
|
3822
|
-
}
|
|
3823
|
-
if (res.callerid) {
|
|
3824
|
-
localStorage.setItem('callerID', res.callerid);
|
|
3825
|
-
this.extService.changeMessage(res.callerid);
|
|
3826
|
-
}
|
|
3827
|
-
else {
|
|
3828
|
-
localStorage.setItem('callerID', 'Not set');
|
|
3829
|
-
this.extService.changeMessage('Not set');
|
|
3830
|
-
}
|
|
3831
|
-
return (localStorage.getItem('callerID') !== 'Not set');
|
|
3832
|
-
}
|
|
3833
|
-
catch (e) {
|
|
3834
|
-
console.log(e);
|
|
3835
|
-
return false;
|
|
3836
|
-
}
|
|
3837
|
-
});
|
|
3838
|
-
}
|
|
3839
|
-
checkMicrophonePermission() {
|
|
3840
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3841
|
-
try {
|
|
3842
|
-
const stream = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
3843
|
-
stream.getTracks().forEach(track => track.stop());
|
|
3844
|
-
return true;
|
|
3845
|
-
}
|
|
3846
|
-
catch (error) {
|
|
3847
|
-
if (error.name === 'NotAllowedError') {
|
|
3848
|
-
return false;
|
|
3849
|
-
}
|
|
3850
|
-
else {
|
|
3851
|
-
return false;
|
|
3852
|
-
}
|
|
3853
|
-
}
|
|
3854
|
-
});
|
|
3855
|
-
}
|
|
3856
|
-
askForMicrophonePermission() {
|
|
3857
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3858
|
-
try {
|
|
3859
|
-
const stream = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
3860
|
-
stream.getTracks().forEach(track => track.stop());
|
|
3861
|
-
}
|
|
3862
|
-
catch (error) {
|
|
3863
|
-
console.error('User denied microphone permission:', error);
|
|
3864
|
-
}
|
|
3865
|
-
});
|
|
3866
|
-
}
|
|
3867
|
-
// below function is to get the country code with number from server
|
|
3868
|
-
getToNumber(dialedNumber) {
|
|
4028
|
+
// }catch(e){
|
|
4029
|
+
// console.error('Error in initiateCall:', e);
|
|
4030
|
+
// this.showDialAlert('Failed to initiate call. Please try again.');
|
|
4031
|
+
// this.isCallInProgress = false;
|
|
4032
|
+
// return false;
|
|
4033
|
+
// }
|
|
4034
|
+
// }
|
|
4035
|
+
initiateCall() {
|
|
3869
4036
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
const res = yield this.twilioService.getToNumber(dialedNumber, ipAddress.address.countryCode).toPromise();
|
|
3874
|
-
if (res.status == 200) {
|
|
3875
|
-
this.toastTimeout = res.timeInterval * 1000;
|
|
3876
|
-
yield this.showNumberToast(res);
|
|
4037
|
+
try {
|
|
4038
|
+
if (!this.dialedNumber && this.lastDialed) {
|
|
4039
|
+
this.sanitizedNum = this.lastDialed.number;
|
|
3877
4040
|
}
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
isAlertEnable() {
|
|
3882
|
-
return localStorage.getItem('isAlertEnable');
|
|
3883
|
-
}
|
|
3884
|
-
showNumberToast(data) {
|
|
3885
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3886
|
-
const isAlertOn = (localStorage.getItem('isCountryCodeToastOn'));
|
|
3887
|
-
if (isAlertOn == 'true') {
|
|
3888
|
-
this.callNumberToast.show = true;
|
|
3889
|
-
this.callNumberToast.number = data.toNumber;
|
|
3890
|
-
this.callNumberToast.displayNum = data.displayNumber;
|
|
3891
|
-
}
|
|
3892
|
-
this.callData.displayNum = data.displayNumber;
|
|
3893
|
-
//this.callData.phone = data.toNumber;
|
|
3894
|
-
yield this.delay(this.toastTimeout);
|
|
3895
|
-
this.dialedNumber = data.toNumber;
|
|
3896
|
-
this.sanitizedNum = data.toNumber;
|
|
3897
|
-
this.callNumberToast.show = false;
|
|
3898
|
-
this.callNumberToast.number = '';
|
|
3899
|
-
this.callNumberToast.displayNum = '';
|
|
3900
|
-
});
|
|
3901
|
-
}
|
|
3902
|
-
delay(ms) {
|
|
3903
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
3904
|
-
}
|
|
3905
|
-
onMinimise(isMinimised) {
|
|
3906
|
-
this.isMinimised = isMinimised;
|
|
3907
|
-
this.minimiseEvent.emit(isMinimised);
|
|
3908
|
-
}
|
|
3909
|
-
handleNumberPaste(event) {
|
|
3910
|
-
event.preventDefault();
|
|
3911
|
-
const clipboardData = event.clipboardData || window.clipboardData;
|
|
3912
|
-
const pastedData = clipboardData.getData('text');
|
|
3913
|
-
// Log the pasted content to the console
|
|
3914
|
-
if (pastedData) {
|
|
3915
|
-
this.dialedNumber = pastedData;
|
|
3916
|
-
this.sanitizedNum = pastedData;
|
|
3917
|
-
}
|
|
3918
|
-
}
|
|
3919
|
-
onEnter(num) {
|
|
3920
|
-
// console.log(num, 'number fn')
|
|
3921
|
-
this.dialedNumber = this.dialedNumber + num;
|
|
3922
|
-
this.sanitizedNum = this.dialedNumber;
|
|
3923
|
-
this.showInputClearBtn = true;
|
|
3924
|
-
this.numberDialed.emit(this.dialedNumber);
|
|
3925
|
-
}
|
|
3926
|
-
getUserCallSetting() {
|
|
3927
|
-
const tkn = localStorage.getItem('ext_token');
|
|
3928
|
-
this.extService.fetchCallerId(tkn || '').subscribe((resp) => {
|
|
3929
|
-
if (resp.status == 200) {
|
|
3930
|
-
//this.callPrefernce = resp.userSetting;
|
|
3931
|
-
this.callPreference = resp.callerid;
|
|
3932
|
-
this.getCallerIdList();
|
|
3933
|
-
}
|
|
3934
|
-
});
|
|
3935
|
-
}
|
|
3936
|
-
onDedicatedNumSelect(id) {
|
|
3937
|
-
this.selectedCallerId = id;
|
|
3938
|
-
this.isCallerIdHidden = true;
|
|
3939
|
-
this.extService.setCallerId(id);
|
|
3940
|
-
}
|
|
3941
|
-
cancelDialNumber() {
|
|
3942
|
-
this.terminateCall = true;
|
|
3943
|
-
this.callNumberToast.show = false;
|
|
3944
|
-
}
|
|
3945
|
-
handleDivKeydown(ev) {
|
|
3946
|
-
if (this.dialedNumber.length == 0) {
|
|
3947
|
-
this.dialInputElement.nativeElement.focus();
|
|
3948
|
-
}
|
|
3949
|
-
if (ev.key === 'Enter') {
|
|
3950
|
-
// Check if the dialpad is open
|
|
3951
|
-
if (!this.isDialpadHidden) {
|
|
3952
|
-
if (this.dialedNumber.length > 2 && this.selectedCallerId) {
|
|
3953
|
-
this.initiateCall();
|
|
4041
|
+
const isInvalid = yield this.isInvalidNumber();
|
|
4042
|
+
if (isInvalid) {
|
|
4043
|
+
return false;
|
|
3954
4044
|
}
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
4045
|
+
this.saveLastDialed();
|
|
4046
|
+
this.isSavedContactDialled();
|
|
4047
|
+
this.isPaymentDue = localStorage.getItem('paymentDue') === 'false' ? false : true;
|
|
4048
|
+
if (this.isPaymentDue) {
|
|
4049
|
+
swal('Warning', 'Please note that your payment is due, To continue on your services kindly subscribe to use uninterrupted services.');
|
|
4050
|
+
return false;
|
|
3960
4051
|
}
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
if (!this.selectedCallerId || (this.selectedCallerId == 'alwaysAsk') || (this.selectedCallerId == 'smartDialing')) {
|
|
3966
|
-
this.shakeDedicatedBtn = true;
|
|
3967
|
-
}
|
|
3968
|
-
}
|
|
3969
|
-
onCallBtnMouseLeave(ev) {
|
|
3970
|
-
if (!this.selectedCallerId || (this.selectedCallerId == 'alwaysAsk') || (this.selectedCallerId == 'smartDialing')) {
|
|
3971
|
-
this.shakeDedicatedBtn = false;
|
|
3972
|
-
}
|
|
3973
|
-
}
|
|
3974
|
-
acceptNewIncomingCall(call) {
|
|
3975
|
-
//first cut the current call
|
|
3976
|
-
//this.callData = call;
|
|
3977
|
-
this.newIncomingCallData = call;
|
|
3978
|
-
}
|
|
3979
|
-
rejectNewIncomingCall(call) {
|
|
3980
|
-
call.reject();
|
|
3981
|
-
this.newIncomingCalls = this.newIncomingCalls.filter((item) => item.parameters.CallSid !== call.parameters['CallSid']);
|
|
3982
|
-
this.incomingCallsList = this.incomingCallsList.filter((item) => item.parameters.CallSid !== call.parameters['CallSid']);
|
|
3983
|
-
}
|
|
3984
|
-
newIncomingCallInitiated() {
|
|
3985
|
-
console.log('dd12');
|
|
3986
|
-
this.isCallInProgress = true;
|
|
3987
|
-
this.newIncomingCalls = [];
|
|
3988
|
-
this.incomingCallInitiated.emit();
|
|
3989
|
-
}
|
|
3990
|
-
incomingCallsNewInfo(data) {
|
|
3991
|
-
this.incomingCallsList = data;
|
|
3992
|
-
this.incomingCallsNewInfoEvent.emit(data);
|
|
3993
|
-
}
|
|
3994
|
-
ngOnDestroy() {
|
|
3995
|
-
try {
|
|
3996
|
-
console.log('Cleaning up C2cDialpadComponent');
|
|
3997
|
-
// Unsubscribe from all subscriptions
|
|
3998
|
-
if (this.subscriptions) {
|
|
3999
|
-
this.subscriptions.unsubscribe();
|
|
4000
|
-
}
|
|
4001
|
-
// Clean up Twilio device when component is destroyed
|
|
4002
|
-
if (this.twilioService['device']) {
|
|
4003
|
-
this.twilioService['device'].destroy();
|
|
4004
|
-
}
|
|
4005
|
-
// End any active call
|
|
4006
|
-
if (this.isCallInProgress) {
|
|
4007
|
-
this.endCall();
|
|
4008
|
-
}
|
|
4009
|
-
// Clear any timeouts or intervals if they exist
|
|
4010
|
-
if (this.toastTimeout) {
|
|
4011
|
-
clearTimeout(this.toastTimeout);
|
|
4012
|
-
}
|
|
4013
|
-
console.log('C2cDialpadComponent cleanup complete');
|
|
4014
|
-
}
|
|
4015
|
-
catch (error) {
|
|
4016
|
-
console.error('Error during component cleanup:', error);
|
|
4017
|
-
}
|
|
4018
|
-
}
|
|
4019
|
-
}
|
|
4020
|
-
DialboxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DialboxComponent, deps: [{ token: TwilioService }, { token: ExtensionService }, { token: i3$1.MatDialog }, { token: IpAddressService }, { token: ExtensionService }, { token: i0.ChangeDetectorRef }, { token: i5.Router }, { token: IncomeingCallSocketService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4021
|
-
DialboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DialboxComponent, selector: "lib-dialbox", inputs: { autoOpenOnIncoming: "autoOpenOnIncoming", contactInfo: "contactInfo", deviceId: "deviceId", isDialpadHidden: "isDialpadHidden", incomingCallData: "incomingCallData" }, outputs: { closeDialpadEvent: "closeDialpadEvent", callInitiated: "callInitiated", endCallEvent: "endCallEvent", minimiseEvent: "minimiseEvent", incomingCallsNewInfoEvent: "incomingCallsNewInfoEvent", incomingCallInitiated: "incomingCallInitiated", numberDialed: "numberDialed" }, viewQueries: [{ propertyName: "dialInputElement", first: true, predicate: ["dialInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"dragparent1\" [ngStyle]=\"{'display':isDialpadHidden ? 'none': 'block'}\">\r\n <lib-call-progress *ngIf=\"isCallInProgress\"\r\n (endCallEvent)=\"endCall()\"\r\n (minimiseEvent)=\"onMinimise($event)\"\r\n (incomingCallInitiated)=\"newIncomingCallInitiated()\"\r\n [newIncomingCallData]=\"newIncomingCallData\"\r\n [deviceId]=\"deviceId\"\r\n [newIncomingCallsList]=\"incomingCallsList\"\r\n (incomingCallsNewInfo)=\"incomingCallsNewInfo($event)\"\r\n [selectedCallerId]=\"selectedCallerId\"\r\n [callData]=\"callData\">\r\n </lib-call-progress>\r\n <div class=\"dialpad-container\" *ngIf=\"!isCallInProgress\" [ngClass]=\"{'mini-dialpad': isMinimised}\" tabindex=\"0\" (keydown)=\"handleDivKeydown($event)\">\r\n <div id=\"topPanel\" [ngStyle]=\"{'height': callerIdList.length ? '40%' : '39%'}\">\r\n <div class=\"dialpad-alerts\" *ngIf=\"dialAlert.show\">\r\n <div class=\"no-selection-alert\">\r\n <!-- <p class=\"mb-0\">Select C2C number to call</p> -->\r\n <p class=\"mb-0\">{{dialAlert.msg}}</p>\r\n <span class=\"fa fa-times\" (click)=\"shakeDedicatedBtn = false\"></span>\r\n </div>\r\n </div>\r\n <div class=\"dialpad-alerts\" *ngIf=\"callNumberToast.show\">\r\n <div class=\"dialbox-pop1 alert fade show\" [ngClass]=\"callNumberToast.type\" role=\"alert\">\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"flex-grow-1 my-auto text-left\">\r\n You'r calling <strong>{{callNumberToast.displayNum}}</strong>\r\n </div>\r\n <div class=\"text-right\">\r\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelDialNumber()\">Cancel Call</button>\r\n <!-- <button class=\"btn btn-link btn-success btn-disc p-0 px-2\">Continue</button> -->\r\n </div>\r\n \r\n </div>\r\n </div>\r\n </div>\r\n <div style=\"padding: 0 18px\" (paste)=\"handleNumberPaste($event)\">\r\n <div class=\"d-flex justify-content-between mt-2\">\r\n <p></p>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"hideDialpad()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"#ffffff\"><path 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\"/></svg>\r\n </span>\r\n </div>\r\n <div class=\"input-box\">\r\n <input type=\"text\" #dialInput placeholder=\"Enter a name or number\" tabindex=\"1\" [(ngModel)]=\"dialedNumber\" (ngModelChange)=\"onDialInputChange($event)\"/>\r\n <span class=\"\" id=\"input-clear-btn\" (click)=\"clearInput()\" *ngIf=\"showInputClearBtn\">\r\n <svg width=\"50px\" height=\"30px\" viewBox=\"0 10 40 60\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" baseProfile=\"full\" enable-background=\"new 0 0 76.00 76.00\" xml:space=\"preserve\">\r\n <path fill=\"#5d6061\" fill-opacity=\"1\" stroke-width=\"0.2\" stroke-linejoin=\"round\" d=\"M 47.5282,42.9497L 42.5784,38L 47.5282,33.0502L 44.9497,30.4718L 40,35.4216L 35.0502,30.4718L 32.4718,33.0502L 37.4216,38L 32.4718,42.9497L 35.0502,45.5282L 40,40.5784L 44.9497,45.5282L 47.5282,42.9497 Z M 18.0147,41.5355L 26.9646,50.4854C 28.0683,51.589 29,52 31,52L 52,52C 54.7614,52 57,49.7614 57,47L 57,29C 57,26.2386 54.7614,24 52,24L 31,24C 29,24 28.0683,24.4113 26.9646,25.5149L 18.0147,34.4645C 16.0621,36.4171 16.0621,39.5829 18.0147,41.5355 Z M 31,49C 30,49 29.6048,48.8828 29.086,48.3641L 20.1361,39.4142C 19.355,38.6332 19.355,37.3669 20.1361,36.5858L 29.086,27.6362C 29.6048,27.1175 30,27 31,27.0001L 52,27.0001C 53.1046,27.0001 54,27.8955 54,29.0001L 54,47.0001C 54,48.1046 53.1046,49.0001 52,49.0001L 31,49 Z \"/>\r\n </svg> \r\n </span>\r\n <span class=\"input-info-icon\" placement=\"bottom-right\" tooltipClass=\"input-tooltip\" ngbTooltip=\"For extension dialing, use formats like +12345678910 x123,+12345678910 ext.123, +12345678910,123\"><i class=\"fa fa-info-circle\"></i></span>\r\n </div>\r\n <div class=\"guide\" *ngIf=\"callerIdList.length && !(dialedNumber.length > 2)\">\r\n <span class=\"guidetext\">Please enter a number or select a saved contact</span>\r\n </div>\r\n <!-- <div class=\"input-error\" *ngIf=\"dialAlert.show\">\r\n <span>{{dialAlert.msg}}</span>\r\n </div> -->\r\n <div>\r\n <div class=\"contact-card\" *ngFor=\"let contact of filteredContactList\" (click)=\"onContactSelect(contact)\">\r\n <div class=\"contact-img\">\r\n <img [src]=\"contact.image\" alt=\"user image\" loading=\"lazy\" *ngIf=\"contact.image else alphaName\"/>\r\n <ng-template #alphaName>\r\n <span class=\"contact-alpha-img\">{{getFirstLetter(contact.firstName)}}</span>\r\n </ng-template>\r\n </div>\r\n <div class=\"contact-details\">\r\n <p style=\"margin-bottom: 4px\" class=\"contact-name\">{{getFullName(contact) }}</p>\r\n <p>{{contact.numbersList[0].number}}</p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"wave-container\">\r\n <svg\r\n class=\"waves\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 24 150 28\"\r\n preserveAspectRatio=\"none\"\r\n shape-rendering=\"auto\"\r\n >\r\n <defs>\r\n <path\r\n 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 />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"0\"\r\n fill=\"rgba(255,255,255,0.7)\"\r\n />\r\n <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"3\"\r\n fill=\"rgba(255,255,255,0.5)\"\r\n />\r\n <!-- <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"5\"\r\n fill=\"rgba(255,255,255,0.3)\"\r\n /> -->\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n </div>\r\n <div class=\"btn-container\" *ngIf=\"!isMinimised\">\r\n <button class=\"dial-btn\" *ngFor=\"let key of keypadVal;let i = index\"\r\n (keydown.enter)=\"onEnter(key.num)\" (click)=\"addNumber(key.num)\"\r\n [ngStyle]=\"{'margin-top': key.text === '+' ? '3px' : '0'}\"\r\n [tabindex]=\"dialedNumber.length ? '0': i+2\" longPress (longPress)=\"addNumber(key.text)\" shortPress (shortPress)=\"addNumber(key.num)\">\r\n {{key.num}} \r\n <span *ngIf=\"key.num == 1;else otherThanOne\" class=\"material-symbols-outlined voicemail\">\r\n voicemail\r\n </span>\r\n <ng-template #otherThanOne>\r\n <span class=\"btn-albhabets\" [ngClass]=\"{'plusSign': key.text === '+'}\">{{key.text ? key.text : ' '}}</span>\r\n </ng-template>\r\n </button>\r\n </div>\r\n <div class=\"call-btn-container\" *ngIf=\"!isMinimised\" (mouseenter)=\"onCallBtnMouseEnter($event)\" (mouseleave)=\"onCallBtnMouseLeave($event)\">\r\n <div class=\"call-btn\" (click)=\"initiateCall()\" [tabindex]=\"dialedNumber.length ? '2': '15'\"\r\n [ngStyle]=\"{'pointer-events': dialedNumber.length && selectedCallerId ? 'auto' : 'none', 'opacity': dialedNumber.length && selectedCallerId ? '1' : '0.5'}\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call\r\n </span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"callerIdList.length && !isMinimised\" class=\"position-relative\">\r\n <div class=\"shownCallerId\" *ngIf=\"selectedCallerId; else askBlock\" (click)=\"toggleCallerIdDiv()\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + selectedCallerId?.isoCode?.toLowerCase()\"></span>\r\n {{selectedCallerId?.number}}\r\n </div>\r\n </div>\r\n <ng-template #askBlock>\r\n <div class=\"shownCallerId\" (click)=\"toggleCallerIdDiv()\" [ngClass]=\"{ 'tilt-shaking': shakeDedicatedBtn }\">\r\n <div class=\"d-flex justify-content-center\">\r\n <h5 class=\"mb-0\">Select C2C number</h5>\r\n <!-- <span class=\"ml-2\" style=\"opacity:.8;margin-top:2px\">\r\n <img src=\"assets/images/icon_down_arrow.svg\" alt=\"down\" width=\"10px\">\r\n </span> -->\r\n <span class=\"fa fa-angle-down ml-2 text-blue\" style=\"margin-top:2px\"></span>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <div class=\"guide2\" *ngIf=\"shakeDedicatedBtn\">\r\n <span class=\"guidetext\">Please select a number from below dropdown</span>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"callerIdList.length; else noCallerIdMessage\">\r\n <div class=\"caller-id-list-container\" *ngIf=\"callerIdList.length && !isMinimised\" id=\"callerIdContainer\" [ngClass]=\"{'visible': !isCallerIdHidden}\" >\r\n <div style=\"display: flex; justify-content: space-between\">\r\n <!-- <h4>Select C2C Softphone Number</h4> -->\r\n <h4>Make outgoing call using</h4>\r\n <span\r\n class=\"material-symbols-outlined\"\r\n style=\"cursor: pointer\"\r\n (click)=\"isCallerIdHidden = true\"\r\n >\r\n close\r\n </span>\r\n </div>\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\" (click)=\"onDedicatedNumSelect(callerId)\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n <ng-template #noCallerIdMessage>\r\n <span class=\"no-caller-id-message\">To make any voice calls, please <a routerLink=\"/extension/dedicatednumber/{{token}}\" class=\"click-here-link\" title=\"Settings > C2C Number\">subscribe</a> to a voice capable C2C Number.\r\n </span>\r\n </ng-template>\r\n <div class=\"dedicated-overlay\" *ngIf=\"showDedicatedPopup\">\r\n <div class=\"card dedicatedNumPopup\">\r\n <div class=\"card-header chooseDedicatedHeader\">\r\n <h5>Choose C2C Number</h5>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDedicatedPopup = false\">close</span>\r\n </div>\r\n <div class=\"card-body dedicatedNumList\">\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\" (click)=\"showDedicatedPopup = false\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- <div class=\"incoming-call-widget\" *ngFor=\"let call of newIncomingCalls;let i = index\" [ngStyle]=\"{'top': (30 + i * 72) + 'px'}\">\r\n <div>\r\n <div class=\"inc-user-img\">\r\n <img src=\"assets/images/user.jpg\" alt=\"user image\">\r\n </div>\r\n \r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <p class=\"inc-user-name\">{{call.customParameters.get('name')}}</p>\r\n <p>{{call.parameters.From}}</p>\r\n </div>\r\n <div class=\"d-flex\">\r\n <button class=\"inc-call-btn inc-accept-btn mr-2\" (click)=\"acceptNewIncomingCall(call)\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call\r\n </span>\r\n </button>\r\n <button class=\"inc-call-btn inc-reject-btn\" (click)=\"rejectNewIncomingCall(call)\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call_end\r\n </span>\r\n </button>\r\n </div>\r\n \r\n </div> -->\r\n </div>\r\n</div>\r\n", styles: ["#dragparent1{position:fixed;left:100px;z-index:9999999;font-family:Lato,sans-serif;display:none}.dialpad-container{width:320px!important;height:600px!important;background:white;margin:auto;border-radius:30px;box-shadow:#00000040 0 54px 55px,#0000001f 0 -12px 30px,#0000001f 0 4px 6px,#0000002b 0 12px 13px,#00000017 0 -3px 5px;display:flex;flex-direction:column;box-sizing:border-box;position:relative;line-height:1.1}.dialpad-alerts{position:absolute;width:calc(100% - 28px);left:14px;top:8px;z-index:1200}.btn-disc{font-size:12px}.dialbox-pop1{font-size:.8rem;z-index:9;padding:8px}.input-error>span{color:#dfdfdf;margin-bottom:2px}.dial-close-btn{cursor:pointer;opacity:.6}.dial-close-btn:hover{opacity:1}.btn-container{display:flex;flex-wrap:wrap;padding:0 18px}.dial-btn{width:50px;height:50px;background-color:#fff;border-radius:4px;text-align:center;box-sizing:border-box;margin:4px 22px;font-size:28px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#2b434d;cursor:pointer;opacity:.8;border:none}.dial-btn:hover{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:focus{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:active{box-shadow:#32325d40 0 30px 60px -12px inset,#0000004d 0 18px 36px -18px inset}.call-btn-container{display:flex;margin-top:8px;justify-content:center;position:relative}.call-btn{display:flex;align-items:center;justify-content:center;width:54px;height:54px;border-radius:27px;background-color:#2ecc71;outline:none;border:none;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;opacity:.8;cursor:pointer}.call-btn:hover{opacity:1}.call-btn:focus{opacity:1}.caller-id-list-container{width:100%;height:auto;position:absolute;bottom:-100%;left:0;border-radius:0 0 30px 30px/0px 0px 30px 30px;padding:8px 12px 32px;box-sizing:border-box;color:#8a8a8a}.visible{animation:slideUp .8s forwards}#callerIdContainer ul{list-style:none;padding-left:0;margin:0}.dialpad-container h4{font-family:Lato,sans-serif;margin:0 0 8px}#callerIdContainer ul li{background-color:#fff;padding:8px;margin-top:7px;display:flex;border-radius:4px;justify-content:space-between;font-size:14px;cursor:pointer}.fi{border-radius:2px;margin-right:2px}@keyframes slideUp{0%{bottom:-100%}to{bottom:0}}.selectedCallerIdClass{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;border:1px solid #e0e0e0;color:#3a3a3a}.toggleBtn{color:gray;border:none;background-color:#e5eef1}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.plusSign{font-weight:600;font-size:14px}.shownCallerId{text-align:center;padding:8px 10px;font-family:Lato,sans-serif;color:#2ecc71;border:1px solid #d7d7d7;background-color:#fff;width:80%;margin:12px auto auto;border-radius:12px;position:relative;cursor:pointer}.input-box{width:100%;background-color:#fff;padding:4px 10px;border:1px solid rgb(197,197,197);box-sizing:border-box;border-radius:24px;margin-top:12px;display:flex;justify-content:space-between}.input-box:focus-within{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026}.input-box input{font-size:18px;padding:8px 6px;width:100%;box-sizing:border-box;border:none;outline:none;font-weight:600;color:#2b434d}.input-box input::placeholder{font-size:16px;font-weight:500}#input-clear-btn{color:gray;display:flex;align-items:center;cursor:pointer}.contact-card{width:100%;height:54px;display:flex;border-radius:12px;overflow:hidden;margin-top:4px;box-shadow:6px 6px 10px -1px #e6eefc26;cursor:pointer;opacity:0;transform:translateY(20px);animation:slideIn .5s forwards}@keyframes slideIn{to{opacity:1;transform:translateY(0)}}.contact-img{width:50px;display:flex;align-items:center;justify-content:center;border-right:1px solid #bebebe;background-color:#fff}.contact-img img{max-width:50px}.contact-alpha-img{width:50px;display:flex;justify-content:center;align-items:center;font-size:38px;font-weight:600}.contact-details{padding:4px 8px;display:flex;flex-direction:column;justify-content:center}.contact-details p{margin:0;line-height:1;color:#fff}.contact-name{font-weight:600}#topPanel{height:39%;position:relative;margin-bottom:4px;padding:0;border-top-right-radius:30px;border-top-left-radius:30px}.wave-container{position:absolute;bottom:2px}.waves{width:320px;position:relative;margin-bottom:-7px;height:31px;min-height:31px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}app-call-progress{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1000}.mini-dialpad{height:124px!important}.voicemail{line-height:.7;font-size:18px}.dedicated-overlay{position:absolute;width:100%;height:100%;background-color:#2b434d99;display:flex;align-items:center;justify-content:center}.dedicatedNumPopup{width:90%;height:auto;box-sizing:border-box;color:#8a8a8a;background-color:#cbe7df}.chooseDedicatedHeader{padding:.75rem;display:flex;justify-content:space-between}.chooseDedicatedHeader h5{margin-bottom:0}.dedicatedNumList>ul{list-style-type:none;padding:0}.dedicatedNumList>ul li{background-color:#fff;padding:4px;cursor:pointer}@keyframes tilt-shaking{0%{transform:rotate(0)}25%{transform:rotate(5deg)}50%{transform:rotate(0)}75%{transform:rotate(-5deg)}to{transform:rotate(0)}}.tilt-shaking{background-color:#d45858;animation:tilt-shaking .5s infinite;color:#fff}.tilt-shaking h5,.dark .tilt-shaking span,.tilt-shaking span{color:#fff}.no-caller-id-message{display:inline-block;text-align:center;height:10vh;background-color:#fff3cd;color:#000;font-size:.9rem;line-height:1.5;padding:8px}.click-here-link{color:#0f9aee;text-decoration:underline;font-weight:700}.input-info-icon{margin-top:9px;cursor:pointer;color:#2b434d;opacity:.7}::ng-deep .input-tooltip .tooltip-inner{background-color:#000!important}.no-selection-alert{padding:3px 11px;border:1px solid;border-radius:4px;display:flex;justify-content:space-between;color:#721c24;background-color:#f8d7da;border-color:#f5c6cb;align-items:center}.guide{position:relative;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px}.guide:before{content:\"\";position:absolute;top:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid #303030}.guide2{position:absolute;top:-32px;left:24px;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px;pointer-events:none}.guide2:before{content:\"\";position:absolute;bottom:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #303030}.incoming-call-widget{position:absolute;right:-320px;top:30px;width:320px;height:68px;background-color:#3052cd;border-top-right-radius:8px;border-bottom-right-radius:8px;display:flex;align-items:center;padding:4px 12px}.incoming-call-widget h6,.incoming-call-widget p{margin-bottom:0;line-height:1.2;color:#fff}.inc-user-img{width:48px;height:48px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;box-sizing:border-box;margin-right:8px}.inc-user-img img{width:100%}.inc-call-btn{width:40px;height:40px;border-radius:50%;outline:none;border-width:0;display:flex;align-items:center;justify-content:center}.inc-call-btn span{font-size:16px}.inc-accept-btn{background-color:#2ecc71;color:#fff}.inc-reject-btn{background-color:#e14e4e;color:#fff}.inc-user-name{font-weight:600}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i4.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: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: CallProgressComponent, selector: "lib-call-progress", inputs: ["callData", "selectedCallerId", "newIncomingCallData", "newIncomingCallsList", "deviceId"], outputs: ["endCallEvent", "incomingCallsNewInfo", "minimiseEvent", "incomingCallInitiated"] }] });
|
|
4022
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DialboxComponent, decorators: [{
|
|
4023
|
-
type: Component,
|
|
4024
|
-
args: [{ selector: 'lib-dialbox', template: "<div id=\"dragparent1\" [ngStyle]=\"{'display':isDialpadHidden ? 'none': 'block'}\">\r\n <lib-call-progress *ngIf=\"isCallInProgress\"\r\n (endCallEvent)=\"endCall()\"\r\n (minimiseEvent)=\"onMinimise($event)\"\r\n (incomingCallInitiated)=\"newIncomingCallInitiated()\"\r\n [newIncomingCallData]=\"newIncomingCallData\"\r\n [deviceId]=\"deviceId\"\r\n [newIncomingCallsList]=\"incomingCallsList\"\r\n (incomingCallsNewInfo)=\"incomingCallsNewInfo($event)\"\r\n [selectedCallerId]=\"selectedCallerId\"\r\n [callData]=\"callData\">\r\n </lib-call-progress>\r\n <div class=\"dialpad-container\" *ngIf=\"!isCallInProgress\" [ngClass]=\"{'mini-dialpad': isMinimised}\" tabindex=\"0\" (keydown)=\"handleDivKeydown($event)\">\r\n <div id=\"topPanel\" [ngStyle]=\"{'height': callerIdList.length ? '40%' : '39%'}\">\r\n <div class=\"dialpad-alerts\" *ngIf=\"dialAlert.show\">\r\n <div class=\"no-selection-alert\">\r\n <!-- <p class=\"mb-0\">Select C2C number to call</p> -->\r\n <p class=\"mb-0\">{{dialAlert.msg}}</p>\r\n <span class=\"fa fa-times\" (click)=\"shakeDedicatedBtn = false\"></span>\r\n </div>\r\n </div>\r\n <div class=\"dialpad-alerts\" *ngIf=\"callNumberToast.show\">\r\n <div class=\"dialbox-pop1 alert fade show\" [ngClass]=\"callNumberToast.type\" role=\"alert\">\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"flex-grow-1 my-auto text-left\">\r\n You'r calling <strong>{{callNumberToast.displayNum}}</strong>\r\n </div>\r\n <div class=\"text-right\">\r\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelDialNumber()\">Cancel Call</button>\r\n <!-- <button class=\"btn btn-link btn-success btn-disc p-0 px-2\">Continue</button> -->\r\n </div>\r\n \r\n </div>\r\n </div>\r\n </div>\r\n <div style=\"padding: 0 18px\" (paste)=\"handleNumberPaste($event)\">\r\n <div class=\"d-flex justify-content-between mt-2\">\r\n <p></p>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"hideDialpad()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"#ffffff\"><path 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\"/></svg>\r\n </span>\r\n </div>\r\n <div class=\"input-box\">\r\n <input type=\"text\" #dialInput placeholder=\"Enter a name or number\" tabindex=\"1\" [(ngModel)]=\"dialedNumber\" (ngModelChange)=\"onDialInputChange($event)\"/>\r\n <span class=\"\" id=\"input-clear-btn\" (click)=\"clearInput()\" *ngIf=\"showInputClearBtn\">\r\n <svg width=\"50px\" height=\"30px\" viewBox=\"0 10 40 60\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" baseProfile=\"full\" enable-background=\"new 0 0 76.00 76.00\" xml:space=\"preserve\">\r\n <path fill=\"#5d6061\" fill-opacity=\"1\" stroke-width=\"0.2\" stroke-linejoin=\"round\" d=\"M 47.5282,42.9497L 42.5784,38L 47.5282,33.0502L 44.9497,30.4718L 40,35.4216L 35.0502,30.4718L 32.4718,33.0502L 37.4216,38L 32.4718,42.9497L 35.0502,45.5282L 40,40.5784L 44.9497,45.5282L 47.5282,42.9497 Z M 18.0147,41.5355L 26.9646,50.4854C 28.0683,51.589 29,52 31,52L 52,52C 54.7614,52 57,49.7614 57,47L 57,29C 57,26.2386 54.7614,24 52,24L 31,24C 29,24 28.0683,24.4113 26.9646,25.5149L 18.0147,34.4645C 16.0621,36.4171 16.0621,39.5829 18.0147,41.5355 Z M 31,49C 30,49 29.6048,48.8828 29.086,48.3641L 20.1361,39.4142C 19.355,38.6332 19.355,37.3669 20.1361,36.5858L 29.086,27.6362C 29.6048,27.1175 30,27 31,27.0001L 52,27.0001C 53.1046,27.0001 54,27.8955 54,29.0001L 54,47.0001C 54,48.1046 53.1046,49.0001 52,49.0001L 31,49 Z \"/>\r\n </svg> \r\n </span>\r\n <span class=\"input-info-icon\" placement=\"bottom-right\" tooltipClass=\"input-tooltip\" ngbTooltip=\"For extension dialing, use formats like +12345678910 x123,+12345678910 ext.123, +12345678910,123\"><i class=\"fa fa-info-circle\"></i></span>\r\n </div>\r\n <div class=\"guide\" *ngIf=\"callerIdList.length && !(dialedNumber.length > 2)\">\r\n <span class=\"guidetext\">Please enter a number or select a saved contact</span>\r\n </div>\r\n <!-- <div class=\"input-error\" *ngIf=\"dialAlert.show\">\r\n <span>{{dialAlert.msg}}</span>\r\n </div> -->\r\n <div>\r\n <div class=\"contact-card\" *ngFor=\"let contact of filteredContactList\" (click)=\"onContactSelect(contact)\">\r\n <div class=\"contact-img\">\r\n <img [src]=\"contact.image\" alt=\"user image\" loading=\"lazy\" *ngIf=\"contact.image else alphaName\"/>\r\n <ng-template #alphaName>\r\n <span class=\"contact-alpha-img\">{{getFirstLetter(contact.firstName)}}</span>\r\n </ng-template>\r\n </div>\r\n <div class=\"contact-details\">\r\n <p style=\"margin-bottom: 4px\" class=\"contact-name\">{{getFullName(contact) }}</p>\r\n <p>{{contact.numbersList[0].number}}</p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"wave-container\">\r\n <svg\r\n class=\"waves\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 24 150 28\"\r\n preserveAspectRatio=\"none\"\r\n shape-rendering=\"auto\"\r\n >\r\n <defs>\r\n <path\r\n 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 />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"0\"\r\n fill=\"rgba(255,255,255,0.7)\"\r\n />\r\n <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"3\"\r\n fill=\"rgba(255,255,255,0.5)\"\r\n />\r\n <!-- <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"5\"\r\n fill=\"rgba(255,255,255,0.3)\"\r\n /> -->\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n </div>\r\n <div class=\"btn-container\" *ngIf=\"!isMinimised\">\r\n <button class=\"dial-btn\" *ngFor=\"let key of keypadVal;let i = index\"\r\n (keydown.enter)=\"onEnter(key.num)\" (click)=\"addNumber(key.num)\"\r\n [ngStyle]=\"{'margin-top': key.text === '+' ? '3px' : '0'}\"\r\n [tabindex]=\"dialedNumber.length ? '0': i+2\" longPress (longPress)=\"addNumber(key.text)\" shortPress (shortPress)=\"addNumber(key.num)\">\r\n {{key.num}} \r\n <span *ngIf=\"key.num == 1;else otherThanOne\" class=\"material-symbols-outlined voicemail\">\r\n voicemail\r\n </span>\r\n <ng-template #otherThanOne>\r\n <span class=\"btn-albhabets\" [ngClass]=\"{'plusSign': key.text === '+'}\">{{key.text ? key.text : ' '}}</span>\r\n </ng-template>\r\n </button>\r\n </div>\r\n <div class=\"call-btn-container\" *ngIf=\"!isMinimised\" (mouseenter)=\"onCallBtnMouseEnter($event)\" (mouseleave)=\"onCallBtnMouseLeave($event)\">\r\n <div class=\"call-btn\" (click)=\"initiateCall()\" [tabindex]=\"dialedNumber.length ? '2': '15'\"\r\n [ngStyle]=\"{'pointer-events': dialedNumber.length && selectedCallerId ? 'auto' : 'none', 'opacity': dialedNumber.length && selectedCallerId ? '1' : '0.5'}\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call\r\n </span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"callerIdList.length && !isMinimised\" class=\"position-relative\">\r\n <div class=\"shownCallerId\" *ngIf=\"selectedCallerId; else askBlock\" (click)=\"toggleCallerIdDiv()\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + selectedCallerId?.isoCode?.toLowerCase()\"></span>\r\n {{selectedCallerId?.number}}\r\n </div>\r\n </div>\r\n <ng-template #askBlock>\r\n <div class=\"shownCallerId\" (click)=\"toggleCallerIdDiv()\" [ngClass]=\"{ 'tilt-shaking': shakeDedicatedBtn }\">\r\n <div class=\"d-flex justify-content-center\">\r\n <h5 class=\"mb-0\">Select C2C number</h5>\r\n <!-- <span class=\"ml-2\" style=\"opacity:.8;margin-top:2px\">\r\n <img src=\"assets/images/icon_down_arrow.svg\" alt=\"down\" width=\"10px\">\r\n </span> -->\r\n <span class=\"fa fa-angle-down ml-2 text-blue\" style=\"margin-top:2px\"></span>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <div class=\"guide2\" *ngIf=\"shakeDedicatedBtn\">\r\n <span class=\"guidetext\">Please select a number from below dropdown</span>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"callerIdList.length; else noCallerIdMessage\">\r\n <div class=\"caller-id-list-container\" *ngIf=\"callerIdList.length && !isMinimised\" id=\"callerIdContainer\" [ngClass]=\"{'visible': !isCallerIdHidden}\" >\r\n <div style=\"display: flex; justify-content: space-between\">\r\n <!-- <h4>Select C2C Softphone Number</h4> -->\r\n <h4>Make outgoing call using</h4>\r\n <span\r\n class=\"material-symbols-outlined\"\r\n style=\"cursor: pointer\"\r\n (click)=\"isCallerIdHidden = true\"\r\n >\r\n close\r\n </span>\r\n </div>\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\" (click)=\"onDedicatedNumSelect(callerId)\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n <ng-template #noCallerIdMessage>\r\n <span class=\"no-caller-id-message\">To make any voice calls, please <a routerLink=\"/extension/dedicatednumber/{{token}}\" class=\"click-here-link\" title=\"Settings > C2C Number\">subscribe</a> to a voice capable C2C Number.\r\n </span>\r\n </ng-template>\r\n <div class=\"dedicated-overlay\" *ngIf=\"showDedicatedPopup\">\r\n <div class=\"card dedicatedNumPopup\">\r\n <div class=\"card-header chooseDedicatedHeader\">\r\n <h5>Choose C2C Number</h5>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDedicatedPopup = false\">close</span>\r\n </div>\r\n <div class=\"card-body dedicatedNumList\">\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\" (click)=\"showDedicatedPopup = false\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- <div class=\"incoming-call-widget\" *ngFor=\"let call of newIncomingCalls;let i = index\" [ngStyle]=\"{'top': (30 + i * 72) + 'px'}\">\r\n <div>\r\n <div class=\"inc-user-img\">\r\n <img src=\"assets/images/user.jpg\" alt=\"user image\">\r\n </div>\r\n \r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <p class=\"inc-user-name\">{{call.customParameters.get('name')}}</p>\r\n <p>{{call.parameters.From}}</p>\r\n </div>\r\n <div class=\"d-flex\">\r\n <button class=\"inc-call-btn inc-accept-btn mr-2\" (click)=\"acceptNewIncomingCall(call)\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call\r\n </span>\r\n </button>\r\n <button class=\"inc-call-btn inc-reject-btn\" (click)=\"rejectNewIncomingCall(call)\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call_end\r\n </span>\r\n </button>\r\n </div>\r\n \r\n </div> -->\r\n </div>\r\n</div>\r\n", styles: ["#dragparent1{position:fixed;left:100px;z-index:9999999;font-family:Lato,sans-serif;display:none}.dialpad-container{width:320px!important;height:600px!important;background:white;margin:auto;border-radius:30px;box-shadow:#00000040 0 54px 55px,#0000001f 0 -12px 30px,#0000001f 0 4px 6px,#0000002b 0 12px 13px,#00000017 0 -3px 5px;display:flex;flex-direction:column;box-sizing:border-box;position:relative;line-height:1.1}.dialpad-alerts{position:absolute;width:calc(100% - 28px);left:14px;top:8px;z-index:1200}.btn-disc{font-size:12px}.dialbox-pop1{font-size:.8rem;z-index:9;padding:8px}.input-error>span{color:#dfdfdf;margin-bottom:2px}.dial-close-btn{cursor:pointer;opacity:.6}.dial-close-btn:hover{opacity:1}.btn-container{display:flex;flex-wrap:wrap;padding:0 18px}.dial-btn{width:50px;height:50px;background-color:#fff;border-radius:4px;text-align:center;box-sizing:border-box;margin:4px 22px;font-size:28px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#2b434d;cursor:pointer;opacity:.8;border:none}.dial-btn:hover{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:focus{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:active{box-shadow:#32325d40 0 30px 60px -12px inset,#0000004d 0 18px 36px -18px inset}.call-btn-container{display:flex;margin-top:8px;justify-content:center;position:relative}.call-btn{display:flex;align-items:center;justify-content:center;width:54px;height:54px;border-radius:27px;background-color:#2ecc71;outline:none;border:none;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;opacity:.8;cursor:pointer}.call-btn:hover{opacity:1}.call-btn:focus{opacity:1}.caller-id-list-container{width:100%;height:auto;position:absolute;bottom:-100%;left:0;border-radius:0 0 30px 30px/0px 0px 30px 30px;padding:8px 12px 32px;box-sizing:border-box;color:#8a8a8a}.visible{animation:slideUp .8s forwards}#callerIdContainer ul{list-style:none;padding-left:0;margin:0}.dialpad-container h4{font-family:Lato,sans-serif;margin:0 0 8px}#callerIdContainer ul li{background-color:#fff;padding:8px;margin-top:7px;display:flex;border-radius:4px;justify-content:space-between;font-size:14px;cursor:pointer}.fi{border-radius:2px;margin-right:2px}@keyframes slideUp{0%{bottom:-100%}to{bottom:0}}.selectedCallerIdClass{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;border:1px solid #e0e0e0;color:#3a3a3a}.toggleBtn{color:gray;border:none;background-color:#e5eef1}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.plusSign{font-weight:600;font-size:14px}.shownCallerId{text-align:center;padding:8px 10px;font-family:Lato,sans-serif;color:#2ecc71;border:1px solid #d7d7d7;background-color:#fff;width:80%;margin:12px auto auto;border-radius:12px;position:relative;cursor:pointer}.input-box{width:100%;background-color:#fff;padding:4px 10px;border:1px solid rgb(197,197,197);box-sizing:border-box;border-radius:24px;margin-top:12px;display:flex;justify-content:space-between}.input-box:focus-within{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026}.input-box input{font-size:18px;padding:8px 6px;width:100%;box-sizing:border-box;border:none;outline:none;font-weight:600;color:#2b434d}.input-box input::placeholder{font-size:16px;font-weight:500}#input-clear-btn{color:gray;display:flex;align-items:center;cursor:pointer}.contact-card{width:100%;height:54px;display:flex;border-radius:12px;overflow:hidden;margin-top:4px;box-shadow:6px 6px 10px -1px #e6eefc26;cursor:pointer;opacity:0;transform:translateY(20px);animation:slideIn .5s forwards}@keyframes slideIn{to{opacity:1;transform:translateY(0)}}.contact-img{width:50px;display:flex;align-items:center;justify-content:center;border-right:1px solid #bebebe;background-color:#fff}.contact-img img{max-width:50px}.contact-alpha-img{width:50px;display:flex;justify-content:center;align-items:center;font-size:38px;font-weight:600}.contact-details{padding:4px 8px;display:flex;flex-direction:column;justify-content:center}.contact-details p{margin:0;line-height:1;color:#fff}.contact-name{font-weight:600}#topPanel{height:39%;position:relative;margin-bottom:4px;padding:0;border-top-right-radius:30px;border-top-left-radius:30px}.wave-container{position:absolute;bottom:2px}.waves{width:320px;position:relative;margin-bottom:-7px;height:31px;min-height:31px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}app-call-progress{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1000}.mini-dialpad{height:124px!important}.voicemail{line-height:.7;font-size:18px}.dedicated-overlay{position:absolute;width:100%;height:100%;background-color:#2b434d99;display:flex;align-items:center;justify-content:center}.dedicatedNumPopup{width:90%;height:auto;box-sizing:border-box;color:#8a8a8a;background-color:#cbe7df}.chooseDedicatedHeader{padding:.75rem;display:flex;justify-content:space-between}.chooseDedicatedHeader h5{margin-bottom:0}.dedicatedNumList>ul{list-style-type:none;padding:0}.dedicatedNumList>ul li{background-color:#fff;padding:4px;cursor:pointer}@keyframes tilt-shaking{0%{transform:rotate(0)}25%{transform:rotate(5deg)}50%{transform:rotate(0)}75%{transform:rotate(-5deg)}to{transform:rotate(0)}}.tilt-shaking{background-color:#d45858;animation:tilt-shaking .5s infinite;color:#fff}.tilt-shaking h5,.dark .tilt-shaking span,.tilt-shaking span{color:#fff}.no-caller-id-message{display:inline-block;text-align:center;height:10vh;background-color:#fff3cd;color:#000;font-size:.9rem;line-height:1.5;padding:8px}.click-here-link{color:#0f9aee;text-decoration:underline;font-weight:700}.input-info-icon{margin-top:9px;cursor:pointer;color:#2b434d;opacity:.7}::ng-deep .input-tooltip .tooltip-inner{background-color:#000!important}.no-selection-alert{padding:3px 11px;border:1px solid;border-radius:4px;display:flex;justify-content:space-between;color:#721c24;background-color:#f8d7da;border-color:#f5c6cb;align-items:center}.guide{position:relative;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px}.guide:before{content:\"\";position:absolute;top:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid #303030}.guide2{position:absolute;top:-32px;left:24px;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px;pointer-events:none}.guide2:before{content:\"\";position:absolute;bottom:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #303030}.incoming-call-widget{position:absolute;right:-320px;top:30px;width:320px;height:68px;background-color:#3052cd;border-top-right-radius:8px;border-bottom-right-radius:8px;display:flex;align-items:center;padding:4px 12px}.incoming-call-widget h6,.incoming-call-widget p{margin-bottom:0;line-height:1.2;color:#fff}.inc-user-img{width:48px;height:48px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;box-sizing:border-box;margin-right:8px}.inc-user-img img{width:100%}.inc-call-btn{width:40px;height:40px;border-radius:50%;outline:none;border-width:0;display:flex;align-items:center;justify-content:center}.inc-call-btn span{font-size:16px}.inc-accept-btn{background-color:#2ecc71;color:#fff}.inc-reject-btn{background-color:#e14e4e;color:#fff}.inc-user-name{font-weight:600}\n"] }]
|
|
4025
|
-
}], ctorParameters: function () { return [{ type: TwilioService }, { type: ExtensionService }, { type: i3$1.MatDialog }, { type: IpAddressService }, { type: ExtensionService }, { type: i0.ChangeDetectorRef }, { type: i5.Router }, { type: IncomeingCallSocketService }]; }, propDecorators: { autoOpenOnIncoming: [{
|
|
4026
|
-
type: Input
|
|
4027
|
-
}], contactInfo: [{
|
|
4028
|
-
type: Input
|
|
4029
|
-
}], deviceId: [{
|
|
4030
|
-
type: Input
|
|
4031
|
-
}], isDialpadHidden: [{
|
|
4032
|
-
type: Input
|
|
4033
|
-
}], incomingCallData: [{
|
|
4034
|
-
type: Input
|
|
4035
|
-
}], closeDialpadEvent: [{
|
|
4036
|
-
type: Output
|
|
4037
|
-
}], callInitiated: [{
|
|
4038
|
-
type: Output
|
|
4039
|
-
}], endCallEvent: [{
|
|
4040
|
-
type: Output
|
|
4041
|
-
}], minimiseEvent: [{
|
|
4042
|
-
type: Output
|
|
4043
|
-
}], incomingCallsNewInfoEvent: [{
|
|
4044
|
-
type: Output
|
|
4045
|
-
}], incomingCallInitiated: [{
|
|
4046
|
-
type: Output
|
|
4047
|
-
}], dialInputElement: [{
|
|
4048
|
-
type: ViewChild,
|
|
4049
|
-
args: ['dialInput']
|
|
4050
|
-
}], numberDialed: [{
|
|
4051
|
-
type: Output
|
|
4052
|
-
}] } });
|
|
4053
|
-
|
|
4054
|
-
const GlobalConstant = {
|
|
4055
|
-
ErrorMsg500: "Unable to process request. Please try again later.",
|
|
4056
|
-
isSMSVisible: true,
|
|
4057
|
-
dedicatedNumText: 'C2C Number'
|
|
4058
|
-
};
|
|
4059
|
-
|
|
4060
|
-
class IncomingCallComponent {
|
|
4061
|
-
constructor(extensionService, twilioService, notificationSerivce) {
|
|
4062
|
-
this.extensionService = extensionService;
|
|
4063
|
-
this.twilioService = twilioService;
|
|
4064
|
-
this.notificationSerivce = notificationSerivce;
|
|
4065
|
-
this.showRingAnimation = true;
|
|
4066
|
-
this.selectedIncomingCall = {};
|
|
4067
|
-
this.dedicatedNum = '';
|
|
4068
|
-
this.shouldRecordCall = false;
|
|
4069
|
-
this.isClickExpand = false;
|
|
4070
|
-
this.isRecording = false;
|
|
4071
|
-
this.isPaused = false;
|
|
4072
|
-
this.isTwilioConnected = false;
|
|
4073
|
-
this.closeIncomingCallDiv = new EventEmitter();
|
|
4074
|
-
this.incomingCallsNewList = new EventEmitter();
|
|
4075
|
-
this.selectedIncomingCallInfo = new EventEmitter();
|
|
4076
|
-
this.disbaleEndCallBtn = false;
|
|
4077
|
-
this.incomingCallSid = '';
|
|
4078
|
-
this.incomingRecordCall = false;
|
|
4079
|
-
this.timeElapsed = 0;
|
|
4080
|
-
console.log('IncomingCallComponent');
|
|
4081
|
-
}
|
|
4082
|
-
ngOnInit() {
|
|
4083
|
-
// this.twilioService.currentCall.subscribe((call: any) => {
|
|
4084
|
-
// if (call) {
|
|
4085
|
-
// this.twilioCallData = call;
|
|
4086
|
-
// this.notificationSerivce.showNotification(call);
|
|
4087
|
-
// // Handle the call UI
|
|
4088
|
-
// }
|
|
4089
|
-
// });
|
|
4090
|
-
console.log('IncomingCallComponent ngOnInit');
|
|
4091
|
-
try {
|
|
4092
|
-
this.twilioService.currentCall.subscribe(call => {
|
|
4093
|
-
if (call) {
|
|
4094
|
-
this.twilioCallData = call;
|
|
4095
|
-
this.twilioAuthId = call.customParameters.get('twilioAuthId');
|
|
4096
|
-
if (!call.parameters) {
|
|
4097
|
-
call.parameters = {};
|
|
4098
|
-
}
|
|
4099
|
-
this.sendIPforIncomingCall(this.twilioAuthId, '');
|
|
4100
|
-
call.on('cancel', () => {
|
|
4101
|
-
if (this.incomingCallData && this.incomingCallData.parameters && this.incomingCallData.parameters.CallSid) {
|
|
4102
|
-
this.newIncomingCallsList = this.newIncomingCallsList.filter((item) => item.parameters && item.parameters.CallSid !== this.incomingCallData.parameters.CallSid);
|
|
4103
|
-
}
|
|
4104
|
-
this.rejectCallFromList(call);
|
|
4105
|
-
});
|
|
4106
|
-
call.on('disconnect', () => {
|
|
4107
|
-
if (this.incomingCallData && this.incomingCallData.parameters && this.incomingCallData.parameters.CallSid) {
|
|
4108
|
-
this.newIncomingCallsList = this.newIncomingCallsList.filter((item) => item.parameters && item.parameters.CallSid !== this.incomingCallData.parameters.CallSid);
|
|
4109
|
-
}
|
|
4110
|
-
this.rejectCallFromList(call);
|
|
4111
|
-
});
|
|
4052
|
+
this.isTrialPeriodOver = localStorage.getItem('trialOver') === 'false' ? false : true;
|
|
4053
|
+
if (this.sanitizedNum === localStorage.getItem('twilioNumber')) {
|
|
4054
|
+
swal('Error', 'You can not dial this number');
|
|
4055
|
+
return false;
|
|
4112
4056
|
}
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4057
|
+
const hasPermission = yield this.checkMicrophonePermission();
|
|
4058
|
+
if (!hasPermission) {
|
|
4059
|
+
yield this.askForMicrophonePermission();
|
|
4060
|
+
return false;
|
|
4061
|
+
}
|
|
4062
|
+
if (!this.selectedCallerId) {
|
|
4063
|
+
this.shakeDedicatedBtn = true;
|
|
4064
|
+
this.showDialAlert('Select a C2C number to call');
|
|
4065
|
+
setTimeout(() => {
|
|
4066
|
+
this.shakeDedicatedBtn = false;
|
|
4067
|
+
}, 3000);
|
|
4068
|
+
return false;
|
|
4069
|
+
}
|
|
4070
|
+
// Clear displayNum if value is bound from previous call
|
|
4071
|
+
this.callData.displayNum = '';
|
|
4072
|
+
// Get number to be dialed from backend
|
|
4073
|
+
yield this.getToNumber(this.sanitizedNum);
|
|
4074
|
+
if (this.terminateCall) {
|
|
4075
|
+
this.terminateCall = false;
|
|
4076
|
+
return;
|
|
4077
|
+
}
|
|
4078
|
+
// Update call data in a single operation
|
|
4079
|
+
this.callData = Object.assign(Object.assign({}, this.callData), { phone: this.sanitizedNum, isIncomingCall: false, dial: true, from: this.isSmartDialCall ? this.callData.from : this.selectedCallerId.number, timestamp: new Date().toISOString() });
|
|
4080
|
+
// console.log('Initiating call with data:', this.callData);
|
|
4081
|
+
console.log('dd10');
|
|
4082
|
+
this.isCallInProgress = true;
|
|
4083
|
+
this.callInitiated.emit(Object.assign({}, this.callData));
|
|
4084
|
+
return true;
|
|
4085
|
+
}
|
|
4086
|
+
catch (e) {
|
|
4087
|
+
// console.error('Error in initiateCall:', e);
|
|
4088
|
+
this.showDialAlert('Failed to initiate call. Please try again.');
|
|
4089
|
+
console.log('dd11');
|
|
4090
|
+
this.isCallInProgress = false;
|
|
4091
|
+
return false;
|
|
4092
|
+
}
|
|
4093
|
+
});
|
|
4118
4094
|
}
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
const otherConnected = this.newIncomingCallsList.find((item) => item.isCallConnected && item !== data);
|
|
4126
|
-
if (otherConnected) {
|
|
4127
|
-
try {
|
|
4128
|
-
otherConnected.disconnect();
|
|
4095
|
+
isInvalidNumber() {
|
|
4096
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4097
|
+
try {
|
|
4098
|
+
if (this.sanitizedNum == '') {
|
|
4099
|
+
this.showDialAlert('Invalid Number');
|
|
4100
|
+
return true;
|
|
4129
4101
|
}
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4102
|
+
const validNumberPattern = /^[+\d\s()-]*$/; // Regular expression to match valid characters
|
|
4103
|
+
const phoneNumber = this.sanitizedNum;
|
|
4104
|
+
if (!validNumberPattern.test(phoneNumber)) {
|
|
4105
|
+
this.showDialAlert('Invalid Number');
|
|
4106
|
+
return true;
|
|
4107
|
+
}
|
|
4108
|
+
return false;
|
|
4109
|
+
}
|
|
4110
|
+
catch (error) {
|
|
4111
|
+
this.showDialAlert('Invalid Number');
|
|
4112
|
+
return true; // Return true if an error occurred, meaning the number is invalid
|
|
4133
4113
|
}
|
|
4134
|
-
}
|
|
4135
|
-
// Accept this call and mark as the active one
|
|
4136
|
-
data.accept();
|
|
4137
|
-
data.isCallConnected = true;
|
|
4138
|
-
data.isFirstCall = true;
|
|
4139
|
-
this.extensionService.setCallSid(this.CallSid, this.recordCall);
|
|
4140
|
-
this.sendIPforIncomingCall(data.customParameters.get('twilioAuthId'), 'answered').then(() => {
|
|
4141
|
-
this.closeIncomingCallWrapper(1);
|
|
4142
4114
|
});
|
|
4143
4115
|
}
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
data.parameters['isCallConnected'] = false; // Should be false when rejecting
|
|
4153
|
-
}
|
|
4154
|
-
if (data.customParameters) {
|
|
4155
|
-
this.sendIPforIncomingCall(data.customParameters.get('twilioAuthId'), 'answered');
|
|
4116
|
+
saveLastDialed() {
|
|
4117
|
+
const contact = this.filteredContactList.find((c) => c.numbersList.some((n) => n.number === this.dialedNumber));
|
|
4118
|
+
if (contact) {
|
|
4119
|
+
this.lastDialed = {
|
|
4120
|
+
name: contact.name,
|
|
4121
|
+
image: contact.image,
|
|
4122
|
+
number: this.dialedNumber
|
|
4123
|
+
};
|
|
4156
4124
|
}
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
if (this.newIncomingCallsList.length == 0) {
|
|
4161
|
-
this.closeIncomingCallDiv.emit({ show: 0, call: data });
|
|
4125
|
+
else {
|
|
4126
|
+
if (this.dialedNumber) {
|
|
4127
|
+
this.lastDialed = { number: this.dialedNumber };
|
|
4162
4128
|
}
|
|
4163
4129
|
}
|
|
4164
4130
|
}
|
|
4165
|
-
|
|
4166
|
-
this.
|
|
4131
|
+
isSavedContactDialled() {
|
|
4132
|
+
let phoneNum = this.sanitizedNum.replace(/\s+/g, '');
|
|
4133
|
+
let contact = this.contactList.filter((contact) => {
|
|
4134
|
+
return contact.numbersList.some((num) => num.number === phoneNum);
|
|
4135
|
+
});
|
|
4136
|
+
if (contact.length) {
|
|
4137
|
+
this.callData.name = `${contact[0].firstName} ${contact[0].middleName} ${contact[0].lastName}`.toLowerCase();
|
|
4138
|
+
this.callData.img = contact[0].image || 'assets/images/user.jpg';
|
|
4139
|
+
this.callData.phone = this.sanitizedNum;
|
|
4140
|
+
return true;
|
|
4141
|
+
}
|
|
4142
|
+
return false;
|
|
4167
4143
|
}
|
|
4168
|
-
|
|
4169
|
-
this.
|
|
4170
|
-
|
|
4144
|
+
showDialAlert(message) {
|
|
4145
|
+
this.dialAlert = {
|
|
4146
|
+
msg: message,
|
|
4147
|
+
show: true
|
|
4148
|
+
};
|
|
4149
|
+
setTimeout(() => {
|
|
4150
|
+
this.dialAlert.show = false;
|
|
4151
|
+
}, 3000);
|
|
4171
4152
|
}
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
const
|
|
4153
|
+
isCallerIdSet() {
|
|
4154
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4155
|
+
try {
|
|
4156
|
+
const tkn = localStorage.getItem('ext_token');
|
|
4157
|
+
const res = yield this.extService.fetchCallerId(tkn || '').toPromise();
|
|
4177
4158
|
if (res.status == 200) {
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
this.shouldRecordCall = false;
|
|
4187
|
-
}
|
|
4188
|
-
}
|
|
4189
|
-
else {
|
|
4190
|
-
// swal("Error", "Missing call authentication details.", "error");
|
|
4191
|
-
}
|
|
4192
|
-
resolve();
|
|
4159
|
+
localStorage.setItem('trialOver', res.trialOver);
|
|
4160
|
+
this.twilioService.isTrialOver.next(res.trialOver);
|
|
4161
|
+
localStorage.setItem('paymentDue', res.paymentDue);
|
|
4162
|
+
this.twilioService.isPaymentDue.next(res.paymentDue);
|
|
4163
|
+
}
|
|
4164
|
+
if (res.callerid) {
|
|
4165
|
+
localStorage.setItem('callerID', res.callerid);
|
|
4166
|
+
this.extService.changeMessage(res.callerid);
|
|
4193
4167
|
}
|
|
4194
4168
|
else {
|
|
4195
|
-
|
|
4196
|
-
|
|
4169
|
+
localStorage.setItem('callerID', 'Not set');
|
|
4170
|
+
this.extService.changeMessage('Not set');
|
|
4197
4171
|
}
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4172
|
+
return (localStorage.getItem('callerID') !== 'Not set');
|
|
4173
|
+
}
|
|
4174
|
+
catch (e) {
|
|
4175
|
+
console.log(e);
|
|
4176
|
+
return false;
|
|
4177
|
+
}
|
|
4202
4178
|
});
|
|
4203
4179
|
}
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4180
|
+
checkMicrophonePermission() {
|
|
4181
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4182
|
+
try {
|
|
4183
|
+
const stream = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
4184
|
+
stream.getTracks().forEach(track => track.stop());
|
|
4185
|
+
return true;
|
|
4186
|
+
}
|
|
4187
|
+
catch (error) {
|
|
4188
|
+
if (error.name === 'NotAllowedError') {
|
|
4189
|
+
return false;
|
|
4190
|
+
}
|
|
4191
|
+
else {
|
|
4192
|
+
return false;
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
});
|
|
4208
4196
|
}
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
info.pointName && info.pointName !== '-' ||
|
|
4220
|
-
info.sourceName && info.sourceName !== '-' ||
|
|
4221
|
-
info.extension && info.extension !== '-' ||
|
|
4222
|
-
info.url ||
|
|
4223
|
-
info.latitude ||
|
|
4224
|
-
info.longitude);
|
|
4225
|
-
}
|
|
4226
|
-
return false;
|
|
4197
|
+
askForMicrophonePermission() {
|
|
4198
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4199
|
+
try {
|
|
4200
|
+
const stream = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
4201
|
+
stream.getTracks().forEach(track => track.stop());
|
|
4202
|
+
}
|
|
4203
|
+
catch (error) {
|
|
4204
|
+
console.error('User denied microphone permission:', error);
|
|
4205
|
+
}
|
|
4206
|
+
});
|
|
4227
4207
|
}
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
if (this.newIncomingCallsList && this.newIncomingCallsList.length > 0) {
|
|
4240
|
-
this.newIncomingCallsList.forEach((call) => {
|
|
4241
|
-
if (call !== this.selectedIncomingCall) {
|
|
4242
|
-
call['isClickExpand'] = false;
|
|
4243
|
-
}
|
|
4244
|
-
});
|
|
4208
|
+
// below function is to get the country code with number from server
|
|
4209
|
+
getToNumber(dialedNumber) {
|
|
4210
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4211
|
+
if (dialedNumber[0] !== '+') {
|
|
4212
|
+
// this is case when user geolocation dial code is on
|
|
4213
|
+
let ipAddress = yield this.ipService.getIpAddressInfo().toPromise();
|
|
4214
|
+
const res = yield this.twilioService.getToNumber(dialedNumber, ipAddress.address.countryCode).toPromise();
|
|
4215
|
+
if (res.status == 200) {
|
|
4216
|
+
this.toastTimeout = res.timeInterval * 1000;
|
|
4217
|
+
yield this.showNumberToast(res);
|
|
4218
|
+
}
|
|
4245
4219
|
}
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4220
|
+
});
|
|
4221
|
+
}
|
|
4222
|
+
isAlertEnable() {
|
|
4223
|
+
return localStorage.getItem('isAlertEnable');
|
|
4224
|
+
}
|
|
4225
|
+
showNumberToast(data) {
|
|
4226
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
4227
|
+
const isAlertOn = (localStorage.getItem('isCountryCodeToastOn'));
|
|
4228
|
+
if (isAlertOn == 'true') {
|
|
4229
|
+
this.callNumberToast.show = true;
|
|
4230
|
+
this.callNumberToast.number = data.toNumber;
|
|
4231
|
+
this.callNumberToast.displayNum = data.displayNumber;
|
|
4249
4232
|
}
|
|
4233
|
+
this.callData.displayNum = data.displayNumber;
|
|
4234
|
+
//this.callData.phone = data.toNumber;
|
|
4235
|
+
yield this.delay(this.toastTimeout);
|
|
4236
|
+
this.dialedNumber = data.toNumber;
|
|
4237
|
+
this.sanitizedNum = data.toNumber;
|
|
4238
|
+
this.callNumberToast.show = false;
|
|
4239
|
+
this.callNumberToast.number = '';
|
|
4240
|
+
this.callNumberToast.displayNum = '';
|
|
4241
|
+
});
|
|
4242
|
+
}
|
|
4243
|
+
delay(ms) {
|
|
4244
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
4245
|
+
}
|
|
4246
|
+
onMinimise(isMinimised) {
|
|
4247
|
+
this.isMinimised = isMinimised;
|
|
4248
|
+
this.minimiseEvent.emit(isMinimised);
|
|
4249
|
+
}
|
|
4250
|
+
handleNumberPaste(event) {
|
|
4251
|
+
event.preventDefault();
|
|
4252
|
+
const clipboardData = event.clipboardData || window.clipboardData;
|
|
4253
|
+
const pastedData = clipboardData.getData('text');
|
|
4254
|
+
// Log the pasted content to the console
|
|
4255
|
+
if (pastedData) {
|
|
4256
|
+
this.dialedNumber = pastedData;
|
|
4257
|
+
this.sanitizedNum = pastedData;
|
|
4250
4258
|
}
|
|
4251
4259
|
}
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
this.
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
+
onEnter(num) {
|
|
4261
|
+
// console.log(num, 'number fn')
|
|
4262
|
+
this.dialedNumber = this.dialedNumber + num;
|
|
4263
|
+
this.sanitizedNum = this.dialedNumber;
|
|
4264
|
+
this.showInputClearBtn = true;
|
|
4265
|
+
this.numberDialed.emit(this.dialedNumber);
|
|
4266
|
+
}
|
|
4267
|
+
getUserCallSetting() {
|
|
4268
|
+
const tkn = localStorage.getItem('ext_token');
|
|
4269
|
+
this.extService.fetchCallerId(tkn || '').subscribe((resp) => {
|
|
4270
|
+
if (resp.status == 200) {
|
|
4271
|
+
//this.callPrefernce = resp.userSetting;
|
|
4272
|
+
this.callPreference = resp.callerid;
|
|
4273
|
+
this.getCallerIdList();
|
|
4274
|
+
}
|
|
4260
4275
|
});
|
|
4261
4276
|
}
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
}, {});
|
|
4277
|
+
onDedicatedNumSelect(id) {
|
|
4278
|
+
this.selectedCallerId = id;
|
|
4279
|
+
this.isCallerIdHidden = true;
|
|
4280
|
+
this.extService.setCallerId(id);
|
|
4267
4281
|
}
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4282
|
+
cancelDialNumber() {
|
|
4283
|
+
this.terminateCall = true;
|
|
4284
|
+
this.callNumberToast.show = false;
|
|
4285
|
+
}
|
|
4286
|
+
handleDivKeydown(ev) {
|
|
4287
|
+
if (this.dialedNumber.length == 0) {
|
|
4288
|
+
this.dialInputElement.nativeElement.focus();
|
|
4271
4289
|
}
|
|
4272
|
-
|
|
4273
|
-
|
|
4290
|
+
if (ev.key === 'Enter') {
|
|
4291
|
+
// Check if the dialpad is open
|
|
4292
|
+
if (!this.isDialpadHidden) {
|
|
4293
|
+
if (this.dialedNumber.length > 2 && this.selectedCallerId) {
|
|
4294
|
+
this.initiateCall();
|
|
4295
|
+
}
|
|
4296
|
+
if (!this.selectedCallerId) {
|
|
4297
|
+
this.shakeDedicatedBtn = true;
|
|
4298
|
+
setTimeout(() => {
|
|
4299
|
+
this.shakeDedicatedBtn = false;
|
|
4300
|
+
}, 10000);
|
|
4301
|
+
}
|
|
4302
|
+
}
|
|
4274
4303
|
}
|
|
4275
4304
|
}
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
this.incomingCallSid = details.callSid;
|
|
4280
|
-
this.incomingRecordCall = details.recordCall;
|
|
4281
|
-
sid = this.incomingCallSid ? this.incomingCallSid : this.CallSid;
|
|
4282
|
-
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
4283
|
-
// return;
|
|
4284
|
-
// }
|
|
4285
|
-
this.extensionService.getCallRecording(sid).subscribe(response => {
|
|
4286
|
-
this.isRecording = true;
|
|
4287
|
-
this.isPaused = false;
|
|
4288
|
-
// this.timeElapsed = 0;
|
|
4289
|
-
this.startTimer1();
|
|
4290
|
-
}, error => {
|
|
4291
|
-
console.error('Error starting recording', error);
|
|
4292
|
-
});
|
|
4293
|
-
}
|
|
4294
|
-
stopRecording() {
|
|
4295
|
-
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
4296
|
-
// return;
|
|
4297
|
-
// }
|
|
4298
|
-
this.isRecording = false;
|
|
4299
|
-
this.isPaused = false;
|
|
4300
|
-
if (this.timerSubscription) {
|
|
4301
|
-
this.timerSubscription.unsubscribe();
|
|
4305
|
+
onCallBtnMouseEnter(ev) {
|
|
4306
|
+
if (!this.selectedCallerId || (this.selectedCallerId == 'alwaysAsk') || (this.selectedCallerId == 'smartDialing')) {
|
|
4307
|
+
this.shakeDedicatedBtn = true;
|
|
4302
4308
|
}
|
|
4303
4309
|
}
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
const sid = this.incomingCallSid ? this.incomingCallSid : this.CallSid;
|
|
4309
|
-
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
4310
|
-
// return;
|
|
4311
|
-
// }
|
|
4312
|
-
this.extensionService.pauseOrResumeRecording(sid, 'pause').subscribe(response => {
|
|
4313
|
-
// this.stopRecordingTimer();
|
|
4314
|
-
this.isPaused = true;
|
|
4315
|
-
}, error => {
|
|
4316
|
-
console.error('Error pausing recording:', error);
|
|
4317
|
-
// Consider updating the UI to show the error state
|
|
4318
|
-
});
|
|
4310
|
+
onCallBtnMouseLeave(ev) {
|
|
4311
|
+
if (!this.selectedCallerId || (this.selectedCallerId == 'alwaysAsk') || (this.selectedCallerId == 'smartDialing')) {
|
|
4312
|
+
this.shakeDedicatedBtn = false;
|
|
4313
|
+
}
|
|
4319
4314
|
}
|
|
4320
|
-
|
|
4321
|
-
//
|
|
4322
|
-
|
|
4323
|
-
this.
|
|
4324
|
-
this.incomingRecordCall = details.recordCall;
|
|
4325
|
-
sid = this.incomingCallSid ? this.incomingCallSid : this.CallSid;
|
|
4326
|
-
// if (!this.incomingRecordCall && !this.recordCall) {
|
|
4327
|
-
// return; // Skip if recording is not enabled
|
|
4328
|
-
// }
|
|
4329
|
-
this.extensionService.pauseOrResumeRecording(sid, 'resume').subscribe(response => {
|
|
4330
|
-
this.isPaused = false;
|
|
4331
|
-
this.startTimer1();
|
|
4332
|
-
}, error => {
|
|
4333
|
-
console.error('Error resuming recording', error);
|
|
4334
|
-
});
|
|
4315
|
+
acceptNewIncomingCall(call) {
|
|
4316
|
+
//first cut the current call
|
|
4317
|
+
//this.callData = call;
|
|
4318
|
+
this.newIncomingCallData = call;
|
|
4335
4319
|
}
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4320
|
+
rejectNewIncomingCall(call) {
|
|
4321
|
+
call.reject();
|
|
4322
|
+
this.newIncomingCalls = this.newIncomingCalls.filter((item) => item.parameters.CallSid !== call.parameters['CallSid']);
|
|
4323
|
+
this.incomingCallsList = this.incomingCallsList.filter((item) => item.parameters.CallSid !== call.parameters['CallSid']);
|
|
4340
4324
|
}
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4325
|
+
newIncomingCallInitiated() {
|
|
4326
|
+
console.log('dd12');
|
|
4327
|
+
this.isCallInProgress = true;
|
|
4328
|
+
this.newIncomingCalls = [];
|
|
4329
|
+
this.incomingCallInitiated.emit();
|
|
4346
4330
|
}
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
this.
|
|
4331
|
+
incomingCallsNewInfo(data) {
|
|
4332
|
+
this.incomingCallsList = data;
|
|
4333
|
+
this.incomingCallsNewInfoEvent.emit(data);
|
|
4350
4334
|
}
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4335
|
+
ngOnDestroy() {
|
|
4336
|
+
try {
|
|
4337
|
+
console.log('Cleaning up C2cDialpadComponent');
|
|
4338
|
+
// Unsubscribe from all subscriptions
|
|
4339
|
+
if (this.subscriptions) {
|
|
4340
|
+
this.subscriptions.unsubscribe();
|
|
4356
4341
|
}
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
});
|
|
4342
|
+
// Clean up Twilio device when component is destroyed
|
|
4343
|
+
if (this.twilioService['device']) {
|
|
4344
|
+
this.twilioService['device'].destroy();
|
|
4361
4345
|
}
|
|
4362
|
-
//
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4346
|
+
// End any active call
|
|
4347
|
+
if (this.isCallInProgress) {
|
|
4348
|
+
this.endCall();
|
|
4349
|
+
}
|
|
4350
|
+
// Clear any timeouts or intervals if they exist
|
|
4351
|
+
if (this.toastTimeout) {
|
|
4352
|
+
clearTimeout(this.toastTimeout);
|
|
4353
|
+
}
|
|
4354
|
+
console.log('C2cDialpadComponent cleanup complete');
|
|
4355
|
+
}
|
|
4356
|
+
catch (error) {
|
|
4357
|
+
console.error('Error during component cleanup:', error);
|
|
4358
|
+
}
|
|
4366
4359
|
}
|
|
4367
4360
|
}
|
|
4368
|
-
|
|
4369
|
-
IncomingCallComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: IncomingCallComponent, selector: "lib-incoming-call", inputs: { incomingCallData: "incomingCallData", newIncomingCallsList: "newIncomingCallsList", deviceId: "deviceId" }, outputs: { closeIncomingCallDiv: "closeIncomingCallDiv", incomingCallsNewList: "incomingCallsNewList", selectedIncomingCallInfo: "selectedIncomingCallInfo" }, ngImport: i0, template: "<div class=\"call-container\" *ngIf=\"newIncomingCallsList?.length === 1\">\r\n <div style=\"display: flex; flex-direction: column;\">\r\n <div class=\"callToNum\">Incoming call on <br/><span>{{incomingCallData?.phone || 'Unknown Number'}}</span></div>\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" [src]=\"newIncomingCallsList[0]?.img || incomingCallData?.img\" alt=\"\" width=\"120\" />\r\n </div>\r\n <div class=\"callerDetails\">\r\n <!-- <h1>{{newIncomingCallsList[0]?.userInfo?.c2cInformation?.name || incomingCallData?.name || 'Unknown Number'}}</h1> -->\r\n <!-- <p>{{newIncomingCallsList[0]?.userInfo?.displayNum ? newIncomingCallsList[0]?.userInfo?.c2cInformation?.number : newIncomingCallsList[0]?.userInfo?.c2cInformation?.number || incomingCallData?.displayNum || incomingCallData?.phone}}</p> -->\r\n <h1>{{incomingCallData?.name || 'Unknown Number'}}</h1>\r\n <p>{{incomingCallData?.phone}}</p>\r\n </div>\r\n \r\n <!-- <div class=\"callerDetails\">\r\n <h1 [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{callData.name}}</h1>\r\n <p>{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\r\n <h4 style=\"margin-top: 4px\">{{timer}}</h4>\r\n </div> -->\r\n <div class=\"call-action-btns\">\r\n <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected || incomingCallData\">\r\n <span class=\"material-symbols-outlined\" (click)=\"add(newIncomingCallsList[0])\"> call </span> \r\n </button>\r\n <!-- <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected || incomingCallData\">\r\n <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(newIncomingCallsList[0])\"> call </span>\r\n </button> -->\r\n <button class=\"call-btn mute-btn\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected\" (click)=\"toggleMute(newIncomingCallsList[0])\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container \">\r\n <button class=\"record-btn start-stop\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\r\n <span class=\"recording-icon\"></span>\r\n </button> \r\n <div class=\"\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected && 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=\"newIncomingCallsList[0]?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <!-- <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(newIncomingCallsList[0])\"> call_end </span>\r\n </button> -->\r\n <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"onEndCall()\"> 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\" 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<div class=\"call-container\" style=\"width: 100%;\" *ngIf=\"newIncomingCallsList?.length > 1\" [ngClass]=\"{'call-container-open': selectedIncomingCall?.isClickExpand}\">\r\n <div class=\"collops\">\r\n <div class=\"d-flex w-100\">\r\n <div class=\"d-flex flex-column container-fluid\" >\r\n <div class=\"callToNum\">Incoming call <br/><span>{{dedicatedNum}}</span></div>\r\n <ng-container *ngFor=\"let data of newIncomingCallsList\"> \r\n <div class=\"p-2 \">\r\n <div class=\"call-info-wrapper w-100 d-flex align-items-center\">\r\n <div class=\"img\">\r\n <img class=\"avatar-img-wrapper\" [src]=\"data?.img\" alt=\"\" width=\"45\" />\r\n </div>\r\n <div class=\"d-flex justify-content-between w-100 align-items-center mr-2\">\r\n <div class=\"callerDetails-wrapper\">\r\n <h5 class=\"break-word\">{{data?.userInfo?.c2cInformation?.name || '-'}}</h5>\r\n <p class=\"break-word\">{{data?.userInfo?.displayNum ? data?.userInfo?.c2cInformation?.number : data?.userInfo?.c2cInformation?.number }}</p>\r\n </div> \r\n <div class=\"d-flex align-items-center\">\r\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!data?.isCallConnected\">\r\n <!-- <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(data)\"> call </span> -->\r\n <span class=\"material-symbols-outlined\" (click)=\"add(data)\"> call </span>\r\n </button>\r\n <button class=\"call-btn-wrapper mute-btn\" *ngIf=\"data?.isCallConnected\" (click)=\"toggleMute(data)\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container\">\r\n <button class=\"record-btn start-stop\" *ngIf=\"data?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\r\n <span class=\"recording-icon\"></span>\r\n </button> \r\n <div class=\"\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"data?.isCallConnected && 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=\"data?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <button class=\"call-btn-wrapper reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(data)\"> call_end </span>\r\n </button>\r\n <div class=\"togglearrow-arrow me-2\" id=\"togglearrow\" \r\n (click)=\"hasDetailedInfo(data) ? onClickExpand(data) : null\" \r\n [ngClass]=\"{'disabled': !hasDetailedInfo(data)}\"\r\n [title]=\"hasDetailedInfo(data) ? 'View details' : 'No details available'\">\r\n <i class=\"fa fa-angle-right\"></i>\r\n </div>\r\n <!-- <div *ngIf=\"data?.customParameters?.get('c2cNumber') === true || data?.customParameters?.get('c2cNumber') === 'true'\" class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"onClickExpand(data)\"> \r\n <i class=\"fa fa-angle-right\"></i> \r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div class=\"call-container p-3 text-white model-content\" *ngIf=\"isClickExpand \"> \r\n <div class=\"mb-2\" style=\"width: 100%; height: 100%;\">\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" [src]=\"incomingCallData.img\" alt=\"\" width=\"100\" />\r\n </div>\r\n <div class=\"text-center\">\r\n <h3 class=\"text-white\">{{selectedIncomingCall?.userInfo?.c2cInformation?.name || '-'}}</h3>\r\n </div>\r\n <div class=\"f-13\">\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Subject:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.subject || '-'}}</div>\r\n </div> \r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Email:</div>\r\n <div>{{selectedIncomingCall?.userInfo?.c2cInformation?.email || '-'}}</div>\r\n </div> \r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Number:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.number}}</div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"\">Language:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.language || '-'}}</div>\r\n </div>\r\n </div>\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Extension:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.extension || '-'}}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Image:</div>\r\n <div class=\"text-ellipsis\">\r\n <ng-container *ngIf=\"selectedIncomingCall?.userInfo?.c2cInformation?.image && selectedIncomingCall?.userInfo?.c2cInformation?.image !== '-'; else noImage\">\r\n <img src=\"{{selectedIncomingCall?.userInfo?.c2cInformation?.image}}\" alt=\"\" width=\"42\" height=\"42\" 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\r\n <div class=\" mb-4\">\r\n <div class=\"\">\r\n <div class=\"\">Message:</div>\r\n <div class=\"text-ellipsis\">{{selectedIncomingCall?.userInfo?.c2cInformation?.message || '-'}}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Point Name:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.pointName || '-'}}</div>\r\n </div>\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Source Name:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.sourceName || '-'}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"call-action-btns mt-0\">\r\n <button class=\"call-btn receive-btn\" *ngIf=\"!selectedIncomingCall?.isCallConnected\">\r\n <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(selectedIncomingCall)\"> call </span>\r\n </button>\r\n <button class=\"call-btn mute-btn\" *ngIf=\"selectedIncomingCall?.isCallConnected\" (click)=\"toggleMute(selectedIncomingCall)\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container\">\r\n <button class=\"record-btn start-stop\" *ngIf=\"selectedIncomingCall?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\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=\"selectedIncomingCall?.isCallConnected && 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=\"selectedIncomingCall?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(selectedIncomingCall)\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\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\" [ngStyle]=\"{'width': '756px'}\">\r\n <defs>\r\n <path id=\"gentle-wave\" d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" /> \r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n</div>", styles: [".call-container{width:385px!important;height:646px!important;margin:auto;border-radius:30px;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}.collops{display:flex;flex-direction:column;width:100%;height:100%}.container-fluid{width:400px;height:100%;margin-top:10px}.model-content{background-color:#0d6efd;border-radius:20px;width:395px!important}.call-container-open{width:752px!important}.calls-side-by-side{position:fixed;top:0;width:30%;height:498px;z-index:1050;pointer-events:auto;display:flex;align-items:flex-start;left:-10rem;transform:translate(.2rem);transition:left 1s ease-in-out}.move{left:41vw!important}.f-13{font-size:13px!important}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto;border-radius:100%;border:solid 4px #fff}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.avatar-img-wrapper{border-radius:100%;margin:0 5px}.call-btn-wrapper{height:38px;background-color:#fff;border-radius:30px;margin:0 4px;opacity:.9;width:40px}.call-btn-wrapper span{color:#fff;line-height:unset!important}.hold-btn{background-color:#bebebe26;border:none}.hold-btn span,.mute-btn span{color:#fff!important}.active-hold{background-color:#fff!important}.active-hold span{color:#000!important}.active-mute{background-color:transparent}.call-info-wrapper{border:1px solid white;border-radius:7px;padding:8px 1px!important;word-break:break-all}.call-animation-play{animation:play 3s linear infinite}.avatar-img{width:94px;height:94px;border-radius:100%;position:absolute;left:0;top:0}@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}.callerDetails h1{margin:12px 0 0;color:#fff}.callerDetails-wrapper{margin:0 5px;color:#fff;display:flex;flex-direction:column}.callerDetails-wrapper h3,.callerDetails-wrapper h5{margin:0;color:#fff}.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}.callerDetails h4{margin:0;color:#fff}.callerDetails p,.callerDetails-wrapper p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-btn{position:relative;width:50px;height:50px;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}.call-sec-btn span{color:#cccbcb}.call-btn{width:48px;height:45px;background-color:#fff;border-radius:30px;box-sizing:border-box;margin:0 8px;opacity:.9}.call-btn:hover{opacity:1}.call-btn span{color:#fff;line-height:unset!important}.receive-btn{background-color:#28a745;border:2px solid #28a745}.mute-btn{position:relative;border:none;background-color:#bebebe26}.reject-btn{background-color:#e03131;border:2px solid #e03131}.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}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.call-action-btns{text-align:center;display:flex;justify-content:center;align-items:center;margin-top:240px}#call-input{background-color:transparent;border:none;outline:none;text-align:center;color:#fff}.wave-container{position:absolute;bottom:0}.waves{width:660px;position:relative;margin-bottom:-7px;height:40px;min-height:40px}.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}.callToNum{color:#fff;font-weight:400;text-align:center}.callToNum span{font-weight:600}.text-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;display:block}.record-action-btns{display:flex;flex-direction:column;align-items:center}.record-btn-container{position:relative}.record-btn{border:none;border-radius:50%;width:48px;height:48px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;overflow:hidden}.record-btn-side{border:none;border-radius:50%;width:44px;height:44px;display:flex;align-items:center;justify-content:center;cursor:pointer;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;justify-content:center;width:48px;height:48px;background-color:#fff;border-radius:30px}.record-btn.pause-resume{border:none;border-radius:50%;width:48px;height:48px;background:white;display:flex;align-items:center;justify-content:center}.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%}.togglearrow-arrow.disabled{opacity:.3;cursor:not-allowed;pointer-events:none}.togglearrow-arrow.disabled:hover{opacity:.3;cursor:not-allowed}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
4370
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type:
|
|
4361
|
+
DialboxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DialboxComponent, deps: [{ token: TwilioService }, { token: ExtensionService }, { token: i3.MatDialog }, { token: IpAddressService }, { token: ExtensionService }, { token: i0.ChangeDetectorRef }, { token: i5.Router }, { token: IncomeingCallSocketService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4362
|
+
DialboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DialboxComponent, selector: "lib-dialbox", inputs: { autoOpenOnIncoming: "autoOpenOnIncoming", contactInfo: "contactInfo", deviceId: "deviceId", isDialpadHidden: "isDialpadHidden", incomingCallData: "incomingCallData" }, outputs: { closeDialpadEvent: "closeDialpadEvent", callInitiated: "callInitiated", endCallEvent: "endCallEvent", minimiseEvent: "minimiseEvent", incomingCallsNewInfoEvent: "incomingCallsNewInfoEvent", incomingCallInitiated: "incomingCallInitiated", numberDialed: "numberDialed" }, viewQueries: [{ propertyName: "dialInputElement", first: true, predicate: ["dialInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"dragparent1\" [ngStyle]=\"{'display':isDialpadHidden ? 'none': 'block'}\">\r\n <lib-call-progress *ngIf=\"isCallInProgress\"\r\n (endCallEvent)=\"endCall()\"\r\n (minimiseEvent)=\"onMinimise($event)\"\r\n (incomingCallInitiated)=\"newIncomingCallInitiated()\"\r\n [newIncomingCallData]=\"newIncomingCallData\"\r\n [deviceId]=\"deviceId\"\r\n [newIncomingCallsList]=\"incomingCallsList\"\r\n (incomingCallsNewInfo)=\"incomingCallsNewInfo($event)\"\r\n [selectedCallerId]=\"selectedCallerId\"\r\n [callData]=\"callData\">\r\n </lib-call-progress>\r\n <div class=\"dialpad-container\" *ngIf=\"!isCallInProgress\" [ngClass]=\"{'mini-dialpad': isMinimised}\" tabindex=\"0\" (keydown)=\"handleDivKeydown($event)\">\r\n <div id=\"topPanel\" [ngStyle]=\"{'height': callerIdList.length ? '40%' : '39%'}\">\r\n <div class=\"dialpad-alerts\" *ngIf=\"dialAlert.show\">\r\n <div class=\"no-selection-alert\">\r\n <!-- <p class=\"mb-0\">Select C2C number to call</p> -->\r\n <p class=\"mb-0\">{{dialAlert.msg}}</p>\r\n <span class=\"fa fa-times\" (click)=\"shakeDedicatedBtn = false\"></span>\r\n </div>\r\n </div>\r\n <div class=\"dialpad-alerts\" *ngIf=\"callNumberToast.show\">\r\n <div class=\"dialbox-pop1 alert fade show\" [ngClass]=\"callNumberToast.type\" role=\"alert\">\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"flex-grow-1 my-auto text-left\">\r\n You'r calling <strong>{{callNumberToast.displayNum}}</strong>\r\n </div>\r\n <div class=\"text-right\">\r\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelDialNumber()\">Cancel Call</button>\r\n <!-- <button class=\"btn btn-link btn-success btn-disc p-0 px-2\">Continue</button> -->\r\n </div>\r\n \r\n </div>\r\n </div>\r\n </div>\r\n <div style=\"padding: 0 18px\" (paste)=\"handleNumberPaste($event)\">\r\n <div class=\"d-flex justify-content-between mt-2\">\r\n <p></p>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"hideDialpad()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"#ffffff\"><path 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\"/></svg>\r\n </span>\r\n </div>\r\n <div class=\"input-box\">\r\n <input type=\"text\" #dialInput placeholder=\"Enter a name or number\" tabindex=\"1\" [(ngModel)]=\"dialedNumber\" (ngModelChange)=\"onDialInputChange($event)\"/>\r\n <span class=\"\" id=\"input-clear-btn\" (click)=\"clearInput()\" *ngIf=\"showInputClearBtn\">\r\n <svg width=\"50px\" height=\"30px\" viewBox=\"0 10 40 60\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" baseProfile=\"full\" enable-background=\"new 0 0 76.00 76.00\" xml:space=\"preserve\">\r\n <path fill=\"#5d6061\" fill-opacity=\"1\" stroke-width=\"0.2\" stroke-linejoin=\"round\" d=\"M 47.5282,42.9497L 42.5784,38L 47.5282,33.0502L 44.9497,30.4718L 40,35.4216L 35.0502,30.4718L 32.4718,33.0502L 37.4216,38L 32.4718,42.9497L 35.0502,45.5282L 40,40.5784L 44.9497,45.5282L 47.5282,42.9497 Z M 18.0147,41.5355L 26.9646,50.4854C 28.0683,51.589 29,52 31,52L 52,52C 54.7614,52 57,49.7614 57,47L 57,29C 57,26.2386 54.7614,24 52,24L 31,24C 29,24 28.0683,24.4113 26.9646,25.5149L 18.0147,34.4645C 16.0621,36.4171 16.0621,39.5829 18.0147,41.5355 Z M 31,49C 30,49 29.6048,48.8828 29.086,48.3641L 20.1361,39.4142C 19.355,38.6332 19.355,37.3669 20.1361,36.5858L 29.086,27.6362C 29.6048,27.1175 30,27 31,27.0001L 52,27.0001C 53.1046,27.0001 54,27.8955 54,29.0001L 54,47.0001C 54,48.1046 53.1046,49.0001 52,49.0001L 31,49 Z \"/>\r\n </svg> \r\n </span>\r\n <span class=\"input-info-icon\" placement=\"bottom-right\" tooltipClass=\"input-tooltip\" ngbTooltip=\"For extension dialing, use formats like +12345678910 x123,+12345678910 ext.123, +12345678910,123\"><i class=\"fa fa-info-circle\"></i></span>\r\n </div>\r\n <div class=\"guide\" *ngIf=\"callerIdList.length && !(dialedNumber.length > 2)\">\r\n <span class=\"guidetext\">Please enter a number or select a saved contact</span>\r\n </div>\r\n <!-- <div class=\"input-error\" *ngIf=\"dialAlert.show\">\r\n <span>{{dialAlert.msg}}</span>\r\n </div> -->\r\n <div>\r\n <div class=\"contact-card\" *ngFor=\"let contact of filteredContactList\" (click)=\"onContactSelect(contact)\">\r\n <div class=\"contact-img\">\r\n <img [src]=\"contact.image\" alt=\"user image\" loading=\"lazy\" *ngIf=\"contact.image else alphaName\"/>\r\n <ng-template #alphaName>\r\n <span class=\"contact-alpha-img\">{{getFirstLetter(contact.firstName)}}</span>\r\n </ng-template>\r\n </div>\r\n <div class=\"contact-details\">\r\n <p style=\"margin-bottom: 4px\" class=\"contact-name\">{{getFullName(contact) }}</p>\r\n <p>{{contact.numbersList[0].number}}</p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"wave-container\">\r\n <svg\r\n class=\"waves\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 24 150 28\"\r\n preserveAspectRatio=\"none\"\r\n shape-rendering=\"auto\"\r\n >\r\n <defs>\r\n <path\r\n 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 />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"0\"\r\n fill=\"rgba(255,255,255,0.7)\"\r\n />\r\n <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"3\"\r\n fill=\"rgba(255,255,255,0.5)\"\r\n />\r\n <!-- <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"5\"\r\n fill=\"rgba(255,255,255,0.3)\"\r\n /> -->\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n </div>\r\n <div class=\"btn-container\" *ngIf=\"!isMinimised\">\r\n <button class=\"dial-btn\" *ngFor=\"let key of keypadVal;let i = index\"\r\n (keydown.enter)=\"onEnter(key.num)\" (click)=\"addNumber(key.num)\"\r\n [ngStyle]=\"{'margin-top': key.text === '+' ? '3px' : '0'}\"\r\n [tabindex]=\"dialedNumber.length ? '0': i+2\" longPress (longPress)=\"addNumber(key.text)\" shortPress (shortPress)=\"addNumber(key.num)\">\r\n {{key.num}} \r\n <span *ngIf=\"key.num == 1;else otherThanOne\" class=\"material-symbols-outlined voicemail\">\r\n voicemail\r\n </span>\r\n <ng-template #otherThanOne>\r\n <span class=\"btn-albhabets\" [ngClass]=\"{'plusSign': key.text === '+'}\">{{key.text ? key.text : ' '}}</span>\r\n </ng-template>\r\n </button>\r\n </div>\r\n <div class=\"call-btn-container\" *ngIf=\"!isMinimised\" (mouseenter)=\"onCallBtnMouseEnter($event)\" (mouseleave)=\"onCallBtnMouseLeave($event)\">\r\n <div class=\"call-btn\" (click)=\"initiateCall()\" [tabindex]=\"dialedNumber.length ? '2': '15'\"\r\n [ngStyle]=\"{'pointer-events': dialedNumber.length && selectedCallerId ? 'auto' : 'none', 'opacity': dialedNumber.length && selectedCallerId ? '1' : '0.5'}\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call\r\n </span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"callerIdList.length && !isMinimised\" class=\"position-relative\">\r\n <div class=\"shownCallerId\" *ngIf=\"selectedCallerId; else askBlock\" (click)=\"toggleCallerIdDiv()\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + selectedCallerId?.isoCode?.toLowerCase()\"></span>\r\n {{selectedCallerId?.number}}\r\n </div>\r\n </div>\r\n <ng-template #askBlock>\r\n <div class=\"shownCallerId\" (click)=\"toggleCallerIdDiv()\" [ngClass]=\"{ 'tilt-shaking': shakeDedicatedBtn }\">\r\n <div class=\"d-flex justify-content-center\">\r\n <h5 class=\"mb-0\">Select C2C number</h5>\r\n <!-- <span class=\"ml-2\" style=\"opacity:.8;margin-top:2px\">\r\n <img src=\"assets/images/icon_down_arrow.svg\" alt=\"down\" width=\"10px\">\r\n </span> -->\r\n <span class=\"fa fa-angle-down ml-2 text-blue\" style=\"margin-top:2px\"></span>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <div class=\"guide2\" *ngIf=\"shakeDedicatedBtn\">\r\n <span class=\"guidetext\">Please select a number from below dropdown</span>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"callerIdList.length; else noCallerIdMessage\">\r\n <div class=\"caller-id-list-container\" *ngIf=\"callerIdList.length && !isMinimised\" id=\"callerIdContainer\" [ngClass]=\"{'visible': !isCallerIdHidden}\" >\r\n <div style=\"display: flex; justify-content: space-between\">\r\n <!-- <h4>Select C2C Softphone Number</h4> -->\r\n <h4>Make outgoing call using</h4>\r\n <span\r\n class=\"material-symbols-outlined\"\r\n style=\"cursor: pointer\"\r\n (click)=\"isCallerIdHidden = true\"\r\n >\r\n close\r\n </span>\r\n </div>\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\" (click)=\"onDedicatedNumSelect(callerId)\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n <ng-template #noCallerIdMessage>\r\n <span class=\"no-caller-id-message\">To make any voice calls, please <a routerLink=\"/extension/dedicatednumber/{{token}}\" class=\"click-here-link\" title=\"Settings > C2C Number\">subscribe</a> to a voice capable C2C Number.\r\n </span>\r\n </ng-template>\r\n <div class=\"dedicated-overlay\" *ngIf=\"showDedicatedPopup\">\r\n <div class=\"card dedicatedNumPopup\">\r\n <div class=\"card-header chooseDedicatedHeader\">\r\n <h5>Choose C2C Number</h5>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDedicatedPopup = false\">close</span>\r\n </div>\r\n <div class=\"card-body dedicatedNumList\">\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\" (click)=\"showDedicatedPopup = false\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- <div class=\"incoming-call-widget\" *ngFor=\"let call of newIncomingCalls;let i = index\" [ngStyle]=\"{'top': (30 + i * 72) + 'px'}\">\r\n <div>\r\n <div class=\"inc-user-img\">\r\n <img src=\"assets/images/user.jpg\" alt=\"user image\">\r\n </div>\r\n \r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <p class=\"inc-user-name\">{{call.customParameters.get('name')}}</p>\r\n <p>{{call.parameters.From}}</p>\r\n </div>\r\n <div class=\"d-flex\">\r\n <button class=\"inc-call-btn inc-accept-btn mr-2\" (click)=\"acceptNewIncomingCall(call)\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call\r\n </span>\r\n </button>\r\n <button class=\"inc-call-btn inc-reject-btn\" (click)=\"rejectNewIncomingCall(call)\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call_end\r\n </span>\r\n </button>\r\n </div>\r\n \r\n </div> -->\r\n </div>\r\n</div>\r\n", styles: ["#dragparent1{position:fixed;left:100px;z-index:9999999;font-family:Lato,sans-serif;display:none}.dialpad-container{width:320px!important;height:600px!important;background:white;margin:auto;border-radius:30px;box-shadow:#00000040 0 54px 55px,#0000001f 0 -12px 30px,#0000001f 0 4px 6px,#0000002b 0 12px 13px,#00000017 0 -3px 5px;display:flex;flex-direction:column;box-sizing:border-box;position:relative;line-height:1.1}.dialpad-alerts{position:absolute;width:calc(100% - 28px);left:14px;top:8px;z-index:1200}.btn-disc{font-size:12px}.dialbox-pop1{font-size:.8rem;z-index:9;padding:8px}.input-error>span{color:#dfdfdf;margin-bottom:2px}.dial-close-btn{cursor:pointer;opacity:.6}.dial-close-btn:hover{opacity:1}.btn-container{display:flex;flex-wrap:wrap;padding:0 18px}.dial-btn{width:50px;height:50px;background-color:#fff;border-radius:4px;text-align:center;box-sizing:border-box;margin:4px 22px;font-size:28px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#2b434d;cursor:pointer;opacity:.8;border:none}.dial-btn:hover{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:focus{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:active{box-shadow:#32325d40 0 30px 60px -12px inset,#0000004d 0 18px 36px -18px inset}.call-btn-container{display:flex;margin-top:8px;justify-content:center;position:relative}.call-btn{display:flex;align-items:center;justify-content:center;width:54px;height:54px;border-radius:27px;background-color:#2ecc71;outline:none;border:none;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;opacity:.8;cursor:pointer}.call-btn:hover{opacity:1}.call-btn:focus{opacity:1}.caller-id-list-container{width:100%;height:auto;position:absolute;bottom:-100%;left:0;border-radius:0 0 30px 30px/0px 0px 30px 30px;padding:8px 12px 32px;box-sizing:border-box;color:#8a8a8a}.visible{animation:slideUp .8s forwards}#callerIdContainer ul{list-style:none;padding-left:0;margin:0}.dialpad-container h4{font-family:Lato,sans-serif;margin:0 0 8px}#callerIdContainer ul li{background-color:#fff;padding:8px;margin-top:7px;display:flex;border-radius:4px;justify-content:space-between;font-size:14px;cursor:pointer}.fi{border-radius:2px;margin-right:2px}@keyframes slideUp{0%{bottom:-100%}to{bottom:0}}.selectedCallerIdClass{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;border:1px solid #e0e0e0;color:#3a3a3a}.toggleBtn{color:gray;border:none;background-color:#e5eef1}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.plusSign{font-weight:600;font-size:14px}.shownCallerId{text-align:center;padding:8px 10px;font-family:Lato,sans-serif;color:#2ecc71;border:1px solid #d7d7d7;background-color:#fff;width:80%;margin:12px auto auto;border-radius:12px;position:relative;cursor:pointer}.input-box{width:100%;background-color:#fff;padding:4px 10px;border:1px solid rgb(197,197,197);box-sizing:border-box;border-radius:24px;margin-top:12px;display:flex;justify-content:space-between}.input-box:focus-within{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026}.input-box input{font-size:18px;padding:8px 6px;width:100%;box-sizing:border-box;border:none;outline:none;font-weight:600;color:#2b434d}.input-box input::placeholder{font-size:16px;font-weight:500}#input-clear-btn{color:gray;display:flex;align-items:center;cursor:pointer}.contact-card{width:100%;height:54px;display:flex;border-radius:12px;overflow:hidden;margin-top:4px;box-shadow:6px 6px 10px -1px #e6eefc26;cursor:pointer;opacity:0;transform:translateY(20px);animation:slideIn .5s forwards}@keyframes slideIn{to{opacity:1;transform:translateY(0)}}.contact-img{width:50px;display:flex;align-items:center;justify-content:center;border-right:1px solid #bebebe;background-color:#fff}.contact-img img{max-width:50px}.contact-alpha-img{width:50px;display:flex;justify-content:center;align-items:center;font-size:38px;font-weight:600}.contact-details{padding:4px 8px;display:flex;flex-direction:column;justify-content:center}.contact-details p{margin:0;line-height:1;color:#fff}.contact-name{font-weight:600}#topPanel{height:39%;position:relative;margin-bottom:4px;padding:0;border-top-right-radius:30px;border-top-left-radius:30px}.wave-container{position:absolute;bottom:2px}.waves{width:320px;position:relative;margin-bottom:-7px;height:31px;min-height:31px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}app-call-progress{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1000}.mini-dialpad{height:124px!important}.voicemail{line-height:.7;font-size:18px}.dedicated-overlay{position:absolute;width:100%;height:100%;background-color:#2b434d99;display:flex;align-items:center;justify-content:center}.dedicatedNumPopup{width:90%;height:auto;box-sizing:border-box;color:#8a8a8a;background-color:#cbe7df}.chooseDedicatedHeader{padding:.75rem;display:flex;justify-content:space-between}.chooseDedicatedHeader h5{margin-bottom:0}.dedicatedNumList>ul{list-style-type:none;padding:0}.dedicatedNumList>ul li{background-color:#fff;padding:4px;cursor:pointer}@keyframes tilt-shaking{0%{transform:rotate(0)}25%{transform:rotate(5deg)}50%{transform:rotate(0)}75%{transform:rotate(-5deg)}to{transform:rotate(0)}}.tilt-shaking{background-color:#d45858;animation:tilt-shaking .5s infinite;color:#fff}.tilt-shaking h5,.dark .tilt-shaking span,.tilt-shaking span{color:#fff}.no-caller-id-message{display:inline-block;text-align:center;height:10vh;background-color:#fff3cd;color:#000;font-size:.9rem;line-height:1.5;padding:8px}.click-here-link{color:#0f9aee;text-decoration:underline;font-weight:700}.input-info-icon{margin-top:9px;cursor:pointer;color:#2b434d;opacity:.7}::ng-deep .input-tooltip .tooltip-inner{background-color:#000!important}.no-selection-alert{padding:3px 11px;border:1px solid;border-radius:4px;display:flex;justify-content:space-between;color:#721c24;background-color:#f8d7da;border-color:#f5c6cb;align-items:center}.guide{position:relative;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px}.guide:before{content:\"\";position:absolute;top:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid #303030}.guide2{position:absolute;top:-32px;left:24px;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px;pointer-events:none}.guide2:before{content:\"\";position:absolute;bottom:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #303030}.incoming-call-widget{position:absolute;right:-320px;top:30px;width:320px;height:68px;background-color:#3052cd;border-top-right-radius:8px;border-bottom-right-radius:8px;display:flex;align-items:center;padding:4px 12px}.incoming-call-widget h6,.incoming-call-widget p{margin-bottom:0;line-height:1.2;color:#fff}.inc-user-img{width:48px;height:48px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;box-sizing:border-box;margin-right:8px}.inc-user-img img{width:100%}.inc-call-btn{width:40px;height:40px;border-radius:50%;outline:none;border-width:0;display:flex;align-items:center;justify-content:center}.inc-call-btn span{font-size:16px}.inc-accept-btn{background-color:#2ecc71;color:#fff}.inc-reject-btn{background-color:#e14e4e;color:#fff}.inc-user-name{font-weight:600}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i4$1.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: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: CallProgressComponent, selector: "lib-call-progress", inputs: ["callData", "selectedCallerId", "newIncomingCallData", "newIncomingCallsList", "deviceId"], outputs: ["endCallEvent", "incomingCallsNewInfo", "minimiseEvent", "incomingCallInitiated"] }] });
|
|
4363
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DialboxComponent, decorators: [{
|
|
4371
4364
|
type: Component,
|
|
4372
|
-
args: [{ selector: 'lib-incoming-call', template: "<div class=\"call-container\" *ngIf=\"newIncomingCallsList?.length === 1\">\r\n <div style=\"display: flex; flex-direction: column;\">\r\n <div class=\"callToNum\">Incoming call on <br/><span>{{incomingCallData?.phone || 'Unknown Number'}}</span></div>\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" [src]=\"newIncomingCallsList[0]?.img || incomingCallData?.img\" alt=\"\" width=\"120\" />\r\n </div>\r\n <div class=\"callerDetails\">\r\n <!-- <h1>{{newIncomingCallsList[0]?.userInfo?.c2cInformation?.name || incomingCallData?.name || 'Unknown Number'}}</h1> -->\r\n <!-- <p>{{newIncomingCallsList[0]?.userInfo?.displayNum ? newIncomingCallsList[0]?.userInfo?.c2cInformation?.number : newIncomingCallsList[0]?.userInfo?.c2cInformation?.number || incomingCallData?.displayNum || incomingCallData?.phone}}</p> -->\r\n <h1>{{incomingCallData?.name || 'Unknown Number'}}</h1>\r\n <p>{{incomingCallData?.phone}}</p>\r\n </div>\r\n \r\n <!-- <div class=\"callerDetails\">\r\n <h1 [ngStyle]=\"{'margin-top': showKeypad ? '0': '8px'}\">{{callData.name}}</h1>\r\n <p>{{callData.displayNum ? callData.displayNum : callData.phone }}</p>\r\n <h4 style=\"margin-top: 4px\">{{timer}}</h4>\r\n </div> -->\r\n <div class=\"call-action-btns\">\r\n <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected || incomingCallData\">\r\n <span class=\"material-symbols-outlined\" (click)=\"add(newIncomingCallsList[0])\"> call </span> \r\n </button>\r\n <!-- <button class=\"call-btn receive-btn\" *ngIf=\"!newIncomingCallsList[0]?.isCallConnected || incomingCallData\">\r\n <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(newIncomingCallsList[0])\"> call </span>\r\n </button> -->\r\n <button class=\"call-btn mute-btn\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected\" (click)=\"toggleMute(newIncomingCallsList[0])\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container \">\r\n <button class=\"record-btn start-stop\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\r\n <span class=\"recording-icon\"></span>\r\n </button> \r\n <div class=\"\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"newIncomingCallsList[0]?.isCallConnected && 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=\"newIncomingCallsList[0]?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <!-- <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(newIncomingCallsList[0])\"> call_end </span>\r\n </button> -->\r\n <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"onEndCall()\"> 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\" 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<div class=\"call-container\" style=\"width: 100%;\" *ngIf=\"newIncomingCallsList?.length > 1\" [ngClass]=\"{'call-container-open': selectedIncomingCall?.isClickExpand}\">\r\n <div class=\"collops\">\r\n <div class=\"d-flex w-100\">\r\n <div class=\"d-flex flex-column container-fluid\" >\r\n <div class=\"callToNum\">Incoming call <br/><span>{{dedicatedNum}}</span></div>\r\n <ng-container *ngFor=\"let data of newIncomingCallsList\"> \r\n <div class=\"p-2 \">\r\n <div class=\"call-info-wrapper w-100 d-flex align-items-center\">\r\n <div class=\"img\">\r\n <img class=\"avatar-img-wrapper\" [src]=\"data?.img\" alt=\"\" width=\"45\" />\r\n </div>\r\n <div class=\"d-flex justify-content-between w-100 align-items-center mr-2\">\r\n <div class=\"callerDetails-wrapper\">\r\n <h5 class=\"break-word\">{{data?.userInfo?.c2cInformation?.name || '-'}}</h5>\r\n <p class=\"break-word\">{{data?.userInfo?.displayNum ? data?.userInfo?.c2cInformation?.number : data?.userInfo?.c2cInformation?.number }}</p>\r\n </div> \r\n <div class=\"d-flex align-items-center\">\r\n <button class=\"call-btn-wrapper receive-btn\" *ngIf=\"!data?.isCallConnected\">\r\n <!-- <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(data)\"> call </span> -->\r\n <span class=\"material-symbols-outlined\" (click)=\"add(data)\"> call </span>\r\n </button>\r\n <button class=\"call-btn-wrapper mute-btn\" *ngIf=\"data?.isCallConnected\" (click)=\"toggleMute(data)\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container\">\r\n <button class=\"record-btn start-stop\" *ngIf=\"data?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\r\n <span class=\"recording-icon\"></span>\r\n </button> \r\n <div class=\"\">\r\n <button class=\"record-btn pause-resume\" *ngIf=\"data?.isCallConnected && 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=\"data?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <button class=\"call-btn-wrapper reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(data)\"> call_end </span>\r\n </button>\r\n <div class=\"togglearrow-arrow me-2\" id=\"togglearrow\" \r\n (click)=\"hasDetailedInfo(data) ? onClickExpand(data) : null\" \r\n [ngClass]=\"{'disabled': !hasDetailedInfo(data)}\"\r\n [title]=\"hasDetailedInfo(data) ? 'View details' : 'No details available'\">\r\n <i class=\"fa fa-angle-right\"></i>\r\n </div>\r\n <!-- <div *ngIf=\"data?.customParameters?.get('c2cNumber') === true || data?.customParameters?.get('c2cNumber') === 'true'\" class=\"togglearrow-arrow me-2\" id=\"togglearrow\" (click)=\"onClickExpand(data)\"> \r\n <i class=\"fa fa-angle-right\"></i> \r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div class=\"call-container p-3 text-white model-content\" *ngIf=\"isClickExpand \"> \r\n <div class=\"mb-2\" style=\"width: 100%; height: 100%;\">\r\n <div class=\"call-animation\" [ngClass]=\"{'call-animation-play': showRingAnimation}\">\r\n <img class=\"avatar-img\" [src]=\"incomingCallData.img\" alt=\"\" width=\"100\" />\r\n </div>\r\n <div class=\"text-center\">\r\n <h3 class=\"text-white\">{{selectedIncomingCall?.userInfo?.c2cInformation?.name || '-'}}</h3>\r\n </div>\r\n <div class=\"f-13\">\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Subject:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.subject || '-'}}</div>\r\n </div> \r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Email:</div>\r\n <div>{{selectedIncomingCall?.userInfo?.c2cInformation?.email || '-'}}</div>\r\n </div> \r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Number:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.number}}</div>\r\n </div>\r\n <div class=\"col-6\">\r\n <div class=\"\">Language:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.language || '-'}}</div>\r\n </div>\r\n </div>\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Extension:</div>\r\n <div class=\"ml-2\">{{selectedIncomingCall?.userInfo?.c2cInformation?.extension || '-'}}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-3\">\r\n <div class=\"col-12 d-flex align-items-center mb-2\">\r\n <div class=\"me-2\">Image:</div>\r\n <div class=\"text-ellipsis\">\r\n <ng-container *ngIf=\"selectedIncomingCall?.userInfo?.c2cInformation?.image && selectedIncomingCall?.userInfo?.c2cInformation?.image !== '-'; else noImage\">\r\n <img src=\"{{selectedIncomingCall?.userInfo?.c2cInformation?.image}}\" alt=\"\" width=\"42\" height=\"42\" 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\r\n <div class=\" mb-4\">\r\n <div class=\"\">\r\n <div class=\"\">Message:</div>\r\n <div class=\"text-ellipsis\">{{selectedIncomingCall?.userInfo?.c2cInformation?.message || '-'}}</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-2\">\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Point Name:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.pointName || '-'}}</div>\r\n </div>\r\n <div class=\"col-6 mb-2\">\r\n <div class=\"\">Source Name:</div>\r\n <div class=\"\">{{selectedIncomingCall?.userInfo?.c2cInformation?.sourceName || '-'}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"call-action-btns mt-0\">\r\n <button class=\"call-btn receive-btn\" *ngIf=\"!selectedIncomingCall?.isCallConnected\">\r\n <span class=\"material-symbols-outlined\" (click)=\"acceptCallFromList(selectedIncomingCall)\"> call </span>\r\n </button>\r\n <button class=\"call-btn mute-btn\" *ngIf=\"selectedIncomingCall?.isCallConnected\" (click)=\"toggleMute(selectedIncomingCall)\" [ngClass]=\"{'active-mute': isMute}\">\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 <div class=\"record-btn-container\">\r\n <button class=\"record-btn start-stop\" *ngIf=\"selectedIncomingCall?.isCallConnected && !isRecording\" [ngClass]=\"{'recording': isRecording, 'stopped': !isRecording}\" (click)=\"toggleRecording('')\" [title]=\"isRecording ? 'Stop Recording' : 'Start Recording'\" [disabled]=\"disbaleEndCallBtn\">\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=\"selectedIncomingCall?.isCallConnected && 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=\"selectedIncomingCall?.isCallConnected && isPaused\" (click)=\"resumeRecording('')\">\r\n <span class=\"material-symbols-outlined\"> play_arrow </span>\r\n </button>\r\n </div>\r\n </div>\r\n <button class=\"call-btn reject-btn\">\r\n <span class=\"material-symbols-outlined\" (click)=\"rejectCallFromList(selectedIncomingCall)\"> call_end </span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\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\" [ngStyle]=\"{'width': '756px'}\">\r\n <defs>\r\n <path id=\"gentle-wave\" d=\"M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z\" />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"0\" fill=\"rgba(255,255,255,0.7)\" />\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"3\" fill=\"rgba(255,255,255,0.5)\" /> \r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n</div>", styles: [".call-container{width:385px!important;height:646px!important;margin:auto;border-radius:30px;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}.collops{display:flex;flex-direction:column;width:100%;height:100%}.container-fluid{width:400px;height:100%;margin-top:10px}.model-content{background-color:#0d6efd;border-radius:20px;width:395px!important}.call-container-open{width:752px!important}.calls-side-by-side{position:fixed;top:0;width:30%;height:498px;z-index:1050;pointer-events:auto;display:flex;align-items:flex-start;left:-10rem;transform:translate(.2rem);transition:left 1s ease-in-out}.move{left:41vw!important}.f-13{font-size:13px!important}.call-animation{background:#fff;width:100px;height:100px;position:relative;margin:20px auto;border-radius:100%;border:solid 4px #fff}.call-animation:before{position:absolute;content:\"\";top:0;left:0;width:100%;height:100%;backface-visibility:hidden;border-radius:50%}.avatar-img-wrapper{border-radius:100%;margin:0 5px}.call-btn-wrapper{height:38px;background-color:#fff;border-radius:30px;margin:0 4px;opacity:.9;width:40px}.call-btn-wrapper span{color:#fff;line-height:unset!important}.hold-btn{background-color:#bebebe26;border:none}.hold-btn span,.mute-btn span{color:#fff!important}.active-hold{background-color:#fff!important}.active-hold span{color:#000!important}.active-mute{background-color:transparent}.call-info-wrapper{border:1px solid white;border-radius:7px;padding:8px 1px!important;word-break:break-all}.call-animation-play{animation:play 3s linear infinite}.avatar-img{width:94px;height:94px;border-radius:100%;position:absolute;left:0;top:0}@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}.callerDetails h1{margin:12px 0 0;color:#fff}.callerDetails-wrapper{margin:0 5px;color:#fff;display:flex;flex-direction:column}.callerDetails-wrapper h3,.callerDetails-wrapper h5{margin:0;color:#fff}.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}.callerDetails h4{margin:0;color:#fff}.callerDetails p,.callerDetails-wrapper p{margin-top:-3px;margin-bottom:0;color:#fff}.call-sec-btn{position:relative;width:50px;height:50px;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}.call-sec-btn span{color:#cccbcb}.call-btn{width:48px;height:45px;background-color:#fff;border-radius:30px;box-sizing:border-box;margin:0 8px;opacity:.9}.call-btn:hover{opacity:1}.call-btn span{color:#fff;line-height:unset!important}.receive-btn{background-color:#28a745;border:2px solid #28a745}.mute-btn{position:relative;border:none;background-color:#bebebe26}.reject-btn{background-color:#e03131;border:2px solid #e03131}.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}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.call-action-btns{text-align:center;display:flex;justify-content:center;align-items:center;margin-top:240px}#call-input{background-color:transparent;border:none;outline:none;text-align:center;color:#fff}.wave-container{position:absolute;bottom:0}.waves{width:660px;position:relative;margin-bottom:-7px;height:40px;min-height:40px}.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}.callToNum{color:#fff;font-weight:400;text-align:center}.callToNum span{font-weight:600}.text-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;display:block}.record-action-btns{display:flex;flex-direction:column;align-items:center}.record-btn-container{position:relative}.record-btn{border:none;border-radius:50%;width:48px;height:48px!important;display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;overflow:hidden}.record-btn-side{border:none;border-radius:50%;width:44px;height:44px;display:flex;align-items:center;justify-content:center;cursor:pointer;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;justify-content:center;width:48px;height:48px;background-color:#fff;border-radius:30px}.record-btn.pause-resume{border:none;border-radius:50%;width:48px;height:48px;background:white;display:flex;align-items:center;justify-content:center}.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%}.togglearrow-arrow.disabled{opacity:.3;cursor:not-allowed;pointer-events:none}.togglearrow-arrow.disabled:hover{opacity:.3;cursor:not-allowed}\n"] }]
|
|
4373
|
-
}], ctorParameters: function () { return [{ type: ExtensionService }, { type:
|
|
4365
|
+
args: [{ selector: 'lib-dialbox', template: "<div id=\"dragparent1\" [ngStyle]=\"{'display':isDialpadHidden ? 'none': 'block'}\">\r\n <lib-call-progress *ngIf=\"isCallInProgress\"\r\n (endCallEvent)=\"endCall()\"\r\n (minimiseEvent)=\"onMinimise($event)\"\r\n (incomingCallInitiated)=\"newIncomingCallInitiated()\"\r\n [newIncomingCallData]=\"newIncomingCallData\"\r\n [deviceId]=\"deviceId\"\r\n [newIncomingCallsList]=\"incomingCallsList\"\r\n (incomingCallsNewInfo)=\"incomingCallsNewInfo($event)\"\r\n [selectedCallerId]=\"selectedCallerId\"\r\n [callData]=\"callData\">\r\n </lib-call-progress>\r\n <div class=\"dialpad-container\" *ngIf=\"!isCallInProgress\" [ngClass]=\"{'mini-dialpad': isMinimised}\" tabindex=\"0\" (keydown)=\"handleDivKeydown($event)\">\r\n <div id=\"topPanel\" [ngStyle]=\"{'height': callerIdList.length ? '40%' : '39%'}\">\r\n <div class=\"dialpad-alerts\" *ngIf=\"dialAlert.show\">\r\n <div class=\"no-selection-alert\">\r\n <!-- <p class=\"mb-0\">Select C2C number to call</p> -->\r\n <p class=\"mb-0\">{{dialAlert.msg}}</p>\r\n <span class=\"fa fa-times\" (click)=\"shakeDedicatedBtn = false\"></span>\r\n </div>\r\n </div>\r\n <div class=\"dialpad-alerts\" *ngIf=\"callNumberToast.show\">\r\n <div class=\"dialbox-pop1 alert fade show\" [ngClass]=\"callNumberToast.type\" role=\"alert\">\r\n <div class=\"d-flex justify-content-between\">\r\n <div class=\"flex-grow-1 my-auto text-left\">\r\n You'r calling <strong>{{callNumberToast.displayNum}}</strong>\r\n </div>\r\n <div class=\"text-right\">\r\n <button class=\"btn btn-link btn-disc p-0 px-1\" (click)=\"cancelDialNumber()\">Cancel Call</button>\r\n <!-- <button class=\"btn btn-link btn-success btn-disc p-0 px-2\">Continue</button> -->\r\n </div>\r\n \r\n </div>\r\n </div>\r\n </div>\r\n <div style=\"padding: 0 18px\" (paste)=\"handleNumberPaste($event)\">\r\n <div class=\"d-flex justify-content-between mt-2\">\r\n <p></p>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"hideDialpad()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"#ffffff\"><path 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\"/></svg>\r\n </span>\r\n </div>\r\n <div class=\"input-box\">\r\n <input type=\"text\" #dialInput placeholder=\"Enter a name or number\" tabindex=\"1\" [(ngModel)]=\"dialedNumber\" (ngModelChange)=\"onDialInputChange($event)\"/>\r\n <span class=\"\" id=\"input-clear-btn\" (click)=\"clearInput()\" *ngIf=\"showInputClearBtn\">\r\n <svg width=\"50px\" height=\"30px\" viewBox=\"0 10 40 60\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" baseProfile=\"full\" enable-background=\"new 0 0 76.00 76.00\" xml:space=\"preserve\">\r\n <path fill=\"#5d6061\" fill-opacity=\"1\" stroke-width=\"0.2\" stroke-linejoin=\"round\" d=\"M 47.5282,42.9497L 42.5784,38L 47.5282,33.0502L 44.9497,30.4718L 40,35.4216L 35.0502,30.4718L 32.4718,33.0502L 37.4216,38L 32.4718,42.9497L 35.0502,45.5282L 40,40.5784L 44.9497,45.5282L 47.5282,42.9497 Z M 18.0147,41.5355L 26.9646,50.4854C 28.0683,51.589 29,52 31,52L 52,52C 54.7614,52 57,49.7614 57,47L 57,29C 57,26.2386 54.7614,24 52,24L 31,24C 29,24 28.0683,24.4113 26.9646,25.5149L 18.0147,34.4645C 16.0621,36.4171 16.0621,39.5829 18.0147,41.5355 Z M 31,49C 30,49 29.6048,48.8828 29.086,48.3641L 20.1361,39.4142C 19.355,38.6332 19.355,37.3669 20.1361,36.5858L 29.086,27.6362C 29.6048,27.1175 30,27 31,27.0001L 52,27.0001C 53.1046,27.0001 54,27.8955 54,29.0001L 54,47.0001C 54,48.1046 53.1046,49.0001 52,49.0001L 31,49 Z \"/>\r\n </svg> \r\n </span>\r\n <span class=\"input-info-icon\" placement=\"bottom-right\" tooltipClass=\"input-tooltip\" ngbTooltip=\"For extension dialing, use formats like +12345678910 x123,+12345678910 ext.123, +12345678910,123\"><i class=\"fa fa-info-circle\"></i></span>\r\n </div>\r\n <div class=\"guide\" *ngIf=\"callerIdList.length && !(dialedNumber.length > 2)\">\r\n <span class=\"guidetext\">Please enter a number or select a saved contact</span>\r\n </div>\r\n <!-- <div class=\"input-error\" *ngIf=\"dialAlert.show\">\r\n <span>{{dialAlert.msg}}</span>\r\n </div> -->\r\n <div>\r\n <div class=\"contact-card\" *ngFor=\"let contact of filteredContactList\" (click)=\"onContactSelect(contact)\">\r\n <div class=\"contact-img\">\r\n <img [src]=\"contact.image\" alt=\"user image\" loading=\"lazy\" *ngIf=\"contact.image else alphaName\"/>\r\n <ng-template #alphaName>\r\n <span class=\"contact-alpha-img\">{{getFirstLetter(contact.firstName)}}</span>\r\n </ng-template>\r\n </div>\r\n <div class=\"contact-details\">\r\n <p style=\"margin-bottom: 4px\" class=\"contact-name\">{{getFullName(contact) }}</p>\r\n <p>{{contact.numbersList[0].number}}</p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"wave-container\">\r\n <svg\r\n class=\"waves\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 24 150 28\"\r\n preserveAspectRatio=\"none\"\r\n shape-rendering=\"auto\"\r\n >\r\n <defs>\r\n <path\r\n 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 />\r\n </defs>\r\n <g class=\"parallax\">\r\n <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"0\"\r\n fill=\"rgba(255,255,255,0.7)\"\r\n />\r\n <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"3\"\r\n fill=\"rgba(255,255,255,0.5)\"\r\n />\r\n <!-- <use\r\n xlink:href=\"#gentle-wave\"\r\n x=\"48\"\r\n y=\"5\"\r\n fill=\"rgba(255,255,255,0.3)\"\r\n /> -->\r\n <use xlink:href=\"#gentle-wave\" x=\"48\" y=\"7\" fill=\"#fff\" />\r\n </g>\r\n </svg>\r\n </div>\r\n </div>\r\n <div class=\"btn-container\" *ngIf=\"!isMinimised\">\r\n <button class=\"dial-btn\" *ngFor=\"let key of keypadVal;let i = index\"\r\n (keydown.enter)=\"onEnter(key.num)\" (click)=\"addNumber(key.num)\"\r\n [ngStyle]=\"{'margin-top': key.text === '+' ? '3px' : '0'}\"\r\n [tabindex]=\"dialedNumber.length ? '0': i+2\" longPress (longPress)=\"addNumber(key.text)\" shortPress (shortPress)=\"addNumber(key.num)\">\r\n {{key.num}} \r\n <span *ngIf=\"key.num == 1;else otherThanOne\" class=\"material-symbols-outlined voicemail\">\r\n voicemail\r\n </span>\r\n <ng-template #otherThanOne>\r\n <span class=\"btn-albhabets\" [ngClass]=\"{'plusSign': key.text === '+'}\">{{key.text ? key.text : ' '}}</span>\r\n </ng-template>\r\n </button>\r\n </div>\r\n <div class=\"call-btn-container\" *ngIf=\"!isMinimised\" (mouseenter)=\"onCallBtnMouseEnter($event)\" (mouseleave)=\"onCallBtnMouseLeave($event)\">\r\n <div class=\"call-btn\" (click)=\"initiateCall()\" [tabindex]=\"dialedNumber.length ? '2': '15'\"\r\n [ngStyle]=\"{'pointer-events': dialedNumber.length && selectedCallerId ? 'auto' : 'none', 'opacity': dialedNumber.length && selectedCallerId ? '1' : '0.5'}\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call\r\n </span>\r\n </div>\r\n </div>\r\n <div *ngIf=\"callerIdList.length && !isMinimised\" class=\"position-relative\">\r\n <div class=\"shownCallerId\" *ngIf=\"selectedCallerId; else askBlock\" (click)=\"toggleCallerIdDiv()\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + selectedCallerId?.isoCode?.toLowerCase()\"></span>\r\n {{selectedCallerId?.number}}\r\n </div>\r\n </div>\r\n <ng-template #askBlock>\r\n <div class=\"shownCallerId\" (click)=\"toggleCallerIdDiv()\" [ngClass]=\"{ 'tilt-shaking': shakeDedicatedBtn }\">\r\n <div class=\"d-flex justify-content-center\">\r\n <h5 class=\"mb-0\">Select C2C number</h5>\r\n <!-- <span class=\"ml-2\" style=\"opacity:.8;margin-top:2px\">\r\n <img src=\"assets/images/icon_down_arrow.svg\" alt=\"down\" width=\"10px\">\r\n </span> -->\r\n <span class=\"fa fa-angle-down ml-2 text-blue\" style=\"margin-top:2px\"></span>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <div class=\"guide2\" *ngIf=\"shakeDedicatedBtn\">\r\n <span class=\"guidetext\">Please select a number from below dropdown</span>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"callerIdList.length; else noCallerIdMessage\">\r\n <div class=\"caller-id-list-container\" *ngIf=\"callerIdList.length && !isMinimised\" id=\"callerIdContainer\" [ngClass]=\"{'visible': !isCallerIdHidden}\" >\r\n <div style=\"display: flex; justify-content: space-between\">\r\n <!-- <h4>Select C2C Softphone Number</h4> -->\r\n <h4>Make outgoing call using</h4>\r\n <span\r\n class=\"material-symbols-outlined\"\r\n style=\"cursor: pointer\"\r\n (click)=\"isCallerIdHidden = true\"\r\n >\r\n close\r\n </span>\r\n </div>\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\" (click)=\"onDedicatedNumSelect(callerId)\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n <ng-template #noCallerIdMessage>\r\n <span class=\"no-caller-id-message\">To make any voice calls, please <a routerLink=\"/extension/dedicatednumber/{{token}}\" class=\"click-here-link\" title=\"Settings > C2C Number\">subscribe</a> to a voice capable C2C Number.\r\n </span>\r\n </ng-template>\r\n <div class=\"dedicated-overlay\" *ngIf=\"showDedicatedPopup\">\r\n <div class=\"card dedicatedNumPopup\">\r\n <div class=\"card-header chooseDedicatedHeader\">\r\n <h5>Choose C2C Number</h5>\r\n <span class=\"material-symbols-outlined dial-close-btn\" (click)=\"showDedicatedPopup = false\">close</span>\r\n </div>\r\n <div class=\"card-body dedicatedNumList\">\r\n <ul>\r\n <ng-container *ngFor=\"let callerId of callerIdList\">\r\n <li [ngClass]=\"{'selectedCallerIdClass': callerId?.number == selectedCallerId?.number}\" (click)=\"showDedicatedPopup = false\">\r\n <div>\r\n <span [ngClass]=\"'fi fi-' + callerId?.isoCode?.toLowerCase()\"></span>\r\n {{callerId?.number}}\r\n </div>\r\n <span>{{callerId?.countryName}}</span>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- <div class=\"incoming-call-widget\" *ngFor=\"let call of newIncomingCalls;let i = index\" [ngStyle]=\"{'top': (30 + i * 72) + 'px'}\">\r\n <div>\r\n <div class=\"inc-user-img\">\r\n <img src=\"assets/images/user.jpg\" alt=\"user image\">\r\n </div>\r\n \r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <p class=\"inc-user-name\">{{call.customParameters.get('name')}}</p>\r\n <p>{{call.parameters.From}}</p>\r\n </div>\r\n <div class=\"d-flex\">\r\n <button class=\"inc-call-btn inc-accept-btn mr-2\" (click)=\"acceptNewIncomingCall(call)\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call\r\n </span>\r\n </button>\r\n <button class=\"inc-call-btn inc-reject-btn\" (click)=\"rejectNewIncomingCall(call)\">\r\n <span class=\"material-symbols-outlined\" style=\"color: white\">\r\n call_end\r\n </span>\r\n </button>\r\n </div>\r\n \r\n </div> -->\r\n </div>\r\n</div>\r\n", styles: ["#dragparent1{position:fixed;left:100px;z-index:9999999;font-family:Lato,sans-serif;display:none}.dialpad-container{width:320px!important;height:600px!important;background:white;margin:auto;border-radius:30px;box-shadow:#00000040 0 54px 55px,#0000001f 0 -12px 30px,#0000001f 0 4px 6px,#0000002b 0 12px 13px,#00000017 0 -3px 5px;display:flex;flex-direction:column;box-sizing:border-box;position:relative;line-height:1.1}.dialpad-alerts{position:absolute;width:calc(100% - 28px);left:14px;top:8px;z-index:1200}.btn-disc{font-size:12px}.dialbox-pop1{font-size:.8rem;z-index:9;padding:8px}.input-error>span{color:#dfdfdf;margin-bottom:2px}.dial-close-btn{cursor:pointer;opacity:.6}.dial-close-btn:hover{opacity:1}.btn-container{display:flex;flex-wrap:wrap;padding:0 18px}.dial-btn{width:50px;height:50px;background-color:#fff;border-radius:4px;text-align:center;box-sizing:border-box;margin:4px 22px;font-size:28px;display:flex;flex-direction:column;justify-content:center;align-items:center;font-family:Lato,sans-serif;font-weight:900;font-style:normal;color:#2b434d;cursor:pointer;opacity:.8;border:none}.dial-btn:hover{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:focus{opacity:1;box-shadow:#00000026 0 2px 8px}.dial-btn:active{box-shadow:#32325d40 0 30px 60px -12px inset,#0000004d 0 18px 36px -18px inset}.call-btn-container{display:flex;margin-top:8px;justify-content:center;position:relative}.call-btn{display:flex;align-items:center;justify-content:center;width:54px;height:54px;border-radius:27px;background-color:#2ecc71;outline:none;border:none;box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;opacity:.8;cursor:pointer}.call-btn:hover{opacity:1}.call-btn:focus{opacity:1}.caller-id-list-container{width:100%;height:auto;position:absolute;bottom:-100%;left:0;border-radius:0 0 30px 30px/0px 0px 30px 30px;padding:8px 12px 32px;box-sizing:border-box;color:#8a8a8a}.visible{animation:slideUp .8s forwards}#callerIdContainer ul{list-style:none;padding-left:0;margin:0}.dialpad-container h4{font-family:Lato,sans-serif;margin:0 0 8px}#callerIdContainer ul li{background-color:#fff;padding:8px;margin-top:7px;display:flex;border-radius:4px;justify-content:space-between;font-size:14px;cursor:pointer}.fi{border-radius:2px;margin-right:2px}@keyframes slideUp{0%{bottom:-100%}to{bottom:0}}.selectedCallerIdClass{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026;border:1px solid #e0e0e0;color:#3a3a3a}.toggleBtn{color:gray;border:none;background-color:#e5eef1}.btn-albhabets{font-family:Lato,sans-serif;font-size:12px;font-weight:400}.plusSign{font-weight:600;font-size:14px}.shownCallerId{text-align:center;padding:8px 10px;font-family:Lato,sans-serif;color:#2ecc71;border:1px solid #d7d7d7;background-color:#fff;width:80%;margin:12px auto auto;border-radius:12px;position:relative;cursor:pointer}.input-box{width:100%;background-color:#fff;padding:4px 10px;border:1px solid rgb(197,197,197);box-sizing:border-box;border-radius:24px;margin-top:12px;display:flex;justify-content:space-between}.input-box:focus-within{box-shadow:6px 6px 10px -1px #00000026,-5px -4px 10px -1px #00000026}.input-box input{font-size:18px;padding:8px 6px;width:100%;box-sizing:border-box;border:none;outline:none;font-weight:600;color:#2b434d}.input-box input::placeholder{font-size:16px;font-weight:500}#input-clear-btn{color:gray;display:flex;align-items:center;cursor:pointer}.contact-card{width:100%;height:54px;display:flex;border-radius:12px;overflow:hidden;margin-top:4px;box-shadow:6px 6px 10px -1px #e6eefc26;cursor:pointer;opacity:0;transform:translateY(20px);animation:slideIn .5s forwards}@keyframes slideIn{to{opacity:1;transform:translateY(0)}}.contact-img{width:50px;display:flex;align-items:center;justify-content:center;border-right:1px solid #bebebe;background-color:#fff}.contact-img img{max-width:50px}.contact-alpha-img{width:50px;display:flex;justify-content:center;align-items:center;font-size:38px;font-weight:600}.contact-details{padding:4px 8px;display:flex;flex-direction:column;justify-content:center}.contact-details p{margin:0;line-height:1;color:#fff}.contact-name{font-weight:600}#topPanel{height:39%;position:relative;margin-bottom:4px;padding:0;border-top-right-radius:30px;border-top-left-radius:30px}.wave-container{position:absolute;bottom:2px}.waves{width:320px;position:relative;margin-bottom:-7px;height:31px;min-height:31px}.parallax>use{animation:move-forever 25s cubic-bezier(.55,.5,.45,.5) infinite}.parallax>use:nth-child(1){animation-delay:-2s;animation-duration:7s}.parallax>use:nth-child(2){animation-delay:-3s;animation-duration:10s}.parallax>use:nth-child(3){animation-delay:-4s;animation-duration:13s}.parallax>use:nth-child(4){animation-delay:-5s;animation-duration:20s}@keyframes move-forever{0%{transform:translate3d(-90px,0,0)}to{transform:translate3d(85px,0,0)}}app-call-progress{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:1000}.mini-dialpad{height:124px!important}.voicemail{line-height:.7;font-size:18px}.dedicated-overlay{position:absolute;width:100%;height:100%;background-color:#2b434d99;display:flex;align-items:center;justify-content:center}.dedicatedNumPopup{width:90%;height:auto;box-sizing:border-box;color:#8a8a8a;background-color:#cbe7df}.chooseDedicatedHeader{padding:.75rem;display:flex;justify-content:space-between}.chooseDedicatedHeader h5{margin-bottom:0}.dedicatedNumList>ul{list-style-type:none;padding:0}.dedicatedNumList>ul li{background-color:#fff;padding:4px;cursor:pointer}@keyframes tilt-shaking{0%{transform:rotate(0)}25%{transform:rotate(5deg)}50%{transform:rotate(0)}75%{transform:rotate(-5deg)}to{transform:rotate(0)}}.tilt-shaking{background-color:#d45858;animation:tilt-shaking .5s infinite;color:#fff}.tilt-shaking h5,.dark .tilt-shaking span,.tilt-shaking span{color:#fff}.no-caller-id-message{display:inline-block;text-align:center;height:10vh;background-color:#fff3cd;color:#000;font-size:.9rem;line-height:1.5;padding:8px}.click-here-link{color:#0f9aee;text-decoration:underline;font-weight:700}.input-info-icon{margin-top:9px;cursor:pointer;color:#2b434d;opacity:.7}::ng-deep .input-tooltip .tooltip-inner{background-color:#000!important}.no-selection-alert{padding:3px 11px;border:1px solid;border-radius:4px;display:flex;justify-content:space-between;color:#721c24;background-color:#f8d7da;border-color:#f5c6cb;align-items:center}.guide{position:relative;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px}.guide:before{content:\"\";position:absolute;top:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid #303030}.guide2{position:absolute;top:-32px;left:24px;padding:8px;background-color:#303030;color:#fff;border-radius:8px;margin-top:8px;font-size:12px;pointer-events:none}.guide2:before{content:\"\";position:absolute;bottom:-8px;left:8px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #303030}.incoming-call-widget{position:absolute;right:-320px;top:30px;width:320px;height:68px;background-color:#3052cd;border-top-right-radius:8px;border-bottom-right-radius:8px;display:flex;align-items:center;padding:4px 12px}.incoming-call-widget h6,.incoming-call-widget p{margin-bottom:0;line-height:1.2;color:#fff}.inc-user-img{width:48px;height:48px;border-radius:50%;overflow:hidden;display:flex;align-items:center;justify-content:center;box-sizing:border-box;margin-right:8px}.inc-user-img img{width:100%}.inc-call-btn{width:40px;height:40px;border-radius:50%;outline:none;border-width:0;display:flex;align-items:center;justify-content:center}.inc-call-btn span{font-size:16px}.inc-accept-btn{background-color:#2ecc71;color:#fff}.inc-reject-btn{background-color:#e14e4e;color:#fff}.inc-user-name{font-weight:600}\n"] }]
|
|
4366
|
+
}], ctorParameters: function () { return [{ type: TwilioService }, { type: ExtensionService }, { type: i3.MatDialog }, { type: IpAddressService }, { type: ExtensionService }, { type: i0.ChangeDetectorRef }, { type: i5.Router }, { type: IncomeingCallSocketService }]; }, propDecorators: { autoOpenOnIncoming: [{
|
|
4374
4367
|
type: Input
|
|
4375
|
-
}],
|
|
4368
|
+
}], contactInfo: [{
|
|
4376
4369
|
type: Input
|
|
4377
4370
|
}], deviceId: [{
|
|
4378
4371
|
type: Input
|
|
4379
|
-
}],
|
|
4372
|
+
}], isDialpadHidden: [{
|
|
4373
|
+
type: Input
|
|
4374
|
+
}], incomingCallData: [{
|
|
4375
|
+
type: Input
|
|
4376
|
+
}], closeDialpadEvent: [{
|
|
4380
4377
|
type: Output
|
|
4381
|
-
}],
|
|
4378
|
+
}], callInitiated: [{
|
|
4382
4379
|
type: Output
|
|
4383
|
-
}],
|
|
4380
|
+
}], endCallEvent: [{
|
|
4381
|
+
type: Output
|
|
4382
|
+
}], minimiseEvent: [{
|
|
4383
|
+
type: Output
|
|
4384
|
+
}], incomingCallsNewInfoEvent: [{
|
|
4385
|
+
type: Output
|
|
4386
|
+
}], incomingCallInitiated: [{
|
|
4387
|
+
type: Output
|
|
4388
|
+
}], dialInputElement: [{
|
|
4389
|
+
type: ViewChild,
|
|
4390
|
+
args: ['dialInput']
|
|
4391
|
+
}], numberDialed: [{
|
|
4384
4392
|
type: Output
|
|
4385
4393
|
}] } });
|
|
4386
4394
|
|
|
@@ -4423,13 +4431,13 @@ class CallerIdDialogComponent {
|
|
|
4423
4431
|
console.log('doNotShowAgain');
|
|
4424
4432
|
}
|
|
4425
4433
|
}
|
|
4426
|
-
CallerIdDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CallerIdDialogComponent, deps: [{ token: i5.Router }, { token: TwilioService }, { token: i3
|
|
4427
|
-
CallerIdDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CallerIdDialogComponent, selector: "lib-caller-id-dialog", ngImport: i0, template: "<div class=\"main-theme {{storedTheme}}\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title\"> Caller ID Not Set</h5>\n <button class=\"close\" (click)=\"closeModal()\">\n <span>x</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <p class=\"mb-1\"><strong>There is no caller ID set in your account</strong> <br /></p>\n <p>The receiver will not be able to identify your call or call you back</p>\n <div class=\"d-flex align-items-center justify-content-center\">\n <input type=\"checkbox\" checked (change)=\"hideMessage($event)\" [(ngModel)]=\"alertToggle\" class=\"mr-2\">\n <label for=\"\" class=\"mb-0 text-muted\">I do not want to see this message again</label>\n </div>\n <button class=\"btn btn-black-outline\" (click)=\"doNotShowAgain()\">Do not show this message again</button>\n </div>\n <div class=\"modal-footer border-top d-flex justify-content-between\">\n <button class=\"btn btn-black-outline\" (click)=\"redirectToCallingPreference()\">Click to set caller ID</button>\n \n <button class=\"btn btn-blue ms-2\" (click)=\"proceed()\">Proceed without Caller ID</button>\n </div>\n</div>", styles: ["::ng-deep .mat-dialog-container{padding:0!important;border-radius:8px;box-shadow:0 4px 10px #0003;text-align:center}::ng-deep .cus-dialog{z-index:111111!important}.btn-black-outline{border:1px solid #000000;border-radius:10px}.btn-blue{background-color:#234de8;color:#fff!important;margin-left:8px}::ng-deep .cdk-overlay-container{z-index:111111}\n"], dependencies: [{ kind: "directive", type: i4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
4434
|
+
CallerIdDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CallerIdDialogComponent, deps: [{ token: i5.Router }, { token: TwilioService }, { token: i3.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
|
|
4435
|
+
CallerIdDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CallerIdDialogComponent, selector: "lib-caller-id-dialog", ngImport: i0, template: "<div class=\"main-theme {{storedTheme}}\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title\"> Caller ID Not Set</h5>\n <button class=\"close\" (click)=\"closeModal()\">\n <span>x</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <p class=\"mb-1\"><strong>There is no caller ID set in your account</strong> <br /></p>\n <p>The receiver will not be able to identify your call or call you back</p>\n <div class=\"d-flex align-items-center justify-content-center\">\n <input type=\"checkbox\" checked (change)=\"hideMessage($event)\" [(ngModel)]=\"alertToggle\" class=\"mr-2\">\n <label for=\"\" class=\"mb-0 text-muted\">I do not want to see this message again</label>\n </div>\n <button class=\"btn btn-black-outline\" (click)=\"doNotShowAgain()\">Do not show this message again</button>\n </div>\n <div class=\"modal-footer border-top d-flex justify-content-between\">\n <button class=\"btn btn-black-outline\" (click)=\"redirectToCallingPreference()\">Click to set caller ID</button>\n \n <button class=\"btn btn-blue ms-2\" (click)=\"proceed()\">Proceed without Caller ID</button>\n </div>\n</div>", styles: ["::ng-deep .mat-dialog-container{padding:0!important;border-radius:8px;box-shadow:0 4px 10px #0003;text-align:center}::ng-deep .cus-dialog{z-index:111111!important}.btn-black-outline{border:1px solid #000000;border-radius:10px}.btn-blue{background-color:#234de8;color:#fff!important;margin-left:8px}::ng-deep .cdk-overlay-container{z-index:111111}\n"], dependencies: [{ kind: "directive", type: i4$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
4428
4436
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CallerIdDialogComponent, decorators: [{
|
|
4429
4437
|
type: Component,
|
|
4430
4438
|
args: [{ selector: 'lib-caller-id-dialog', template: "<div class=\"main-theme {{storedTheme}}\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title\"> Caller ID Not Set</h5>\n <button class=\"close\" (click)=\"closeModal()\">\n <span>x</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <p class=\"mb-1\"><strong>There is no caller ID set in your account</strong> <br /></p>\n <p>The receiver will not be able to identify your call or call you back</p>\n <div class=\"d-flex align-items-center justify-content-center\">\n <input type=\"checkbox\" checked (change)=\"hideMessage($event)\" [(ngModel)]=\"alertToggle\" class=\"mr-2\">\n <label for=\"\" class=\"mb-0 text-muted\">I do not want to see this message again</label>\n </div>\n <button class=\"btn btn-black-outline\" (click)=\"doNotShowAgain()\">Do not show this message again</button>\n </div>\n <div class=\"modal-footer border-top d-flex justify-content-between\">\n <button class=\"btn btn-black-outline\" (click)=\"redirectToCallingPreference()\">Click to set caller ID</button>\n \n <button class=\"btn btn-blue ms-2\" (click)=\"proceed()\">Proceed without Caller ID</button>\n </div>\n</div>", styles: ["::ng-deep .mat-dialog-container{padding:0!important;border-radius:8px;box-shadow:0 4px 10px #0003;text-align:center}::ng-deep .cus-dialog{z-index:111111!important}.btn-black-outline{border:1px solid #000000;border-radius:10px}.btn-blue{background-color:#234de8;color:#fff!important;margin-left:8px}::ng-deep .cdk-overlay-container{z-index:111111}\n"] }]
|
|
4431
4439
|
}], ctorParameters: function () {
|
|
4432
|
-
return [{ type: i5.Router }, { type: TwilioService }, { type: i3
|
|
4440
|
+
return [{ type: i5.Router }, { type: TwilioService }, { type: i3.MatDialogRef }, { type: undefined, decorators: [{
|
|
4433
4441
|
type: Inject,
|
|
4434
4442
|
args: [MAT_DIALOG_DATA]
|
|
4435
4443
|
}] }];
|