@exotel-npm-dev/webrtc-client-sdk 1.0.0

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.
@@ -0,0 +1,468 @@
1
+ import { Call } from "../api/callAPI/Call";
2
+ import { CallController } from "./CallCtrlerDummy";
3
+ import { CallListener } from '../listeners/CallListener';
4
+ import { DoRegister as DoRegisterRL } from '../api/registerAPI/RegisterListener';
5
+ import { UnRegister as UnRegisterRL } from '../api/registerAPI/RegisterListener';
6
+ import { ExotelVoiceClientListener } from '../listeners/ExotelVoiceClientListener';
7
+ import { SessionListener as SessionListenerSL } from '../listeners/SessionListeners';
8
+
9
+ import { initDiagnostics as initDiagnosticsDL} from '../api/omAPI/DiagnosticsListener';
10
+ import { startNetworkDiagnostics as startNetworkDiagnosticsDL} from '../api/omAPI/DiagnosticsListener';
11
+ import { stopNetworkDiagnostics as stopNetworkDiagnosticsDL} from '../api/omAPI/DiagnosticsListener';
12
+ import { startSpeakerDiagnosticsTest as startSpeakerDiagnosticsTestDL} from '../api/omAPI/DiagnosticsListener';
13
+ import { stopSpeakerDiagnosticsTest as stopSpeakerDiagnosticsTestDL} from '../api/omAPI/DiagnosticsListener';
14
+ import { startMicDiagnosticsTest as startMicDiagnosticsTestDL} from '../api/omAPI/DiagnosticsListener';
15
+ import { stopMicDiagnosticsTest as stopMicDiagnosticsTestDL } from '../api/omAPI/DiagnosticsListener';
16
+ import { closeDiagnostics as closeDiagnosticsDL} from '../api/omAPI/DiagnosticsListener';
17
+
18
+ import { callbacks } from '../listeners/Callback';
19
+ import { registerCallback } from '../listeners/Callback';
20
+ import { sessionCallback } from '../listeners/Callback';
21
+ import { webrtcTroubleshooterEventBus } from "./Callback";
22
+
23
+ import { webrtcLogger } from "../api/omAPI/WebrtcLogger";
24
+ var webrtcSIPPhone = require('@exotel-npm-dev/webrtc-core-sdk/src/webrtcSIPPhone').webrtcSIPPhone;
25
+
26
+ var intervalId;
27
+ var intervalIDMap = new Map();
28
+
29
+ var logger = webrtcLogger();
30
+
31
+ function sleep(ms) {
32
+ return new Promise(resolve => setTimeout(resolve, ms));
33
+ }
34
+
35
+ /**
36
+ * FQDN for fetching IP
37
+ */
38
+ function fetchPublicIP(sipAccountInfo) {
39
+ var publicIp = "";
40
+ const pc = new RTCPeerConnection({ iceServers: [ {urls: 'stun:stun.l.google.com:19302'} ] });
41
+ pc.createDataChannel('');
42
+ pc.createOffer().then(offer => pc.setLocalDescription(offer))
43
+ pc.onicecandidate = (ice) => {
44
+ if (!ice || !ice.candidate || !ice.candidate.candidate) {
45
+ logger.log("all done.");
46
+ pc.close();
47
+ return "";
48
+ }
49
+ logger.log("iceCandidate =" + ice.candidate.candidate);
50
+ let split = ice.candidate.candidate.split(" ");
51
+ if (split[7] === "host") {
52
+ logger.log(`fetchPublicIP:Local IP : ${split[4]}`);
53
+ } else {
54
+ logger.log(`fetchPublicIP:External IP : ${split[4]}`);
55
+ publicIp = `${split[4]}`
56
+ logger.log("fetchPublicIP:Public IP :" + publicIp);
57
+ localStorage.setItem("contactHost", publicIp);
58
+ pc.close();
59
+ }
60
+ };
61
+ sleep(500).then(function () {
62
+ logger.log("fetchPublicIP: public ip = ", publicIp)
63
+ if (publicIp == "") {
64
+ sipAccountInfo.contactHost = window.localStorage.getItem('contactHost');
65
+ } else {
66
+ sipAccountInfo.contactHost = publicIp;
67
+ }
68
+ });
69
+ return;
70
+ };
71
+
72
+
73
+ export function ExDelegationHandler(exClient_) {
74
+ var exClient = exClient_;
75
+ this.setTestingMode = function(mode) {
76
+ logger.log("delegationHandler: setTestingMode\n");
77
+ }
78
+
79
+ this.onCallStatSipJsSessionEvent = function(ev) {
80
+ logger.log("delegationHandler: onCallStatSipJsSessionEvent\n");
81
+ }
82
+
83
+ this.sendWebRTCEventsToFSM = function(eventType, sipMethod) {
84
+ logger.log("delegationHandler: sendWebRTCEventsToFSM\n");
85
+ logger.log("delegationHandler: eventType\n", eventType);
86
+ logger.log("delegationHandler: sipMethod\n", sipMethod);
87
+ if (sipMethod == "CONNECTION") {
88
+ exClient.registerEventCallback(eventType, exClient.userName)
89
+ } else if (sipMethod == "CALL") {
90
+ exClient.callEventCallback(eventType, exClient.userName,exClient.call)
91
+ }
92
+ }
93
+
94
+ this.playBeepTone = function() {
95
+ logger.log("delegationHandler: playBeepTone\n");
96
+ }
97
+
98
+ this.onStatPeerConnectionIceGatheringStateChange = function(iceGatheringState) {
99
+ logger.log("delegationHandler: onStatPeerConnectionIceGatheringStateChange\n");
100
+ }
101
+
102
+ this.onCallStatIceCandidate = function(ev,icestate) {
103
+ logger.log("delegationHandler: onCallStatIceCandidate\n");
104
+ }
105
+
106
+ this.onCallStatNegoNeeded = function(icestate) {
107
+ logger.log("delegationHandler: onCallStatNegoNeeded\n");
108
+ }
109
+
110
+ this.onCallStatSignalingStateChange = function(cstate) {
111
+ logger.log("delegationHandler: onCallStatSignalingStateChange\n");
112
+ }
113
+
114
+ this.onStatPeerConnectionIceConnectionStateChange = function() {
115
+ logger.log("delegationHandler: onStatPeerConnectionIceConnectionStateChange\n");
116
+ }
117
+
118
+ this.onStatPeerConnectionConnectionStateChange = function() {
119
+ logger.log("delegationHandler: onStatPeerConnectionConnectionStateChange\n");
120
+ }
121
+
122
+ this.onGetUserMediaSuccessCallstatCallback = function() {
123
+ logger.log("delegationHandler: onGetUserMediaSuccessCallstatCallback\n");
124
+ }
125
+
126
+ this.onGetUserMediaErrorCallstatCallback = function() {
127
+ logger.log("delegationHandler: onGetUserMediaErrorCallstatCallback\n");
128
+ }
129
+
130
+ this.onCallStatAddStream = function() {
131
+ logger.log("delegationHandler: onCallStatAddStream\n");
132
+ }
133
+
134
+ this.onCallStatRemoveStream = function() {
135
+ logger.log("delegationHandler: onCallStatRemoveStream\n");
136
+ }
137
+
138
+ this.setWebRTCFSMMapper = function(stack) {
139
+ logger.log("delegationHandler: setWebRTCFSMMapper : Initialisation complete \n");
140
+ }
141
+
142
+ this.onCallStatSipJsTransportEvent = function() {
143
+ logger.log("delegationHandler: onCallStatSipJsTransportEvent\n");
144
+ }
145
+
146
+ this.onCallStatSipSendCallback = function() {
147
+ logger.log("delegationHandler: onCallStatSipSendCallback\n");
148
+ }
149
+
150
+ this.onCallStatSipRecvCallback = function() {
151
+ logger.log("delegationHandler: onCallStatSipRecvCallback\n");
152
+ }
153
+
154
+ this.stopCallStat = function() {
155
+ logger.log("delegationHandler: stopCallStat\n");
156
+ }
157
+
158
+ this.onRecieveInvite = function() {
159
+ logger.log("delegationHandler: onRecieveInvite\n");
160
+ }
161
+
162
+ this.onPickCall = function() {
163
+ logger.log("delegationHandler: onPickCall\n");
164
+ }
165
+
166
+ this.onRejectCall = function() {
167
+ logger.log("delegationHandler: onRejectCall\n");
168
+ }
169
+
170
+ this.onCreaterAnswer = function() {
171
+ logger.log("delegationHandler: onCreaterAnswer\n");
172
+ }
173
+
174
+ this.onSettingLocalDesc = function() {
175
+ logger.log("delegationHandler: onSettingLocalDesc\n");
176
+ }
177
+
178
+ this.initGetStats = function(pc, callid, username) {
179
+ logger.log("delegationHandler: initGetStats\n");
180
+ }
181
+
182
+ this.onRegisterWebRTCSIPEngine = function(engine) {
183
+ logger.log("delegationHandler: onRegisterWebRTCSIPEngine, engine=\n", engine);
184
+ }
185
+ }
186
+
187
+ export function ExSynchronousHandler() {
188
+
189
+ this.onFailure = function() {
190
+ logger.log("synchronousHandler: onFailure, phone is offline.\n");
191
+ }
192
+
193
+ this.onResponse = function() {
194
+ logger.log("synchronousHandler: onResponse, phone is connected.\n");
195
+ }
196
+ }
197
+
198
+ export const ExotelWebClient = {
199
+
200
+
201
+
202
+ ctrlr : null,
203
+ call : null,
204
+ eventListener : null,
205
+ callListener : null,
206
+ /* OLD-Way to be revisited for multile phone support */
207
+ //this.webRTCPhones = {};
208
+
209
+ sipAccountInfo : null,
210
+
211
+ initWebrtc : (sipAccountInfo_,
212
+ RegisterEventCallBack, CallListenerCallback, SessionCallback) => {
213
+
214
+ if (!ExotelWebClient.eventListener) {
215
+ ExotelWebClient.eventListener = new ExotelVoiceClientListener();
216
+ }
217
+
218
+ if (!ExotelWebClient.callListener) {
219
+ ExotelWebClient.callListener = new CallListener();
220
+ }
221
+
222
+ if (!ExotelWebClient.ctrlr) {
223
+ ExotelWebClient.ctrlr = new CallController();
224
+ }
225
+
226
+ if (!ExotelWebClient.call) {
227
+ ExotelWebClient.call = new Call();
228
+ }
229
+
230
+ logger.log("Exotel Client Initialised with " + JSON.stringify(sipAccountInfo_))
231
+ ExotelWebClient.sipAccountInfo = sipAccountInfo_;
232
+ if ( !ExotelWebClient.sipAccountInfo["userName"] || !ExotelWebClient.sipAccountInfo["sipdomain"] || !ExotelWebClient.sipAccountInfo["port"]) {
233
+ return false;
234
+ }
235
+ ExotelWebClient.sipAccountInfo["sipUri"] = "wss://" + ExotelWebClient.sipAccountInfo["userName"] + "@" + ExotelWebClient.sipAccountInfo["sipdomain"] + ":" + ExotelWebClient.sipAccountInfo["port"];
236
+
237
+ callbacks.initializeCallback(CallListenerCallback);
238
+ registerCallback.initializeRegisterCallback(RegisterEventCallBack);
239
+ logger.log("Initializing session callback")
240
+ sessionCallback.initializeSessionCallback(SessionCallback);
241
+ ExotelWebClient.setEventListener(ExotelWebClient.eventListener);
242
+ return true;
243
+ },
244
+
245
+ DoRegister : () => {
246
+ DoRegisterRL(ExotelWebClient.sipAccountInfo, ExotelWebClient)
247
+ },
248
+
249
+ UnRegister : () => {
250
+ UnRegisterRL(ExotelWebClient.sipAccountInfo, ExotelWebClient)
251
+ },
252
+
253
+ initDiagnostics : (saveDiagnosticsCallback, keyValueSetCallback) => {
254
+ initDiagnosticsDL(saveDiagnosticsCallback, keyValueSetCallback)
255
+ },
256
+
257
+ closeDiagnostics : () => {
258
+ closeDiagnosticsDL()
259
+ },
260
+
261
+ startSpeakerDiagnosticsTest : () => {
262
+ startSpeakerDiagnosticsTestDL()
263
+ },
264
+
265
+ stopSpeakerDiagnosticsTest : (speakerTestResponse='none') => {
266
+ stopSpeakerDiagnosticsTestDL(speakerTestResponse)
267
+ },
268
+
269
+ startMicDiagnosticsTest : () => {
270
+ startMicDiagnosticsTestDL()
271
+ },
272
+
273
+ stopMicDiagnosticsTest : (micTestResponse='none') => {
274
+ stopMicDiagnosticsTestDL(micTestResponse)
275
+ },
276
+
277
+ startNetworkDiagnostics : () => {
278
+ startNetworkDiagnosticsDL()
279
+ ExotelWebClient.DoRegister()
280
+ },
281
+
282
+ stopNetworkDiagnostics : () => {
283
+ stopNetworkDiagnosticsDL()
284
+ },
285
+
286
+ SessionListener : () => {
287
+ SessionListenerSL()
288
+ },
289
+
290
+ /**
291
+ * function that returns the instance of the call controller object object
292
+ */
293
+
294
+ getCallController :() => {
295
+ return ExotelWebClient.ctrlr;
296
+ },
297
+
298
+ getCall :() => {
299
+ if (!ExotelWebClient.call) {
300
+ ExotelWebClient.call = call = new Call();
301
+ }
302
+ return ExotelWebClient.call;
303
+ },
304
+
305
+ /**
306
+ * Dummy function to set the event listener object
307
+ */
308
+ setEventListener :(eventListener) => {
309
+ ExotelWebClient.eventListener = eventListener;
310
+ },
311
+
312
+
313
+ /**
314
+ * Event listener for registration, any change in registration state will trigger the callback here
315
+ * @param {*} event
316
+ * @param {*} phone
317
+ * @param {*} param
318
+ */
319
+
320
+ registerEventCallback :(event, phone, param) => {
321
+
322
+ logger.log("Dialer: registerEventCallback: Received ---> " + event + 'phone....', phone + 'param....', param)
323
+ if (event === "connected") {
324
+ /**
325
+ * When registration is successful then send the phone number of the same to UI
326
+ */
327
+ ExotelWebClient.eventListener.onInitializationSuccess(phone);
328
+ } else if( event === "failed_to_start" || event === "transport_error"){
329
+ /**
330
+ * If registration fails
331
+ */
332
+ ExotelWebClient.eventListener.onInitializationFailure(phone);
333
+ } else if( event === "sent_request"){
334
+ /**
335
+ * If registration request waiting...
336
+ */
337
+ ExotelWebClient.eventListener.onInitializationWaiting(phone);
338
+ }
339
+ },
340
+ /**
341
+ * Event listener for calls, any change in sipjsphone will trigger the callback here
342
+ * @param {*} event
343
+ * @param {*} phone
344
+ * @param {*} param
345
+ */
346
+ callEventCallback :(event, phone, param) => {
347
+ logger.log("Dialer: callEventCallback: Received ---> " + event + 'param sent....' + param + 'for phone....' + phone)
348
+ if (event === "i_new_call") {
349
+ callListener.onIncomingCall(param,phone)
350
+ } else if (event === "connected") {
351
+ callListener.onCallEstablished(param,phone);
352
+ } else if (event === "terminated") {
353
+ callListener.onCallEnded(param,phone);
354
+ }
355
+ },
356
+
357
+ /**
358
+ * Event listener for diagnostic tests, any change in diagnostic tests will trigger this callback
359
+ * @param {*} event
360
+ * @param {*} phone
361
+ * @param {*} param
362
+ */
363
+ diagnosticEventCallback :(event, phone, param) => {
364
+ webrtcTroubleshooterEventBus.sendDiagnosticEvent(event, phone, param)
365
+ },
366
+
367
+ /**
368
+ * Function to unregister a phone
369
+ * @param {*} sipAccountInfo
370
+ */
371
+ unregister :(sipAccountInfo) => {
372
+ // webrtcSIPPhone.unregister(sipAccountInfo)
373
+ webrtcSIPPhone.sipUnRegisterWebRTC();
374
+ },
375
+
376
+
377
+ webRTCStatusCallbackHandler :(msg1, arg1) => {
378
+ logger.log("webRTCStatusCallbackHandler: " + msg1 + " " + arg1)
379
+ },
380
+
381
+ /**
382
+ * initialize function called when user wants to register client
383
+ */
384
+ initialize :(uiContext, hostName,subscriberName,
385
+ displayName,accountSid,subscriberToken,
386
+ sipAccountInfo) => {
387
+
388
+ let wssPort = sipAccountInfo.port;
389
+ let wsPort = 4442;
390
+ ExotelWebClient.sipAccntInfo = {
391
+ 'userName':'',
392
+ 'authUser':'',
393
+ 'domain':'',
394
+ 'sipdomain':'',
395
+ 'displayname':'',
396
+ 'accountSid':'',
397
+ 'secret':'',
398
+ 'sipUri':'',
399
+ 'security':'',
400
+ 'port':'',
401
+ 'contactHost':''
402
+ }
403
+
404
+ logger.log('Sending register for the number..', subscriberName);
405
+
406
+ fetchPublicIP(sipAccountInfo);
407
+
408
+ /* Temporary till we figure out the arguments - Start */
409
+ ExotelWebClient.domain = hostName = sipAccountInfo.domain;
410
+ ExotelWebClient.sipdomain = sipAccountInfo.sipdomain;
411
+ ExotelWebClient.accountName = ExotelWebClient.userName = sipAccountInfo.userName;
412
+ ExotelWebClient.authUser = subscriberName = sipAccountInfo.authUser;
413
+ ExotelWebClient.displayName = sipAccountInfo.displayName;
414
+ ExotelWebClient.accountSid = 'exotelt1';
415
+ ExotelWebClient.subscriberToken = sipAccountInfo.secret;
416
+ ExotelWebClient.secret = ExotelWebClient.password = sipAccountInfo.secret;
417
+ ExotelWebClient.security = sipAccountInfo.security;
418
+ ExotelWebClient.port = sipAccountInfo.port;
419
+ ExotelWebClient.contactHost = sipAccountInfo.contactHost;
420
+ ExotelWebClient.sipWsPort = 5061;
421
+ ExotelWebClient.sipPort = 5061;
422
+ ExotelWebClient.sipSecurePort = 5062;
423
+ /* Temporary till we figure out the arguments - End */
424
+
425
+ /* This is permanent -Start */
426
+ let webrtcPort = wssPort;
427
+
428
+ if (ExotelWebClient.security === 'ws') {
429
+ webrtcPort = wsPort;
430
+ }
431
+
432
+
433
+
434
+ ExotelWebClient.sipAccntInfo['userName'] = userName;
435
+ ExotelWebClient.sipAccntInfo['authUser'] = subscriberName;
436
+ ExotelWebClient.sipAccntInfo['domain'] = hostName;
437
+ ExotelWebClient.sipAccntInfo['sipdomain'] = ExotelWebClient.sipdomain;
438
+ ExotelWebClient.sipAccntInfo['accountName'] = userName;
439
+ ExotelWebClient.sipAccntInfo['secret'] = ExotelWebClient.password;
440
+ ExotelWebClient.sipAccntInfo['sipuri'] = ExotelWebClient.sipuri;
441
+ ExotelWebClient.sipAccntInfo['security'] = ExotelWebClient.security;
442
+ ExotelWebClient.sipAccntInfo['port'] = ExotelWebClient.webrtcPort;
443
+ ExotelWebClient.sipAccntInfo['contactHost'] = ExotelWebClient.contactHost;
444
+ localStorage.setItem('contactHost', ExotelWebClient.contactHost);
445
+ /* This is permanent -End */
446
+
447
+ /**
448
+ * Call the webclient function inside this and pass register and call callbacks as arg
449
+ */
450
+ var synchronousHandler = new ExSynchronousHandler(ExotelWebClient);
451
+ var delegationHandler = new ExDelegationHandler(ExotelWebClient);
452
+
453
+ var userName = userName;
454
+ /* OLD-Way to be revisited for multile phone support */
455
+ //webRTCPhones[userName] = webRTC;
456
+
457
+ /* New-Way */
458
+ webrtcSIPPhone.registerPhone("sipjs",delegationHandler);
459
+ webrtcSIPPhone.registerWebRTCClient(ExotelWebClient.sipAccntInfo, synchronousHandler);
460
+
461
+ /**
462
+ * Store the intervalID against a map
463
+ */
464
+ intervalIDMap.set(userName, intervalId);
465
+ }
466
+ }
467
+
468
+ export default ExotelWebClient;
@@ -0,0 +1,45 @@
1
+ import { registerCallback } from "./Callback";
2
+ import { diagnosticsCallback } from "./Callback";
3
+
4
+ export class ExotelVoiceClientListener{
5
+ onInitializationSuccess(phone) {
6
+ /**
7
+ * Abstract class for Initialization Success
8
+ */
9
+ registerCallback.initializeRegister("registered", phone);
10
+ /**
11
+ * Triggers UI callback to indicate the status of the registered phone
12
+ */
13
+ registerCallback.triggerRegisterCallback();
14
+ diagnosticsCallback.triggerKeyValueSetCallback("userReg", "registered", phone);
15
+ }
16
+
17
+ onInitializationFailure(phone){
18
+ /**
19
+ * If register fails send error message to Callback function
20
+ */
21
+ registerCallback.initializeRegister("unregistered", phone);
22
+ registerCallback.triggerRegisterCallback();
23
+ diagnosticsCallback.triggerKeyValueSetCallback("userReg", "unregistered", phone);
24
+ }
25
+
26
+ onInitializationWaiting(phone){
27
+ /**
28
+ * If register fails send error message to Callback function
29
+ */
30
+ registerCallback.initializeRegister("sent_request", phone);
31
+ registerCallback.triggerRegisterCallback();
32
+ diagnosticsCallback.triggerKeyValueSetCallback("userReg", "sent_request", phone);
33
+ }
34
+
35
+ onLog(LogLevel, tag, message){
36
+ /**
37
+ * To get SDK logs
38
+ */
39
+ }
40
+ onAuthenticationFailure(){
41
+ /**
42
+ * In case if there is any authentication error in registration, handle here
43
+ */
44
+ }
45
+ }
@@ -0,0 +1,123 @@
1
+ import { sessionCallback } from './Callback';
2
+ import { v4 as uuidv4 } from 'uuid';
3
+ import { FetchTabInfo } from '../constants/common';
4
+ import { webrtcLogger } from "../api/omAPI/WebrtcLogger"
5
+
6
+ var logger = webrtcLogger()
7
+ /**
8
+ * Session listeners is invoked when user opens two tabs, the data in tab 1 is
9
+ * copied into tab 2
10
+ */
11
+ export function SessionListener () {
12
+
13
+ const channel = new BroadcastChannel('app-data');
14
+ channel.addEventListener ('message', (event) => {
15
+ if(event.data.message == "re-register-needed"){
16
+ /** Send the hash to app seeking for reregistration */
17
+ sessionCallback.initializeSession('re-register', event.data.hashMsg);
18
+ sessionCallback.triggerSessionCallback();
19
+ }else if(event.data.message == 'logout'){
20
+ sessionCallback.initializeSession('logout', '');
21
+ sessionCallback.triggerSessionCallback();
22
+ }else if(event.data.message == 'login-successful'){
23
+ const loginObj = {
24
+ phone: window.localStorage.getItem('currentUser'),
25
+ tabHash: event.data.tabHash
26
+ }
27
+ sessionCallback.initializeSession('login-successful', JSON.stringify(loginObj));
28
+ sessionCallback.triggerSessionCallback();
29
+ }else if(window.sessionStorage.getItem("activeSessionTab") !== null){
30
+ if(event.data.callState !== null && event.data.callState !== undefined){
31
+ sessionCallback.initializeSession(event.data.callState, event.data.callNumber);
32
+ }
33
+ sessionCallback.triggerSessionCallback();
34
+ }
35
+ });
36
+ /**
37
+ * Add listeners for all storage events
38
+ */
39
+ window.localStorage.setItem('REQUESTING_SHARED_CREDENTIALS', Date.now().toString())
40
+ window.localStorage.removeItem('REQUESTING_SHARED_CREDENTIALS')
41
+
42
+ const credentials = {
43
+ user: window.sessionStorage.getItem('user'),
44
+ selectedPhone: window.localStorage.getItem('selectedPhone'),
45
+ }
46
+
47
+ window.addEventListener('storage', (event) => {
48
+ /**
49
+ * When user tries to duplicate tab, this gets called in Tab1
50
+ */
51
+ if(event.key === 'REQUESTING_SHARED_CREDENTIALS' && credentials) {
52
+ window.localStorage.setItem('CREDENTIALS_SHARING', JSON.stringify(credentials))
53
+ window.localStorage.removeItem('CREDENTIALS_SHARING')
54
+ /**
55
+ * When the data is to be shared between two tabs then add the current state onto that session storage
56
+ */
57
+ //sessionCallback.triggerSessionCallback();
58
+ }
59
+ if(event.key === 'CREDENTIALS_SHARING' && credentials !== null){
60
+
61
+ const newData = JSON.parse(event.newValue);
62
+ if(event.newValue !== null){
63
+ window.sessionStorage.setItem('user', newData.user);
64
+ window.sessionStorage.setItem('isAuthenticated', true);
65
+ }
66
+ /**
67
+ * Fetch the array of tabs and add the tab, put it on session also
68
+ */
69
+ const currentTab = {
70
+ tabID: uuidv4(),
71
+ tabType: 'child',
72
+ tabStatus: 'active'
73
+ }
74
+ const tabArr = JSON.parse(window.localStorage.getItem('tabs'));
75
+ /** Based on activeSessionTab id fetch the type */
76
+
77
+ if(window.sessionStorage.getItem('activeSessionTab') !== null && window.sessionStorage.getItem('activeSessionTab') == "parent0"){
78
+ logger.log('Adding a child tab spawned from parent....');
79
+ /** In order to keep tabID same for all the child ones, we are using below IF to distinguish */
80
+
81
+ if(tabArr.length > 1 && window.sessionStorage.getItem('activeSessionTab') == "parent0") {
82
+ if(!document.hidden){
83
+ const lastIndex = (tabArr.length) - 1;
84
+ window.sessionStorage.setItem('activeSessionTab', tabArr[lastIndex].tabID);
85
+ }
86
+
87
+ }else {
88
+ tabArr.push(currentTab);
89
+ window.localStorage.removeItem('tabs');
90
+ window.localStorage.setItem('tabs', JSON.stringify(tabArr));
91
+ const lastIndex = (tabArr.length) - 1;
92
+ window.sessionStorage.setItem('activeSessionTab', tabArr[lastIndex].tabID);
93
+ }
94
+
95
+
96
+ } else {
97
+ /** pull from the tabarray and then add it to the session storage */
98
+
99
+ const lastIndex = (tabArr.length) - 1;
100
+ window.sessionStorage.setItem('activeSessionTab', tabArr[lastIndex].tabID);
101
+ }
102
+ //window.localStorage.setItem('selectedPhone', newData.selectedPhone);
103
+ return;
104
+ //}
105
+
106
+ }
107
+ /**
108
+ * When a tab is closed
109
+ */
110
+ if(event.key === 'CREDENTIALS_FLUSH' && credentials){
111
+ window.sessionStorage.removeItem('user');
112
+ window.sessionStorage.removeItem('selectedPhone');
113
+ window.sessionStorage.removeItem('isAuthenticated')
114
+ window.sessionStorage.removeItem('activeSession');
115
+ }
116
+ /**
117
+ * When any tab is closed, active call gets terminated
118
+ */
119
+ if(event.key === 'CALL_FLUSH'){
120
+ window.sessionStorage.removeItem('activeSession');
121
+ }
122
+ });
123
+ };