@nethesis/phone-island 1.0.9-dev.6 → 1.0.9-dev.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../node_modules/tslib/tslib.es6.js"),n=require("react");require("../node_modules/react-redux/es/index.js");var t=require("../node_modules/socket.io-client/build/esm/index.js"),r=require("./RestAPI.js"),i=require("../lib/phone/conversation.js"),o=require("../services/user.js"),u=require("../static/busy_ringtone.js"),c=require("../utils/customHooks/useEventListener.js"),a=require("../utils/genericFunctions/eventDispatch.js"),s=require("../utils/genericFunctions/withTimeout.js"),l=require("../utils/genericFunctions/summaryEvents.js"),d=require("../store/index.js");require("../lib/webrtc/janus.js"),require("../node_modules/webrtc-adapter/src/js/adapter_core.js");var v=require("../lib/devices/devices.js"),p=require("../lib/user/default_device.js"),m=require("../utils/genericFunctions/isEmpty.js"),g=require("../utils/streaming/getStreamingSourceId.js"),f=require("../events/SocketEvents.js"),h=require("../utils/genericFunctions/timestamp.js"),b=require("../lib/user/extensions.js"),k=require("../utils/streaming/isFromStreaming.js"),S=require("../lib/phone/queue.js"),y=require("../lib/phone/trunk.js"),w=require("../node_modules/react-redux/es/hooks/useDispatch.js");function C(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var q=C(n);exports.Socket=function(C){var _=C.hostName,N=C.username,I=C.authToken,T=C.reload,U=C.reloadedCallback,j=C.children,D=C.uaType,x=w.useDispatch(),E=n.useRef(),O=n.useRef(),P=n.useRef(!1),A=n.useRef(0),F=n.useRef(null),V=n.useRef(new Map),M=n.useRef({linkedid:null,uniqueid:null});c.useEventListener("phone-island-start-transcription",(function(e){if(O.current){var n=(null==e?void 0:e.linkedid)||(null==e?void 0:e.linkedId),t=(null==e?void 0:e.uniqueid)||(null==e?void 0:e.uniqueId);if(!n&&!t)return;M.current={linkedid:n||null,uniqueid:t||null},O.current.emit("start_transcription",{linkedid:n,uniqueid:t})}})),c.useEventListener("phone-island-stop-transcription",(function(e){if(O.current){var n=(null==e?void 0:e.linkedid)||(null==e?void 0:e.linkedId),t=(null==e?void 0:e.uniqueid)||(null==e?void 0:e.uniqueId);if(!n&&!t)return;M.current={linkedid:null,uniqueid:null},O.current.emit("stop_transcription",{linkedid:n,uniqueid:t})}})),c.useEventListener("phone-island-current-user-queue-call-waiting",(function(e){x.currentCall.updateCurrentCall({throughQueue:!0,queueId:(null==e?void 0:e.queueId)||"",queueName:(null==e?void 0:e.queueName)||"",queueNumber:(null==e?void 0:e.queueNumber)||"",queuePosition:(null==e?void 0:e.queuePosition)||"",queueWaitingTime:(null==e?void 0:e.queueWaitingTime)||0})})),c.useEventListener("phone-island-current-user-queue-call-connected",(function(e){x.currentCall.updateCurrentCall({throughQueue:!0,queueId:(null==e?void 0:e.queueId)||"",queueName:(null==e?void 0:e.queueName)||"",queueNumber:(null==e?void 0:e.queueNumber)||"",queuePosition:(null==e?void 0:e.queuePosition)||"",queueWaitingTime:(null==e?void 0:e.queueWaitingTime)||0})}));return n.useEffect((function(){var n,c=function(e){if(e.counterpartNum&&k.isFromStreaming(e.counterpartNum)){x.island.setIsFromStreaming(!0),x.currentCall.updateCurrentCall({streamingSourceNumber:e.counterpartNum});var n=g.getStreamingSourceId(e.counterpartNum);n&&o.subscribe({id:n}).catch((function(e){return console.error("Error subscribing to streaming source:",e)}))}},w=function(e){var n,t,r,i;if(e){var o=function(e){return S.getCurrentCallQueueContext(e,d.store.getState().queue)}(e),u=function(e,n){var t=d.store.getState().currentCall;return{conversationId:e.id,linkedId:e.linkedId,uniqueId:e.uniqueId,ownerExtension:e.owner,number:"".concat(e.counterpartNum||""),queueId:(null==n?void 0:n.queueId)||t.queueId||"",queueName:(null==n?void 0:n.queueName)||t.queueName||"",queueNumber:(null==n?void 0:n.queueNumber)||t.queueNumber||"",queuePosition:(null==n?void 0:n.queuePosition)||"",queueWaitingTime:(null==n?void 0:n.queueWaitingTime)||0}}(e,o);if(Boolean(u.queueId||u.queueName||u.queueNumber))if(e.connected)((null===(r=F.current)||void 0===r?void 0:r.conversationId)!==e.id||"connected"!==(null===(i=F.current)||void 0===i?void 0:i.phase))&&(f.dispatchCurrentUserQueueCallConnected(u),F.current={conversationId:e.id,phase:"connected"});else((null===(n=F.current)||void 0===n?void 0:n.conversationId)!==e.id||"waiting"!==(null===(t=F.current)||void 0===t?void 0:t.phase))&&(f.dispatchCurrentUserQueueCallWaiting(u),F.current={conversationId:e.id,phase:"waiting"});else F.current=null}else F.current=null},C=function(e){return(null==e?void 0:e.linkedId)||(null==e?void 0:e.linkedid)||""},q=function(e){return(null==e?void 0:e.uniqueId)||(null==e?void 0:e.uniqueid)||""},T=function(e){return!!(null==e?void 0:e.connected)&&!!C(e)&&!!q(e)},U=function(n){var t=d.store.getState().currentUser.conversations,r=n?null==t?void 0:t[n]:void 0,i=function(e){var n,t=null,r=Object.entries(e||{}).filter((function(e){var n=e[1];return n&&Object.keys(n).length>0}));return r.forEach((function(e){var r,i,o=e[0],u=e[1];if(!t)return t=u,void(n=o);var c=T(t),a=T(u);if(a&&!c)return t=u,void(n=o);if(a===c){var s=!!t.connected,l=!!u.connected;if(l&&!s)return t=u,void(n=o);var d=null!==(r=t.startTime)&&void 0!==r?r:0,v=null!==(i=u.startTime)&&void 0!==i?i:0;l===s&&v>d&&(t=u,n=o)}})),{conversation:t,key:n,count:r.length}}(r);if(T(i.conversation))return e.__assign(e.__assign({},i),{source:"live",cacheAgeMs:void 0,hasConversationForCaller:!!r,liveConversationKeys:Object.keys(r||{})});var o=function(n){if(!n)return null;var t=V.current.get(n);if(!t)return null;var r=Date.now()-t.cachedAt;return r>6e5?(V.current.delete(n),null):e.__assign(e.__assign({},t),{cacheAgeMs:r})}(n);return o&&T(o.conversation)?{conversation:o.conversation,key:o.conversation.id,count:i.count,source:"cache",cacheAgeMs:o.cacheAgeMs,hasConversationForCaller:!!r,liveConversationKeys:Object.keys(r||{})}:e.__assign(e.__assign({},i),{source:i.conversation?"live_invalid":"none",cacheAgeMs:null==o?void 0:o.cacheAgeMs,hasConversationForCaller:!!r,liveConversationKeys:Object.keys(r||{})})},j=function(n,t){var r=d.store.getState().currentCall,u=r.transferring,s=r.transferSwitching,l=r.transferCalls,v=d.store.getState().island.view;if(Object.keys(t).length>0){if(n.status){var m=d.store.getState().users.extensions,g=d.store.getState().currentUser.default_device,f=d.store.getState().currentUser,k=f.endpoints,S=f.username,C=d.store.getState().currentCall;C.incoming,C.outgoing;var q=function(){if(!m||!S)return!1;var e=Object.values(m).filter((function(e){return(null==e?void 0:e.username)===S}));return null==e?void 0:e.some((function(e){var n=null==k?void 0:k.extension.find((function(n){return n.id===(null==e?void 0:e.exten)}));return"nethlink"===(null==n?void 0:n.type)&&"offline"!==(null==e?void 0:e.status)}))};switch(n.status){case"ringing":if(function(e){var n=d.store.getState().currentCall,t=n.accepted,r=n.ownerExtension;return t&&!!r&&!!e&&r!==e}(t.owner))break;w(t),c(t),("mobile"===D&&q()||"desktop"===D&&("webrtc"===(null==g?void 0:g.type)||void 0===(null==g?void 0:g.type)&&!q()||!q()&&"physical"===(null==g?void 0:g.type)))&&(x.currentCall.checkIncomingUpdatePlay({conversationId:t.id,displayName:i.getDisplayName(t),number:"".concat(t.counterpartNum),incomingSocket:!0,incoming:!0,username:"".concat(m&&m[t.counterpartNum]&&m[t.counterpartNum].username)||"",ownerExtension:t.owner}),d.store.dispatch.island.setIslandView("call")),P.current||(P.current=!0,o.getCurrentUserInfo().then((function(n){n&&(x.currentUser.updateCurrentUser(n),a.eventDispatch("phone-island-user-informations-update",e.__assign({},n)),n.settings&&n.settings.open_param_url?x.paramUrl.setOpenParamUrlType(n.settings.open_param_url):x.paramUrl.setOpenParamUrlType("never"))})).catch((function(e){console.error("Error getting current user info:",e)})).finally((function(){setTimeout((function(){P.current=!1}),100)})));var _=d.store.getState().paramUrl.openParamUrlType,N=d.store.getState().island.urlOpened;if("ringing"===_&&!N){var I=y.isFromTrunk(t.counterpartNum);d.store.dispatch.paramUrl.setThroughTrunk(I),d.store.dispatch.island.setUrlOpened(!1),a.eventDispatch("phone-island-url-parameter-opened",{counterpartNum:t.counterpartNum,counterpartName:i.getDisplayName(t),owner:t.owner,uniqueId:t.uniqueId,linkedId:t.linkedId,throughQueue:t.throughQueue,throughTrunk:I,direction:t.direction,connected:t.connected})}break;case"busy":if(w(t),c(t),"mobile"===D&&q()||"desktop"===D&&("webrtc"===(null==g?void 0:g.type)||void 0===(null==g?void 0:g.type)&&!q()||!q()&&"physical"===(null==g?void 0:g.type))){if(t&&t.connected)x.currentCall.updateCurrentCall({conversationId:t.id,displayName:i.getDisplayName(t),number:"".concat(t.counterpartNum),ownerExtension:t.owner,username:"".concat(m&&m[t.counterpartNum]&&m[t.counterpartNum].username)||"",chDest:(null==t?void 0:t.chDest)||{},chSource:(null==t?void 0:t.chSource)||{}}),x.currentCall.checkAcceptedUpdate({acceptedSocket:!0}),x.currentCall.addTransferCalls({type:"transferred",displayName:i.getDisplayName(t),number:"".concat(t.counterpartNum),startTime:"".concat(h.getTimestampInSeconds())}),d.store.getState().island.isFromStreaming&&"out"===t.direction&&setTimeout((function(){x.island.setIslandView("streamingAnswer")}),200),p.isPhysical()&&function(e){x.currentCall.updateCurrentCall({conversationId:e.id,accepted:!0,incoming:"in"!==e.direction&&void 0}),a.eventDispatch("phone-island-call-answered",{}),d.store.dispatch.player.stopAudioPlayer(),d.store.dispatch.player.setAudioPlayerLoop(!1)}(t),"call"===v&&u&&x.currentCall.updateCurrentCall({transferring:!1});if(l.length>1)x.currentCall.deleteTransferCalls();else if(t&&!t.connected){if(u&&!s){var T=l.find((function(e){return e.number===t.counterpartNum}));!t.connected&&T&&(x.currentCall.updateCurrentCall({transferring:!1}),a.eventDispatch("phone-island-call-transfer-failed",{}),x.currentCall.updateTransferSwitching(!1))}"REC"===(null==t?void 0:t.counterpartName)&&x.physicalRecorder.setRecordingTempVariable(!0)}t&&!t.connected&&"out"===t.direction&&x.currentCall.checkOutgoingUpdate({outgoingSocket:!0,outgoing:"REC"!==(null==t?void 0:t.counterpartName),displayName:i.getDisplayName(t),number:"".concat(null==t?void 0:t.counterpartNum),username:"".concat(m&&m[null==t?void 0:t.counterpartNum]&&m[null==t?void 0:t.counterpartNum].username)||""})}break;case"onhold":w(t);var U=t.counterpartName,j=t.counterpartNum,E=t.startTime;u&&j&&U&&"<unknown>"!==U&&(x.currentCall.addTransferCalls({type:"destination",displayName:i.getDisplayName(t),number:j,startTime:"".concat(h.getTimestampInSeconds())}),x.currentCall.updateCurrentCall({displayName:i.getDisplayName(t),number:j,startTime:"".concat(E/1e3),conversationId:t.id}),x.island.setIslandView("call"));break;case"busy_ringing":a.eventDispatch("phone-island-call-ringing",{})}}}else"online"==n.status&&b.userTotallyFree()&&(w(null),x.player.stopAudioPlayer(),x.currentCall.reset(),x.physicalRecorder.setRecordingTempVariable(!1),x.island.setIsFromStreaming(!1))};return n={upgrade:!1,transports:["websocket"],reconnection:!0,reconnectionDelay:2e3},"new"===r.getApiMode(N)&&(n.path="/api/ws"),O.current=t.io("https://"+_,n),x.websocket.update({socket:O.current}),O.current.on("connect",(function(){console.debug("Socket connected sid: ".concat(O.current.id)),a.eventDispatch("phone-island-socket-connected",{})})),O.current.on("disconnect",(function(e){console.debug("Socket disconnect - reason: ".concat(e)),E.current&&(clearInterval(E.current),E.current=null),e.includes("server disconnect")?a.eventDispatch("phone-island-server-disconnected",{}):a.eventDispatch("phone-island-socket-disconnected",{})})),O.current.io.on("error",(function(e){console.debug("Socket error: ",e)})),O.current.on("connect_error",(function(e){console.debug("Socket connect_error: ",e)})),O.current.io.on("reconnect",(function(e){A.current=0,a.eventDispatch("phone-island-socket-reconnected",{}),console.debug("Socket reconnect attemp ".concat(e," (sid: ").concat(O.current.id,")"))})),O.current.io.on("reconnect_attempt",(function(e){console.debug("Socket reconnect_attempt ".concat(e))})),O.current.io.on("reconnect_error",(function(e){console.debug("Socket reconnect_error: ",e)})),O.current.io.on("reconnect_failed",(function(){console.debug("Socket reconnect_failed")})),O.current.on("connect",(function(){console.debug("Socket on: "+_+" is connected!"),O.current.emit("login",{accessKeyId:"".concat(N),token:I,uaType:D})})),O.current.on("authe_ok",(function(){console.debug("Socket authentication success!"),a.eventDispatch("phone-island-socket-authorized",{}),E.current&&clearInterval(E.current),E.current=setInterval((function(){O.current.volatile.emit("ping",s.withTimeout((function(){A.current=0,setTimeout((function(){x.alerts.removeAlert("socket_down"),a.eventDispatch("phone-island-alert-removed",{type:"socket_down"}),a.eventDispatch("phone-island-socket-disconnected-popup-close",{})}),0)}),(function(){A.current++,console.debug("Socket ping timeout (".concat(A.current,"/").concat(3,"), connected: ").concat(O.current.connected)),setTimeout((function(){var e,n,t=O.current.connected&&A.current>=3;if(!O.current.connected||t){var r=d.store.getState().webrtc.sipcall,i=d.store.getState().currentCall,o=i.accepted,u=i.outgoing,c=null===(n=null===(e=null==r?void 0:r.webrtcStuff)||void 0===e?void 0:e.pc)||void 0===n?void 0:n.iceConnectionState;if((o||u)&&("connected"===c||"completed"===c))return void console.debug("Socket unreachable but active call with ICE connected - skipping socket_down alert",{iceState:c,accepted:o,outgoing:u,isStaleConnection:t,timestamp:(new Date).toISOString()});t&&(console.warn("Stale socket connection detected - forcing reconnection"),O.current.disconnect()),x.alerts.setAlert("socket_down"),a.eventDispatch("phone-island-socket-disconnected-popup-open",{}),console.error("Socket is unreachable!")}}),0)}),5e3))}),5e3)})),O.current.on("userMainPresenceUpdate",(function(n){d.store.dispatch.users.updateEndpointMainPresence(e.__assign({},n.mainPresence)),f.dispatchMainPresence(n)})),O.current.on("extenHangup",(function(e){var n=d.store.getState().currentUser,t=n.endpoints,r=n.username,i=d.store.getState().conference,o=i.isActive,c=i.conferenceStartedFrom,s=d.store.getState().island,l=s.view,v=s.previewCallFromMobileOrNethlink,p=(null==t?void 0:t.extension)||[],m=p.map((function(e){return e.id})),g=null==e?void 0:e.callerNum;!m.includes(g)&&m.includes(null==e?void 0:e.channelExten)&&(g=null==e?void 0:e.channelExten);var f=p.find((function(n){return n.id===e.callerNum})),h=null==f?void 0:f.type,b=U(g).conversation,k=C(b),S=q(b),y=(null==b?void 0:b.connected)||!1;if(S&&k&&y&&(a.eventDispatch("phone-island-summary-call-check",{linkedid:k,uniqueid:S}),g&&V.current.delete(g)),"normal_clearing"===e.cause&&("physical"===h||"mobile"===h)||"normal_clearing"===e.cause&&("webrtc"===h||"nethlink"===h)&&v||"user_busy"===(null==e?void 0:e.cause)||"not_defined"===(null==e?void 0:e.cause)||"call_rejected"===(null==e?void 0:e.cause)||"interworking"===(null==e?void 0:e.cause)?(setTimeout((function(){d.store.dispatch.island.toggleAvoidToShow(!1),d.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!1)}),500),o&&c!==r&&d.store.dispatch.conference.resetConference()):"normal_circuit_congestion"===(null==e?void 0:e.cause)&&o&&c===r?setTimeout((function(){a.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})}),800):"normal_clearing"!==e.cause&&"user_busy"!==(null==e?void 0:e.cause)&&"not_defined"!==(null==e?void 0:e.cause)&&"call_rejected"!==(null==e?void 0:e.cause)||"webrtc"!==h&&"nethlink"!==h||!o||c===r||d.store.dispatch.conference.resetConference(),("normal_clearing"===e.cause&&("webrtc"===h||"nethlink"===h)||"call_rejected"===(null==e?void 0:e.cause))&&o&&c===r){var w=d.store.getState().conference,_=w.usersList,N=w.pendingUsers,I=_&&Object.keys(_).length>0,T=N&&Object.keys(N).length>0;I||T?setTimeout((function(){a.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})}),800):d.store.dispatch.conference.resetConference()}if("interworking"===(null==e?void 0:e.cause)&&o&&c===r&&"waitingConference"!==l&&setTimeout((function(){a.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})}),800),"user_busy"===(null==e?void 0:e.cause)){var j=d.store.getState().currentUser,D=j.endpoints,x=j.username,E=((null==D?void 0:D.extension)||[]).map((function(e){return e.id})),O=d.store.getState().currentCall,P=O.incoming,A=O.accepted,F=O.transferring,M=d.store.getState().conference,R=M.isActive,L=M.conferenceStartedFrom;!(P&&e.callerNum&&E.includes(e.callerNum))&&(!A||R||F)&&(d.store.dispatch.island.setOperatorBusyActive({callerNumber:e.callerNum||"Unknown"}),setTimeout((function(){d.store.dispatch.player.stopAudioPlayer()}),4e3),setTimeout((function(){d.store.dispatch.player.updateStartAudioPlayer({src:u.default,loop:!0}),d.store.dispatch.island.setIslandView("operatorBusy")}),600),R&&L===x&&setTimeout((function(){a.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})}),4e3))}if("subscriber_absent"===(null==e?void 0:e.cause)){var Q=d.store.getState().conference,W=Q.isActive,B=Q.conferenceStartedFrom,K=d.store.getState().currentUser.username;if(W&&B===K){var H=d.store.getState().conference;_=H.usersList,N=H.pendingUsers,I=_&&Object.keys(_).length>0,T=N&&Object.keys(N).length>0,I||T?(setTimeout((function(){a.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})}),800),N&&N[e.callerNum]&&d.store.dispatch.conference.removePendingUser(e.callerNum)):d.store.dispatch.conference.resetConference()}}})),O.current.on("extenConnected",(function(e){var n=d.store.getState().currentUser,t=n.default_device,r=n.endpoints,i=((null==r?void 0:r.extension)||[]).find((function(n){return n.id===e.extenConnected})),o=null==i?void 0:i.type;(("webrtc"===(null==t?void 0:t.type)||"nethlink"===(null==t?void 0:t.type))&&o&&("mobile"===o||"physical"===o)||"physical"===(null==t?void 0:t.type)&&o&&"physical"!==o)&&(d.store.dispatch.island.toggleAvoidToShow(!0),d.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!0),a.eventDispatch("phone-island-call-answered",{extensionType:o}))})),O.current.on("extenUpdate",(function(e){var n,t,r;x.users.updateExtension(e);var i=d.store.getState().users.extensions,o={},u=d.store.getState().currentUser;for(var c in i){var a=i[c].username,s=i[c].exten;o[a]||(o[a]=[]),o[a].push(s)}var l,v,p=o[e.username],g=Object.keys(e.conversations||{}),h=e.username===N,b=(null===(n=e.conversations)||void 0===n?void 0:n[g[0]])||{};h&&(l=e.exten,v=e.conversations,l&&Object.values(v||{}).forEach((function(e){T(e)&&V.current.set(l,{conversation:e,cachedAt:Date.now()})})));var k=!1;if((null==e?void 0:e.username)===N&&!m.isEmpty(b)&&(null==b?void 0:b.owner)){var S=null===(r=null===(t=null==u?void 0:u.endpoints)||void 0===t?void 0:t.extension)||void 0===r?void 0:r.find((function(e){return e.id===b.owner}));S&&"mobile"===S.type&&(k=!0)}if(f.dispatchExtensions(e),m.isEmpty(b)){var y=null==p?void 0:p.some((function(e){var n,t=null===(n=i[e])||void 0===n?void 0:n.conversations;return!m.isEmpty(t)}));y||f.dispatchConversations(e)}else k||f.dispatchConversations(e);k&&"busy"===(null==e?void 0:e.status)&&(null==e?void 0:e.username)===N&&(d.store.dispatch.island.toggleAvoidToShow(!0),d.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!0)),e.username===N&&(j(e,b),x.currentUser.updateConversations(e))})),O.current.on("queueUpdate",(function(e){x.queue.updateQueue(e);var n,t,r,i=(n=d.store.getState().currentUser.conversations,t=d.store.getState().currentCall.conversationId,r=null,Object.values(n||{}).forEach((function(e){Object.values(e||{}).forEach((function(e){(null==r?void 0:r.id)&&r.id===t||(t&&e.id===t||!r||e.connected&&!r.connected||e.connected===r.connected&&e.startTime>r.startTime)&&(r=e)}))})),r);i&&w(i),f.dispatchQueueUpdate(e)})),O.current.on("queueMemberUpdate",(function(e){x.queue.updateQueueMember(e),f.dispatchQueueMemberUpdate(e)})),O.current.on("takeOver",(function(){f.dispatchAlreadyLogin()})),O.current.on("serverReloaded",(function(){f.dispatchServerReload()})),O.current.on("parkingUpdate",(function(e){f.dispatchParkingUpdate(e)})),O.current.on("actionNethLink",(function(e,n){f.dispatchUrlCall(e,n)})),O.current.on("satellite/summary",(function(e){var n=(null==e?void 0:e.uniqueid)||(null==e?void 0:e.uniqueId),t=(null==e?void 0:e.linkedid)||(null==e?void 0:e.linkedId);n&&l.dispatchSummaryReady({linkedid:t,uniqueid:n,display_name:null==e?void 0:e.display_name,display_number:null==e?void 0:e.display_number,source:"socket"})})),O.current.on("message",(function(e){switch(e.message){case"videoCallStart":var n=d.store.getState(),t=n.currentCall,r=t.incoming,i=t.outgoing,o=t.accepted,u=n.currentUser.default_device,c=n.island,a=c.isFromStreaming,s=c.view;("webrtc"===(null==u?void 0:u.type)||"nethlink"===(null==u?void 0:u.type))&&(r||i||o)&&!a&&"video"!==s&&(x.island.toggleSideViewVisible(!1),x.island.toggleTranscriptionViewVisible(!1),x.island.setIslandView("video")),f.dispatchVideoCallStarted({initiator:"remote",callUser:e.callUser,destUser:e.destUser});break;case"screenSharingStart":x.island.toggleSideViewVisible(!1),x.island.toggleTranscriptionViewVisible(!1),x.island.setIslandView("video"),x.screenShare.update({isJoiningScreenShare:!0,room:e.roomId});break;case"screenSharingStop":x.island.toggleSideViewVisible(!1),x.island.toggleTranscriptionViewVisible(!1),x.island.setIslandView("video"),x.screenShare.update({isLeavingScreenShare:!0});break;default:console.warn("Socket: unknown message type ",e.message)}})),O.current.on("updateDefaultDevice",(function(n){f.dispatchDefaultDeviceUpdate(n);var t=d.store.getState().users.extensions,r=d.store.getState().currentUser.endpoints;if(t&&r){var i=Object.values(t).filter((function(e){return(null==e?void 0:e.exten)===n}));if(0!==i.length){var o=i[0],u=r.extension.find((function(e){return e.id===o.exten}));u&&(o=e.__assign(e.__assign({},o),{type:u.type})),d.store.dispatch.currentUser.updateCurrentDefaultDevice(o),v.checkMediaPermissions()}}})),O.current.on("confBridgeUpdate",(function(n){if(n&&(null==n?void 0:n.users)){var t=null==n?void 0:n.id,r=null==n?void 0:n.users,i=d.store.getState().conference.usersList,o=e.__assign({},r);i&&Object.keys(o).forEach((function(n){i[n]&&(o[n]=e.__assign(e.__assign({},o[n]),{muted:i[n].muted}))})),d.store.dispatch.conference.updateConferenceUsersList(o),d.store.dispatch.conference.updateConferenceId(t)}})),O.current.on("confBridgeEnd",(function(e){e&&(null==e?void 0:e.id)&&(d.store.dispatch.conference.resetConference(),a.eventDispatch("phone-island-conference-finished",{}))})),O.current.on("callWebrtc",(function(e){a.eventDispatch("phone-island-call-start",{number:e})})),O.current.on("newVoiceMessageCounter",(function(e){a.eventDispatch("phone-island-voicemail-received",{voicemailInfo:e})})),O.current.on("streamingSourceUpdate",(function(e){a.eventDispatch("phone-island-streaming-information-received",{res:e});var n=e.streaming||e.res&&e.res.streaming;if(n){var t=n.source,r=n.image;if(t&&r){d.store.getState().island.isFromStreaming;var i=d.store.getState().currentCall.streamingSourceNumber;g.getStreamingSourceId(i),x.streaming.updateSourceImage({source:t,image:r})}}})),O.current.on("satellite/transcription",(function(e){var n=M.current,t=null==e?void 0:e.uniqueid,r=null==e?void 0:e.linkedid;if(n.linkedid&&t){var i=function(e){return null!=e&&(e===n.linkedid||e===n.uniqueid)};if(!i(t)&&!i(r))return}a.eventDispatch("phone-island-conversation-transcription",e)})),function(){clearInterval(E.current),O.current.close()}}),[_,N,I,D,x]),n.useEffect((function(){var e;if(T){console.info("Socket reload requested");var n=d.store.getState().alerts.data,t=d.store.getState().island.forceReload;(null===(e=n.socket_down)||void 0===e?void 0:e.active)||!1||t?(console.info(t?"Force reload requested, performing Socket reconnection":"Socket down detected (alert active), performing reconnection"),t&&d.store.dispatch.island.setForceReload(!1),E.current&&(clearInterval(E.current),E.current=null),setTimeout((function(){O.current.disconnect(),O.current.connect(),U()}),100)):(console.info("Socket already connected (no alert active), skipping reconnection"),U())}}),[T]),q.default.createElement(q.default.Fragment,null,j)};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../node_modules/tslib/tslib.es6.js"),n=require("react");require("../node_modules/react-redux/es/index.js");var t=require("../node_modules/socket.io-client/build/esm/index.js"),r=require("./RestAPI.js"),i=require("../lib/phone/conversation.js"),o=require("../services/user.js"),u=require("../static/busy_ringtone.js"),c=require("../utils/customHooks/useEventListener.js"),a=require("../utils/genericFunctions/eventDispatch.js"),s=require("../utils/genericFunctions/withTimeout.js"),l=require("../utils/genericFunctions/summaryEvents.js"),d=require("../store/index.js");require("../lib/webrtc/janus.js"),require("../node_modules/webrtc-adapter/src/js/adapter_core.js");var v=require("../lib/devices/devices.js"),p=require("../lib/user/default_device.js"),m=require("../utils/genericFunctions/isEmpty.js"),g=require("../utils/streaming/getStreamingSourceId.js"),f=require("../events/SocketEvents.js"),h=require("../utils/genericFunctions/timestamp.js"),b=require("../lib/user/extensions.js"),k=require("../utils/streaming/isFromStreaming.js"),S=require("../lib/phone/queue.js"),y=require("../lib/phone/trunk.js"),q=require("../node_modules/react-redux/es/hooks/useDispatch.js");function w(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var C=w(n);exports.Socket=function(w){var _=w.hostName,N=w.username,I=w.authToken,T=w.reload,U=w.reloadedCallback,j=w.children,D=w.uaType,x=q.useDispatch(),E=n.useRef(),O=n.useRef(),P=n.useRef(!1),A=n.useRef(0),F=n.useRef(null),V=n.useRef(new Map),M=n.useRef({linkedid:null,uniqueid:null});c.useEventListener("phone-island-start-transcription",(function(e){if(O.current){var n=(null==e?void 0:e.linkedid)||(null==e?void 0:e.linkedId)||(null==e?void 0:e.uniqueid)||(null==e?void 0:e.uniqueId)||null,t=(null==e?void 0:e.uniqueid)||(null==e?void 0:e.uniqueId)||n;if(!n&&!t)return;M.current={linkedid:n,uniqueid:t},O.current.emit("start_transcription",{linkedid:n,uniqueid:t})}})),c.useEventListener("phone-island-stop-transcription",(function(e){if(O.current){var n=(null==e?void 0:e.linkedid)||(null==e?void 0:e.linkedId)||(null==e?void 0:e.uniqueid)||(null==e?void 0:e.uniqueId)||null,t=(null==e?void 0:e.uniqueid)||(null==e?void 0:e.uniqueId)||n;if(!n&&!t)return;M.current={linkedid:null,uniqueid:null},O.current.emit("stop_transcription",{linkedid:n,uniqueid:t})}})),c.useEventListener("phone-island-current-user-queue-call-waiting",(function(e){x.currentCall.updateCurrentCall({throughQueue:!0,queueId:(null==e?void 0:e.queueId)||"",queueName:(null==e?void 0:e.queueName)||"",queueNumber:(null==e?void 0:e.queueNumber)||"",queuePosition:(null==e?void 0:e.queuePosition)||"",queueWaitingTime:(null==e?void 0:e.queueWaitingTime)||0})})),c.useEventListener("phone-island-current-user-queue-call-connected",(function(e){x.currentCall.updateCurrentCall({throughQueue:!0,queueId:(null==e?void 0:e.queueId)||"",queueName:(null==e?void 0:e.queueName)||"",queueNumber:(null==e?void 0:e.queueNumber)||"",queuePosition:(null==e?void 0:e.queuePosition)||"",queueWaitingTime:(null==e?void 0:e.queueWaitingTime)||0})}));return n.useEffect((function(){var n,c=function(e){if(e.counterpartNum&&k.isFromStreaming(e.counterpartNum)){x.island.setIsFromStreaming(!0),x.currentCall.updateCurrentCall({streamingSourceNumber:e.counterpartNum});var n=g.getStreamingSourceId(e.counterpartNum);n&&o.subscribe({id:n}).catch((function(e){return console.error("Error subscribing to streaming source:",e)}))}},q=function(e){var n,t,r,i;if(e){var o=function(e){return S.getCurrentCallQueueContext(e,d.store.getState().queue)}(e),u=function(e,n){var t=d.store.getState().currentCall;return{conversationId:e.id,linkedId:e.linkedId,uniqueId:e.uniqueId,ownerExtension:e.owner,number:"".concat(e.counterpartNum||""),queueId:(null==n?void 0:n.queueId)||t.queueId||"",queueName:(null==n?void 0:n.queueName)||t.queueName||"",queueNumber:(null==n?void 0:n.queueNumber)||t.queueNumber||"",queuePosition:(null==n?void 0:n.queuePosition)||"",queueWaitingTime:(null==n?void 0:n.queueWaitingTime)||0}}(e,o);if(Boolean(u.queueId||u.queueName||u.queueNumber))if(e.connected)((null===(r=F.current)||void 0===r?void 0:r.conversationId)!==e.id||"connected"!==(null===(i=F.current)||void 0===i?void 0:i.phase))&&(f.dispatchCurrentUserQueueCallConnected(u),F.current={conversationId:e.id,phase:"connected"});else((null===(n=F.current)||void 0===n?void 0:n.conversationId)!==e.id||"waiting"!==(null===(t=F.current)||void 0===t?void 0:t.phase))&&(f.dispatchCurrentUserQueueCallWaiting(u),F.current={conversationId:e.id,phase:"waiting"});else F.current=null}else F.current=null},w=function(e){return(null==e?void 0:e.linkedId)||(null==e?void 0:e.linkedid)||""},C=function(e){return(null==e?void 0:e.uniqueId)||(null==e?void 0:e.uniqueid)||""},T=function(e){return!!(null==e?void 0:e.connected)&&!!w(e)&&!!C(e)},U=function(n){var t=d.store.getState().currentUser.conversations,r=n?null==t?void 0:t[n]:void 0,i=function(e){var n,t=null,r=Object.entries(e||{}).filter((function(e){var n=e[1];return n&&Object.keys(n).length>0}));return r.forEach((function(e){var r,i,o=e[0],u=e[1];if(!t)return t=u,void(n=o);var c=T(t),a=T(u);if(a&&!c)return t=u,void(n=o);if(a===c){var s=!!t.connected,l=!!u.connected;if(l&&!s)return t=u,void(n=o);var d=null!==(r=t.startTime)&&void 0!==r?r:0,v=null!==(i=u.startTime)&&void 0!==i?i:0;l===s&&v>d&&(t=u,n=o)}})),{conversation:t,key:n,count:r.length}}(r);if(T(i.conversation))return e.__assign(e.__assign({},i),{source:"live",cacheAgeMs:void 0,hasConversationForCaller:!!r,liveConversationKeys:Object.keys(r||{})});var o=function(n){if(!n)return null;var t=V.current.get(n);if(!t)return null;var r=Date.now()-t.cachedAt;return r>6e5?(V.current.delete(n),null):e.__assign(e.__assign({},t),{cacheAgeMs:r})}(n);return o&&T(o.conversation)?{conversation:o.conversation,key:o.conversation.id,count:i.count,source:"cache",cacheAgeMs:o.cacheAgeMs,hasConversationForCaller:!!r,liveConversationKeys:Object.keys(r||{})}:e.__assign(e.__assign({},i),{source:i.conversation?"live_invalid":"none",cacheAgeMs:null==o?void 0:o.cacheAgeMs,hasConversationForCaller:!!r,liveConversationKeys:Object.keys(r||{})})},j=function(n,t){var r=d.store.getState().currentCall,u=r.transferring,s=r.transferSwitching,l=r.transferCalls,v=d.store.getState().island.view;if(Object.keys(t).length>0){if(n.status){var m=d.store.getState().users.extensions,g=d.store.getState().currentUser.default_device,f=d.store.getState().currentUser,k=f.endpoints,S=f.username,w=d.store.getState().currentCall;w.incoming,w.outgoing;var C=function(){if(!m||!S)return!1;var e=Object.values(m).filter((function(e){return(null==e?void 0:e.username)===S}));return null==e?void 0:e.some((function(e){var n=null==k?void 0:k.extension.find((function(n){return n.id===(null==e?void 0:e.exten)}));return"nethlink"===(null==n?void 0:n.type)&&"offline"!==(null==e?void 0:e.status)}))};switch(n.status){case"ringing":if(function(e){var n=d.store.getState().currentCall,t=n.accepted,r=n.ownerExtension;return t&&!!r&&!!e&&r!==e}(t.owner))break;q(t),c(t),("mobile"===D&&C()||"desktop"===D&&("webrtc"===(null==g?void 0:g.type)||void 0===(null==g?void 0:g.type)&&!C()||!C()&&"physical"===(null==g?void 0:g.type)))&&(x.currentCall.checkIncomingUpdatePlay({conversationId:t.id,displayName:i.getDisplayName(t),number:"".concat(t.counterpartNum),incomingSocket:!0,incoming:!0,username:"".concat(m&&m[t.counterpartNum]&&m[t.counterpartNum].username)||"",ownerExtension:t.owner}),d.store.dispatch.island.setIslandView("call")),P.current||(P.current=!0,o.getCurrentUserInfo().then((function(n){n&&(x.currentUser.updateCurrentUser(n),a.eventDispatch("phone-island-user-informations-update",e.__assign({},n)),n.settings&&n.settings.open_param_url?x.paramUrl.setOpenParamUrlType(n.settings.open_param_url):x.paramUrl.setOpenParamUrlType("never"))})).catch((function(e){console.error("Error getting current user info:",e)})).finally((function(){setTimeout((function(){P.current=!1}),100)})));var _=d.store.getState().paramUrl.openParamUrlType,N=d.store.getState().island.urlOpened;if("ringing"===_&&!N){var I=y.isFromTrunk(t.counterpartNum);d.store.dispatch.paramUrl.setThroughTrunk(I),d.store.dispatch.island.setUrlOpened(!1),a.eventDispatch("phone-island-url-parameter-opened",{counterpartNum:t.counterpartNum,counterpartName:i.getDisplayName(t),owner:t.owner,uniqueId:t.uniqueId,linkedId:t.linkedId,throughQueue:t.throughQueue,throughTrunk:I,direction:t.direction,connected:t.connected})}break;case"busy":if(q(t),c(t),"mobile"===D&&C()||"desktop"===D&&("webrtc"===(null==g?void 0:g.type)||void 0===(null==g?void 0:g.type)&&!C()||!C()&&"physical"===(null==g?void 0:g.type))){if(t&&t.connected)x.currentCall.updateCurrentCall({conversationId:t.id,displayName:i.getDisplayName(t),number:"".concat(t.counterpartNum),ownerExtension:t.owner,username:"".concat(m&&m[t.counterpartNum]&&m[t.counterpartNum].username)||"",chDest:(null==t?void 0:t.chDest)||{},chSource:(null==t?void 0:t.chSource)||{}}),x.currentCall.checkAcceptedUpdate({acceptedSocket:!0}),x.currentCall.addTransferCalls({type:"transferred",displayName:i.getDisplayName(t),number:"".concat(t.counterpartNum),startTime:"".concat(h.getTimestampInSeconds())}),d.store.getState().island.isFromStreaming&&"out"===t.direction&&setTimeout((function(){x.island.setIslandView("streamingAnswer")}),200),p.isPhysical()&&function(e){x.currentCall.updateCurrentCall({conversationId:e.id,accepted:!0,incoming:"in"!==e.direction&&void 0}),a.eventDispatch("phone-island-call-answered",{}),d.store.dispatch.player.stopAudioPlayer(),d.store.dispatch.player.setAudioPlayerLoop(!1)}(t),"call"===v&&u&&x.currentCall.updateCurrentCall({transferring:!1});if(l.length>1)x.currentCall.deleteTransferCalls();else if(t&&!t.connected){if(u&&!s){var T=l.find((function(e){return e.number===t.counterpartNum}));!t.connected&&T&&(x.currentCall.updateCurrentCall({transferring:!1}),a.eventDispatch("phone-island-call-transfer-failed",{}),x.currentCall.updateTransferSwitching(!1))}"REC"===(null==t?void 0:t.counterpartName)&&x.physicalRecorder.setRecordingTempVariable(!0)}t&&!t.connected&&"out"===t.direction&&x.currentCall.checkOutgoingUpdate({outgoingSocket:!0,outgoing:"REC"!==(null==t?void 0:t.counterpartName),displayName:i.getDisplayName(t),number:"".concat(null==t?void 0:t.counterpartNum),username:"".concat(m&&m[null==t?void 0:t.counterpartNum]&&m[null==t?void 0:t.counterpartNum].username)||""})}break;case"onhold":q(t);var U=t.counterpartName,j=t.counterpartNum,E=t.startTime;u&&j&&U&&"<unknown>"!==U&&(x.currentCall.addTransferCalls({type:"destination",displayName:i.getDisplayName(t),number:j,startTime:"".concat(h.getTimestampInSeconds())}),x.currentCall.updateCurrentCall({displayName:i.getDisplayName(t),number:j,startTime:"".concat(E/1e3),conversationId:t.id}),x.island.setIslandView("call"));break;case"busy_ringing":a.eventDispatch("phone-island-call-ringing",{})}}}else"online"==n.status&&b.userTotallyFree()&&(q(null),x.player.stopAudioPlayer(),x.currentCall.reset(),x.physicalRecorder.setRecordingTempVariable(!1),x.island.setIsFromStreaming(!1))};return n={upgrade:!1,transports:["websocket"],reconnection:!0,reconnectionDelay:2e3},"new"===r.getApiMode(N)&&(n.path="/api/ws"),O.current=t.io("https://"+_,n),x.websocket.update({socket:O.current}),O.current.on("connect",(function(){console.debug("Socket connected sid: ".concat(O.current.id)),a.eventDispatch("phone-island-socket-connected",{})})),O.current.on("disconnect",(function(e){console.debug("Socket disconnect - reason: ".concat(e)),E.current&&(clearInterval(E.current),E.current=null),e.includes("server disconnect")?a.eventDispatch("phone-island-server-disconnected",{}):a.eventDispatch("phone-island-socket-disconnected",{})})),O.current.io.on("error",(function(e){console.debug("Socket error: ",e)})),O.current.on("connect_error",(function(e){console.debug("Socket connect_error: ",e)})),O.current.io.on("reconnect",(function(e){A.current=0,a.eventDispatch("phone-island-socket-reconnected",{}),console.debug("Socket reconnect attemp ".concat(e," (sid: ").concat(O.current.id,")"))})),O.current.io.on("reconnect_attempt",(function(e){console.debug("Socket reconnect_attempt ".concat(e))})),O.current.io.on("reconnect_error",(function(e){console.debug("Socket reconnect_error: ",e)})),O.current.io.on("reconnect_failed",(function(){console.debug("Socket reconnect_failed")})),O.current.on("connect",(function(){console.debug("Socket on: "+_+" is connected!"),O.current.emit("login",{accessKeyId:"".concat(N),token:I,uaType:D})})),O.current.on("authe_ok",(function(){console.debug("Socket authentication success!"),a.eventDispatch("phone-island-socket-authorized",{}),E.current&&clearInterval(E.current),E.current=setInterval((function(){O.current.volatile.emit("ping",s.withTimeout((function(){A.current=0,setTimeout((function(){x.alerts.removeAlert("socket_down"),a.eventDispatch("phone-island-alert-removed",{type:"socket_down"}),a.eventDispatch("phone-island-socket-disconnected-popup-close",{})}),0)}),(function(){A.current++,console.debug("Socket ping timeout (".concat(A.current,"/").concat(3,"), connected: ").concat(O.current.connected)),setTimeout((function(){var e,n,t=O.current.connected&&A.current>=3;if(!O.current.connected||t){var r=d.store.getState().webrtc.sipcall,i=d.store.getState().currentCall,o=i.accepted,u=i.outgoing,c=null===(n=null===(e=null==r?void 0:r.webrtcStuff)||void 0===e?void 0:e.pc)||void 0===n?void 0:n.iceConnectionState;if((o||u)&&("connected"===c||"completed"===c))return void console.debug("Socket unreachable but active call with ICE connected - skipping socket_down alert",{iceState:c,accepted:o,outgoing:u,isStaleConnection:t,timestamp:(new Date).toISOString()});t&&(console.warn("Stale socket connection detected - forcing reconnection"),O.current.disconnect()),x.alerts.setAlert("socket_down"),a.eventDispatch("phone-island-socket-disconnected-popup-open",{}),console.error("Socket is unreachable!")}}),0)}),5e3))}),5e3)})),O.current.on("userMainPresenceUpdate",(function(n){d.store.dispatch.users.updateEndpointMainPresence(e.__assign({},n.mainPresence)),f.dispatchMainPresence(n)})),O.current.on("extenHangup",(function(e){var n=d.store.getState().currentUser,t=n.endpoints,r=n.username,i=d.store.getState().conference,o=i.isActive,c=i.conferenceStartedFrom,s=d.store.getState().island,l=s.view,v=s.previewCallFromMobileOrNethlink,p=(null==t?void 0:t.extension)||[],m=p.map((function(e){return e.id})),g=null==e?void 0:e.callerNum;!m.includes(g)&&m.includes(null==e?void 0:e.channelExten)&&(g=null==e?void 0:e.channelExten);var f=p.find((function(n){return n.id===e.callerNum})),h=null==f?void 0:f.type,b=U(g).conversation,k=w(b),S=C(b),y=(null==b?void 0:b.connected)||!1;if(S&&k&&y&&(a.eventDispatch("phone-island-summary-call-check",{linkedid:k,uniqueid:S}),g&&V.current.delete(g)),"normal_clearing"===e.cause&&("physical"===h||"mobile"===h)||"normal_clearing"===e.cause&&("webrtc"===h||"nethlink"===h)&&v||"user_busy"===(null==e?void 0:e.cause)||"not_defined"===(null==e?void 0:e.cause)||"call_rejected"===(null==e?void 0:e.cause)||"interworking"===(null==e?void 0:e.cause)?(setTimeout((function(){d.store.dispatch.island.toggleAvoidToShow(!1),d.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!1)}),500),o&&c!==r&&d.store.dispatch.conference.resetConference()):"normal_circuit_congestion"===(null==e?void 0:e.cause)&&o&&c===r?setTimeout((function(){a.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})}),800):"normal_clearing"!==e.cause&&"user_busy"!==(null==e?void 0:e.cause)&&"not_defined"!==(null==e?void 0:e.cause)&&"call_rejected"!==(null==e?void 0:e.cause)||"webrtc"!==h&&"nethlink"!==h||!o||c===r||d.store.dispatch.conference.resetConference(),("normal_clearing"===e.cause&&("webrtc"===h||"nethlink"===h)||"call_rejected"===(null==e?void 0:e.cause))&&o&&c===r){var q=d.store.getState().conference,_=q.usersList,N=q.pendingUsers,I=_&&Object.keys(_).length>0,T=N&&Object.keys(N).length>0;I||T?setTimeout((function(){a.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})}),800):d.store.dispatch.conference.resetConference()}if("interworking"===(null==e?void 0:e.cause)&&o&&c===r&&"waitingConference"!==l&&setTimeout((function(){a.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})}),800),"user_busy"===(null==e?void 0:e.cause)){var j=d.store.getState().currentUser,D=j.endpoints,x=j.username,E=((null==D?void 0:D.extension)||[]).map((function(e){return e.id})),O=d.store.getState().currentCall,P=O.incoming,A=O.accepted,F=O.transferring,M=d.store.getState().conference,R=M.isActive,L=M.conferenceStartedFrom;!(P&&e.callerNum&&E.includes(e.callerNum))&&(!A||R||F)&&(d.store.dispatch.island.setOperatorBusyActive({callerNumber:e.callerNum||"Unknown"}),setTimeout((function(){d.store.dispatch.player.stopAudioPlayer()}),4e3),setTimeout((function(){d.store.dispatch.player.updateStartAudioPlayer({src:u.default,loop:!0}),d.store.dispatch.island.setIslandView("operatorBusy")}),600),R&&L===x&&setTimeout((function(){a.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})}),4e3))}if("subscriber_absent"===(null==e?void 0:e.cause)){var Q=d.store.getState().conference,W=Q.isActive,B=Q.conferenceStartedFrom,K=d.store.getState().currentUser.username;if(W&&B===K){var H=d.store.getState().conference;_=H.usersList,N=H.pendingUsers,I=_&&Object.keys(_).length>0,T=N&&Object.keys(N).length>0,I||T?(setTimeout((function(){a.eventDispatch("phone-island-view-changed",{viewType:"waitingConference"})}),800),N&&N[e.callerNum]&&d.store.dispatch.conference.removePendingUser(e.callerNum)):d.store.dispatch.conference.resetConference()}}})),O.current.on("extenConnected",(function(e){var n=d.store.getState().currentUser,t=n.default_device,r=n.endpoints,i=((null==r?void 0:r.extension)||[]).find((function(n){return n.id===e.extenConnected})),o=null==i?void 0:i.type;(("webrtc"===(null==t?void 0:t.type)||"nethlink"===(null==t?void 0:t.type))&&o&&("mobile"===o||"physical"===o)||"physical"===(null==t?void 0:t.type)&&o&&"physical"!==o)&&(d.store.dispatch.island.toggleAvoidToShow(!0),d.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!0),a.eventDispatch("phone-island-call-answered",{extensionType:o}))})),O.current.on("extenUpdate",(function(e){var n,t,r;x.users.updateExtension(e);var i=d.store.getState().users.extensions,o={},u=d.store.getState().currentUser;for(var c in i){var a=i[c].username,s=i[c].exten;o[a]||(o[a]=[]),o[a].push(s)}var l,v,p=o[e.username],g=Object.keys(e.conversations||{}),h=e.username===N,b=(null===(n=e.conversations)||void 0===n?void 0:n[g[0]])||{};h&&(l=e.exten,v=e.conversations,l&&Object.values(v||{}).forEach((function(e){T(e)&&V.current.set(l,{conversation:e,cachedAt:Date.now()})})));var k=!1;if((null==e?void 0:e.username)===N&&!m.isEmpty(b)&&(null==b?void 0:b.owner)){var S=null===(r=null===(t=null==u?void 0:u.endpoints)||void 0===t?void 0:t.extension)||void 0===r?void 0:r.find((function(e){return e.id===b.owner}));S&&"mobile"===S.type&&(k=!0)}if(f.dispatchExtensions(e),m.isEmpty(b)){var y=null==p?void 0:p.some((function(e){var n,t=null===(n=i[e])||void 0===n?void 0:n.conversations;return!m.isEmpty(t)}));y||f.dispatchConversations(e)}else k||f.dispatchConversations(e);k&&"busy"===(null==e?void 0:e.status)&&(null==e?void 0:e.username)===N&&(d.store.dispatch.island.toggleAvoidToShow(!0),d.store.dispatch.island.setPreviewCallFromMobileOrNethlink(!0)),e.username===N&&(j(e,b),x.currentUser.updateConversations(e))})),O.current.on("queueUpdate",(function(e){x.queue.updateQueue(e);var n,t,r,i=(n=d.store.getState().currentUser.conversations,t=d.store.getState().currentCall.conversationId,r=null,Object.values(n||{}).forEach((function(e){Object.values(e||{}).forEach((function(e){(null==r?void 0:r.id)&&r.id===t||(t&&e.id===t||!r||e.connected&&!r.connected||e.connected===r.connected&&e.startTime>r.startTime)&&(r=e)}))})),r);i&&q(i),f.dispatchQueueUpdate(e)})),O.current.on("queueMemberUpdate",(function(e){x.queue.updateQueueMember(e),f.dispatchQueueMemberUpdate(e)})),O.current.on("takeOver",(function(){f.dispatchAlreadyLogin()})),O.current.on("serverReloaded",(function(){f.dispatchServerReload()})),O.current.on("parkingUpdate",(function(e){f.dispatchParkingUpdate(e)})),O.current.on("actionNethLink",(function(e,n){f.dispatchUrlCall(e,n)})),O.current.on("satellite/summary",(function(e){var n=(null==e?void 0:e.uniqueid)||(null==e?void 0:e.uniqueId),t=(null==e?void 0:e.linkedid)||(null==e?void 0:e.linkedId);n&&l.dispatchSummaryReady({linkedid:t,uniqueid:n,display_name:null==e?void 0:e.display_name,display_number:null==e?void 0:e.display_number,source:"socket"})})),O.current.on("message",(function(e){switch(e.message){case"videoCallStart":var n=d.store.getState(),t=n.currentCall,r=t.incoming,i=t.outgoing,o=t.accepted,u=n.currentUser.default_device,c=n.island,a=c.isFromStreaming,s=c.view;("webrtc"===(null==u?void 0:u.type)||"nethlink"===(null==u?void 0:u.type))&&(r||i||o)&&!a&&"video"!==s&&(x.island.toggleSideViewVisible(!1),x.island.toggleTranscriptionViewVisible(!1),x.island.setIslandView("video")),f.dispatchVideoCallStarted({initiator:"remote",callUser:e.callUser,destUser:e.destUser});break;case"screenSharingStart":x.island.toggleSideViewVisible(!1),x.island.toggleTranscriptionViewVisible(!1),x.island.setIslandView("video"),x.screenShare.update({isJoiningScreenShare:!0,room:e.roomId});break;case"screenSharingStop":x.island.toggleSideViewVisible(!1),x.island.toggleTranscriptionViewVisible(!1),x.island.setIslandView("video"),x.screenShare.update({isLeavingScreenShare:!0});break;default:console.warn("Socket: unknown message type ",e.message)}})),O.current.on("updateDefaultDevice",(function(n){f.dispatchDefaultDeviceUpdate(n);var t=d.store.getState().users.extensions,r=d.store.getState().currentUser.endpoints;if(t&&r){var i=Object.values(t).filter((function(e){return(null==e?void 0:e.exten)===n}));if(0!==i.length){var o=i[0],u=r.extension.find((function(e){return e.id===o.exten}));u&&(o=e.__assign(e.__assign({},o),{type:u.type})),d.store.dispatch.currentUser.updateCurrentDefaultDevice(o),v.checkMediaPermissions()}}})),O.current.on("confBridgeUpdate",(function(n){if(n&&(null==n?void 0:n.users)){var t=null==n?void 0:n.id,r=null==n?void 0:n.users,i=d.store.getState().conference.usersList,o=e.__assign({},r);i&&Object.keys(o).forEach((function(n){i[n]&&(o[n]=e.__assign(e.__assign({},o[n]),{muted:i[n].muted}))})),d.store.dispatch.conference.updateConferenceUsersList(o),d.store.dispatch.conference.updateConferenceId(t)}})),O.current.on("confBridgeEnd",(function(e){e&&(null==e?void 0:e.id)&&(d.store.dispatch.conference.resetConference(),a.eventDispatch("phone-island-conference-finished",{}))})),O.current.on("callWebrtc",(function(e){a.eventDispatch("phone-island-call-start",{number:e})})),O.current.on("newVoiceMessageCounter",(function(e){a.eventDispatch("phone-island-voicemail-received",{voicemailInfo:e})})),O.current.on("streamingSourceUpdate",(function(e){a.eventDispatch("phone-island-streaming-information-received",{res:e});var n=e.streaming||e.res&&e.res.streaming;if(n){var t=n.source,r=n.image;if(t&&r){d.store.getState().island.isFromStreaming;var i=d.store.getState().currentCall.streamingSourceNumber;g.getStreamingSourceId(i),x.streaming.updateSourceImage({source:t,image:r})}}})),O.current.on("satellite/transcription",(function(e){var n=M.current,t=null==e?void 0:e.uniqueid,r=null==e?void 0:e.linkedid;if(n.linkedid&&t){var i=function(e){return null!=e&&(e===n.linkedid||e===n.uniqueid)};if(!i(t)&&!i(r))return}a.eventDispatch("phone-island-conversation-transcription",e)})),function(){clearInterval(E.current),O.current.close()}}),[_,N,I,D,x]),n.useEffect((function(){var e;if(T){console.info("Socket reload requested");var n=d.store.getState().alerts.data,t=d.store.getState().island.forceReload;(null===(e=n.socket_down)||void 0===e?void 0:e.active)||!1||t?(console.info(t?"Force reload requested, performing Socket reconnection":"Socket down detected (alert active), performing reconnection"),t&&d.store.dispatch.island.setForceReload(!1),E.current&&(clearInterval(E.current),E.current=null),setTimeout((function(){O.current.disconnect(),O.current.connect(),U()}),100)):(console.info("Socket already connected (no alert active), skipping reconnection"),U())}}),[T]),C.default.createElement(C.default.Fragment,null,j)};
2
2
  //# sourceMappingURL=Socket.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Socket.js","sources":["../../src/components/Socket.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type ReactNode, FC, useEffect, useRef } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { Dispatch, RootState } from '../store'\nimport { io } from 'socket.io-client'\nimport { getApiMode } from './RestAPI'\nimport { getDisplayName } from '../lib/phone/conversation'\nimport { getCurrentUserInfo } from '../services/user'\nimport busyRingtone from '../static/busy_ringtone'\nimport {\n dispatchMainPresence,\n dispatchConversations,\n dispatchQueueUpdate,\n dispatchQueueMemberUpdate,\n dispatchCurrentUserQueueCallWaiting,\n dispatchCurrentUserQueueCallConnected,\n dispatchAlreadyLogin,\n dispatchServerReload,\n dispatchParkingUpdate,\n dispatchExtensions,\n dispatchUrlCall,\n dispatchDefaultDeviceUpdate,\n dispatchVideoCallStarted,\n} from '../events'\nimport { store } from '../store'\nimport { dispatchSummaryReady, eventDispatch, useEventListener, withTimeout } from '../utils'\nimport type {\n ConversationTypes,\n ExtensionTypes,\n QueuesUpdateTypes,\n QueueUpdateMemberTypes,\n MainPresenceTypes,\n CurrentUserQueueCallEventTypes,\n} from '../types'\nimport { getTimestampInSeconds } from '../utils/genericFunctions/timestamp'\nimport { userTotallyFree } from '../lib/user/extensions'\nimport { isEmpty } from '../utils/genericFunctions/isEmpty'\nimport { isPhysical } from '../lib/user/default_device'\nimport { ScreenSharingMessage, VideoCallMessage } from './VideoView'\nimport { checkMediaPermissions } from '../lib/devices/devices'\nimport { isFromStreaming } from '../utils/streaming/isFromStreaming'\nimport { getStreamingSourceId } from '../utils/streaming/getStreamingSourceId'\nimport { subscribe } from '../services/user'\nimport { isFromTrunk } from '../lib/user/extensions'\nimport { getCurrentCallQueueContext } from '../lib/phone/queue'\n\ninterface SocketProps {\n children: ReactNode\n hostName: string\n username: string\n authToken: string\n reload: boolean\n reloadedCallback: () => void\n uaType: string\n}\n\ninterface SummaryConversationCacheEntry {\n conversation: ConversationTypes\n cachedAt: number\n}\n\nconst SUMMARY_CONVERSATION_CACHE_TTL_MS = 10 * 60 * 1000\n\nexport const Socket: FC<SocketProps> = ({\n hostName,\n username,\n authToken,\n reload,\n reloadedCallback,\n children,\n uaType,\n}) => {\n const dispatch = useDispatch<Dispatch>()\n const connectionCheckInterval = useRef<any>()\n const socket = useRef<any>()\n const isUpdatingUserInfo = useRef(false)\n const consecutivePingTimeouts = useRef(0)\n const currentUserQueueCallPhase = useRef<{\n conversationId: string\n phase: 'waiting' | 'connected'\n } | null>(null)\n const summaryConversationCache = useRef<Map<string, SummaryConversationCacheEntry>>(new Map())\n const STALE_CONNECTION_THRESHOLD = 3 // Force reconnect after 3 consecutive ping timeouts\n // Identifiers of the transcription the user currently has open. Incoming\n // realtime chunks are matched against these to avoid mixing transcripts from\n // a different concurrent call into the open view.\n const activeTranscriptionIdsRef = useRef<{ linkedid: string | null; uniqueid: string | null }>({\n linkedid: null,\n uniqueid: null,\n })\n\n // Event listener for starting transcription\n useEventListener('phone-island-start-transcription', (data: any) => {\n if (socket.current) {\n const linkedid = data?.linkedid || data?.linkedId\n const uniqueid = data?.uniqueid || data?.uniqueId\n if (!linkedid && !uniqueid) {\n return\n }\n activeTranscriptionIdsRef.current = {\n linkedid: linkedid || null,\n uniqueid: uniqueid || null,\n }\n socket.current.emit('start_transcription', {\n linkedid,\n uniqueid,\n })\n }\n })\n\n // Event listener for stopping transcription\n useEventListener('phone-island-stop-transcription', (data: any) => {\n if (socket.current) {\n const linkedid = data?.linkedid || data?.linkedId\n const uniqueid = data?.uniqueid || data?.uniqueId\n if (!linkedid && !uniqueid) {\n return\n }\n activeTranscriptionIdsRef.current = { linkedid: null, uniqueid: null }\n socket.current.emit('stop_transcription', {\n linkedid,\n uniqueid,\n })\n }\n })\n\n useEventListener(\n 'phone-island-current-user-queue-call-waiting',\n (data: CurrentUserQueueCallEventTypes) => {\n dispatch.currentCall.updateCurrentCall({\n throughQueue: true,\n queueId: data?.queueId || '',\n queueName: data?.queueName || '',\n queueNumber: data?.queueNumber || '',\n queuePosition: data?.queuePosition || '',\n queueWaitingTime: data?.queueWaitingTime || 0,\n })\n },\n )\n\n useEventListener(\n 'phone-island-current-user-queue-call-connected',\n (data: CurrentUserQueueCallEventTypes) => {\n dispatch.currentCall.updateCurrentCall({\n throughQueue: true,\n queueId: data?.queueId || '',\n queueName: data?.queueName || '',\n queueNumber: data?.queueNumber || '',\n queuePosition: data?.queuePosition || '',\n queueWaitingTime: data?.queueWaitingTime || 0,\n })\n },\n )\n\n const checkDefaultDeviceConversationActive = (conv: any) => {\n dispatch.currentCall.updateCurrentCall({\n conversationId: conv.id,\n accepted: true,\n incoming: conv.direction === 'in' ? false : undefined,\n })\n eventDispatch('phone-island-call-answered', {})\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n store.dispatch.player.setAudioPlayerLoop(false)\n }\n\n useEffect(() => {\n /**\n * Helper function to handle streaming source detection and subscription\n */\n const handleStreamingSource = (conv: ConversationTypes) => {\n // Check if the call is from a streaming source\n if (conv.counterpartNum && isFromStreaming(conv.counterpartNum)) {\n // Set isFromStreaming flag to true\n dispatch.island.setIsFromStreaming(true)\n\n // Store the streaming source number in the currentCall state for future reference\n dispatch.currentCall.updateCurrentCall({\n streamingSourceNumber: conv.counterpartNum,\n })\n\n // Find the source ID and subscribe to streaming updates\n const sourceId = getStreamingSourceId(conv.counterpartNum)\n if (sourceId) {\n // Subscribe to streaming updates\n subscribe({ id: sourceId }).catch((error) =>\n console.error('Error subscribing to streaming source:', error),\n )\n }\n }\n }\n\n const getCurrentCallQueuePayload = (conv: ConversationTypes) => {\n return getCurrentCallQueueContext(conv, store.getState().queue)\n }\n\n const getQueuePayloadWithFallback = (\n conv: ConversationTypes,\n queueContext: ReturnType<typeof getCurrentCallQueuePayload>,\n ) => {\n const currentCall = store.getState().currentCall\n\n return {\n conversationId: conv.id,\n linkedId: conv.linkedId,\n uniqueId: conv.uniqueId,\n ownerExtension: conv.owner,\n number: `${conv.counterpartNum || ''}`,\n queueId: queueContext?.queueId || currentCall.queueId || '',\n queueName: queueContext?.queueName || currentCall.queueName || '',\n queueNumber: queueContext?.queueNumber || currentCall.queueNumber || '',\n queuePosition: queueContext?.queuePosition || '',\n queueWaitingTime: queueContext?.queueWaitingTime || 0,\n }\n }\n\n const syncCurrentUserQueueCall = (conv: ConversationTypes | null) => {\n if (!conv) {\n currentUserQueueCallPhase.current = null\n return\n }\n\n const queueContext = getCurrentCallQueuePayload(conv)\n const payload = getQueuePayloadWithFallback(conv, queueContext)\n const hasQueueContext = Boolean(payload.queueId || payload.queueName || payload.queueNumber)\n\n if (!hasQueueContext) {\n currentUserQueueCallPhase.current = null\n return\n }\n\n if (!conv.connected) {\n const shouldDispatchWaiting =\n currentUserQueueCallPhase.current?.conversationId !== conv.id ||\n currentUserQueueCallPhase.current?.phase !== 'waiting'\n\n if (shouldDispatchWaiting) {\n dispatchCurrentUserQueueCallWaiting(payload)\n currentUserQueueCallPhase.current = {\n conversationId: conv.id,\n phase: 'waiting',\n }\n }\n\n return\n }\n\n const shouldDispatchConnected =\n currentUserQueueCallPhase.current?.conversationId !== conv.id ||\n currentUserQueueCallPhase.current?.phase !== 'connected'\n\n if (shouldDispatchConnected) {\n dispatchCurrentUserQueueCallConnected(payload)\n currentUserQueueCallPhase.current = {\n conversationId: conv.id,\n phase: 'connected',\n }\n }\n }\n\n const getActiveConversationForCurrentCall = (): ConversationTypes | null => {\n const { conversations } = store.getState().currentUser\n const { conversationId } = store.getState().currentCall\n let selectedConversation: ConversationTypes | null = null\n\n Object.values(conversations || {}).forEach((extensionConversations) => {\n Object.values(extensionConversations || {}).forEach((conversation) => {\n if (selectedConversation?.id && selectedConversation.id === conversationId) {\n return\n }\n\n if (conversationId && conversation.id === conversationId) {\n selectedConversation = conversation\n return\n }\n\n if (!selectedConversation) {\n selectedConversation = conversation\n return\n }\n\n if (conversation.connected && !selectedConversation.connected) {\n selectedConversation = conversation\n return\n }\n\n if (\n conversation.connected === selectedConversation.connected &&\n conversation.startTime > selectedConversation.startTime\n ) {\n selectedConversation = conversation\n }\n })\n })\n\n return selectedConversation\n }\n\n const getConversationLinkedId = (conversation?: any) =>\n conversation?.linkedId || conversation?.linkedid || ''\n\n const getConversationUniqueId = (conversation?: any) =>\n conversation?.uniqueId || conversation?.uniqueid || ''\n\n const isSummaryConversationCandidate = (conversation?: any) =>\n !!conversation?.connected &&\n !!getConversationLinkedId(conversation) &&\n !!getConversationUniqueId(conversation)\n\n const selectLiveSummaryConversation = (extensionConversations?: Record<string, any>) => {\n let selectedConversation: any = null\n let selectedConversationKey: string | undefined\n const entries = Object.entries(extensionConversations || {}).filter(\n ([, conversation]) => conversation && Object.keys(conversation).length > 0,\n )\n\n entries.forEach(([key, currentConversation]) => {\n if (!selectedConversation) {\n selectedConversation = currentConversation\n selectedConversationKey = key\n return\n }\n\n const selectedIsSummaryCandidate = isSummaryConversationCandidate(selectedConversation)\n const currentIsSummaryCandidate = isSummaryConversationCandidate(currentConversation)\n\n if (currentIsSummaryCandidate && !selectedIsSummaryCandidate) {\n selectedConversation = currentConversation\n selectedConversationKey = key\n return\n }\n\n if (currentIsSummaryCandidate === selectedIsSummaryCandidate) {\n const selectedConnected = !!selectedConversation.connected\n const currentConnected = !!currentConversation.connected\n\n if (currentConnected && !selectedConnected) {\n selectedConversation = currentConversation\n selectedConversationKey = key\n return\n }\n\n const selectedStartTime = selectedConversation.startTime ?? 0\n const currentStartTime = currentConversation.startTime ?? 0\n\n if (currentConnected === selectedConnected && currentStartTime > selectedStartTime) {\n selectedConversation = currentConversation\n selectedConversationKey = key\n }\n }\n })\n\n return {\n conversation: selectedConversation,\n key: selectedConversationKey,\n count: entries.length,\n }\n }\n\n const getCachedSummaryConversation = (extension?: string) => {\n if (!extension) {\n return null\n }\n\n const cached = summaryConversationCache.current.get(extension)\n if (!cached) {\n return null\n }\n\n const cacheAgeMs = Date.now() - cached.cachedAt\n if (cacheAgeMs > SUMMARY_CONVERSATION_CACHE_TTL_MS) {\n summaryConversationCache.current.delete(extension)\n return null\n }\n\n return {\n ...cached,\n cacheAgeMs,\n }\n }\n\n const selectSummaryConversationForHangup = (extension?: string) => {\n const { conversations } = store.getState().currentUser\n const extensionConversations = extension ? conversations?.[extension] : undefined\n const liveSelection = selectLiveSummaryConversation(extensionConversations)\n\n if (isSummaryConversationCandidate(liveSelection.conversation)) {\n return {\n ...liveSelection,\n source: 'live',\n cacheAgeMs: undefined,\n hasConversationForCaller: !!extensionConversations,\n liveConversationKeys: Object.keys(extensionConversations || {}),\n }\n }\n\n const cached = getCachedSummaryConversation(extension)\n if (cached && isSummaryConversationCandidate(cached.conversation)) {\n return {\n conversation: cached.conversation,\n key: cached.conversation.id,\n count: liveSelection.count,\n source: 'cache',\n cacheAgeMs: cached.cacheAgeMs,\n hasConversationForCaller: !!extensionConversations,\n liveConversationKeys: Object.keys(extensionConversations || {}),\n }\n }\n\n return {\n ...liveSelection,\n source: liveSelection.conversation ? 'live_invalid' : 'none',\n cacheAgeMs: cached?.cacheAgeMs,\n hasConversationForCaller: !!extensionConversations,\n liveConversationKeys: Object.keys(extensionConversations || {}),\n }\n }\n\n const cacheSummaryConversations = (extension?: string, conversations?: Record<string, any>) => {\n if (!extension) {\n return\n }\n\n Object.values(conversations || {}).forEach((conversation) => {\n if (!isSummaryConversationCandidate(conversation)) {\n return\n }\n\n summaryConversationCache.current.set(extension, {\n conversation,\n cachedAt: Date.now(),\n })\n })\n }\n\n const shouldKeepCurrentAcceptedCall = (ownerExtension?: string) => {\n const { accepted, ownerExtension: currentOwnerExtension } = store.getState().currentCall\n\n return (\n accepted &&\n !!currentOwnerExtension &&\n !!ownerExtension &&\n currentOwnerExtension !== ownerExtension\n )\n }\n\n /**\n * Manages event and data for the currentUser\n *\n * @param res The data from the socket\n * @param conv The conversation data\n */\n const handleCurrentUserEvents = (res: ExtensionTypes, conv: ConversationTypes) => {\n // Handle transferring data\n const { transferring, transferSwitching, transferCalls } = store.getState().currentCall\n\n const view = store.getState().island.view\n // Check conversation isn't empty\n if (Object.keys(conv).length > 0) {\n // With conversation\n if (res.status) {\n const { extensions } = store.getState().users\n const { default_device } = store.getState().currentUser\n const { endpoints, username } = store.getState().currentUser\n const { incoming, outgoing } = store.getState().currentCall\n\n const hasOnlineNethlink = () => {\n if (!extensions || !username) return false\n\n // Get all extensions for current user\n const userExtensions: any = Object.values(extensions).filter(\n (ext) => ext?.username === username,\n )\n\n // Check if any extension is nethlink type and online\n return userExtensions?.some((ext) => {\n const endpointExtension = endpoints?.extension.find(\n (endpoint) => endpoint.id === ext?.exten,\n )\n return endpointExtension?.type === 'nethlink' && ext?.status !== 'offline'\n })\n }\n switch (res.status) {\n case 'ringing':\n if (shouldKeepCurrentAcceptedCall(conv.owner)) {\n break\n }\n\n syncCurrentUserQueueCall(conv)\n\n // Handle streaming source for incoming calls\n handleStreamingSource(conv)\n\n if (\n (uaType === 'mobile' && hasOnlineNethlink()) ||\n (uaType === 'desktop' &&\n (default_device?.type === 'webrtc' ||\n (default_device?.type === undefined && !hasOnlineNethlink()) ||\n (!hasOnlineNethlink() && default_device?.type === 'physical')))\n ) {\n dispatch.currentCall.checkIncomingUpdatePlay({\n conversationId: conv.id,\n displayName: getDisplayName(conv),\n number: `${conv.counterpartNum}`,\n incomingSocket: true,\n incoming: true,\n username:\n `${\n extensions &&\n extensions[conv.counterpartNum] &&\n extensions[conv.counterpartNum].username\n }` || '',\n ownerExtension: conv.owner,\n })\n store.dispatch.island.setIslandView('call')\n }\n // Get updated user info to refresh open url param type\n if (!isUpdatingUserInfo.current) {\n isUpdatingUserInfo.current = true\n getCurrentUserInfo()\n .then((userInfo) => {\n if (userInfo) {\n dispatch.currentUser.updateCurrentUser(userInfo)\n eventDispatch('phone-island-user-informations-update', { ...userInfo })\n if (userInfo.settings && userInfo.settings.open_param_url) {\n dispatch.paramUrl.setOpenParamUrlType(userInfo.settings.open_param_url)\n } else {\n dispatch.paramUrl.setOpenParamUrlType('never')\n }\n }\n })\n .catch((error) => {\n console.error('Error getting current user info:', error)\n })\n .finally(() => {\n setTimeout(() => {\n isUpdatingUserInfo.current = false\n }, 100)\n })\n }\n const { openParamUrlType } = store.getState().paramUrl\n const { urlOpened } = store.getState().island\n if (openParamUrlType === 'ringing' && !urlOpened) {\n // Calculate throughTrunk based on counterpartNum\n const calculatedThroughTrunk = isFromTrunk(conv.counterpartNum)\n\n // Update throughTrunk in paramUrl store\n store.dispatch.paramUrl.setThroughTrunk(calculatedThroughTrunk)\n\n store.dispatch.island.setUrlOpened(false)\n eventDispatch('phone-island-url-parameter-opened', {\n counterpartNum: conv.counterpartNum,\n counterpartName: getDisplayName(conv),\n owner: conv.owner,\n uniqueId: conv.uniqueId,\n linkedId: conv.linkedId,\n throughQueue: conv.throughQueue,\n throughTrunk: calculatedThroughTrunk,\n direction: conv.direction,\n connected: conv.connected,\n })\n }\n break\n // @ts-ignore\n case 'busy':\n syncCurrentUserQueueCall(conv)\n\n // Handle streaming source for outgoing calls\n handleStreamingSource(conv)\n\n if (\n (uaType === 'mobile' && hasOnlineNethlink()) ||\n (uaType === 'desktop' &&\n (default_device?.type === 'webrtc' ||\n (default_device?.type === undefined && !hasOnlineNethlink()) ||\n (!hasOnlineNethlink() && default_device?.type === 'physical')))\n ) {\n if (conv && conv.connected) {\n // Current call accepted and update connected call\n dispatch.currentCall.updateCurrentCall({\n conversationId: conv.id,\n displayName: getDisplayName(conv),\n number: `${conv.counterpartNum}`,\n ownerExtension: conv.owner,\n username:\n `${\n extensions &&\n extensions[conv.counterpartNum] &&\n extensions[conv.counterpartNum].username\n }` || '',\n chDest: conv?.chDest || {},\n chSource: conv?.chSource || {},\n })\n // Update the current call informations for physical devices\n dispatch.currentCall.checkAcceptedUpdate({\n acceptedSocket: true,\n })\n // Add call to transfer calls\n dispatch.currentCall.addTransferCalls({\n type: 'transferred',\n displayName: getDisplayName(conv),\n number: `${conv.counterpartNum}`,\n startTime: `${getTimestampInSeconds()}`,\n })\n\n // Check if this is a streaming call that was accepted\n const { isFromStreaming } = store.getState().island\n if (isFromStreaming && conv.direction === 'out') {\n // Set view to streamingAnswer for outgoing streaming calls when accepted\n setTimeout(() => {\n dispatch.island.setIslandView('streamingAnswer')\n }, 200)\n }\n\n if (isPhysical()) {\n checkDefaultDeviceConversationActive(conv)\n }\n if (view === 'call' && transferring) {\n dispatch.currentCall.updateCurrentCall({\n transferring: false,\n })\n }\n }\n // Delete transfer calls if there are more than one ( in case of call switch after transfer)\n if (transferCalls.length > 1) {\n dispatch.currentCall.deleteTransferCalls()\n }\n // Handle not connected calls\n else if (conv && !conv.connected) {\n if (transferring && !transferSwitching) {\n // Handle hangup during transfer\n const inTransferCalls = transferCalls.find(\n (item) => item.number === conv.counterpartNum,\n )\n if (!conv.connected && inTransferCalls) {\n // Update transferring data for the current call\n dispatch.currentCall.updateCurrentCall({\n transferring: false,\n })\n eventDispatch('phone-island-call-transfer-failed', {})\n // Reset transfer switching\n // TODO - It needs to enhance how conversation connections (conv.connected) are updated server side\n // TODO - The transfer end is not handled when the an user hangups or after call switch\n dispatch.currentCall.updateTransferSwitching(false)\n }\n }\n if (conv?.counterpartName === 'REC') {\n dispatch.physicalRecorder.setRecordingTempVariable(true)\n }\n }\n // Handle outgoing call\n if (conv && !conv.connected && conv.direction === 'out') {\n // Update the current outgoing conversation\n dispatch.currentCall.checkOutgoingUpdate({\n outgoingSocket: true,\n outgoing: conv?.counterpartName === 'REC' ? false : true,\n displayName: getDisplayName(conv),\n number: `${conv?.counterpartNum}`,\n username:\n `${\n extensions &&\n extensions[conv?.counterpartNum] &&\n extensions[conv?.counterpartNum].username\n }` || '',\n })\n }\n }\n break\n\n case 'onhold':\n syncCurrentUserQueueCall(conv)\n\n // The new conversation during transferring\n const { counterpartName, counterpartNum, startTime } = conv\n if (\n transferring &&\n counterpartNum &&\n counterpartName &&\n counterpartName !== '<unknown>'\n ) {\n // Add call to transfer calls\n dispatch.currentCall.addTransferCalls({\n type: 'destination',\n displayName: getDisplayName(conv),\n number: counterpartNum,\n startTime: `${getTimestampInSeconds()}`,\n })\n // Set the current call informations\n dispatch.currentCall.updateCurrentCall({\n displayName: getDisplayName(conv),\n number: counterpartNum,\n startTime: `${startTime / 1000}`,\n conversationId: conv.id,\n })\n // Set the view of the island to call\n dispatch.island.setIslandView('call')\n }\n break\n case 'busy_ringing':\n eventDispatch('phone-island-call-ringing', {})\n break\n default:\n break\n }\n }\n } else {\n // Without conversation for physical phone management\n if (res.status == 'online' && userTotallyFree()) {\n syncCurrentUserQueueCall(null)\n\n // Stop ringing sounds\n dispatch.player.stopAudioPlayer()\n // Reset current call info\n dispatch.currentCall.reset()\n dispatch.physicalRecorder.setRecordingTempVariable(false)\n // Reset isFromStreaming flag\n dispatch.island.setIsFromStreaming(false)\n }\n }\n }\n\n /**\n * Initialize socket connection and listeners\n */\n const initSocketConnection = () => {\n const currentApiMode = getApiMode(username)\n\n const socketOptions: any = {\n upgrade: false,\n transports: ['websocket'],\n reconnection: true,\n reconnectionDelay: 2000,\n }\n\n // Only set path for new API mode\n if (currentApiMode === 'new') {\n socketOptions.path = '/api/ws'\n }\n\n socket.current = io('https://' + hostName, socketOptions)\n\n // save websocket to store\n dispatch.websocket.update({ socket: socket.current })\n\n // Handle socket errors\n socket.current.on('connect', () => {\n console.debug(`Socket connected sid: ${socket.current.id}`)\n eventDispatch('phone-island-socket-connected', {})\n })\n socket.current.on('disconnect', (reason) => {\n console.debug(`Socket disconnect - reason: ${reason}`)\n // Clear the connection check interval on disconnect to avoid stale pings\n if (connectionCheckInterval.current) {\n clearInterval(connectionCheckInterval.current)\n connectionCheckInterval.current = null\n }\n if (reason.includes('server disconnect')) {\n eventDispatch('phone-island-server-disconnected', {})\n } else {\n eventDispatch('phone-island-socket-disconnected', {})\n }\n })\n socket.current.io.on('error', (err) => {\n console.debug(`Socket error: `, err)\n })\n socket.current.on('connect_error', (err) => {\n console.debug(`Socket connect_error: `, err)\n })\n socket.current.io.on('reconnect', (attempt) => {\n // Reset consecutive ping timeout counter on successful reconnection\n consecutivePingTimeouts.current = 0\n eventDispatch('phone-island-socket-reconnected', {})\n console.debug(`Socket reconnect attemp ${attempt} (sid: ${socket.current.id})`)\n })\n socket.current.io.on('reconnect_attempt', (attempt) => {\n console.debug(`Socket reconnect_attempt ${attempt}`)\n })\n socket.current.io.on('reconnect_error', (err) => {\n console.debug(`Socket reconnect_error: `, err)\n })\n socket.current.io.on('reconnect_failed', () => {\n console.debug(`Socket reconnect_failed`)\n })\n\n // Connection check interval is now started in the authe_ok handler\n // to ensure it only runs after successful authentication\n\n // Handle connection message\n socket.current.on('connect', () => {\n console.debug('Socket on: ' + hostName + ' is connected!')\n socket.current.emit('login', {\n accessKeyId: `${username}`,\n token: authToken,\n uaType: uaType,\n })\n })\n\n // Handle authentication success message\n socket.current.on('authe_ok', () => {\n console.debug('Socket authentication success!')\n eventDispatch('phone-island-socket-authorized', {})\n\n // Start connection check interval after successful authentication\n // Clear any existing interval first to avoid duplicates\n if (connectionCheckInterval.current) {\n clearInterval(connectionCheckInterval.current)\n }\n connectionCheckInterval.current = setInterval(() => {\n socket.current.volatile.emit(\n 'ping',\n withTimeout(\n () => {\n // Ping success - reset consecutive timeout counter\n consecutivePingTimeouts.current = 0\n // Remove socket_down alert (async to avoid React error #300 with framer-motion)\n setTimeout(() => {\n dispatch.alerts.removeAlert('socket_down')\n eventDispatch('phone-island-alert-removed', {\n type: 'socket_down',\n })\n eventDispatch('phone-island-socket-disconnected-popup-close', {})\n }, 0)\n },\n () => {\n // Ping timeout - increment counter\n consecutivePingTimeouts.current++\n console.debug(\n `Socket ping timeout (${consecutivePingTimeouts.current}/${STALE_CONNECTION_THRESHOLD}), connected: ${socket.current.connected}`,\n )\n\n // Set socket_down alert (async to avoid React error #300 with framer-motion)\n setTimeout(() => {\n // Check for stale connection: socket reports connected but pings keep timing out\n const isStaleConnection =\n socket.current.connected &&\n consecutivePingTimeouts.current >= STALE_CONNECTION_THRESHOLD\n\n if (!socket.current.connected || isStaleConnection) {\n // Check if there's an active call with ICE still connected\n // If so, skip showing alert - let ICE grace period mechanism handle it\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n const { accepted, outgoing } = store.getState().currentCall\n const iceState = sipcall?.webrtcStuff?.pc?.iceConnectionState\n const hasActiveCallWithIce =\n (accepted || outgoing) &&\n (iceState === 'connected' || iceState === 'completed')\n\n if (hasActiveCallWithIce) {\n console.debug(\n 'Socket unreachable but active call with ICE connected - skipping socket_down alert',\n {\n iceState,\n accepted,\n outgoing,\n isStaleConnection,\n timestamp: new Date().toISOString(),\n },\n )\n return\n }\n\n if (isStaleConnection) {\n console.warn('Stale socket connection detected - forcing reconnection')\n // Force disconnect to trigger reconnection\n socket.current.disconnect()\n }\n\n dispatch.alerts.setAlert('socket_down')\n eventDispatch('phone-island-socket-disconnected-popup-open', {})\n console.error('Socket is unreachable!')\n }\n }, 0)\n },\n 5 * 1000,\n ),\n )\n }, 5 * 1000)\n })\n\n socket.current.on('userMainPresenceUpdate', (res: MainPresenceTypes) => {\n // Update endpoints store\n store.dispatch.users.updateEndpointMainPresence({ ...res.mainPresence })\n // Dispatch dispatchMainPresence Event\n dispatchMainPresence(res)\n })\n\n socket.current.on('extenHangup', (res: any) => {\n const { endpoints, username } = store.getState().currentUser\n const { isActive, conferenceStartedFrom } = store.getState().conference\n const { view, previewCallFromMobileOrNethlink } = store.getState().island\n\n // Get user extensions\n const userExtensions = endpoints?.extension || []\n const userExtensionIds = userExtensions.map((ext) => ext.id)\n let summaryExtension = res?.callerNum\n if (\n !userExtensionIds.includes(summaryExtension) &&\n userExtensionIds.includes(res?.channelExten)\n ) {\n summaryExtension = res?.channelExten\n }\n\n // Find the extension type based on callerNum\n const connectedExtension = userExtensions.find((ext) => ext.id === res.callerNum)\n\n const extensionType: any = connectedExtension?.type\n\n const summaryConversationSelection = selectSummaryConversationForHangup(summaryExtension)\n const selectedConversation: any = summaryConversationSelection.conversation\n\n // Check summary/transcription only for answered calls with a valid uniqueid.\n const linkedId = getConversationLinkedId(selectedConversation)\n const uniqueId = getConversationUniqueId(selectedConversation)\n const conversationWasConnected = selectedConversation?.connected || false\n\n if (uniqueId && linkedId && conversationWasConnected) {\n eventDispatch('phone-island-summary-call-check', { linkedid: linkedId, uniqueid: uniqueId })\n if (summaryExtension) {\n summaryConversationCache.current.delete(summaryExtension)\n }\n }\n\n // If cause is normal_clearing and extension is physical or mobile\n // Clean phone-island visibility also after user_busy ( useful for physical devices )\n if (\n (res.cause === 'normal_clearing' &&\n (extensionType === 'physical' || extensionType === 'mobile')) ||\n (res.cause === 'normal_clearing' &&\n (extensionType === 'webrtc' || extensionType === 'nethlink') &&\n previewCallFromMobileOrNethlink) ||\n res?.cause === 'user_busy' ||\n res?.cause === 'not_defined' ||\n res?.cause === 'call_rejected' ||\n res?.cause === 'interworking'\n ) {\n // Reset phone island visibility after 2 seconds to avoid glitches\n setTimeout(() => {\n store.dispatch.island.toggleAvoidToShow(false)\n store.dispatch.island.setPreviewCallFromMobileOrNethlink(false)\n }, 500)\n // Only reset conference if there are no more participants or if user is not in a conference\n if (isActive && conferenceStartedFrom !== username) {\n store.dispatch.conference.resetConference()\n }\n } else if (\n res?.cause === 'normal_circuit_congestion' &&\n isActive &&\n conferenceStartedFrom === username\n ) {\n setTimeout(() => {\n eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\n }, 800)\n } else if (\n (res.cause === 'normal_clearing' ||\n res?.cause === 'user_busy' ||\n res?.cause === 'not_defined' ||\n res?.cause === 'call_rejected') &&\n (extensionType === 'webrtc' || extensionType === 'nethlink') &&\n isActive &&\n conferenceStartedFrom !== username\n ) {\n store.dispatch.conference.resetConference()\n }\n // if conference owner and added participant refuses or hangs up with normal_clearing\n if (\n ((res.cause === 'normal_clearing' &&\n (extensionType === 'webrtc' || extensionType === 'nethlink')) ||\n res?.cause === 'call_rejected') &&\n isActive &&\n conferenceStartedFrom === username\n ) {\n const { usersList, pendingUsers } = store.getState().conference\n // Check if there are still participants in the conference (both confirmed and pending)\n const hasConfirmedParticipants = usersList && Object.keys(usersList).length > 0\n const hasPendingParticipants = pendingUsers && Object.keys(pendingUsers).length > 0\n const hasParticipants = hasConfirmedParticipants || hasPendingParticipants\n\n if (!hasParticipants) {\n store.dispatch.conference.resetConference()\n } else {\n // If there are still participants, keep the waitingConference view\n setTimeout(() => {\n eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\n }, 800)\n }\n }\n // if conference owner call the call with the added user inside conference\n if (\n res?.cause === 'interworking' &&\n isActive &&\n conferenceStartedFrom === username &&\n view !== 'waitingConference'\n ) {\n setTimeout(() => {\n eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\n }, 800)\n }\n if (res?.cause === 'user_busy') {\n // Get current user's extensions\n const { endpoints, username } = store.getState().currentUser\n const userExtensions = endpoints?.extension || []\n const userExtensionIds = userExtensions.map((ext) => ext.id)\n\n // Get the current call state to understand if we're the caller or receiver\n const { incoming, accepted, transferring } = store.getState().currentCall\n\n // Check if there's an active conference\n const { isActive, conferenceStartedFrom } = store.getState().conference\n\n // When we RECEIVE a call on our extension, callerNum is the busy extension (our own)\n // When we CALL someone, channelExten is one of our extensions (the one we're calling from)\n const isReceivingCall =\n incoming && !!res.callerNum && userExtensionIds.includes(res.callerNum)\n\n // If we are already on an active call, suppress the busy popup unless it belongs\n // to a conference-owner flow or an attended transfer started by this user.\n const shouldShowOperatorBusy = !isReceivingCall && (!accepted || isActive || transferring)\n\n // Only show operator busy view if:\n // 1. We are NOT receiving an incoming call to our own extension\n if (shouldShowOperatorBusy) {\n // Set operator busy active with caller information\n store.dispatch.island.setOperatorBusyActive({\n callerNumber: res.callerNum || 'Unknown',\n })\n\n // Stop busy tone after 4 seconds\n setTimeout(() => {\n store.dispatch.player.stopAudioPlayer()\n }, 4000)\n\n setTimeout(() => {\n // Play busy tone\n store.dispatch.player.updateStartAudioPlayer({\n src: busyRingtone,\n loop: true,\n })\n store.dispatch.island.setIslandView('operatorBusy')\n }, 600)\n\n // If conference is active and we're the owner, return to conference after timeout\n if (isActive && conferenceStartedFrom === username) {\n setTimeout(() => {\n eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\n }, 4000)\n }\n }\n }\n\n // Handle subscriber_absent - when added participant rejects the call\n if (res?.cause === 'subscriber_absent') {\n const { isActive, conferenceStartedFrom } = store.getState().conference\n const { username } = store.getState().currentUser\n\n // Only handle if conference is active and current user is the owner\n if (isActive && conferenceStartedFrom === username) {\n // Check if there are still participants in the conference (both confirmed and pending)\n const { usersList, pendingUsers } = store.getState().conference\n const hasConfirmedParticipants = usersList && Object.keys(usersList).length > 0\n const hasPendingParticipants = pendingUsers && Object.keys(pendingUsers).length > 0\n const hasParticipants = hasConfirmedParticipants || hasPendingParticipants\n\n if (hasParticipants) {\n // Return to waiting conference view to manage other participants\n setTimeout(() => {\n eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\n }, 800)\n // Remove from pending users if exists\n if (pendingUsers && pendingUsers[res.callerNum]) {\n store.dispatch.conference.removePendingUser(res.callerNum)\n }\n } else {\n // No participants left, reset conference\n store.dispatch.conference.resetConference()\n }\n }\n }\n })\n\n // Avoid to show phone island if call is connected with other extension\n socket.current.on('extenConnected', (res: { extenConnected: string }) => {\n // Get the current user's extensions\n\n const { default_device, endpoints } = store.getState().currentUser\n const userExtensions = endpoints?.extension || []\n\n // Find the extension type\n const connectedExtension = userExtensions.find((ext) => ext.id === res.extenConnected)\n const extensionType: any = connectedExtension?.type\n\n // Reset only if the extension type is not webrtc or nethlink\n // ( avoid to not show phone island if default is physical and extensionType is physical)\n if (\n ((default_device?.type === 'webrtc' || default_device?.type === 'nethlink') &&\n extensionType &&\n (extensionType === 'mobile' || extensionType === 'physical')) ||\n (default_device?.type === 'physical' && extensionType && extensionType !== 'physical')\n ) {\n // Avoid to show phone island in case of answer from physical or mobile device\n store.dispatch.island.toggleAvoidToShow(true)\n // Set the preview call flag\n store.dispatch.island.setPreviewCallFromMobileOrNethlink(true)\n // Launch an event to advert the user that the call it's answered from another device\n eventDispatch('phone-island-call-answered', { extensionType })\n }\n })\n\n socket.current.on('extenUpdate', (res: ExtensionTypes) => {\n // Update extensions and conversations in users store\n dispatch.users.updateExtension(res)\n\n //retrieve all extensions from store\n const { extensions }: any = store.getState().users\n const deviceMap: any = {}\n\n const userInformation = store.getState().currentUser\n // Create a map of extensions for each user\n for (const key in extensions) {\n const user: any = extensions[key].username\n const ext: any = extensions[key].exten\n\n if (!deviceMap[user]) {\n deviceMap[user] = []\n }\n\n deviceMap[user].push(ext)\n }\n\n const associatedExtensions: any = deviceMap[res.username]\n const conversationKeys = Object.keys(res.conversations || {})\n const isCurrentUserUpdate = res.username === username\n\n // Initialize conversation\n let conv = res.conversations?.[conversationKeys[0]] || {}\n if (isCurrentUserUpdate) {\n cacheSummaryConversations(res.exten, res.conversations)\n }\n\n // Check if this is a mobile extension call for the current user\n let isMobileExtensionCall = false\n if (res?.username === username && !isEmpty(conv) && conv?.owner) {\n const matchingExtension = userInformation?.endpoints?.extension?.find(\n (ext: any) => ext.id === conv.owner,\n )\n if (matchingExtension && matchingExtension.type === 'mobile') {\n isMobileExtensionCall = true\n }\n }\n\n // Update all extensions and send the dispatch event\n dispatchExtensions(res)\n\n // second step update conversation\n\n // Check if conversation is empty\n if (isEmpty(conv)) {\n // Check if there is at least one conversation not empty\n const hasNonEmptyConversation = associatedExtensions?.some((ext: any) => {\n const extConversations = extensions[ext]?.conversations\n\n if (!isEmpty(extConversations)) {\n // not empty conversation found\n return true\n }\n\n return false\n })\n\n if (!hasNonEmptyConversation) {\n // Conversation is empty and there is no conversation for the user\n dispatchConversations(res)\n }\n } else if (!isMobileExtensionCall) {\n // Dispatch conversation event\n dispatchConversations(res)\n }\n\n if (isMobileExtensionCall && res?.status === 'busy' && res?.username === username) {\n store.dispatch.island.toggleAvoidToShow(true)\n store.dispatch.island.setPreviewCallFromMobileOrNethlink(true)\n }\n // Handle only the events of the user\n if (res.username === username) {\n handleCurrentUserEvents(res, conv)\n // Update the conversations of the user\n dispatch.currentUser.updateConversations(res)\n }\n })\n\n // `queueUpdate` is the socket event when the data of a queue updates\n socket.current.on('queueUpdate', (res: QueuesUpdateTypes) => {\n dispatch.queue.updateQueue(res)\n\n const activeConversation = getActiveConversationForCurrentCall()\n\n if (activeConversation) {\n syncCurrentUserQueueCall(activeConversation)\n }\n\n // Dispatch queueUpdate event\n dispatchQueueUpdate(res)\n })\n\n // `queueMemberUpdate` is the socket event when the data of a queue member changes\n socket.current.on('queueMemberUpdate', (res: QueueUpdateMemberTypes) => {\n dispatch.queue.updateQueueMember(res)\n // Dispatch queueMemberUpdate event\n dispatchQueueMemberUpdate(res)\n })\n\n // `takeOver` is the socket event when the user does login from another new window\n socket.current.on('takeOver', () => {\n // Dispatch takeOver event\n dispatchAlreadyLogin()\n })\n\n // `serverReload` is the socket event when server is reloaded\n socket.current.on('serverReloaded', () => {\n // Dispatch serverReload event\n dispatchServerReload()\n })\n\n // `parkingUpdate` is the socket event when a call is parked or unparked\n socket.current.on('parkingUpdate', (event) => {\n // Dispatch parking update event with the parking information\n dispatchParkingUpdate(event)\n })\n\n // `actionNethLink` is the socket event when user make a call or a action from NethLink and has a physical device\n socket.current.on('actionNethLink', (link, urlType) => {\n // Dispatch phone island physical call event with the link and the urlType\n dispatchUrlCall(link, urlType)\n })\n\n // `satellite/summary` is the socket event when summary is ready\n socket.current.on('satellite/summary', (data: any) => {\n const uniqueid = data?.uniqueid || data?.uniqueId\n const linkedid = data?.linkedid || data?.linkedId\n\n if (uniqueid) {\n dispatchSummaryReady({\n linkedid,\n uniqueid,\n display_name: data?.display_name,\n display_number: data?.display_number,\n source: 'socket',\n })\n }\n })\n\n socket.current.on('message', (data: any) => {\n switch (data.message) {\n case 'videoCallStart':\n {\n const {\n currentCall: { incoming, outgoing, accepted },\n currentUser: { default_device },\n island: { isFromStreaming, view },\n } = store.getState()\n\n const isWebrtcDevice =\n default_device?.type === 'webrtc' || default_device?.type === 'nethlink'\n const hasCompatibleCallState = incoming || outgoing || accepted\n const canOpenVideoView =\n isWebrtcDevice && hasCompatibleCallState && !isFromStreaming && view !== 'video'\n\n if (canOpenVideoView) {\n dispatch.island.toggleSideViewVisible(false)\n dispatch.island.toggleTranscriptionViewVisible(false)\n dispatch.island.setIslandView('video')\n }\n }\n\n dispatchVideoCallStarted({\n initiator: 'remote',\n callUser: (data as VideoCallMessage).callUser,\n destUser: (data as VideoCallMessage).destUser,\n })\n break\n case 'screenSharingStart':\n dispatch.island.toggleSideViewVisible(false)\n dispatch.island.toggleTranscriptionViewVisible(false)\n dispatch.island.setIslandView('video')\n\n dispatch.screenShare.update({\n isJoiningScreenShare: true,\n room: (data as ScreenSharingMessage).roomId,\n })\n break\n case 'screenSharingStop':\n dispatch.island.toggleSideViewVisible(false)\n dispatch.island.toggleTranscriptionViewVisible(false)\n dispatch.island.setIslandView('video')\n\n dispatch.screenShare.update({\n isLeavingScreenShare: true,\n })\n break\n default:\n console.warn('Socket: unknown message type ', data.message)\n }\n })\n\n // `updateDefaultDevice` is the socket event when user change the default device\n socket.current.on('updateDefaultDevice', (extension: string) => {\n // Dispatch phone island physical call event with the link and the urlType\n dispatchDefaultDeviceUpdate(extension)\n // Update the internal store\n const { extensions } = store.getState().users\n const { endpoints } = store.getState().currentUser\n if (!extensions || !endpoints) return\n\n const extensionInformations: any = Object.values(extensions).filter(\n (ext) => ext?.exten === extension,\n )\n if (extensionInformations.length === 0) return\n\n let objectComplete = extensionInformations[0]\n const endpointExtension = endpoints.extension.find(\n (endpoint) => endpoint.id === objectComplete.exten,\n )\n if (endpointExtension) {\n objectComplete = { ...objectComplete, type: endpointExtension.type }\n }\n\n store.dispatch.currentUser.updateCurrentDefaultDevice(objectComplete)\n //make sure to check the media permissions\n checkMediaPermissions()\n })\n\n socket.current.on('confBridgeUpdate', (res: any) => {\n if (res && res?.users) {\n // Get User informations\n const conferenceId = res?.id\n const conferenceUsers = res?.users\n\n // Get current users list to preserve mute status\n const { usersList } = store.getState().conference\n\n // Create a copy of the new conference users while preserving mute status\n const updatedConferenceUsers = { ...conferenceUsers }\n\n // Preserve mute status for existing users\n if (usersList) {\n Object.keys(updatedConferenceUsers).forEach((userId) => {\n if (usersList[userId]) {\n // Keep the existing mute status instead of using the server's value\n updatedConferenceUsers[userId] = {\n ...updatedConferenceUsers[userId],\n muted: usersList[userId].muted,\n }\n }\n })\n }\n\n store.dispatch.conference.updateConferenceUsersList(updatedConferenceUsers)\n store.dispatch.conference.updateConferenceId(conferenceId)\n }\n })\n\n socket.current.on('confBridgeEnd', (res: any) => {\n if (res && res?.id) {\n // Reset the conference store when conference ends\n store.dispatch.conference.resetConference()\n eventDispatch('phone-island-conference-finished', {})\n }\n })\n\n socket.current.on('callWebrtc', (res: any) => {\n // On call event from socket dispatch the call start event\n eventDispatch('phone-island-call-start', { number: res })\n })\n\n socket.current.on('newVoiceMessageCounter', (res: any) => {\n eventDispatch('phone-island-voicemail-received', { voicemailInfo: res })\n })\n\n socket.current.on('streamingSourceUpdate', (res: any) => {\n eventDispatch('phone-island-streaming-information-received', { res })\n const streamingData = res.streaming || (res.res && res.res.streaming)\n\n if (streamingData) {\n const { source, image } = streamingData\n if (source && image) {\n const { isFromStreaming } = store.getState().island\n const { streamingSourceNumber } = store.getState().currentCall\n const sourceId = getStreamingSourceId(streamingSourceNumber)\n\n dispatch.streaming.updateSourceImage({\n source: source,\n image: image,\n })\n }\n }\n })\n\n // Handle satellite/transcription messages\n socket.current.on('satellite/transcription', (transcriptionData: any) => {\n // Drop chunks belonging to a different call than the one open in the\n // transcription view, to prevent cross-call transcript mixing when more\n // than one call is being transcribed at the same time.\n //\n // The realtime chunk identifies its call in the `uniqueid` field, which\n // actually carries the call_id (linkedid when available — see satellite\n // backend). We only filter when we know the active linkedid: in that case\n // matching is reliable. If we don't, we forward everything (unchanged\n // behaviour) to avoid ever dropping a valid chunk.\n const active = activeTranscriptionIdsRef.current\n const chunkId = transcriptionData?.uniqueid\n const chunkLinkedId = transcriptionData?.linkedid\n if (active.linkedid && chunkId) {\n const matchesActive = (id: any) =>\n id != null && (id === active.linkedid || id === active.uniqueid)\n if (!matchesActive(chunkId) && !matchesActive(chunkLinkedId)) {\n return\n }\n }\n // Dispatch the transcription event to external listeners\n eventDispatch('phone-island-conversation-transcription', transcriptionData)\n })\n }\n\n initSocketConnection()\n\n // Stop the check socket interval\n // Close the socket connection\n return () => {\n clearInterval(connectionCheckInterval.current)\n socket.current.close()\n }\n }, [hostName, username, authToken, uaType, dispatch])\n\n // Manage reload events\n useEffect(() => {\n if (reload) {\n console.info('Socket reload requested')\n const { data } = store.getState().alerts\n const { forceReload } = store.getState().island\n\n // Check if socket is actually down using alerts (more reliable than socket.connected)\n const isSocketDown = data.socket_down?.active || false\n\n // Only reconnect if socket_down alert is active OR force reload is requested\n if (isSocketDown || forceReload) {\n console.info(\n forceReload\n ? 'Force reload requested, performing Socket reconnection'\n : 'Socket down detected (alert active), performing reconnection',\n )\n // Reset force reload flag\n if (forceReload) {\n store.dispatch.island.setForceReload(false)\n }\n // Clear the connection check interval to avoid stale ping timeouts during reconnection\n if (connectionCheckInterval.current) {\n clearInterval(connectionCheckInterval.current)\n connectionCheckInterval.current = null\n }\n // Disconnect and reconnect socket\n setTimeout(() => {\n socket.current.disconnect()\n socket.current.connect()\n // Execute the reloaded callback\n reloadedCallback()\n }, 100)\n } else {\n console.info('Socket already connected (no alert active), skipping reconnection')\n // Execute callback without reload\n reloadedCallback()\n }\n }\n }, [reload])\n\n return <>{children}</>\n}\n"],"names":["_a","hostName","username","authToken","reload","reloadedCallback","children","uaType","dispatch","useDispatch","connectionCheckInterval","useRef","socket","isUpdatingUserInfo","consecutivePingTimeouts","currentUserQueueCallPhase","summaryConversationCache","Map","activeTranscriptionIdsRef","linkedid","uniqueid","useEventListener","data","current","linkedId","uniqueId","emit","currentCall","updateCurrentCall","throughQueue","queueId","queueName","queueNumber","queuePosition","queueWaitingTime","useEffect","socketOptions","handleStreamingSource","conv","counterpartNum","isFromStreaming","island","setIsFromStreaming","streamingSourceNumber","sourceId","getStreamingSourceId","subscribe","id","catch","error","console","syncCurrentUserQueueCall","queueContext","getCurrentCallQueueContext","store","getState","queue","getCurrentCallQueuePayload","payload","conversationId","ownerExtension","owner","number","concat","getQueuePayloadWithFallback","Boolean","connected","_c","_d","phase","dispatchCurrentUserQueueCallConnected","_b","dispatchCurrentUserQueueCallWaiting","getConversationLinkedId","conversation","getConversationUniqueId","isSummaryConversationCandidate","selectSummaryConversationForHangup","extension","conversations","currentUser","extensionConversations","undefined","liveSelection","selectedConversationKey","selectedConversation","entries","Object","filter","keys","length","forEach","key","currentConversation","selectedIsSummaryCandidate","currentIsSummaryCandidate","selectedConnected","currentConnected","selectedStartTime","startTime","currentStartTime","count","selectLiveSummaryConversation","__assign","source","cacheAgeMs","hasConversationForCaller","liveConversationKeys","cached","get","Date","now","cachedAt","delete","getCachedSummaryConversation","handleCurrentUserEvents","res","transferring","transferSwitching","transferCalls","view","status","extensions_1","users","extensions","default_device","endpoints_1","endpoints","username_1","incoming","hasOnlineNethlink","userExtensions","values","ext","some","endpointExtension","find","endpoint","exten","type","accepted","currentOwnerExtension","shouldKeepCurrentAcceptedCall","checkIncomingUpdatePlay","displayName","getDisplayName","incomingSocket","setIslandView","getCurrentUserInfo","then","userInfo","updateCurrentUser","eventDispatch","settings","open_param_url","paramUrl","setOpenParamUrlType","finally","setTimeout","openParamUrlType","urlOpened","calculatedThroughTrunk","isFromTrunk","setThroughTrunk","setUrlOpened","counterpartName","throughTrunk","direction","chDest","chSource","checkAcceptedUpdate","acceptedSocket","addTransferCalls","getTimestampInSeconds","isPhysical","player","stopAudioPlayer","setAudioPlayerLoop","checkDefaultDeviceConversationActive","deleteTransferCalls","inTransferCalls","item","updateTransferSwitching","physicalRecorder","setRecordingTempVariable","checkOutgoingUpdate","outgoingSocket","outgoing","userTotallyFree","reset","upgrade","transports","reconnection","reconnectionDelay","getApiMode","path","io","websocket","update","on","debug","reason","clearInterval","includes","err","attempt","accessKeyId","token","setInterval","volatile","withTimeout","alerts","removeAlert","isStaleConnection","sipcall","webrtc","iceState","webrtcStuff","pc","iceConnectionState","timestamp","toISOString","warn","disconnect","setAlert","updateEndpointMainPresence","mainPresence","dispatchMainPresence","conference","isActive","conferenceStartedFrom","previewCallFromMobileOrNethlink","userExtensionIds","map","summaryExtension","callerNum","channelExten","connectedExtension","extensionType","conversationWasConnected","cause","toggleAvoidToShow","setPreviewCallFromMobileOrNethlink","resetConference","viewType","usersList","pendingUsers","hasConfirmedParticipants","hasPendingParticipants","_e","endpoints_2","username_2","userExtensionIds_1","_f","_g","isActive_1","conferenceStartedFrom_1","setOperatorBusyActive","callerNumber","updateStartAudioPlayer","src","busyRingtone","loop","_h","isActive_2","conferenceStartedFrom_2","username_3","_j","removePendingUser","extenConnected","updateExtension","deviceMap","userInformation","user","push","associatedExtensions","conversationKeys","isCurrentUserUpdate","set","isMobileExtensionCall","isEmpty","matchingExtension","dispatchExtensions","hasNonEmptyConversation","extConversations","dispatchConversations","updateConversations","updateQueue","activeConversation","dispatchQueueUpdate","updateQueueMember","dispatchQueueMemberUpdate","dispatchAlreadyLogin","dispatchServerReload","event","dispatchParkingUpdate","link","urlType","dispatchUrlCall","dispatchSummaryReady","display_name","display_number","message","isFromStreaming_2","toggleSideViewVisible","toggleTranscriptionViewVisible","dispatchVideoCallStarted","initiator","callUser","destUser","screenShare","isJoiningScreenShare","room","roomId","isLeavingScreenShare","dispatchDefaultDeviceUpdate","extensionInformations","objectComplete","updateCurrentDefaultDevice","checkMediaPermissions","conferenceId","conferenceUsers","usersList_1","updatedConferenceUsers_1","userId","muted","updateConferenceUsersList","updateConferenceId","voicemailInfo","streamingData","streaming","image","updateSourceImage","transcriptionData","active","chunkId","chunkLinkedId","matchesActive","close","info","forceReload","socket_down","setForceReload","connect","React","createElement","Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"Socket.js","sources":["../../src/components/Socket.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type ReactNode, FC, useEffect, useRef } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { Dispatch, RootState } from '../store'\nimport { io } from 'socket.io-client'\nimport { getApiMode } from './RestAPI'\nimport { getDisplayName } from '../lib/phone/conversation'\nimport { getCurrentUserInfo } from '../services/user'\nimport busyRingtone from '../static/busy_ringtone'\nimport {\n dispatchMainPresence,\n dispatchConversations,\n dispatchQueueUpdate,\n dispatchQueueMemberUpdate,\n dispatchCurrentUserQueueCallWaiting,\n dispatchCurrentUserQueueCallConnected,\n dispatchAlreadyLogin,\n dispatchServerReload,\n dispatchParkingUpdate,\n dispatchExtensions,\n dispatchUrlCall,\n dispatchDefaultDeviceUpdate,\n dispatchVideoCallStarted,\n} from '../events'\nimport { store } from '../store'\nimport { dispatchSummaryReady, eventDispatch, useEventListener, withTimeout } from '../utils'\nimport type {\n ConversationTypes,\n ExtensionTypes,\n QueuesUpdateTypes,\n QueueUpdateMemberTypes,\n MainPresenceTypes,\n CurrentUserQueueCallEventTypes,\n} from '../types'\nimport { getTimestampInSeconds } from '../utils/genericFunctions/timestamp'\nimport { userTotallyFree } from '../lib/user/extensions'\nimport { isEmpty } from '../utils/genericFunctions/isEmpty'\nimport { isPhysical } from '../lib/user/default_device'\nimport { ScreenSharingMessage, VideoCallMessage } from './VideoView'\nimport { checkMediaPermissions } from '../lib/devices/devices'\nimport { isFromStreaming } from '../utils/streaming/isFromStreaming'\nimport { getStreamingSourceId } from '../utils/streaming/getStreamingSourceId'\nimport { subscribe } from '../services/user'\nimport { isFromTrunk } from '../lib/user/extensions'\nimport { getCurrentCallQueueContext } from '../lib/phone/queue'\n\ninterface SocketProps {\n children: ReactNode\n hostName: string\n username: string\n authToken: string\n reload: boolean\n reloadedCallback: () => void\n uaType: string\n}\n\ninterface SummaryConversationCacheEntry {\n conversation: ConversationTypes\n cachedAt: number\n}\n\nconst SUMMARY_CONVERSATION_CACHE_TTL_MS = 10 * 60 * 1000\n\nexport const Socket: FC<SocketProps> = ({\n hostName,\n username,\n authToken,\n reload,\n reloadedCallback,\n children,\n uaType,\n}) => {\n const dispatch = useDispatch<Dispatch>()\n const connectionCheckInterval = useRef<any>()\n const socket = useRef<any>()\n const isUpdatingUserInfo = useRef(false)\n const consecutivePingTimeouts = useRef(0)\n const currentUserQueueCallPhase = useRef<{\n conversationId: string\n phase: 'waiting' | 'connected'\n } | null>(null)\n const summaryConversationCache = useRef<Map<string, SummaryConversationCacheEntry>>(new Map())\n const STALE_CONNECTION_THRESHOLD = 3 // Force reconnect after 3 consecutive ping timeouts\n // Identifiers of the transcription the user currently has open. Incoming\n // realtime chunks are matched against these to avoid mixing transcripts from\n // a different concurrent call into the open view.\n const activeTranscriptionIdsRef = useRef<{ linkedid: string | null; uniqueid: string | null }>({\n linkedid: null,\n uniqueid: null,\n })\n\n // Event listener for starting transcription\n useEventListener('phone-island-start-transcription', (data: any) => {\n if (socket.current) {\n // Fall back to the other identifier so both fields are always populated\n // (the backend keys the stream on linkedid || uniqueid).\n const linkedid = data?.linkedid || data?.linkedId || data?.uniqueid || data?.uniqueId || null\n const uniqueid = data?.uniqueid || data?.uniqueId || linkedid\n if (!linkedid && !uniqueid) {\n return\n }\n activeTranscriptionIdsRef.current = { linkedid, uniqueid }\n socket.current.emit('start_transcription', {\n linkedid,\n uniqueid,\n })\n }\n })\n\n // Event listener for stopping transcription\n useEventListener('phone-island-stop-transcription', (data: any) => {\n if (socket.current) {\n // Fall back to the other identifier so both fields are always populated\n // (matches the start_transcription payload above).\n const linkedid = data?.linkedid || data?.linkedId || data?.uniqueid || data?.uniqueId || null\n const uniqueid = data?.uniqueid || data?.uniqueId || linkedid\n if (!linkedid && !uniqueid) {\n return\n }\n activeTranscriptionIdsRef.current = { linkedid: null, uniqueid: null }\n socket.current.emit('stop_transcription', {\n linkedid,\n uniqueid,\n })\n }\n })\n\n useEventListener(\n 'phone-island-current-user-queue-call-waiting',\n (data: CurrentUserQueueCallEventTypes) => {\n dispatch.currentCall.updateCurrentCall({\n throughQueue: true,\n queueId: data?.queueId || '',\n queueName: data?.queueName || '',\n queueNumber: data?.queueNumber || '',\n queuePosition: data?.queuePosition || '',\n queueWaitingTime: data?.queueWaitingTime || 0,\n })\n },\n )\n\n useEventListener(\n 'phone-island-current-user-queue-call-connected',\n (data: CurrentUserQueueCallEventTypes) => {\n dispatch.currentCall.updateCurrentCall({\n throughQueue: true,\n queueId: data?.queueId || '',\n queueName: data?.queueName || '',\n queueNumber: data?.queueNumber || '',\n queuePosition: data?.queuePosition || '',\n queueWaitingTime: data?.queueWaitingTime || 0,\n })\n },\n )\n\n const checkDefaultDeviceConversationActive = (conv: any) => {\n dispatch.currentCall.updateCurrentCall({\n conversationId: conv.id,\n accepted: true,\n incoming: conv.direction === 'in' ? false : undefined,\n })\n eventDispatch('phone-island-call-answered', {})\n\n // Stop the local audio element ringing\n store.dispatch.player.stopAudioPlayer()\n store.dispatch.player.setAudioPlayerLoop(false)\n }\n\n useEffect(() => {\n /**\n * Helper function to handle streaming source detection and subscription\n */\n const handleStreamingSource = (conv: ConversationTypes) => {\n // Check if the call is from a streaming source\n if (conv.counterpartNum && isFromStreaming(conv.counterpartNum)) {\n // Set isFromStreaming flag to true\n dispatch.island.setIsFromStreaming(true)\n\n // Store the streaming source number in the currentCall state for future reference\n dispatch.currentCall.updateCurrentCall({\n streamingSourceNumber: conv.counterpartNum,\n })\n\n // Find the source ID and subscribe to streaming updates\n const sourceId = getStreamingSourceId(conv.counterpartNum)\n if (sourceId) {\n // Subscribe to streaming updates\n subscribe({ id: sourceId }).catch((error) =>\n console.error('Error subscribing to streaming source:', error),\n )\n }\n }\n }\n\n const getCurrentCallQueuePayload = (conv: ConversationTypes) => {\n return getCurrentCallQueueContext(conv, store.getState().queue)\n }\n\n const getQueuePayloadWithFallback = (\n conv: ConversationTypes,\n queueContext: ReturnType<typeof getCurrentCallQueuePayload>,\n ) => {\n const currentCall = store.getState().currentCall\n\n return {\n conversationId: conv.id,\n linkedId: conv.linkedId,\n uniqueId: conv.uniqueId,\n ownerExtension: conv.owner,\n number: `${conv.counterpartNum || ''}`,\n queueId: queueContext?.queueId || currentCall.queueId || '',\n queueName: queueContext?.queueName || currentCall.queueName || '',\n queueNumber: queueContext?.queueNumber || currentCall.queueNumber || '',\n queuePosition: queueContext?.queuePosition || '',\n queueWaitingTime: queueContext?.queueWaitingTime || 0,\n }\n }\n\n const syncCurrentUserQueueCall = (conv: ConversationTypes | null) => {\n if (!conv) {\n currentUserQueueCallPhase.current = null\n return\n }\n\n const queueContext = getCurrentCallQueuePayload(conv)\n const payload = getQueuePayloadWithFallback(conv, queueContext)\n const hasQueueContext = Boolean(payload.queueId || payload.queueName || payload.queueNumber)\n\n if (!hasQueueContext) {\n currentUserQueueCallPhase.current = null\n return\n }\n\n if (!conv.connected) {\n const shouldDispatchWaiting =\n currentUserQueueCallPhase.current?.conversationId !== conv.id ||\n currentUserQueueCallPhase.current?.phase !== 'waiting'\n\n if (shouldDispatchWaiting) {\n dispatchCurrentUserQueueCallWaiting(payload)\n currentUserQueueCallPhase.current = {\n conversationId: conv.id,\n phase: 'waiting',\n }\n }\n\n return\n }\n\n const shouldDispatchConnected =\n currentUserQueueCallPhase.current?.conversationId !== conv.id ||\n currentUserQueueCallPhase.current?.phase !== 'connected'\n\n if (shouldDispatchConnected) {\n dispatchCurrentUserQueueCallConnected(payload)\n currentUserQueueCallPhase.current = {\n conversationId: conv.id,\n phase: 'connected',\n }\n }\n }\n\n const getActiveConversationForCurrentCall = (): ConversationTypes | null => {\n const { conversations } = store.getState().currentUser\n const { conversationId } = store.getState().currentCall\n let selectedConversation: ConversationTypes | null = null\n\n Object.values(conversations || {}).forEach((extensionConversations) => {\n Object.values(extensionConversations || {}).forEach((conversation) => {\n if (selectedConversation?.id && selectedConversation.id === conversationId) {\n return\n }\n\n if (conversationId && conversation.id === conversationId) {\n selectedConversation = conversation\n return\n }\n\n if (!selectedConversation) {\n selectedConversation = conversation\n return\n }\n\n if (conversation.connected && !selectedConversation.connected) {\n selectedConversation = conversation\n return\n }\n\n if (\n conversation.connected === selectedConversation.connected &&\n conversation.startTime > selectedConversation.startTime\n ) {\n selectedConversation = conversation\n }\n })\n })\n\n return selectedConversation\n }\n\n const getConversationLinkedId = (conversation?: any) =>\n conversation?.linkedId || conversation?.linkedid || ''\n\n const getConversationUniqueId = (conversation?: any) =>\n conversation?.uniqueId || conversation?.uniqueid || ''\n\n const isSummaryConversationCandidate = (conversation?: any) =>\n !!conversation?.connected &&\n !!getConversationLinkedId(conversation) &&\n !!getConversationUniqueId(conversation)\n\n const selectLiveSummaryConversation = (extensionConversations?: Record<string, any>) => {\n let selectedConversation: any = null\n let selectedConversationKey: string | undefined\n const entries = Object.entries(extensionConversations || {}).filter(\n ([, conversation]) => conversation && Object.keys(conversation).length > 0,\n )\n\n entries.forEach(([key, currentConversation]) => {\n if (!selectedConversation) {\n selectedConversation = currentConversation\n selectedConversationKey = key\n return\n }\n\n const selectedIsSummaryCandidate = isSummaryConversationCandidate(selectedConversation)\n const currentIsSummaryCandidate = isSummaryConversationCandidate(currentConversation)\n\n if (currentIsSummaryCandidate && !selectedIsSummaryCandidate) {\n selectedConversation = currentConversation\n selectedConversationKey = key\n return\n }\n\n if (currentIsSummaryCandidate === selectedIsSummaryCandidate) {\n const selectedConnected = !!selectedConversation.connected\n const currentConnected = !!currentConversation.connected\n\n if (currentConnected && !selectedConnected) {\n selectedConversation = currentConversation\n selectedConversationKey = key\n return\n }\n\n const selectedStartTime = selectedConversation.startTime ?? 0\n const currentStartTime = currentConversation.startTime ?? 0\n\n if (currentConnected === selectedConnected && currentStartTime > selectedStartTime) {\n selectedConversation = currentConversation\n selectedConversationKey = key\n }\n }\n })\n\n return {\n conversation: selectedConversation,\n key: selectedConversationKey,\n count: entries.length,\n }\n }\n\n const getCachedSummaryConversation = (extension?: string) => {\n if (!extension) {\n return null\n }\n\n const cached = summaryConversationCache.current.get(extension)\n if (!cached) {\n return null\n }\n\n const cacheAgeMs = Date.now() - cached.cachedAt\n if (cacheAgeMs > SUMMARY_CONVERSATION_CACHE_TTL_MS) {\n summaryConversationCache.current.delete(extension)\n return null\n }\n\n return {\n ...cached,\n cacheAgeMs,\n }\n }\n\n const selectSummaryConversationForHangup = (extension?: string) => {\n const { conversations } = store.getState().currentUser\n const extensionConversations = extension ? conversations?.[extension] : undefined\n const liveSelection = selectLiveSummaryConversation(extensionConversations)\n\n if (isSummaryConversationCandidate(liveSelection.conversation)) {\n return {\n ...liveSelection,\n source: 'live',\n cacheAgeMs: undefined,\n hasConversationForCaller: !!extensionConversations,\n liveConversationKeys: Object.keys(extensionConversations || {}),\n }\n }\n\n const cached = getCachedSummaryConversation(extension)\n if (cached && isSummaryConversationCandidate(cached.conversation)) {\n return {\n conversation: cached.conversation,\n key: cached.conversation.id,\n count: liveSelection.count,\n source: 'cache',\n cacheAgeMs: cached.cacheAgeMs,\n hasConversationForCaller: !!extensionConversations,\n liveConversationKeys: Object.keys(extensionConversations || {}),\n }\n }\n\n return {\n ...liveSelection,\n source: liveSelection.conversation ? 'live_invalid' : 'none',\n cacheAgeMs: cached?.cacheAgeMs,\n hasConversationForCaller: !!extensionConversations,\n liveConversationKeys: Object.keys(extensionConversations || {}),\n }\n }\n\n const cacheSummaryConversations = (extension?: string, conversations?: Record<string, any>) => {\n if (!extension) {\n return\n }\n\n Object.values(conversations || {}).forEach((conversation) => {\n if (!isSummaryConversationCandidate(conversation)) {\n return\n }\n\n summaryConversationCache.current.set(extension, {\n conversation,\n cachedAt: Date.now(),\n })\n })\n }\n\n const shouldKeepCurrentAcceptedCall = (ownerExtension?: string) => {\n const { accepted, ownerExtension: currentOwnerExtension } = store.getState().currentCall\n\n return (\n accepted &&\n !!currentOwnerExtension &&\n !!ownerExtension &&\n currentOwnerExtension !== ownerExtension\n )\n }\n\n /**\n * Manages event and data for the currentUser\n *\n * @param res The data from the socket\n * @param conv The conversation data\n */\n const handleCurrentUserEvents = (res: ExtensionTypes, conv: ConversationTypes) => {\n // Handle transferring data\n const { transferring, transferSwitching, transferCalls } = store.getState().currentCall\n\n const view = store.getState().island.view\n // Check conversation isn't empty\n if (Object.keys(conv).length > 0) {\n // With conversation\n if (res.status) {\n const { extensions } = store.getState().users\n const { default_device } = store.getState().currentUser\n const { endpoints, username } = store.getState().currentUser\n const { incoming, outgoing } = store.getState().currentCall\n\n const hasOnlineNethlink = () => {\n if (!extensions || !username) return false\n\n // Get all extensions for current user\n const userExtensions: any = Object.values(extensions).filter(\n (ext) => ext?.username === username,\n )\n\n // Check if any extension is nethlink type and online\n return userExtensions?.some((ext) => {\n const endpointExtension = endpoints?.extension.find(\n (endpoint) => endpoint.id === ext?.exten,\n )\n return endpointExtension?.type === 'nethlink' && ext?.status !== 'offline'\n })\n }\n switch (res.status) {\n case 'ringing':\n if (shouldKeepCurrentAcceptedCall(conv.owner)) {\n break\n }\n\n syncCurrentUserQueueCall(conv)\n\n // Handle streaming source for incoming calls\n handleStreamingSource(conv)\n\n if (\n (uaType === 'mobile' && hasOnlineNethlink()) ||\n (uaType === 'desktop' &&\n (default_device?.type === 'webrtc' ||\n (default_device?.type === undefined && !hasOnlineNethlink()) ||\n (!hasOnlineNethlink() && default_device?.type === 'physical')))\n ) {\n dispatch.currentCall.checkIncomingUpdatePlay({\n conversationId: conv.id,\n displayName: getDisplayName(conv),\n number: `${conv.counterpartNum}`,\n incomingSocket: true,\n incoming: true,\n username:\n `${\n extensions &&\n extensions[conv.counterpartNum] &&\n extensions[conv.counterpartNum].username\n }` || '',\n ownerExtension: conv.owner,\n })\n store.dispatch.island.setIslandView('call')\n }\n // Get updated user info to refresh open url param type\n if (!isUpdatingUserInfo.current) {\n isUpdatingUserInfo.current = true\n getCurrentUserInfo()\n .then((userInfo) => {\n if (userInfo) {\n dispatch.currentUser.updateCurrentUser(userInfo)\n eventDispatch('phone-island-user-informations-update', { ...userInfo })\n if (userInfo.settings && userInfo.settings.open_param_url) {\n dispatch.paramUrl.setOpenParamUrlType(userInfo.settings.open_param_url)\n } else {\n dispatch.paramUrl.setOpenParamUrlType('never')\n }\n }\n })\n .catch((error) => {\n console.error('Error getting current user info:', error)\n })\n .finally(() => {\n setTimeout(() => {\n isUpdatingUserInfo.current = false\n }, 100)\n })\n }\n const { openParamUrlType } = store.getState().paramUrl\n const { urlOpened } = store.getState().island\n if (openParamUrlType === 'ringing' && !urlOpened) {\n // Calculate throughTrunk based on counterpartNum\n const calculatedThroughTrunk = isFromTrunk(conv.counterpartNum)\n\n // Update throughTrunk in paramUrl store\n store.dispatch.paramUrl.setThroughTrunk(calculatedThroughTrunk)\n\n store.dispatch.island.setUrlOpened(false)\n eventDispatch('phone-island-url-parameter-opened', {\n counterpartNum: conv.counterpartNum,\n counterpartName: getDisplayName(conv),\n owner: conv.owner,\n uniqueId: conv.uniqueId,\n linkedId: conv.linkedId,\n throughQueue: conv.throughQueue,\n throughTrunk: calculatedThroughTrunk,\n direction: conv.direction,\n connected: conv.connected,\n })\n }\n break\n // @ts-ignore\n case 'busy':\n syncCurrentUserQueueCall(conv)\n\n // Handle streaming source for outgoing calls\n handleStreamingSource(conv)\n\n if (\n (uaType === 'mobile' && hasOnlineNethlink()) ||\n (uaType === 'desktop' &&\n (default_device?.type === 'webrtc' ||\n (default_device?.type === undefined && !hasOnlineNethlink()) ||\n (!hasOnlineNethlink() && default_device?.type === 'physical')))\n ) {\n if (conv && conv.connected) {\n // Current call accepted and update connected call\n dispatch.currentCall.updateCurrentCall({\n conversationId: conv.id,\n displayName: getDisplayName(conv),\n number: `${conv.counterpartNum}`,\n ownerExtension: conv.owner,\n username:\n `${\n extensions &&\n extensions[conv.counterpartNum] &&\n extensions[conv.counterpartNum].username\n }` || '',\n chDest: conv?.chDest || {},\n chSource: conv?.chSource || {},\n })\n // Update the current call informations for physical devices\n dispatch.currentCall.checkAcceptedUpdate({\n acceptedSocket: true,\n })\n // Add call to transfer calls\n dispatch.currentCall.addTransferCalls({\n type: 'transferred',\n displayName: getDisplayName(conv),\n number: `${conv.counterpartNum}`,\n startTime: `${getTimestampInSeconds()}`,\n })\n\n // Check if this is a streaming call that was accepted\n const { isFromStreaming } = store.getState().island\n if (isFromStreaming && conv.direction === 'out') {\n // Set view to streamingAnswer for outgoing streaming calls when accepted\n setTimeout(() => {\n dispatch.island.setIslandView('streamingAnswer')\n }, 200)\n }\n\n if (isPhysical()) {\n checkDefaultDeviceConversationActive(conv)\n }\n if (view === 'call' && transferring) {\n dispatch.currentCall.updateCurrentCall({\n transferring: false,\n })\n }\n }\n // Delete transfer calls if there are more than one ( in case of call switch after transfer)\n if (transferCalls.length > 1) {\n dispatch.currentCall.deleteTransferCalls()\n }\n // Handle not connected calls\n else if (conv && !conv.connected) {\n if (transferring && !transferSwitching) {\n // Handle hangup during transfer\n const inTransferCalls = transferCalls.find(\n (item) => item.number === conv.counterpartNum,\n )\n if (!conv.connected && inTransferCalls) {\n // Update transferring data for the current call\n dispatch.currentCall.updateCurrentCall({\n transferring: false,\n })\n eventDispatch('phone-island-call-transfer-failed', {})\n // Reset transfer switching\n // TODO - It needs to enhance how conversation connections (conv.connected) are updated server side\n // TODO - The transfer end is not handled when the an user hangups or after call switch\n dispatch.currentCall.updateTransferSwitching(false)\n }\n }\n if (conv?.counterpartName === 'REC') {\n dispatch.physicalRecorder.setRecordingTempVariable(true)\n }\n }\n // Handle outgoing call\n if (conv && !conv.connected && conv.direction === 'out') {\n // Update the current outgoing conversation\n dispatch.currentCall.checkOutgoingUpdate({\n outgoingSocket: true,\n outgoing: conv?.counterpartName === 'REC' ? false : true,\n displayName: getDisplayName(conv),\n number: `${conv?.counterpartNum}`,\n username:\n `${\n extensions &&\n extensions[conv?.counterpartNum] &&\n extensions[conv?.counterpartNum].username\n }` || '',\n })\n }\n }\n break\n\n case 'onhold':\n syncCurrentUserQueueCall(conv)\n\n // The new conversation during transferring\n const { counterpartName, counterpartNum, startTime } = conv\n if (\n transferring &&\n counterpartNum &&\n counterpartName &&\n counterpartName !== '<unknown>'\n ) {\n // Add call to transfer calls\n dispatch.currentCall.addTransferCalls({\n type: 'destination',\n displayName: getDisplayName(conv),\n number: counterpartNum,\n startTime: `${getTimestampInSeconds()}`,\n })\n // Set the current call informations\n dispatch.currentCall.updateCurrentCall({\n displayName: getDisplayName(conv),\n number: counterpartNum,\n startTime: `${startTime / 1000}`,\n conversationId: conv.id,\n })\n // Set the view of the island to call\n dispatch.island.setIslandView('call')\n }\n break\n case 'busy_ringing':\n eventDispatch('phone-island-call-ringing', {})\n break\n default:\n break\n }\n }\n } else {\n // Without conversation for physical phone management\n if (res.status == 'online' && userTotallyFree()) {\n syncCurrentUserQueueCall(null)\n\n // Stop ringing sounds\n dispatch.player.stopAudioPlayer()\n // Reset current call info\n dispatch.currentCall.reset()\n dispatch.physicalRecorder.setRecordingTempVariable(false)\n // Reset isFromStreaming flag\n dispatch.island.setIsFromStreaming(false)\n }\n }\n }\n\n /**\n * Initialize socket connection and listeners\n */\n const initSocketConnection = () => {\n const currentApiMode = getApiMode(username)\n\n const socketOptions: any = {\n upgrade: false,\n transports: ['websocket'],\n reconnection: true,\n reconnectionDelay: 2000,\n }\n\n // Only set path for new API mode\n if (currentApiMode === 'new') {\n socketOptions.path = '/api/ws'\n }\n\n socket.current = io('https://' + hostName, socketOptions)\n\n // save websocket to store\n dispatch.websocket.update({ socket: socket.current })\n\n // Handle socket errors\n socket.current.on('connect', () => {\n console.debug(`Socket connected sid: ${socket.current.id}`)\n eventDispatch('phone-island-socket-connected', {})\n })\n socket.current.on('disconnect', (reason) => {\n console.debug(`Socket disconnect - reason: ${reason}`)\n // Clear the connection check interval on disconnect to avoid stale pings\n if (connectionCheckInterval.current) {\n clearInterval(connectionCheckInterval.current)\n connectionCheckInterval.current = null\n }\n if (reason.includes('server disconnect')) {\n eventDispatch('phone-island-server-disconnected', {})\n } else {\n eventDispatch('phone-island-socket-disconnected', {})\n }\n })\n socket.current.io.on('error', (err) => {\n console.debug(`Socket error: `, err)\n })\n socket.current.on('connect_error', (err) => {\n console.debug(`Socket connect_error: `, err)\n })\n socket.current.io.on('reconnect', (attempt) => {\n // Reset consecutive ping timeout counter on successful reconnection\n consecutivePingTimeouts.current = 0\n eventDispatch('phone-island-socket-reconnected', {})\n console.debug(`Socket reconnect attemp ${attempt} (sid: ${socket.current.id})`)\n })\n socket.current.io.on('reconnect_attempt', (attempt) => {\n console.debug(`Socket reconnect_attempt ${attempt}`)\n })\n socket.current.io.on('reconnect_error', (err) => {\n console.debug(`Socket reconnect_error: `, err)\n })\n socket.current.io.on('reconnect_failed', () => {\n console.debug(`Socket reconnect_failed`)\n })\n\n // Connection check interval is now started in the authe_ok handler\n // to ensure it only runs after successful authentication\n\n // Handle connection message\n socket.current.on('connect', () => {\n console.debug('Socket on: ' + hostName + ' is connected!')\n socket.current.emit('login', {\n accessKeyId: `${username}`,\n token: authToken,\n uaType: uaType,\n })\n })\n\n // Handle authentication success message\n socket.current.on('authe_ok', () => {\n console.debug('Socket authentication success!')\n eventDispatch('phone-island-socket-authorized', {})\n\n // Start connection check interval after successful authentication\n // Clear any existing interval first to avoid duplicates\n if (connectionCheckInterval.current) {\n clearInterval(connectionCheckInterval.current)\n }\n connectionCheckInterval.current = setInterval(() => {\n socket.current.volatile.emit(\n 'ping',\n withTimeout(\n () => {\n // Ping success - reset consecutive timeout counter\n consecutivePingTimeouts.current = 0\n // Remove socket_down alert (async to avoid React error #300 with framer-motion)\n setTimeout(() => {\n dispatch.alerts.removeAlert('socket_down')\n eventDispatch('phone-island-alert-removed', {\n type: 'socket_down',\n })\n eventDispatch('phone-island-socket-disconnected-popup-close', {})\n }, 0)\n },\n () => {\n // Ping timeout - increment counter\n consecutivePingTimeouts.current++\n console.debug(\n `Socket ping timeout (${consecutivePingTimeouts.current}/${STALE_CONNECTION_THRESHOLD}), connected: ${socket.current.connected}`,\n )\n\n // Set socket_down alert (async to avoid React error #300 with framer-motion)\n setTimeout(() => {\n // Check for stale connection: socket reports connected but pings keep timing out\n const isStaleConnection =\n socket.current.connected &&\n consecutivePingTimeouts.current >= STALE_CONNECTION_THRESHOLD\n\n if (!socket.current.connected || isStaleConnection) {\n // Check if there's an active call with ICE still connected\n // If so, skip showing alert - let ICE grace period mechanism handle it\n const { sipcall }: { sipcall: any } = store.getState().webrtc\n const { accepted, outgoing } = store.getState().currentCall\n const iceState = sipcall?.webrtcStuff?.pc?.iceConnectionState\n const hasActiveCallWithIce =\n (accepted || outgoing) &&\n (iceState === 'connected' || iceState === 'completed')\n\n if (hasActiveCallWithIce) {\n console.debug(\n 'Socket unreachable but active call with ICE connected - skipping socket_down alert',\n {\n iceState,\n accepted,\n outgoing,\n isStaleConnection,\n timestamp: new Date().toISOString(),\n },\n )\n return\n }\n\n if (isStaleConnection) {\n console.warn('Stale socket connection detected - forcing reconnection')\n // Force disconnect to trigger reconnection\n socket.current.disconnect()\n }\n\n dispatch.alerts.setAlert('socket_down')\n eventDispatch('phone-island-socket-disconnected-popup-open', {})\n console.error('Socket is unreachable!')\n }\n }, 0)\n },\n 5 * 1000,\n ),\n )\n }, 5 * 1000)\n })\n\n socket.current.on('userMainPresenceUpdate', (res: MainPresenceTypes) => {\n // Update endpoints store\n store.dispatch.users.updateEndpointMainPresence({ ...res.mainPresence })\n // Dispatch dispatchMainPresence Event\n dispatchMainPresence(res)\n })\n\n socket.current.on('extenHangup', (res: any) => {\n const { endpoints, username } = store.getState().currentUser\n const { isActive, conferenceStartedFrom } = store.getState().conference\n const { view, previewCallFromMobileOrNethlink } = store.getState().island\n\n // Get user extensions\n const userExtensions = endpoints?.extension || []\n const userExtensionIds = userExtensions.map((ext) => ext.id)\n let summaryExtension = res?.callerNum\n if (\n !userExtensionIds.includes(summaryExtension) &&\n userExtensionIds.includes(res?.channelExten)\n ) {\n summaryExtension = res?.channelExten\n }\n\n // Find the extension type based on callerNum\n const connectedExtension = userExtensions.find((ext) => ext.id === res.callerNum)\n\n const extensionType: any = connectedExtension?.type\n\n const summaryConversationSelection = selectSummaryConversationForHangup(summaryExtension)\n const selectedConversation: any = summaryConversationSelection.conversation\n\n // Check summary/transcription only for answered calls with a valid uniqueid.\n const linkedId = getConversationLinkedId(selectedConversation)\n const uniqueId = getConversationUniqueId(selectedConversation)\n const conversationWasConnected = selectedConversation?.connected || false\n\n if (uniqueId && linkedId && conversationWasConnected) {\n eventDispatch('phone-island-summary-call-check', { linkedid: linkedId, uniqueid: uniqueId })\n if (summaryExtension) {\n summaryConversationCache.current.delete(summaryExtension)\n }\n }\n\n // If cause is normal_clearing and extension is physical or mobile\n // Clean phone-island visibility also after user_busy ( useful for physical devices )\n if (\n (res.cause === 'normal_clearing' &&\n (extensionType === 'physical' || extensionType === 'mobile')) ||\n (res.cause === 'normal_clearing' &&\n (extensionType === 'webrtc' || extensionType === 'nethlink') &&\n previewCallFromMobileOrNethlink) ||\n res?.cause === 'user_busy' ||\n res?.cause === 'not_defined' ||\n res?.cause === 'call_rejected' ||\n res?.cause === 'interworking'\n ) {\n // Reset phone island visibility after 2 seconds to avoid glitches\n setTimeout(() => {\n store.dispatch.island.toggleAvoidToShow(false)\n store.dispatch.island.setPreviewCallFromMobileOrNethlink(false)\n }, 500)\n // Only reset conference if there are no more participants or if user is not in a conference\n if (isActive && conferenceStartedFrom !== username) {\n store.dispatch.conference.resetConference()\n }\n } else if (\n res?.cause === 'normal_circuit_congestion' &&\n isActive &&\n conferenceStartedFrom === username\n ) {\n setTimeout(() => {\n eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\n }, 800)\n } else if (\n (res.cause === 'normal_clearing' ||\n res?.cause === 'user_busy' ||\n res?.cause === 'not_defined' ||\n res?.cause === 'call_rejected') &&\n (extensionType === 'webrtc' || extensionType === 'nethlink') &&\n isActive &&\n conferenceStartedFrom !== username\n ) {\n store.dispatch.conference.resetConference()\n }\n // if conference owner and added participant refuses or hangs up with normal_clearing\n if (\n ((res.cause === 'normal_clearing' &&\n (extensionType === 'webrtc' || extensionType === 'nethlink')) ||\n res?.cause === 'call_rejected') &&\n isActive &&\n conferenceStartedFrom === username\n ) {\n const { usersList, pendingUsers } = store.getState().conference\n // Check if there are still participants in the conference (both confirmed and pending)\n const hasConfirmedParticipants = usersList && Object.keys(usersList).length > 0\n const hasPendingParticipants = pendingUsers && Object.keys(pendingUsers).length > 0\n const hasParticipants = hasConfirmedParticipants || hasPendingParticipants\n\n if (!hasParticipants) {\n store.dispatch.conference.resetConference()\n } else {\n // If there are still participants, keep the waitingConference view\n setTimeout(() => {\n eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\n }, 800)\n }\n }\n // if conference owner call the call with the added user inside conference\n if (\n res?.cause === 'interworking' &&\n isActive &&\n conferenceStartedFrom === username &&\n view !== 'waitingConference'\n ) {\n setTimeout(() => {\n eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\n }, 800)\n }\n if (res?.cause === 'user_busy') {\n // Get current user's extensions\n const { endpoints, username } = store.getState().currentUser\n const userExtensions = endpoints?.extension || []\n const userExtensionIds = userExtensions.map((ext) => ext.id)\n\n // Get the current call state to understand if we're the caller or receiver\n const { incoming, accepted, transferring } = store.getState().currentCall\n\n // Check if there's an active conference\n const { isActive, conferenceStartedFrom } = store.getState().conference\n\n // When we RECEIVE a call on our extension, callerNum is the busy extension (our own)\n // When we CALL someone, channelExten is one of our extensions (the one we're calling from)\n const isReceivingCall =\n incoming && !!res.callerNum && userExtensionIds.includes(res.callerNum)\n\n // If we are already on an active call, suppress the busy popup unless it belongs\n // to a conference-owner flow or an attended transfer started by this user.\n const shouldShowOperatorBusy = !isReceivingCall && (!accepted || isActive || transferring)\n\n // Only show operator busy view if:\n // 1. We are NOT receiving an incoming call to our own extension\n if (shouldShowOperatorBusy) {\n // Set operator busy active with caller information\n store.dispatch.island.setOperatorBusyActive({\n callerNumber: res.callerNum || 'Unknown',\n })\n\n // Stop busy tone after 4 seconds\n setTimeout(() => {\n store.dispatch.player.stopAudioPlayer()\n }, 4000)\n\n setTimeout(() => {\n // Play busy tone\n store.dispatch.player.updateStartAudioPlayer({\n src: busyRingtone,\n loop: true,\n })\n store.dispatch.island.setIslandView('operatorBusy')\n }, 600)\n\n // If conference is active and we're the owner, return to conference after timeout\n if (isActive && conferenceStartedFrom === username) {\n setTimeout(() => {\n eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\n }, 4000)\n }\n }\n }\n\n // Handle subscriber_absent - when added participant rejects the call\n if (res?.cause === 'subscriber_absent') {\n const { isActive, conferenceStartedFrom } = store.getState().conference\n const { username } = store.getState().currentUser\n\n // Only handle if conference is active and current user is the owner\n if (isActive && conferenceStartedFrom === username) {\n // Check if there are still participants in the conference (both confirmed and pending)\n const { usersList, pendingUsers } = store.getState().conference\n const hasConfirmedParticipants = usersList && Object.keys(usersList).length > 0\n const hasPendingParticipants = pendingUsers && Object.keys(pendingUsers).length > 0\n const hasParticipants = hasConfirmedParticipants || hasPendingParticipants\n\n if (hasParticipants) {\n // Return to waiting conference view to manage other participants\n setTimeout(() => {\n eventDispatch('phone-island-view-changed', { viewType: 'waitingConference' })\n }, 800)\n // Remove from pending users if exists\n if (pendingUsers && pendingUsers[res.callerNum]) {\n store.dispatch.conference.removePendingUser(res.callerNum)\n }\n } else {\n // No participants left, reset conference\n store.dispatch.conference.resetConference()\n }\n }\n }\n })\n\n // Avoid to show phone island if call is connected with other extension\n socket.current.on('extenConnected', (res: { extenConnected: string }) => {\n // Get the current user's extensions\n\n const { default_device, endpoints } = store.getState().currentUser\n const userExtensions = endpoints?.extension || []\n\n // Find the extension type\n const connectedExtension = userExtensions.find((ext) => ext.id === res.extenConnected)\n const extensionType: any = connectedExtension?.type\n\n // Reset only if the extension type is not webrtc or nethlink\n // ( avoid to not show phone island if default is physical and extensionType is physical)\n if (\n ((default_device?.type === 'webrtc' || default_device?.type === 'nethlink') &&\n extensionType &&\n (extensionType === 'mobile' || extensionType === 'physical')) ||\n (default_device?.type === 'physical' && extensionType && extensionType !== 'physical')\n ) {\n // Avoid to show phone island in case of answer from physical or mobile device\n store.dispatch.island.toggleAvoidToShow(true)\n // Set the preview call flag\n store.dispatch.island.setPreviewCallFromMobileOrNethlink(true)\n // Launch an event to advert the user that the call it's answered from another device\n eventDispatch('phone-island-call-answered', { extensionType })\n }\n })\n\n socket.current.on('extenUpdate', (res: ExtensionTypes) => {\n // Update extensions and conversations in users store\n dispatch.users.updateExtension(res)\n\n //retrieve all extensions from store\n const { extensions }: any = store.getState().users\n const deviceMap: any = {}\n\n const userInformation = store.getState().currentUser\n // Create a map of extensions for each user\n for (const key in extensions) {\n const user: any = extensions[key].username\n const ext: any = extensions[key].exten\n\n if (!deviceMap[user]) {\n deviceMap[user] = []\n }\n\n deviceMap[user].push(ext)\n }\n\n const associatedExtensions: any = deviceMap[res.username]\n const conversationKeys = Object.keys(res.conversations || {})\n const isCurrentUserUpdate = res.username === username\n\n // Initialize conversation\n let conv = res.conversations?.[conversationKeys[0]] || {}\n if (isCurrentUserUpdate) {\n cacheSummaryConversations(res.exten, res.conversations)\n }\n\n // Check if this is a mobile extension call for the current user\n let isMobileExtensionCall = false\n if (res?.username === username && !isEmpty(conv) && conv?.owner) {\n const matchingExtension = userInformation?.endpoints?.extension?.find(\n (ext: any) => ext.id === conv.owner,\n )\n if (matchingExtension && matchingExtension.type === 'mobile') {\n isMobileExtensionCall = true\n }\n }\n\n // Update all extensions and send the dispatch event\n dispatchExtensions(res)\n\n // second step update conversation\n\n // Check if conversation is empty\n if (isEmpty(conv)) {\n // Check if there is at least one conversation not empty\n const hasNonEmptyConversation = associatedExtensions?.some((ext: any) => {\n const extConversations = extensions[ext]?.conversations\n\n if (!isEmpty(extConversations)) {\n // not empty conversation found\n return true\n }\n\n return false\n })\n\n if (!hasNonEmptyConversation) {\n // Conversation is empty and there is no conversation for the user\n dispatchConversations(res)\n }\n } else if (!isMobileExtensionCall) {\n // Dispatch conversation event\n dispatchConversations(res)\n }\n\n if (isMobileExtensionCall && res?.status === 'busy' && res?.username === username) {\n store.dispatch.island.toggleAvoidToShow(true)\n store.dispatch.island.setPreviewCallFromMobileOrNethlink(true)\n }\n // Handle only the events of the user\n if (res.username === username) {\n handleCurrentUserEvents(res, conv)\n // Update the conversations of the user\n dispatch.currentUser.updateConversations(res)\n }\n })\n\n // `queueUpdate` is the socket event when the data of a queue updates\n socket.current.on('queueUpdate', (res: QueuesUpdateTypes) => {\n dispatch.queue.updateQueue(res)\n\n const activeConversation = getActiveConversationForCurrentCall()\n\n if (activeConversation) {\n syncCurrentUserQueueCall(activeConversation)\n }\n\n // Dispatch queueUpdate event\n dispatchQueueUpdate(res)\n })\n\n // `queueMemberUpdate` is the socket event when the data of a queue member changes\n socket.current.on('queueMemberUpdate', (res: QueueUpdateMemberTypes) => {\n dispatch.queue.updateQueueMember(res)\n // Dispatch queueMemberUpdate event\n dispatchQueueMemberUpdate(res)\n })\n\n // `takeOver` is the socket event when the user does login from another new window\n socket.current.on('takeOver', () => {\n // Dispatch takeOver event\n dispatchAlreadyLogin()\n })\n\n // `serverReload` is the socket event when server is reloaded\n socket.current.on('serverReloaded', () => {\n // Dispatch serverReload event\n dispatchServerReload()\n })\n\n // `parkingUpdate` is the socket event when a call is parked or unparked\n socket.current.on('parkingUpdate', (event) => {\n // Dispatch parking update event with the parking information\n dispatchParkingUpdate(event)\n })\n\n // `actionNethLink` is the socket event when user make a call or a action from NethLink and has a physical device\n socket.current.on('actionNethLink', (link, urlType) => {\n // Dispatch phone island physical call event with the link and the urlType\n dispatchUrlCall(link, urlType)\n })\n\n // `satellite/summary` is the socket event when summary is ready\n socket.current.on('satellite/summary', (data: any) => {\n const uniqueid = data?.uniqueid || data?.uniqueId\n const linkedid = data?.linkedid || data?.linkedId\n\n if (uniqueid) {\n dispatchSummaryReady({\n linkedid,\n uniqueid,\n display_name: data?.display_name,\n display_number: data?.display_number,\n source: 'socket',\n })\n }\n })\n\n socket.current.on('message', (data: any) => {\n switch (data.message) {\n case 'videoCallStart':\n {\n const {\n currentCall: { incoming, outgoing, accepted },\n currentUser: { default_device },\n island: { isFromStreaming, view },\n } = store.getState()\n\n const isWebrtcDevice =\n default_device?.type === 'webrtc' || default_device?.type === 'nethlink'\n const hasCompatibleCallState = incoming || outgoing || accepted\n const canOpenVideoView =\n isWebrtcDevice && hasCompatibleCallState && !isFromStreaming && view !== 'video'\n\n if (canOpenVideoView) {\n dispatch.island.toggleSideViewVisible(false)\n dispatch.island.toggleTranscriptionViewVisible(false)\n dispatch.island.setIslandView('video')\n }\n }\n\n dispatchVideoCallStarted({\n initiator: 'remote',\n callUser: (data as VideoCallMessage).callUser,\n destUser: (data as VideoCallMessage).destUser,\n })\n break\n case 'screenSharingStart':\n dispatch.island.toggleSideViewVisible(false)\n dispatch.island.toggleTranscriptionViewVisible(false)\n dispatch.island.setIslandView('video')\n\n dispatch.screenShare.update({\n isJoiningScreenShare: true,\n room: (data as ScreenSharingMessage).roomId,\n })\n break\n case 'screenSharingStop':\n dispatch.island.toggleSideViewVisible(false)\n dispatch.island.toggleTranscriptionViewVisible(false)\n dispatch.island.setIslandView('video')\n\n dispatch.screenShare.update({\n isLeavingScreenShare: true,\n })\n break\n default:\n console.warn('Socket: unknown message type ', data.message)\n }\n })\n\n // `updateDefaultDevice` is the socket event when user change the default device\n socket.current.on('updateDefaultDevice', (extension: string) => {\n // Dispatch phone island physical call event with the link and the urlType\n dispatchDefaultDeviceUpdate(extension)\n // Update the internal store\n const { extensions } = store.getState().users\n const { endpoints } = store.getState().currentUser\n if (!extensions || !endpoints) return\n\n const extensionInformations: any = Object.values(extensions).filter(\n (ext) => ext?.exten === extension,\n )\n if (extensionInformations.length === 0) return\n\n let objectComplete = extensionInformations[0]\n const endpointExtension = endpoints.extension.find(\n (endpoint) => endpoint.id === objectComplete.exten,\n )\n if (endpointExtension) {\n objectComplete = { ...objectComplete, type: endpointExtension.type }\n }\n\n store.dispatch.currentUser.updateCurrentDefaultDevice(objectComplete)\n //make sure to check the media permissions\n checkMediaPermissions()\n })\n\n socket.current.on('confBridgeUpdate', (res: any) => {\n if (res && res?.users) {\n // Get User informations\n const conferenceId = res?.id\n const conferenceUsers = res?.users\n\n // Get current users list to preserve mute status\n const { usersList } = store.getState().conference\n\n // Create a copy of the new conference users while preserving mute status\n const updatedConferenceUsers = { ...conferenceUsers }\n\n // Preserve mute status for existing users\n if (usersList) {\n Object.keys(updatedConferenceUsers).forEach((userId) => {\n if (usersList[userId]) {\n // Keep the existing mute status instead of using the server's value\n updatedConferenceUsers[userId] = {\n ...updatedConferenceUsers[userId],\n muted: usersList[userId].muted,\n }\n }\n })\n }\n\n store.dispatch.conference.updateConferenceUsersList(updatedConferenceUsers)\n store.dispatch.conference.updateConferenceId(conferenceId)\n }\n })\n\n socket.current.on('confBridgeEnd', (res: any) => {\n if (res && res?.id) {\n // Reset the conference store when conference ends\n store.dispatch.conference.resetConference()\n eventDispatch('phone-island-conference-finished', {})\n }\n })\n\n socket.current.on('callWebrtc', (res: any) => {\n // On call event from socket dispatch the call start event\n eventDispatch('phone-island-call-start', { number: res })\n })\n\n socket.current.on('newVoiceMessageCounter', (res: any) => {\n eventDispatch('phone-island-voicemail-received', { voicemailInfo: res })\n })\n\n socket.current.on('streamingSourceUpdate', (res: any) => {\n eventDispatch('phone-island-streaming-information-received', { res })\n const streamingData = res.streaming || (res.res && res.res.streaming)\n\n if (streamingData) {\n const { source, image } = streamingData\n if (source && image) {\n const { isFromStreaming } = store.getState().island\n const { streamingSourceNumber } = store.getState().currentCall\n const sourceId = getStreamingSourceId(streamingSourceNumber)\n\n dispatch.streaming.updateSourceImage({\n source: source,\n image: image,\n })\n }\n }\n })\n\n // Handle satellite/transcription messages\n socket.current.on('satellite/transcription', (transcriptionData: any) => {\n // Drop chunks belonging to a different call than the one open in the\n // transcription view, to prevent cross-call transcript mixing when more\n // than one call is being transcribed at the same time.\n //\n // The realtime chunk identifies its call in the `uniqueid` field, which\n // actually carries the call_id (linkedid when available — see satellite\n // backend). We only filter when we know the active linkedid: in that case\n // matching is reliable. If we don't, we forward everything (unchanged\n // behaviour) to avoid ever dropping a valid chunk.\n const active = activeTranscriptionIdsRef.current\n const chunkId = transcriptionData?.uniqueid\n const chunkLinkedId = transcriptionData?.linkedid\n if (active.linkedid && chunkId) {\n const matchesActive = (id: any) =>\n id != null && (id === active.linkedid || id === active.uniqueid)\n if (!matchesActive(chunkId) && !matchesActive(chunkLinkedId)) {\n return\n }\n }\n // Dispatch the transcription event to external listeners\n eventDispatch('phone-island-conversation-transcription', transcriptionData)\n })\n }\n\n initSocketConnection()\n\n // Stop the check socket interval\n // Close the socket connection\n return () => {\n clearInterval(connectionCheckInterval.current)\n socket.current.close()\n }\n }, [hostName, username, authToken, uaType, dispatch])\n\n // Manage reload events\n useEffect(() => {\n if (reload) {\n console.info('Socket reload requested')\n const { data } = store.getState().alerts\n const { forceReload } = store.getState().island\n\n // Check if socket is actually down using alerts (more reliable than socket.connected)\n const isSocketDown = data.socket_down?.active || false\n\n // Only reconnect if socket_down alert is active OR force reload is requested\n if (isSocketDown || forceReload) {\n console.info(\n forceReload\n ? 'Force reload requested, performing Socket reconnection'\n : 'Socket down detected (alert active), performing reconnection',\n )\n // Reset force reload flag\n if (forceReload) {\n store.dispatch.island.setForceReload(false)\n }\n // Clear the connection check interval to avoid stale ping timeouts during reconnection\n if (connectionCheckInterval.current) {\n clearInterval(connectionCheckInterval.current)\n connectionCheckInterval.current = null\n }\n // Disconnect and reconnect socket\n setTimeout(() => {\n socket.current.disconnect()\n socket.current.connect()\n // Execute the reloaded callback\n reloadedCallback()\n }, 100)\n } else {\n console.info('Socket already connected (no alert active), skipping reconnection')\n // Execute callback without reload\n reloadedCallback()\n }\n }\n }, [reload])\n\n return <>{children}</>\n}\n"],"names":["_a","hostName","username","authToken","reload","reloadedCallback","children","uaType","dispatch","useDispatch","connectionCheckInterval","useRef","socket","isUpdatingUserInfo","consecutivePingTimeouts","currentUserQueueCallPhase","summaryConversationCache","Map","activeTranscriptionIdsRef","linkedid","uniqueid","useEventListener","data","current","linkedId","uniqueId","emit","currentCall","updateCurrentCall","throughQueue","queueId","queueName","queueNumber","queuePosition","queueWaitingTime","useEffect","socketOptions","handleStreamingSource","conv","counterpartNum","isFromStreaming","island","setIsFromStreaming","streamingSourceNumber","sourceId","getStreamingSourceId","subscribe","id","catch","error","console","syncCurrentUserQueueCall","queueContext","getCurrentCallQueueContext","store","getState","queue","getCurrentCallQueuePayload","payload","conversationId","ownerExtension","owner","number","concat","getQueuePayloadWithFallback","Boolean","connected","_c","_d","phase","dispatchCurrentUserQueueCallConnected","_b","dispatchCurrentUserQueueCallWaiting","getConversationLinkedId","conversation","getConversationUniqueId","isSummaryConversationCandidate","selectSummaryConversationForHangup","extension","conversations","currentUser","extensionConversations","undefined","liveSelection","selectedConversationKey","selectedConversation","entries","Object","filter","keys","length","forEach","key","currentConversation","selectedIsSummaryCandidate","currentIsSummaryCandidate","selectedConnected","currentConnected","selectedStartTime","startTime","currentStartTime","count","selectLiveSummaryConversation","__assign","source","cacheAgeMs","hasConversationForCaller","liveConversationKeys","cached","get","Date","now","cachedAt","delete","getCachedSummaryConversation","handleCurrentUserEvents","res","transferring","transferSwitching","transferCalls","view","status","extensions_1","users","extensions","default_device","endpoints_1","endpoints","username_1","incoming","hasOnlineNethlink","userExtensions","values","ext","some","endpointExtension","find","endpoint","exten","type","accepted","currentOwnerExtension","shouldKeepCurrentAcceptedCall","checkIncomingUpdatePlay","displayName","getDisplayName","incomingSocket","setIslandView","getCurrentUserInfo","then","userInfo","updateCurrentUser","eventDispatch","settings","open_param_url","paramUrl","setOpenParamUrlType","finally","setTimeout","openParamUrlType","urlOpened","calculatedThroughTrunk","isFromTrunk","setThroughTrunk","setUrlOpened","counterpartName","throughTrunk","direction","chDest","chSource","checkAcceptedUpdate","acceptedSocket","addTransferCalls","getTimestampInSeconds","isPhysical","player","stopAudioPlayer","setAudioPlayerLoop","checkDefaultDeviceConversationActive","deleteTransferCalls","inTransferCalls","item","updateTransferSwitching","physicalRecorder","setRecordingTempVariable","checkOutgoingUpdate","outgoingSocket","outgoing","userTotallyFree","reset","upgrade","transports","reconnection","reconnectionDelay","getApiMode","path","io","websocket","update","on","debug","reason","clearInterval","includes","err","attempt","accessKeyId","token","setInterval","volatile","withTimeout","alerts","removeAlert","isStaleConnection","sipcall","webrtc","iceState","webrtcStuff","pc","iceConnectionState","timestamp","toISOString","warn","disconnect","setAlert","updateEndpointMainPresence","mainPresence","dispatchMainPresence","conference","isActive","conferenceStartedFrom","previewCallFromMobileOrNethlink","userExtensionIds","map","summaryExtension","callerNum","channelExten","connectedExtension","extensionType","conversationWasConnected","cause","toggleAvoidToShow","setPreviewCallFromMobileOrNethlink","resetConference","viewType","usersList","pendingUsers","hasConfirmedParticipants","hasPendingParticipants","_e","endpoints_2","username_2","userExtensionIds_1","_f","_g","isActive_1","conferenceStartedFrom_1","setOperatorBusyActive","callerNumber","updateStartAudioPlayer","src","busyRingtone","loop","_h","isActive_2","conferenceStartedFrom_2","username_3","_j","removePendingUser","extenConnected","updateExtension","deviceMap","userInformation","user","push","associatedExtensions","conversationKeys","isCurrentUserUpdate","set","isMobileExtensionCall","isEmpty","matchingExtension","dispatchExtensions","hasNonEmptyConversation","extConversations","dispatchConversations","updateConversations","updateQueue","activeConversation","dispatchQueueUpdate","updateQueueMember","dispatchQueueMemberUpdate","dispatchAlreadyLogin","dispatchServerReload","event","dispatchParkingUpdate","link","urlType","dispatchUrlCall","dispatchSummaryReady","display_name","display_number","message","isFromStreaming_2","toggleSideViewVisible","toggleTranscriptionViewVisible","dispatchVideoCallStarted","initiator","callUser","destUser","screenShare","isJoiningScreenShare","room","roomId","isLeavingScreenShare","dispatchDefaultDeviceUpdate","extensionInformations","objectComplete","updateCurrentDefaultDevice","checkMediaPermissions","conferenceId","conferenceUsers","usersList_1","updatedConferenceUsers_1","userId","muted","updateConferenceUsersList","updateConferenceId","voicemailInfo","streamingData","streaming","image","updateSourceImage","transcriptionData","active","chunkId","chunkLinkedId","matchesActive","close","info","forceReload","socket_down","setForceReload","connect","React","createElement","Fragment"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="@nethesis/phone-island",s="Nethesis",t="1.0.9-dev.6",i="NethVoice CTI Phone Island",r=["nethserver","nethesis","nethvoice","phone","island"],o="https://github.com/nethesis/phone-island#readme",n="https://github.com/nethesis/dev/issues",p={type:"git",url:"https://github.com/nethesis/phone-island.git"},l=["dist"],d="dist/index.js",a="dist/index.d.ts",c={access:"public"},m={main:!1,types:!1,default:{distDir:"./dist-widget"}},u={"@fortawesome/fontawesome-svg-core":"6.7.2","@fortawesome/free-solid-svg-icons":"6.7.2","@fortawesome/react-fontawesome":"0.2.6","@headlessui/react":"^2.2.8","@nethesis/nethesis-solid-svg-icons":"github:nethesis/Font-Awesome#ns-solid","@rematch/core":"^2.2.0","@rematch/immer":"^2.1.3","@rematch/select":"^3.1.2","@testing-library/jest-dom":"^5.11.4","@testing-library/user-event":"^12.1.10","framer-motion":"^12.0.0",i18next:"^22.4.9","i18next-browser-languagedetector":"^7.0.1","js-base64":"^3.7.3",lodash:"^4.17.21","mic-check":"^1.1.0",react:"^18.2.0","react-dom":"^18.2.0","react-i18next":"^12.1.5","react-moment":"^1.1.2","react-redux":"^8.0.5","react-tooltip":"^5.28.0","socket.io-client":"^4.5.3","styled-components":"^5.3.6","webrtc-adapter":"^9.0.1"},h={start:"npm run dev",dev:"node scripts/generate-dev-host.js && parcel .dev/phone-island-dev.html --port 6006 --open",test:"tsc --noEmit",watch:"rollup -w -c","watch:css":"BROWSERSLIST_IGNORE_OLD_DATA=1 npx tailwindcss -o ./dist/index.css --watch",build:"rm -rf ./dist && npm run build:css && rollup -c","build:css":"BROWSERSLIST_IGNORE_OLD_DATA=1 NODE_ENV=production npx tailwindcss -o ./dist/index.css --minify","build:win":"del /s /q dist && npm run build:wincss && rollup -c --configPlugin typescript","build:wincss":"set BROWSERSLIST_IGNORE_OLD_DATA=1 && set NODE_ENV=production && npx tailwindcss -o ./dist/index.css --minify","build:widget":"rm -rf ./dist-widget && parcel build ./src/index.widget.tsx --no-source-maps","serve:widget":"rm -rf ./widget-example/static/* && cp -rf ./dist-widget/* ./widget-example/static && npx http-server ./widget-example -o -c-1",release:"npm publish","release:widget":"node check-publish.js patch && npm version patch -m v%s",format:"prettier --write './**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc",bump:"node bump-version.js","build-pack":"npm run bump && npm run build && npm pack","build-pack:win":"npm run bump && npm run build:win && npm pack","publish:minor":"node check-publish.js minor && npm version minor --allow-same-version -m v%s --force","publish:major":"node check-publish.js major && npm version major --allow-same-version -m v%s --force","publish:patch":"node check-publish.js patch && npm version patch --allow-same-version -m v%s --force","publish:dev":"node publish-dev.js",preversion:"rm -rf dist-widget && npm run build:widget && git add dist-widget/index.widget.js dist-widget/index.widget.css && git commit -m 'chore(widget): release for jsDelivr'",postversion:"git push origin main --tags","revert-bump":"node revert-bump.js"},b={production:[">0.2%","not dead","not op_mini all"],development:["last 1 chrome version","last 1 firefox version","last 1 safari version"]},g={"@babel/core":"^7.20.2","@babel/preset-env":"^7.20.2","@parcel/transformer-typescript-types":"^2.8.0","@rollup/plugin-babel":"^6.0.2","@rollup/plugin-commonjs":"^23.0.2","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^15.0.1","@rollup/plugin-terser":"^0.4.4","@rollup/plugin-typescript":"^9.0.2","@testing-library/react":"^13.4.0","@types/audioworklet":"^0.0.100","@types/jest":"^29.2.2","@types/react":"^18.0.26","@types/react-dom":"^18.0.9","@types/styled-components":"^5.1.26",babel:"^6.23.0",buffer:"^5.7.1",parcel:"^2.0.0",postcss:"^8.4.49",prettier:"^2.8.0","prop-types":"^15.8.1",rollup:"^2.79.1","rollup-plugin-generate-package-json":"^3.2.0","rollup-plugin-postcss":"^4.0.2","tailwind-scrollbar":"^3.1.0",tailwindcss:"^3.4.16",typescript:"^4.8.4","webm-duration-fix":"^1.0.4",webpack:"^5.74.0"},v={"@tootallnate/once":"^3.0.0",esbuild:"^0.25.11","nth-check":"^2.0.1","serialize-javascript":"^7.0.0",tar:"^7.5.1"},w="GPL-3.0-or-later",x={name:e,author:s,version:t,description:i,keywords:r,homepage:o,bugs:n,repository:p,private:!1,files:l,main:d,types:a,publishConfig:c,targets:m,dependencies:u,scripts:h,browserslist:b,devDependencies:g,overrides:v,license:w};exports.author=s,exports.browserslist=b,exports.bugs=n,exports.default=x,exports.dependencies=u,exports.description=i,exports.devDependencies=g,exports.files=l,exports.homepage=o,exports.keywords=r,exports.license=w,exports.main=d,exports.name=e,exports.overrides=v,exports.publishConfig=c,exports.repository=p,exports.scripts=h,exports.targets=m,exports.types=a,exports.version=t;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="@nethesis/phone-island",s="Nethesis",t="1.0.9-dev.7",i="NethVoice CTI Phone Island",r=["nethserver","nethesis","nethvoice","phone","island"],o="https://github.com/nethesis/phone-island#readme",n="https://github.com/nethesis/dev/issues",p={type:"git",url:"https://github.com/nethesis/phone-island.git"},l=["dist"],d="dist/index.js",a="dist/index.d.ts",c={access:"public"},m={main:!1,types:!1,default:{distDir:"./dist-widget"}},u={"@fortawesome/fontawesome-svg-core":"6.7.2","@fortawesome/free-solid-svg-icons":"6.7.2","@fortawesome/react-fontawesome":"0.2.6","@headlessui/react":"^2.2.8","@nethesis/nethesis-solid-svg-icons":"github:nethesis/Font-Awesome#ns-solid","@rematch/core":"^2.2.0","@rematch/immer":"^2.1.3","@rematch/select":"^3.1.2","@testing-library/jest-dom":"^5.11.4","@testing-library/user-event":"^12.1.10","framer-motion":"^12.0.0",i18next:"^22.4.9","i18next-browser-languagedetector":"^7.0.1","js-base64":"^3.7.3",lodash:"^4.17.21","mic-check":"^1.1.0",react:"^18.2.0","react-dom":"^18.2.0","react-i18next":"^12.1.5","react-moment":"^1.1.2","react-redux":"^8.0.5","react-tooltip":"^5.28.0","socket.io-client":"^4.5.3","styled-components":"^5.3.6","webrtc-adapter":"^9.0.1"},h={start:"npm run dev",dev:"node scripts/generate-dev-host.js && parcel .dev/phone-island-dev.html --port 6006 --open",test:"tsc --noEmit",watch:"rollup -w -c","watch:css":"BROWSERSLIST_IGNORE_OLD_DATA=1 npx tailwindcss -o ./dist/index.css --watch",build:"rm -rf ./dist && npm run build:css && rollup -c","build:css":"BROWSERSLIST_IGNORE_OLD_DATA=1 NODE_ENV=production npx tailwindcss -o ./dist/index.css --minify","build:win":"del /s /q dist && npm run build:wincss && rollup -c --configPlugin typescript","build:wincss":"set BROWSERSLIST_IGNORE_OLD_DATA=1 && set NODE_ENV=production && npx tailwindcss -o ./dist/index.css --minify","build:widget":"rm -rf ./dist-widget && parcel build ./src/index.widget.tsx --no-source-maps","serve:widget":"rm -rf ./widget-example/static/* && cp -rf ./dist-widget/* ./widget-example/static && npx http-server ./widget-example -o -c-1",release:"npm publish","release:widget":"node check-publish.js patch && npm version patch -m v%s",format:"prettier --write './**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc",bump:"node bump-version.js","build-pack":"npm run bump && npm run build && npm pack","build-pack:win":"npm run bump && npm run build:win && npm pack","publish:minor":"node check-publish.js minor && npm version minor --allow-same-version -m v%s --force","publish:major":"node check-publish.js major && npm version major --allow-same-version -m v%s --force","publish:patch":"node check-publish.js patch && npm version patch --allow-same-version -m v%s --force","publish:dev":"node publish-dev.js",preversion:"rm -rf dist-widget && npm run build:widget && git add dist-widget/index.widget.js dist-widget/index.widget.css && git commit -m 'chore(widget): release for jsDelivr'",postversion:"git push origin main --tags","revert-bump":"node revert-bump.js"},b={production:[">0.2%","not dead","not op_mini all"],development:["last 1 chrome version","last 1 firefox version","last 1 safari version"]},g={"@babel/core":"^7.20.2","@babel/preset-env":"^7.20.2","@parcel/transformer-typescript-types":"^2.8.0","@rollup/plugin-babel":"^6.0.2","@rollup/plugin-commonjs":"^23.0.2","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^15.0.1","@rollup/plugin-terser":"^0.4.4","@rollup/plugin-typescript":"^9.0.2","@testing-library/react":"^13.4.0","@types/audioworklet":"^0.0.100","@types/jest":"^29.2.2","@types/react":"^18.0.26","@types/react-dom":"^18.0.9","@types/styled-components":"^5.1.26",babel:"^6.23.0",buffer:"^5.7.1",parcel:"^2.0.0",postcss:"^8.4.49",prettier:"^2.8.0","prop-types":"^15.8.1",rollup:"^2.79.1","rollup-plugin-generate-package-json":"^3.2.0","rollup-plugin-postcss":"^4.0.2","tailwind-scrollbar":"^3.1.0",tailwindcss:"^3.4.16",typescript:"^4.8.4","webm-duration-fix":"^1.0.4",webpack:"^5.74.0"},v={"@tootallnate/once":"^3.0.0",esbuild:"^0.25.11","nth-check":"^2.0.1","serialize-javascript":"^7.0.0",tar:"^7.5.1"},w="GPL-3.0-or-later",x={name:e,author:s,version:t,description:i,keywords:r,homepage:o,bugs:n,repository:p,private:!1,files:l,main:d,types:a,publishConfig:c,targets:m,dependencies:u,scripts:h,browserslist:b,devDependencies:g,overrides:v,license:w};exports.author=s,exports.browserslist=b,exports.bugs=n,exports.default=x,exports.dependencies=u,exports.description=i,exports.devDependencies=g,exports.files=l,exports.homepage=o,exports.keywords=r,exports.license=w,exports.main=d,exports.name=e,exports.overrides=v,exports.publishConfig=c,exports.repository=p,exports.scripts=h,exports.targets=m,exports.types=a,exports.version=t;
2
2
  //# sourceMappingURL=package.json.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","sources":["../../src/services/user.ts"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport { store } from '../store'\nimport type { UserInfoTypes, AvatarsTypes, UsersEndpointsTypes } from '../types'\n\n/**\n * Get current user info\n */\nexport async function getCurrentUserInfo(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/me`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function setDefaultDevice(\n default_type: string,\n extensionNumber: string,\n): Promise<any> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n\n let webrtcId: any = { id: extensionNumber }\n let physicalId: any = { id: extensionNumber }\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: default_type === 'physical' ? JSON.stringify(physicalId) : JSON.stringify(webrtcId),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\n/**\n * Get all avatars\n */\nexport async function getAllAvatars(): Promise<AvatarsTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n\n const response = await fetch(`${baseURL}/user/all_avatars`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\n/**\n * Get all users endpoints\n */\nexport async function getAllUsersEndpoints(): Promise<UsersEndpointsTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/endpoints/all`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function changeOperatorStatus(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/presence`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function changeDefaultDevice(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function setMainDevice(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\n/**\n * Get parameter URL information\n */\nexport async function getParamUrl(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/paramurl`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function getVideoSources(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/sources`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function openVideoSource(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/open`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function subscribe(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/subscribe`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function unsubscribe(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/unsubscribe`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function setIncomingCallsPreference(settingsStatus: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/settings`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(settingsStatus),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n const contentType = response.headers.get('content-type')\n if (contentType && contentType.includes('application/json')) {\n const text = await response.text()\n return text ? JSON.parse(text) : {}\n }\n\n return { success: true }\n } catch (error: any) {\n console.error('Error updating user settings:', error)\n throw error\n }\n}\n\n/**\n * Get feature codes\n */\nexport async function getFeatureCodes(): Promise<any> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/astproxy/feature_codes`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\n/**\n * Check if a call summary/transcription exists for a given uniqueid\n * Returns: { has_summary: boolean }\n * Throws:\n * - Error with status 204 when the summary is not ready yet.\n * - Error with the corresponding HTTP status code for any other non-200 response\n * (including, but not limited to, 401, 403, 404, 503).\n */\nexport async function checkSummaryCall(uniqueid: string, linkedid?: string): Promise<void> {\n const { baseURL, headers } = store.getState().fetchDefaults\n const queryString = linkedid ? `?linkedid=${encodeURIComponent(linkedid)}` : ''\n const url = `${baseURL}/summary/${uniqueid}${queryString}`\n const response = await fetch(url, {\n method: 'HEAD',\n headers: { ...headers },\n })\n\n // 200 - Summary exists\n if (response.status === 200) {\n return\n }\n\n // 204 - Summary not present yet (not an error, just not ready)\n if (response.status === 204) {\n const error: any = new Error('Summary not ready')\n error.status = 204\n throw error\n }\n\n // 401, 403, 404, 503 - Real errors\n const error: any = new Error(`Failed to check summary: ${response.statusText}`)\n error.status = response.status\n throw error\n}\n\n/**\n * Watch for call summary/transcription for a given linkedid and uniqueid.\n * If uniqueid differs from linkedid (e.g. queue call), both are sent.\n */\nexport async function watchSummaryCall(linkedid: string, uniqueid: string): Promise<void> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const url = `${baseURL}/summary/watch`\n const response = await fetch(url, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify({ linkedid, uniqueid }),\n })\n if (!response.ok) {\n throw new Error(`Failed to watch summary call: ${response.status} ${response.statusText}`)\n }\n } catch (error: any) {\n console.error('Error watching summary call:', error)\n throw error\n }\n}\n"],"names":["obj","_a","store","getState","fetchDefaults","baseURL","headers","fetch","concat","method","__assign","body","JSON","stringify","response","_b","sent","ok","Error","statusText","uniqueid","linkedid","queryString","encodeURIComponent","url","status","error_15","error","json","error_3","error_4","error_1","error_14","error_8","error_9","default_type","extensionNumber","webrtcId","id","physicalId","error_2","settingsStatus","contentType","get","includes","text","parse","success","console","error_13","error_16"],"mappings":"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"}
1
+ {"version":3,"file":"user.js","sources":["../../src/services/user.ts"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport { store } from '../store'\nimport type { UserInfoTypes, AvatarsTypes, UsersEndpointsTypes } from '../types'\n\n/**\n * Get current user info\n */\nexport async function getCurrentUserInfo(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/me`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function setDefaultDevice(\n default_type: string,\n extensionNumber: string,\n): Promise<any> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n\n let webrtcId: any = { id: extensionNumber }\n let physicalId: any = { id: extensionNumber }\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: default_type === 'physical' ? JSON.stringify(physicalId) : JSON.stringify(webrtcId),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\n/**\n * Get all avatars\n */\nexport async function getAllAvatars(): Promise<AvatarsTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n\n const response = await fetch(`${baseURL}/user/all_avatars`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\n/**\n * Get all users endpoints\n */\nexport async function getAllUsersEndpoints(): Promise<UsersEndpointsTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/endpoints/all`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function changeOperatorStatus(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/presence`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function changeDefaultDevice(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function setMainDevice(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/default_device`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\n/**\n * Get parameter URL information\n */\nexport async function getParamUrl(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/paramurl`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function getVideoSources(): Promise<UserInfoTypes | undefined> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/sources`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\nexport async function openVideoSource(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/open`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function subscribe(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/subscribe`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function unsubscribe(obj: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/streaming/unsubscribe`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(obj),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n return true\n } catch (error: any) {\n throw error\n }\n}\n\nexport async function setIncomingCallsPreference(settingsStatus: any) {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/user/settings`, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify(settingsStatus),\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n\n const contentType = response.headers.get('content-type')\n if (contentType && contentType.includes('application/json')) {\n const text = await response.text()\n return text ? JSON.parse(text) : {}\n }\n\n return { success: true }\n } catch (error: any) {\n console.error('Error updating user settings:', error)\n throw error\n }\n}\n\n/**\n * Get feature codes\n */\nexport async function getFeatureCodes(): Promise<any> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const response = await fetch(`${baseURL}/astproxy/feature_codes`, {\n headers: { ...headers },\n })\n if (!response.ok) {\n throw new Error(response.statusText)\n }\n const data = await response.json()\n return data\n } catch (error: any) {\n throw new Error(error)\n }\n}\n\n/**\n * Check if a call summary/transcription exists for a given uniqueid.\n * Resolves (returns void) when the summary exists (HTTP 200).\n * Throws:\n * - Error with status 204 when the summary is not ready yet.\n * - Error with the corresponding HTTP status code for any other non-200 response\n * (including, but not limited to, 401, 403, 404, 503).\n */\nexport async function checkSummaryCall(uniqueid: string, linkedid?: string): Promise<void> {\n const { baseURL, headers } = store.getState().fetchDefaults\n const queryString = linkedid ? `?linkedid=${encodeURIComponent(linkedid)}` : ''\n const url = `${baseURL}/summary/${uniqueid}${queryString}`\n const response = await fetch(url, {\n method: 'HEAD',\n headers: { ...headers },\n })\n\n // 200 - Summary exists\n if (response.status === 200) {\n return\n }\n\n // 204 - Summary not present yet (not an error, just not ready)\n if (response.status === 204) {\n const error: any = new Error('Summary not ready')\n error.status = 204\n throw error\n }\n\n // 401, 403, 404, 503 - Real errors\n const error: any = new Error(`Failed to check summary: ${response.statusText}`)\n error.status = response.status\n throw error\n}\n\n/**\n * Watch for call summary/transcription for a given linkedid and uniqueid.\n * If uniqueid differs from linkedid (e.g. queue call), both are sent.\n */\nexport async function watchSummaryCall(linkedid: string, uniqueid: string): Promise<void> {\n try {\n const { baseURL, headers } = store.getState().fetchDefaults\n const url = `${baseURL}/summary/watch`\n const response = await fetch(url, {\n method: 'POST',\n headers: { ...headers },\n body: JSON.stringify({ linkedid, uniqueid }),\n })\n if (!response.ok) {\n throw new Error(`Failed to watch summary call: ${response.status} ${response.statusText}`)\n }\n } catch (error: any) {\n console.error('Error watching summary call:', error)\n throw error\n }\n}\n"],"names":["obj","_a","store","getState","fetchDefaults","baseURL","headers","fetch","concat","method","__assign","body","JSON","stringify","response","_b","sent","ok","Error","statusText","uniqueid","linkedid","queryString","encodeURIComponent","url","status","error_15","error","json","error_3","error_4","error_1","error_14","error_8","error_9","default_type","extensionNumber","webrtcId","id","physicalId","error_2","settingsStatus","contentType","get","includes","text","parse","success","console","error_13","error_16"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nethesis/phone-island",
3
3
  "author": "Nethesis",
4
- "version": "1.0.9-dev.6",
4
+ "version": "1.0.9-dev.7",
5
5
  "description": "NethVoice CTI Phone Island",
6
6
  "keywords": [
7
7
  "nethserver",